Create a Flash game like Deflection
Multipart tutorial: available parts 1, 2, 3
Today I spent some time with a game called Deflection.
According to his author, it’s an addictive physics based game where the objective is to deflect the ball into the goal by creating deflection walls.
I bet I scared most of you with the word “physics”. This means a physics engine, massive AS3 coding, and so on.
Although I am seriously determined to start a tutorial series about latest physics engines, I played a bit with Deflection and I noticed the only physics involved in the game is used to determine the bounce of a regular shape (a circle – the ball) when collides with a line.
So I thought there was another way to create an engine like this one without using physics libraries.
The answer lies in an old vector tutorial made by Tony Pa called Ball in the corner.
I suggest you to read all Tony’s vector tutorials to understand the math behind the engine.
I made some changes to the tutorial in order to make it more “AS2 like” (it’s an old AS1 tutorial) and to manage an arbitrary number of lines.
In this step you will only see the engine working with 4 lines and no user interaction, but it’s really easy to add lines at runtime with the mouse (I’ll cover it in the next step).
Moreover, this is another good example about how to use a Flash game tutorial to make your own game.
Ok, now it’s time to show you the modified actionscript:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
// create game object game = {gravity:0, dragging:false, clip:_root.game_mc, stageW:500, stageH:400, maxV:20}; // create object // point p0 is its starting point in the coordinates x/y _root.attachMovie("ball", "ball", 1); game.myOb = {clip:ball, airf:1, b:1, f:1, r:20, lastTime:getTimer()}; game.myOb.p0 = {x:150, y:80}; // vectors x/y components game.myOb.vx = 8; game.myOb.vy = 12; // create first vector // point p0 is its starting point in the coordinates x/y // point p1 is its end point in the coordinates x/y game.v = new Array(); game.v[0] = {p0:{x:50, y:40}, p1:{x:450, y:40}, b:1, f:1}; game.v[1] = {p0:{x:50, y:40}, p1:{x:50, y:360}, b:1, f:1}; game.v[2] = {p0:{x:50, y:360}, p1:{x:450, y:360}, b:1, f:1}; game.v[3] = {p0:{x:100, y:80}, p1:{x:400, y:320}, b:1, f:1}; _root.createEmptyMovieClip("lines", 2); lines.lineStyle(1, 0xff0000); // draw and calculate all parameters for the wall vectors for (x=0; x<game.v.length; x++) { lines.moveTo(game.v[x].p0.x, game.v[x].p0.y); lines.lineTo(game.v[x].p1.x, game.v[x].p1.y); updateVector(game.v[x], true); } _root.onEnterFrame = function() { _root.runMe(); }; // function to draw the points, lines and show text function drawAll(v) { // place ob mc v.clip._x = v.p1.x; v.clip._y = v.p1.y; } // main function function runMe() { // start to calculate movement var ob = game.myOb; // add air resistance ob.vx *= ob.airf; ob.vy *= ob.airf; // dont let it go over max speed if (ob.vx>game.maxV) { ob.vx = game.maxV; } else if (ob.vx<-game.maxV) { ob.vx = -game.maxV; } if (ob.vy>game.maxV) { ob.vy = game.maxV; } else if (ob.vy<-game.maxV) { ob.vy = -game.maxV; } // update the vector parameters updateObject(ob); // check the walls for collisions for (x=0; x<game.v.length; x++) { var w = game.v[x]; var v = findIntersection(ob, w); v = updateVector(v, false); var pen = ob.r-v.len; // if we have hit the wall if (pen>=0) { // move object away from the wall ob.p1.x += v.dx*pen; ob.p1.y += v.dy*pen; // change movement, bounce off from the normal of v var vbounce = {dx:v.lx, dy:v.ly, lx:v.dx, ly:v.dy, b:1, f:1}; var vb = bounce(ob, vbounce); ob.vx = vb.vx; ob.vy = vb.vy; } } // reset object to other side if gone out of stage if (ob.p1.x>game.stageW+ob.r) { ob.p1.x = -ob.r; } else if (ob.p1.x<-ob.r) { ob.p1.x = game.stageW+ob.r; } if (ob.p1.y>game.stageH+ob.r) { ob.p1.y = -ob.r; } else if (ob.p1.y<-ob.r) { ob.p1.y = game.stageH+ob.r; } // draw it drawAll(ob); // make end point equal to starting point for next cycle ob.p0 = ob.p1; // save the movement without time ob.vx = ob.vx/ob.timeFrame; ob.vy = ob.vy/ob.timeFrame; } // function to find all parameters for the vector function updateVector(v, frompoints) { // x and y components if (frompoints) { v.vx = v.p1.x-v.p0.x; v.vy = v.p1.y-v.p0.y; } else { v.p1.x = v.p0.x+v.vx; v.p1.y = v.p0.y+v.vy; } // length of vector v.len = Math.sqrt(v.vx*v.vx+v.vy*v.vy); // normalized unti-sized components if (v.len>0) { v.dx = v.vx/v.len; v.dy = v.vy/v.len; } else { v.dx = 0; v.dy = 0; } // right hand normal v.rx = -v.dy; v.ry = v.dx; // left hand normal v.lx = v.dy; v.ly = -v.dx; return v; } function updateObject(v) { // find time passed from last update var thisTime = getTimer(); var time = (thisTime-v.lastTime)/100; // we use time, not frames to move so multiply movement vector with time passed v.vx *= time; v.vy *= time; // add gravity, also based on time v.vy = v.vy+time*game.gravity; v.p1 = {}; // find end point coordinates v.p1.x = v.p0.x+v.vx; v.p1.y = v.p0.y+v.vy; // length of vector v.len = Math.sqrt(v.vx*v.vx+v.vy*v.vy); // normalized unti-sized components v.dx = v.vx/v.len; v.dy = v.vy/v.len; // right hand normal v.rx = -v.vy; v.ry = v.vx; // left hand normal v.lx = v.vy; v.ly = -v.vx; // save the current time v.lastTime = thisTime; // save time passed v.timeFrame = time; } // find intersection point of 2 vectors function findIntersection(v1, v2) { // vector between center of ball and starting point of wall var v3 = {}; v3.vx = v1.p1.x-v2.p0.x; v3.vy = v1.p1.y-v2.p0.y; // check if we have hit starting point var dp = v3.vx*v2.dx+v3.vy*v2.dy; if (dp<0) { // hits starting point var v = v3; } else { var v4 = {}; v4.vx = v1.p1.x-v2.p1.x; v4.vy = v1.p1.y-v2.p1.y; // check if we have hit side or endpoint var dp = v4.vx*v2.dx+v4.vy*v2.dy; if (dp>0) { // hits ending point var v = v4; } else { // it hits the wall // project this vector on the normal of the wall var v = projectVector(v3, v2.lx, v2.ly); } } return v; } // find new vector bouncing from v2 function bounce(v1, v2) { // projection of v1 on v2 var proj1 = projectVector(v1, v2.dx, v2.dy); // projection of v1 on v2 normal var proj2 = projectVector(v1, v2.lx, v2.ly); var proj = {}; // reverse projection on v2 normal proj2.len = Math.sqrt(proj2.vx*proj2.vx+proj2.vy*proj2.vy); proj2.vx = v2.lx*proj2.len; proj2.vy = v2.ly*proj2.len; // add the projections proj.vx = v1.f*v2.f*proj1.vx+v1.b*v2.b*proj2.vx; proj.vy = v1.f*v2.f*proj1.vy+v1.b*v2.b*proj2.vy; return proj; } // project vector v1 on unit-sized vector dx/dy function projectVector(v1, dx, dy) { // find dot product var dp = v1.vx*dx+v1.vy*dy; var proj = {}; // projection components proj.vx = dp*dx; proj.vy = dp*dy; return proj; } |
and this is the result… your own AS2 deflection engine ready for you to create a game.
If you want to write the code for player interaction, I will be happy to publish it, otherwise wait for me to do it.
Download the source code and enjoy.
Multipart tutorial: available parts 1, 2, 3
They can be easily customized to meet the unique requirements of your project.






