Create a Flash game like Deflection

Multipart tutorial: available parts 1, 2, 3

Today I spent some time with a game called Deflection.

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:

ACTIONSCRIPT:
  1. // create game object
  2. game = {gravity:0, dragging:false, clip:_root.game_mc, stageW:500, stageH:400, maxV:20};
  3. // create object
  4. // point p0 is its starting point in the coordinates x/y
  5. _root.attachMovie("ball", "ball", 1);
  6. game.myOb = {clip:ball, airf:1, b:1, f:1, r:20, lastTime:getTimer()};
  7. game.myOb.p0 = {x:150, y:80};
  8. // vectors x/y components
  9. game.myOb.vx = 8;
  10. game.myOb.vy = 12;
  11. // create first vector
  12. // point p0 is its starting point in the coordinates x/y
  13. // point p1 is its end point in the coordinates x/y
  14. game.v = new Array();
  15. game.v[0] = {p0:{x:50, y:40}, p1:{x:450, y:40}, b:1, f:1};
  16. game.v[1] = {p0:{x:50, y:40}, p1:{x:50, y:360}, b:1, f:1};
  17. game.v[2] = {p0:{x:50, y:360}, p1:{x:450, y:360}, b:1, f:1};
  18. game.v[3] = {p0:{x:100, y:80}, p1:{x:400, y:320}, b:1, f:1};
  19. _root.createEmptyMovieClip("lines", 2);
  20. lines.lineStyle(1, 0xff0000);
  21. // draw and calculate all parameters for the wall vectors
  22. for (x=0; x<game.v.length; x++) {
  23.     lines.moveTo(game.v[x].p0.x, game.v[x].p0.y);
  24.     lines.lineTo(game.v[x].p1.x, game.v[x].p1.y);
  25.     updateVector(game.v[x], true);
  26. }
  27. _root.onEnterFrame = function() {
  28.     _root.runMe();
  29. };
  30. // function to draw the points, lines and show text
  31. function drawAll(v) {
  32.     // place ob mc
  33.     v.clip._x = v.p1.x;
  34.     v.clip._y = v.p1.y;
  35. }
  36. // main function
  37. function runMe() {
  38.     // start to calculate movement 
  39.     var ob = game.myOb;
  40.     // add air resistance
  41.     ob.vx *= ob.airf;
  42.     ob.vy *= ob.airf;
  43.     // dont let it go over max speed
  44.     if (ob.vx>game.maxV) {
  45.         ob.vx = game.maxV;
  46.     } else if (ob.vx<-game.maxV) {
  47.         ob.vx = -game.maxV;
  48.     }
  49.     if (ob.vy>game.maxV) {
  50.         ob.vy = game.maxV;
  51.     } else if (ob.vy<-game.maxV) {
  52.         ob.vy = -game.maxV;
  53.     }
  54.     // update the vector parameters       
  55.     updateObject(ob);
  56.     // check the walls for collisions
  57.     for (x=0; x<game.v.length; x++) {
  58.         var w = game.v[x];
  59.         var v = findIntersection(ob, w);
  60.         v = updateVector(v, false);
  61.         var pen = ob.r-v.len;
  62.         // if we have hit the wall
  63.         if (pen>=0) {
  64.             // move object away from the wall
  65.             ob.p1.x += v.dx*pen;
  66.             ob.p1.y += v.dy*pen;
  67.             // change movement, bounce off from the normal of v
  68.             var vbounce = {dx:v.lx, dy:v.ly, lx:v.dx, ly:v.dy, b:1, f:1};
  69.             var vb = bounce(ob, vbounce);
  70.             ob.vx = vb.vx;
  71.             ob.vy = vb.vy;
  72.         }
  73.     }
  74.     // reset object to other side if gone out of stage
  75.     if (ob.p1.x>game.stageW+ob.r) {
  76.         ob.p1.x = -ob.r;
  77.     } else if (ob.p1.x<-ob.r) {
  78.         ob.p1.x = game.stageW+ob.r;
  79.     }
  80.     if (ob.p1.y>game.stageH+ob.r) {
  81.         ob.p1.y = -ob.r;
  82.     } else if (ob.p1.y<-ob.r) {
  83.         ob.p1.y = game.stageH+ob.r;
  84.     }
  85.     // draw it       
  86.     drawAll(ob);
  87.     // make end point equal to starting point for next cycle
  88.     ob.p0 = ob.p1;
  89.     // save the movement without time
  90.     ob.vx = ob.vx/ob.timeFrame;
  91.     ob.vy = ob.vy/ob.timeFrame;
  92. }
  93. // function to find all parameters for the vector
  94. function updateVector(v, frompoints) {
  95.     // x and y components
  96.     if (frompoints) {
  97.         v.vx = v.p1.x-v.p0.x;
  98.         v.vy = v.p1.y-v.p0.y;
  99.     } else {
  100.         v.p1.x = v.p0.x+v.vx;
  101.         v.p1.y = v.p0.y+v.vy;
  102.     }
  103.     // length of vector
  104.     v.len = Math.sqrt(v.vx*v.vx+v.vy*v.vy);
  105.     // normalized unti-sized components
  106.     if (v.len>0) {
  107.         v.dx = v.vx/v.len;
  108.         v.dy = v.vy/v.len;
  109.     } else {
  110.         v.dx = 0;
  111.         v.dy = 0;
  112.     }
  113.     // right hand normal
  114.     v.rx = -v.dy;
  115.     v.ry = v.dx;
  116.     // left hand normal
  117.     v.lx = v.dy;
  118.     v.ly = -v.dx;
  119.     return v;
  120. }
  121. function updateObject(v) {
  122.     // find time passed from last update
  123.     var thisTime = getTimer();
  124.     var time = (thisTime-v.lastTime)/100;
  125.     // we use time, not frames to move so multiply movement vector with time passed
  126.     v.vx *= time;
  127.     v.vy *= time;
  128.     // add gravity, also based on time
  129.     v.vy = v.vy+time*game.gravity;
  130.     v.p1 = {};
  131.     // find end point coordinates
  132.     v.p1.x = v.p0.x+v.vx;
  133.     v.p1.y = v.p0.y+v.vy;
  134.     // length of vector
  135.     v.len = Math.sqrt(v.vx*v.vx+v.vy*v.vy);
  136.     // normalized unti-sized components
  137.     v.dx = v.vx/v.len;
  138.     v.dy = v.vy/v.len;
  139.     // right hand normal
  140.     v.rx = -v.vy;
  141.     v.ry = v.vx;
  142.     // left hand normal
  143.     v.lx = v.vy;
  144.     v.ly = -v.vx;
  145.     // save the current time
  146.     v.lastTime = thisTime;
  147.     // save time passed
  148.     v.timeFrame = time;
  149. }
  150. // find intersection point of 2 vectors
  151. function findIntersection(v1, v2) {
  152.     // vector between center of ball and starting point of wall
  153.     var v3 = {};
  154.     v3.vx = v1.p1.x-v2.p0.x;
  155.     v3.vy = v1.p1.y-v2.p0.y;
  156.     // check if we have hit starting point
  157.     var dp = v3.vx*v2.dx+v3.vy*v2.dy;
  158.     if (dp<0) {
  159.         // hits starting point
  160.         var v = v3;
  161.     } else {
  162.         var v4 = {};
  163.         v4.vx = v1.p1.x-v2.p1.x;
  164.         v4.vy = v1.p1.y-v2.p1.y;
  165.         // check if we have hit side or endpoint
  166.         var dp = v4.vx*v2.dx+v4.vy*v2.dy;
  167.         if (dp>0) {
  168.             // hits ending point
  169.             var v = v4;
  170.         } else {
  171.             // it hits the wall
  172.             // project this vector on the normal of the wall
  173.             var v = projectVector(v3, v2.lx, v2.ly);
  174.         }
  175.     }
  176.     return v;
  177. }
  178. // find new vector bouncing from v2
  179. function bounce(v1, v2) {
  180.     // projection of v1 on v2
  181.     var proj1 = projectVector(v1, v2.dx, v2.dy);
  182.     // projection of v1 on v2 normal
  183.     var proj2 = projectVector(v1, v2.lx, v2.ly);
  184.     var proj = {};
  185.     // reverse projection on v2 normal
  186.     proj2.len = Math.sqrt(proj2.vx*proj2.vx+proj2.vy*proj2.vy);
  187.     proj2.vx = v2.lx*proj2.len;
  188.     proj2.vy = v2.ly*proj2.len;
  189.     // add the projections
  190.     proj.vx = v1.f*v2.f*proj1.vx+v1.b*v2.b*proj2.vx;
  191.     proj.vy = v1.f*v2.f*proj1.vy+v1.b*v2.b*proj2.vy;
  192.     return proj;
  193. }
  194. // project vector v1 on unit-sized vector dx/dy
  195. function projectVector(v1, dx, dy) {
  196.     // find dot product
  197.     var dp = v1.vx*dx+v1.vy*dy;
  198.     var proj = {};
  199.     // projection components
  200.     proj.vx = dp*dx;
  201.     proj.vy = dp*dy;
  202.     return proj;
  203. }

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