(28 votes, average: 4.36 out of 5)








This post has 14 comments
CatFurnace
“I am seriously determined to start a tutorial series about latest physics engines” – Please do this! I’m very keen to learn either Box2D AS3 or APE, but can’t get over the first hurdle.
An Emanuele Tutorial is just what I need!
Very exciting news.
Emanuele Cipolloni
Yes I guess the word “physics” scares the vast majority of developers, my self included!
Very nice article and very interesting blog!
FrozenHaddock
An Emanuele tutorial on Box2DAS3 would be perfect.
This looks snazzy too, looking forward to the next part!
Josh Dura
Um, correct me if I am wrong, but this isn’t AS2 :) You aren’t even typing your variables. Don’t get me wrong, it’s fairly well structured AS1, but I just don’t see how this is AS2.
Kaolin Fire
Thanks for the link to the vector tutorials. The graphics really made things click faster than otherwise :)
D&G
Thank you,learning…..
ssusnic
Hi all,
You can find the source code of my implementation for the player interaction as an addition to this
tutorial at my website
http://www.askforgametask.com !
Jack Hopkins
Did any of you guys hear? APE has been discontinued (physics….)
Create a Flash game like Deflection - part 2 : Emanuele Feronato - italian geek and PROgrammer
[...] the 1st part I showed you how to make a deflection engine starting from an old tutorial, now it’s time to let [...]
Web-Game Magazine - the best free action/adventure web games and casual games, reviewed daily » Blog Archive » Create a Flash game like Deflection - part 2
[...] the 1st part I showed you how to make a deflection engine starting from an old tutorial, now it’s time to [...]
Chicen
The game looks a lot like inkball (http://en.wikipedia.org/wiki/Inkball)
Create a Flash game like Deflection - part 3 : Emanuele Feronato - italian geek and PROgrammer
[...] tutorial: available parts 1, 2, [...]
ithkul
always loved your work mr.Feronato. you inspired me lots.
to “CatFurnace”.. you like box2D? download the source for this and play around with it (you might wanna look at this too mr.Feronato):
http://www.actionscript.org/resources/articles/742/1/Physics-in-ActionScript-30/Page1.html#postedcomment
Adobe Flash Tutorials Part 2
[...] Deflection game where the objective is to deflect the ball into the goal by creating deflection walls. [...]