Improve the blog rating this post
Tell me what do you think about this post. I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (25 votes, average: 4.28 out of 5)
Loading ... Loading ...

» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

14 Responses to “Create a Flash game like Deflection”

  1. CatFurnace on July 9th, 2008 12:34 pm

    “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.

  2. Emanuele Cipolloni on July 9th, 2008 1:19 pm

    Yes I guess the word “physics” scares the vast majority of developers, my self included!

    Very nice article and very interesting blog!

  3. FrozenHaddock on July 9th, 2008 3:22 pm

    An Emanuele tutorial on Box2DAS3 would be perfect.

    This looks snazzy too, looking forward to the next part!

  4. Josh Dura on July 9th, 2008 5:10 pm

    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.

  5. Kaolin Fire on July 10th, 2008 7:02 am

    Thanks for the link to the vector tutorials. The graphics really made things click faster than otherwise :)

  6. D&G on July 10th, 2008 9:59 am

    Thank you,learning…..

  7. ssusnic on July 10th, 2008 5:52 pm

    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 !

  8. Jack Hopkins on July 10th, 2008 9:49 pm

    Did any of you guys hear? APE has been discontinued (physics….)

  9. Chicen on July 24th, 2008 6:09 pm

    The game looks a lot like inkball (http://en.wikipedia.org/wiki/Inkball)

  10. ithkul on August 7th, 2008 2:48 pm

    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

Leave a Reply




Trackbacks

  1. Create a Flash game like Deflection - part 2 : Emanuele Feronato - italian geek and PROgrammer on July 12th, 2008 1:09 pm

    [...] the 1st part I showed you how to make a deflection engine starting from an old tutorial, now it’s time to let [...]

  2. 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 on July 14th, 2008 8:59 pm

    [...] the 1st part I showed you how to make a deflection engine starting from an old tutorial, now it’s time to [...]

  3. Create a Flash game like Deflection - part 3 : Emanuele Feronato - italian geek and PROgrammer on July 25th, 2008 6:47 pm

    [...] tutorial: available parts 1, 2, [...]

  4. Adobe Flash Tutorials Part 2 on September 9th, 2008 4:25 am

    [...] Deflection game where the objective is to deflect the ball into the goal by creating deflection walls. [...]