• home
  • forum
  • my
  • kt
  • download
  • Home / 2D Graphics / Flash / Games /

    Create a Flash ball game with visual from above

    Author: 2008-10-06 09:00:39 From:

    This tutorial does not cover anything new (well, this first part of this tutorial) but shows you how to create a Flash ball game with a visual from above and some decent graphics.

    Being a ball game, I suggest you all to read the basics for a ball game movement in this tutorial.

    In this one, there is no gravity but the method is the same.

    In this tutorial I'll cover two types of gameplay: one with the ball that runs on a static stage, and one with a fixed ball with a scrolling stage. We'll see the pros and cons of both type of games.

    First of all, let's start with the aim of the game: you have to take your ball to the exit of each level avoiding any kind of traps.

    In this first part, there isn't any exit nor traps, just walkable tiles. So, at the moment the game will sound like "try not to fall off the tiles".

    Game type 1: moving ball on a static stage

    PLAIN TEXT
    ACTIONSCRIPT:
    1. level = new Array();
    2. _root.attachMovie("starz", "starz", 1);
    3. _root.createEmptyMovieClip("bricks", 2);
    4. level[0] = new Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
    5. level[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1);
    6. level[2] = new Array(1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1);
    7. level[3] = new Array(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1);
    8. level[4] = new Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    9. level[5] = new Array(1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);
    10. level[6] = new Array(1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1);
    11. level[7] = new Array(1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1);
    12. level[8] = new Array(1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1);
    13. level[9] = new Array(1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1);
    14. level[10] = new Array(0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1);
    15. for (y=0; y<=10; y++) {
    16.     for (x=0; x<=11; x++) {
    17.         if (level[y][x] == 1) {
    18.             place_brick = bricks.attachMovie("brick", "brick_"+bricks.getNextHighestDepth(), bricks.getNextHighestDepth(), {_x:x*40+30, _y:y*40+30});
    19.         }
    20.     }
    21. }
    22. _root.attachMovie("ball", "ball", _root.getNextHighestDepth(), {_x:30, _y:30});
    23. ball.texture.setMask(ball.ball_itself);
    24. power = 0.4;
    25. yspeed = 0;
    26. xspeed = 0;
    27. friction = 0.99;
    28. ball.onEnterFrame = function() {
    29.     if (Key.isDown(Key.LEFT)) {
    30.         xspeed -= power;
    31.     }
    32.     if (Key.isDown(Key.RIGHT)) {
    33.         xspeed += power;
    34.     }
    35.     if (Key.isDown(Key.UP)) {
    36.         yspeed -= power;
    37.     }
    38.     if (Key.isDown(Key.DOWN)) {
    39.         yspeed += power;
    40.     }
    41.     xspeed *= friction;
    42.     yspeed *= friction;
    43.     this._y += yspeed;
    44.     this._x += xspeed;
    45.     this.texture._y += yspeed;
    46.     this.texture._x += xspeed;
    47.     if (this.texture._x>53) {
    48.         this.texture._x -= 63;
    49.     }
    50.     if (this.texture._x<-53) {
    51.         this.texture._x += 63;
    52.     }
    53.     if (this.texture._y>53) {
    54.         this.texture._y -= 63;
    55.     }
    56.     if (this.texture._y<-53) {
    57.         this.texture._y += 63;
    58.     }
    59.     brick_x = Math.floor((this._x-10)/40);
    60.     brick_y = Math.floor((this._y-10)/40);
    61.     if (level[brick_y][brick_x]!=1) {
    62.         this._x = 30;
    63.         this._y = 30;
    64.         xspeed = 0;
    65.         yspeed = 0;
    66.     }
    67. };

    Does it look too long? I guess not, because you'll see how easy it can be if you follow all the steps.

    Line 1: Declaration of level, the array that contains level data. Levels in this game will be tile based. I wrote a tutorial about managing the creation of tile based levels here.

    Line 2: Attaching the movie previoulsy created and linkaged as starz. The space scene you can see in the background. I made the scene with the Photoshop action to create an outer space scene.

    Line 3: Creating a new empty movie clip (bricks) that will contain level tiles.

    Lines 4-14: Defining the mapping of the level. In this case, the ones mean a walkable tile while the zeros a hole. You cannot walk over holes.

    Lines 15-21: Scanning all the array and attaching movieclips previously linkaged as brick into the bricks movieclip (the one created at line 3). As said, refer to this tutorial for more information.

    Line 22: Attaching the ball. I created the ball in the same way as in Creation of realistic spheres in Flash with textures and masking tutorial.

    Line 23: Masking the ball texture as explained in the tutorial mentioned above. I strongly suggest you to read if you haven't done it yet, you will learn how to create proper textures for a ball and map them to it with masking.

    Lines 24-27: Defining power, speed and friction as explained in here. Being a game with the visual from above, there is no gravity, and at the moment there is no wind too.

    Line 28: This is the main function, to be called at every frame.

    Lines 29-40: Adjusting ball x and y speed according to the key the player presses, as seen here (maybe one day I'll write an ebook and say "as seen in Chapter I" - cool).

    Lines 41-42: Applying friction to x and y speed.

    Lines 43-44: Adjusting ball position according to its speed.

    Lines 45-58: Adjusting texture position to simulate the rolling effect as seen here.

    Line 59: Determining, according to ball x position, on wich x-tile we are. I need to know the ball position inside the level array because in next tutorial I will introduce special tiles. In the formula I involved the ball radius (10) and tile size (40).

    Line 60: Same thing with y position.

    Lines 61-66: If the position of the ball in level array is different than 1 (solid tile) then start the death sequence: the ball is moved ad its starting position and both x and y speeds are set to zero.

    That's it! Wasn't it easy?

    This is the game

    The second step is making the tiles bigger (otherwise the game may be frustrating) and have a larger, scrollable stage.

    To have a scrollable background, the ball must remail fixed in the center of the stage, and the level must move, like in this tutorial.

    Game type 2: static ball on a moving stage

    PLAIN TEXT
    ACTIONSCRIPT:
    1. level = new Array();
    2. _root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
    3. _root.createEmptyMovieClip("bricks", 2);
    4. level[0] = new Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
    5. level[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1);
    6. level[2] = new Array(1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1);
    7. level[3] = new Array(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1);
    8. level[4] = new Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    9. level[5] = new Array(1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);
    10. level[6] = new Array(1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1);
    11. level[7] = new Array(1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1);
    12. level[8] = new Array(1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1);
    13. level[9] = new Array(1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1);
    14. level[10] = new Array(0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1);
    15. for (y=0; y<=10; y++) {
    16.     for (x=0; x<=11; x++) {
    17.         if (level[y][x] == 1) {
    18.             place_brick = bricks.attachMovie("brick", "brick_"+bricks.getNextHighestDepth(), bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
    19.         }
    20.     }
    21. }
    22. _root.attachMovie("ball", "ball", _root.getNextHighestDepth(), {_x:240, _y:220});
    23. bricks._x = 240;
    24. bricks._y = 220;
    25. ball.texture.setMask(ball.ball_itself);
    26. power = 0.4;
    27. yspeed = 0;
    28. xspeed = 0;
    29. friction = 0.99;
    30. ball.onEnterFrame = function() {
    31.     if (Key.isDown(Key.LEFT)) {
    32.         xspeed -= power;
    33.     }
    34.     if (Key.isDown(Key.RIGHT)) {
    35.         xspeed += power;
    36.     }
    37.     if (Key.isDown(Key.UP)) {
    38.         yspeed -= power;
    39.     }
    40.     if (Key.isDown(Key.DOWN)) {
    41.         yspeed += power;
    42.     }
    43.     xspeed *= friction;
    44.     yspeed *= friction;
    45.     bricks._y -= yspeed;
    46.     bricks._x -= xspeed;
    47.     starz._x = -20+((bricks._x-240)/10);
    48.     starz._y = -20+((bricks._y-220)/10);
    49.     this.texture._y += yspeed;
    50.     this.texture._x += xspeed;
    51.     if (this.texture._x>53) {
    52.         this.texture._x -= 63;
    53.     }
    54.     if (this.texture._x<-53) {
    55.         this.texture._x += 63;
    56.     }
    57.     if (this.texture._y>53) {
    58.         this.texture._y -= 63;
    59.     }
    60.     if (this.texture._y<-53) {
    61.         this.texture._y += 63;
    62.     }
    63.     brick_x = Math.floor((bricks._x-200)/80)*-1;
    64.     brick_y = Math.floor((bricks._y-180)/80)*-1;
    65.     if (level[brick_y][brick_x] != 1) {
    66.         bricks._x = 240;
    67.         bricks._y = 220;
    68.         starz._x = -20;
    69.         starz._y = -20;
    70.         xspeed = 0;
    71.         yspeed = 0;
    72.     }
    73. };

    Main changes are at lines 45-46 where I move the bricks movieclip instead of ball one, and 47-48 where I add a little parallax scrolling to background space scene.

    Ball's position on the level, at lines 63-64, is no long determined by ball position but by bricks position, since the ball is fixed.

    And this is the game. I prefer this version.

    And this is where this tutorial ends.

    Next step will be to create different types of tiles, each with its way to affect ball movement, and a level editor.

    Now I need your creativity: suggest me a type of tile I haven't already planned and your name will be in the credits.

    Planned tiles at the moment are:

    Icy/Sand/etc tiles: Affect ball friction

    Left/Right/Up/Down spinning tiles: Increasing left/right/up/down ball speed

    Glass tiles: Disappear once the ball has rolled out of them

    Crystal tiles: Disappear once the ball has rolled on them (so move fast!)

    Tunnel tiles: You can't see the ball because it's under the tunnel...

    Spinning tiles: Increase ball speed in the direction the ball rolled on them

    Invert tiles: Ball controls are inverted while on these tiles

    Teleport tiles: ... need an explication?

    Exit tile: ...

    Now it's up to you.

    Take the source codes and give me feedback.

    December 13th update: 3rd part released
    January 16th update: 4th part released

    This is the second part of the tutorial about the creation of a Flash ball game with visual from above.

    I suggest you to read part 1 before reading this post. Here I will start adding features to our game as said in the I Had to do it post.

    Let's start with the creation of the first, and most important, tile:

    Exit tile

    Well, an exit tile means there is an exit, and if there is an exit there is another level, and if there is another level I need a way to code levels.

    I stored all levels in a function, in this way:

    PLAIN TEXT
    ACTIONSCRIPT:
    1. function draw_level(number) {
    2.     level = new Array();
    3.     switch (number) {
    4.     case 1 :
    5.         _root.ball_start_x = 0;
    6.         _root.ball_start_y = 0;
    7.         level[0] = new Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
    8.         level[1] = new Array(1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1);
    9.         level[2] = new Array(1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1);
    10.         level[3] = new Array(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1);
    11.         level[4] = new Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    12.         level[5] = new Array(1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);
    13.         level[6] = new Array(1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1);
    14.         level[7] = new Array(1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1);
    15.         level[8] = new Array(1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1);
    16.         level[9] = new Array(1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1);
    17.         level[10] = new Array(0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1);
    18.         break;
    19.     case 2 :
    20.         _root.ball_start_x = 0;
    21.         _root.ball_start_y = 0;
    22.         level[0] = new Array(1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0);
    23.         level[1] = new Array(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1);
    24.         level[2] = new Array(1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1);
    25.         level[3] = new Array(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1);
    26.         level[4] = new Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    27.         level[5] = new Array(1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1);
    28.         level[6] = new Array(1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1);
    29.         level[7] = new Array(1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1);
    30.         level[8] = new Array(1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1);
    31.         level[9] = new Array(1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1);
    32.         level[10] = new Array(0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1);
    33.         break;
    34.     }
    35.     _root.createEmptyMovieClip("bricks", 2);
    36.     bricks._x = 240-(80*ball_start_x);
    37.     bricks._y = 220-(80*ball_start_y);
    38.     for (y=0; y<=10; y++) {
    39.         for (x=0; x<=11; x++) {
    40.             if (level[y][x]>0) {
    41.                 depth = y*12+x;
    42.                 place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
    43.                 place_brick.gotoAndStop(level[y][x]);
    44.             }
    45.         }
    46.     }
    47. }

    The function accepts one parameter, that will be the level number. In this two-level game, the switch at line 3 loads level 1 (lines 4-18) or level 2 (lines 19-33).

    You will notice at lines 5, 6, 20 and 21 two new declarations. ball_start_x and ball_start_y store the starting vertical and horizontal position of the ball in the level.

    Lines 36-37 Places the ground according to ball_start_y and ball_start_x position. Remember that in this game the ball remain fixed in the middle of the screen while the background is scrolling.

    The rest of the code is explained at part 1, except for line 43 that I will explain later.

    Now we have more than 1 level. As much as 2!!

    Before we proceed, let me introduce another feature you will get a lot familiar with:

    The dead

    Since there are several ways to die, I need a function to call everytime the player dies.

    PLAIN TEXT
    ACTIONSCRIPT:
    1. function ball_die() {
    2.     bricks._x = 240-(80*_root.ball_start_x);
    3.     bricks._y = 220-(80*_root.ball_start_y);
    4.     xspeed = 0;
    5.     yspeed = 0;
    6.     draw_level(lev);
    7. }

    It's very easy... when the player dies, the ball position is restored to its initial position and both xspeed and yspeed are set to zero. Then redraws the level.

    Very, very easy.

    Now it's time to explain how to design tiles.

    Look at this picture:

    As you can see, the brick movieclip has several frames (10 in the example). Every frame contains a brick type, and has a stop(); in it to... ehm... stop it at the current frame. Now it should be clear why I wrote that line 43 in the level drawing function: I goto and stop the brick instance according to the value stored in the level array.

    Now it's time to design some nasty levels and explain how does it work.

    In this tutorial, I'll design levels 5 bricks tall and 5 bricks wide, but there is (almost) no limit to levels size you can create.

    It's interesting anyway the complexity of some levels, even if so small.

    Here it is the actionscript, all in the 1st frame as real PROs...

    PLAIN TEXT
    ACTIONSCRIPT:
    1. _root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
    2. _root.attachMovie("ball", "ball", 3, {_x:240, _y:220});
    3. ball.texture.setMask(ball.ball_itself);
    4. yspeed = 0;
    5. xspeed = 0;
    6. lev = 1;
    7. draw_level(lev);
    8. ball.onEnterFrame = function() {
    9.     friction = 0.99;
    10.     power = 0.4;
    11.     brick_x = Math.floor((bricks._x-200)/80)*-1;
    12.     brick_y = Math.floor((bricks._y-180)/80)*-1;
    13.     type_of_tile = level[brick_y][brick_x];
    14.     switch (type_of_tile) {
    15.     case 1 :
    16.         // normal tile
    17.         break;
    18.     case 2 :
    19.         // down spin tile
    20.         yspeed += 0.2;
    21.         break;
    22.     case 3 :
    23.         // up spin tile
    24.         yspeed -= 0.2;
    25.         break;
    26.     case 4 :
    27.         // left spin tile
    28.         xspeed -= 0.2;
    29.         break;
    30.     case 5 :
    31.         // right spin tile
    32.         xspeed += 0.2;
    33.         break;
    34.     case 6 :
    35.         // glass tile
    36.         depth = brick_y*12+brick_x;
    37.         bricks["brick_"+depth]._alpha--;
    38.         if (bricks["brick_"+depth]._alpha<1) {
    39.             level[brick_y][brick_x] = 0;
    40.         }
    41.         break;
    42.     case 7 :
    43.         // spin tile
    44.         xspeed *= 1.05;
    45.         yspeed *= 1.05;
    46.         break;
    47.     case 8 :
    48.         // slip tile
    49.         friction = 1;
    50.         power = 0;
    51.         break;
    52.     case 9 :
    53.         // beam
    54.         depth = brick_y*12+brick_x;
    55.         if (bricks["brick_"+depth].lava._currentframe>90) {
    56.             ball_die();
    57.         }
    58.         break;
    59.     case 10 :
    60.         // exit
    61.         lev++;
    62.         _root.removeMovieClip("bricks");
    63.         draw_level(lev);
    64.         break;
    65.     default :
    66.         // hole
    67.         ball_die();
    68.         break;
    69.     }
    70.     if (Key.isDown(Key.LEFT)) {
    71.         xspeed -= power;
    72.     }
    73.     if (Key.isDown(Key.RIGHT)) {
    74.         xspeed += power;
    75.     }
    76.     if (Key.isDown(Key.UP)) {
    77.         yspeed -= power;
    78.     }
    79.     if (Key.isDown(Key.DOWN)) {
    80.         yspeed += power;
    81.     }
    82.     xspeed *= friction;
    83.     yspeed *= friction;
    84.     if ((xspeed<0.1) and (xspeed>-0.1)) {
    85.         xspeed = 0;
    86.     }
    87.     if ((yspeed<0.1) and (yspeed>-0.1)) {
    88.         yspeed = 0;
    89.     }
    90.     bricks._y -= yspeed;
    91.     bricks._x -= xspeed;
    92.     starz._x = -20+((bricks._x-240)/10);
    93.     starz._y = -20+((bricks._y-220)/10);
    94.     this.texture._y += yspeed;
    95.     this.texture._x += xspeed;
    96.     if (this.texture._x>53) {
    97.         this.texture._x -= 63;
    98.     }
    99.     if (this.texture._x<-53) {
    100.         this.texture._x += 63;
    101.     }
    102.     if (this.texture._y>53) {
    103.         this.texture._y -= 63;
    104.     }
    105.     if (this.texture._y<-53) {
    106.         this.texture._y += 63;
    107.     }
    108. };
    109. function ball_die() {
    110.     bricks._x = 240-(80*_root.ball_start_x);
    111.     bricks._y = 220-(80*_root.ball_start_y);
    112.     xspeed = 0;
    113.     yspeed = 0;
    114.     draw_level(lev);
    115. }
    116. function draw_level(number) {
    117.     level = new Array();
    118.     switch (number) {
    119.     case 1 :
    120.         _root.ball_start_x = 0;
    121.         _root.ball_start_y = 0;
    122.         level[0] = new Array(1, 1, 1, 1, 10);
    123.         level[1] = new Array(0, 0, 0, 0, 0);
    124.         level[2] = new Array(0, 0, 0, 0, 0);
    125.         level[3] = new Array(0, 0, 0, 0, 0);
    126.         level[4] = new Array(0, 0, 0, 0, 0);
    127.         break;
    128.     case 2 :
    129.         _root.ball_start_x = 0;
    130.         _root.ball_start_y = 0;
    131.         level[0] = new Array(1, 4, 4, 5, 0);
    132.         level[1] = new Array(0, 0, 0, 1, 0);
    133.         level[2] = new Array(0, 0, 0, 1, 0);
    134.         level[3] = new Array(0, 0, 0, 10, 0);
    135.         level[4] = new Array(0, 0, 0, 0, 0);
    136.         break;
    137.     case 3 :
    138.         _root.ball_start_x = 0;
    139.         _root.ball_start_y = 0;
    140.         level[0] = new Array(1, 6, 6, 4, 0);
    141.         level[1] = new Array(0, 0, 0, 6, 0);
    142.         level[2] = new Array(6, 5, 5, 6, 0);
    143.         level[3] = new Array(6, 0, 0, 0, 0);
    144.         level[4] = new Array(1, 1, 10, 0, 0);
    145.         break;
    146.     case 4 :
    147.         _root.ball_start_x = 0;
    148.         _root.ball_start_y = 0;
    149.         level[0] = new Array(1, 7, 0, 0, 0);
    150.         level[1] = new Array(0, 7, 0, 7, 10);
    151.         level[2] = new Array(1, 3, 0, 1, 0);
    152.         level[3] = new Array(1, 0, 0, 1, 0);
    153.         level[4] = new Array(1, 1, 1, 7, 0);
    154.         break;
    155.     case 5 :
    156.         _root.ball_start_x = 4;
    157.         _root.ball_start_y = 2;
    158.         level[0] = new Array(7, 8, 8, 8, 10);
    159.         level[1] = new Array(1, 0, 0, 0, 0);
    160.         level[2] = new Array(1, 8, 8, 3, 1);
    161.         level[3] = new Array(0, 0, 0, 0, 0);
    162.         level[4] = new Array(0, 0, 0, 0, 0);
    163.         break;
    164.     case 6 :
    165.         _root.ball_start_x = 2;
    166.         _root.ball_start_y = 2;
    167.         level[0] = new Array(2, 8, 9, 8, 9);
    168.         level[1] = new Array(9, 0, 0, 0, 1);
    169.         level[2] = new Array(2, 8, 1, 0, 3);
    170.         level[3] = new Array(0, 0, 0, 0, 4);
    171.         level[4] = new Array(10, 9, 9, 8, 6);
    172.         break;
    173.     case 7 :
    174.         _root.ball_start_x = 2;
    175.         _root.ball_start_y = 2;
    176.         level[0] = new Array(0, 0, 0, 0, 0);
    177.         level[1] = new Array(0, 0, 0, 0, 0);
    178.         level[2] = new Array(0, 0, 1, 0, 0);
    179.         level[3] = new Array(0, 0, 0, 0, 0);
    180.         level[4] = new Array(0, 0, 0, 0, 0);
    181.         break;
    182.     }
    183.     _root.createEmptyMovieClip("bricks", 2);
    184.     bricks._x = 240-(80*ball_start_x);
    185.     bricks._y = 220-(80*ball_start_y);
    186.     for (y=0; y<=4; y++) {
    187.         for (x=0; x<=4; x++) {
    188.             if (level[y][x]>0) {
    189.                 depth = y*12+x;
    190.                 place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
    191.                 place_brick.gotoAndStop(level[y][x]);
    192.             }
    193.         }
    194.     }
    195. }

    I am going to explain in detail only new features. Read step 1 if you do not understand some code.

    Lines 1-2: Attaching stars and ball movieclips

    Line 3: Masking the ball as explained in Creation of realistic spheres in Flash with textures and masking.

    Lines 4-5: Setting ball's x and y speeds to zero

    Line 6: Set starting level at 1. Don't cheat!!!

    Line 7: Calling function to draw levels

    Line 8: Beginning of the code to be executed to the ball at every frame

    Lines 9-10: Defining friction and power as explained in Flash game creation tutorial - part 1

    Lines 11-12: Determining the position of the ball in the level array according to brick movieclip position.

    Some explication of those strange numbers:

    80: brick width or height
    200: movieclip width (500) divided by 2 (500/2=250) minus the half of the brick width or height (250-80/2=210) minus the radius of the ball (10)
    180: same thing with movieclip height

    Actually, the radius of the ball should not affect ball position but the ball is not in the precise centre of the stage, just radius pixel moved up-left. Why did I do this? Dunno, will be fixed in next tut :)

    Line 13: Obtaining the tile type where the ball is rolling on

    Line 14: Beginning of code to be executed according to tile type.

    Lines 15-17: Normal tile - do nothing

    Lines 18-21: Down spinning tile: increase y speed.

    Lines 22-33: Up, Left and Right spinning tiles: same thing for the Down spinning tile, adjusting x and y speeds according to the direction to be spinned

    Lines 34-41: Glass tile, start breaking once the ball is on it. The actionscript simply decrease the _alpha value of the ball, and once it reaches zero set the array at this position to zero (hole)

    Lines 42-46: Spin tile, multiplies actual x and y speeds

    Lines 47-51: Slippery tile, setting the friction at 1 and the power at zero means that you can't control the ball that will continue running at the same speed on the same direction!

    Lines 52-58: Laser beam tile: this tile is a movieclip that changes its color once every 90 frames and lasts 30 frames. When the tile is highlighted, it's deadly. To determine if the tile is in its deadly status, I simply check its current frame. If it's bigger than 90... ZZZZAP!

    Lines 59-64: Your friend, the exit! Increases lev (the actual level), removes the old level from stage and draws the new one

    Lines 65-68: Default tile... I mean no tile... hole... death... avoid it!

    Lines 70-108: "Engine" of the game, the same explained in part 1.

    Lines 109-115: Death routine, explained above

    Lines 116-195: Level creation routine, with 6 levels (and an "end" level).

    Try to finish the game!

    And this is where part 2 ends. There are tons of new features waiting to be explained during next tutorial... all your suggestion will be included... suggest and get credited in the final game!

    Meanwhile, thanks to Fairlyn (slippery tile) and Frederik J (lava tile, in this game converted in beam tile).

    Download the source code and give me feedback.

    In the third part of this tutorial I am going to fix a minor bug and introduce three new tiles:

    info tile (displays a message when the ball rolls over it)
    reverse control tile (reverses the controls of the ball)
    checkpoint tile (makes you respawn at the checkpoint tile if you die)

    Before continuing, I suggest you to read tutorials 1 and 2.

    The actionscript of the last example has changed to:

    PLAIN TEXT
    ACTIONSCRIPT:
    1. _root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
    2. _root.attachMovie("ball", "ball", 3, {_x:240, _y:220});
    3. _root.attachMovie("info_panel", "info_panel", 4, {_y:410, _alpha:50, _visible:false});
    4. ball.texture.setMask(ball.ball_itself);
    5. yspeed = 0;
    6. xspeed = 0;
    7. checkpoint_passed = false;
    8. lev = 1;
    9. draw_level(lev);
    10. ball.onEnterFrame = function() {
    11.     info_panel._visible = false;
    12.     friction = 0.99;
    13.     power = 0.4;
    14.     brick_x = Math.floor((bricks._x-200)/80)*-1;
    15.     brick_y = Math.floor((bricks._y-180)/80)*-1;
    16.     type_of_tile = level[brick_y][brick_x];
    17.     if (type_of_tile>12000) {
    18.         message_to_show = messages[type_of_tile%12000];
    19.         type_of_tile = 12;
    20.     }
    21.     switch (type_of_tile) {
    22.     case 1 :
    23.         // normal tile
    24.         break;
    25.     case 2 :
    26.         // down spin tile
    27.         yspeed += 0.2;
    28.         break;
    29.     case 3 :
    30.         // up spin tile
    31.         yspeed -= 0.2;
    32.         break;
    33.     case 4 :
    34.         // left spin tile
    35.         xspeed -= 0.2;
    36.         break;
    37.     case 5 :
    38.         // right spin tile
    39.         xspeed += 0.2;
    40.         break;
    41.     case 6 :
    42.         // glass tile
    43.         depth = brick_y*12+brick_x;
    44.         bricks["brick_"+depth]._alpha--;
    45.         if (bricks["brick_"+depth]._alpha<1) {
    46.             level[brick_y][brick_x] = 0;
    47.         }
    48.         break;
    49.     case 7 :
    50.         // spin tile
    51.         xspeed *= 1.05;
    52.         yspeed *= 1.05;
    53.         break;
    54.     case 8 :
    55.         // slip tile
    56.         friction = 1;
    57.         power = 0;
    58.         break;
    59.     case 9 :
    60.         // beam
    61.         depth = brick_y*12+brick_x;
    62.         if (bricks["brick_"+depth].lava._currentframe>90) {
    63.             ball_die();
    64.         }
    65.         break;
    66.     case 10 :
    67.         // exit
    68.         checkpoint_passed = false;
    69.         lev++;
    70.         _root.removeMovieClip("bricks");
    71.         draw_level(lev);
    72.         break;
    73.     case 11 :
    74.         // reverse
    75.         power *= -1;
    76.         break;
    77.     case 12 :
    78.         // info
    79.         info_panel._visible = true;
    80.         info_panel.message_text.text = message_to_show;
    81.         break;
    82.     case 13 :
    83.         //checkpoint
    84.         checkpoint_passed = true;
    85.         save_x = brick_x;
    86.         save_y = brick_y;
    87.         break;
    88.     default :
    89.         // hole
    90.         ball_die();
    91.         break;
    92.     }
    93.     if (Key.isDown(Key.LEFT)) {
    94.         xspeed -= power;
    95.     }
    96.     if (Key.isDown(Key.RIGHT)) {
    97.         xspeed += power;
    98.     }
    99.     if (Key.isDown(Key.UP)) {
    100.         yspeed -= power;
    101.     }
    102.     if (Key.isDown(Key.DOWN)) {
    103.         yspeed += power;
    104.     }
    105.     xspeed *= friction;
    106.     yspeed *= friction;
    107.     if ((xspeed<0.1) and (xspeed>-0.1)) {
    108.         xspeed = 0;
    109.     }
    110.     if ((yspeed<0.1) and (yspeed>-0.1)) {
    111.         yspeed = 0;
    112.     }
    113.     bricks._y -= yspeed;
    114.     bricks._x -= xspeed;
    115.     starz._x = -20+((bricks._x-240)/10);
    116.     starz._y = -20+((bricks._y-220)/10);
    117.     this.texture._y += yspeed;
    118.     this.texture._x += xspeed;
    119.     if (this.texture._x>53) {
    120.         this.texture._x -= 63;
    121.     }
    122.     if (this.texture._x<-53) {
    123.         this.texture._x += 63;
    124.     }
    125.     if (this.texture._y>53) {
    126.         this.texture._y -= 63;
    127.     }
    128.     if (this.texture._y<-53) {
    129.         this.texture._y += 63;
    130.     }
    131. };
    132. function ball_die() {
    133.     bricks._x = 240-(80*_root.ball_start_x);
    134.     bricks._y = 220-(80*_root.ball_start_y);
    135.     xspeed = 0;
    136.     yspeed = 0;
    137.     draw_level(lev);
    138. }
    139. function draw_level(number) {
    140.     yspeed = 0;
    141.     xspeed = 0;
    142.     level = new Array();
    143.     messages = new Array();
    144.     switch (number) {
    145.     case 1 :
    146.         _root.ball_start_x = 0;
    147.         _root.ball_start_y = 0;
    148.         if (checkpoint_passed) {
    149.             _root.ball_start_x = save_x;
    150.             _root.ball_start_y = save_y;
    151.         }
    152.         level[0] = new Array(12001, 11, 11, 11, 11);
    153.         level[1] = new Array(0, 0, 0, 0, 1);
    154.         level[2] = new Array(1, 1, 10, 0, 1);
    155.         level[3] = new Array(1, 0, 0, 0, 1);
    156.         level[4] = new Array(12003, 1, 1, 13, 12002);
    157.         messages[1] = "Welcome to the game";
    158.         messages[2] = "You are about to cross a checkpoint";
    159.         messages[3] = "Ok. Now suicide! You'll respawn on the checkpoint";
    160.         break;
    161.     case 2 :
    162.         _root.ball_start_x = 0;
    163.         _root.ball_start_y = 0;
    164.         level[0] = new Array(1, 4, 4, 5, 0);
    165.         level[1] = new Array(0, 0, 0, 1, 0);
    166.         level[2] = new Array(0, 0, 0, 1, 0);
    167.         level[3] = new Array(0, 0, 0, 10, 0);
    168.         level[4] = new Array(0, 0, 0, 0, 0);
    169.         break;
    170.     case 3 :
    171.         _root.ball_start_x = 0;
    172.         _root.ball_start_y = 0;
    173.         level[0] = new Array(1, 6, 6, 4, 0);
    174.         level[1] = new Array(0, 0, 0, 6, 0);
    175.         level[2] = new Array(6, 5, 5, 6, 0);
    176.         level[3] = new Array(6, 0, 0, 0, 0);
    177.         level[4] = new Array(1, 1, 10, 0, 0);
    178.         break;
    179.     case 4 :
    180.         _root.ball_start_x = 0;
    181.         _root.ball_start_y = 0;
    182.         level[0] = new Array(1, 7, 0, 0, 0);
    183.         level[1] = new Array(0, 7, 0, 7, 10);
    184.         level[2] = new Array(1, 3, 0, 1, 0);
    185.         level[3] = new Array(1, 0, 0, 1, 0);
    186.         level[4] = new Array(1, 1, 1, 7, 0);
    187.         break;
    188.     case 5 :
    189.         _root.ball_start_x = 4;
    190.         _root.ball_start_y = 2;
    191.         level[0] = new Array(7, 8, 8, 8, 10);
    192.         level[1] = new Array(1, 0, 0, 0, 0);
    193.         level[2] = new Array(1, 8, 8, 3, 1);
    194.         level[3] = new Array(0, 0, 0, 0, 0);
    195.         level[4] = new Array(0, 0, 0, 0, 0);
    196.         break;
    197.     case 6 :
    198.         _root.ball_start_x = 2;
    199.         _root.ball_start_y = 2;
    200.         level[0] = new Array(2, 8, 9, 8, 9);
    201.         level[1] = new Array(9, 0, 0, 0, 1);
    202.         level[2] = new Array(2, 8, 1, 0, 3);
    203.         level[3] = new Array(0, 0, 0, 0, 4);
    204.         level[4] = new Array(10, 9, 9, 8, 6);
    205.         break;
    206.     case 7 :
    207.         _root.ball_start_x = 2;
    208.         _root.ball_start_y = 2;
    209.         level[0] = new Array(0, 0, 0, 0, 0);
    210.         level[1] = new Array(0, 0, 0, 0, 0);
    211.         level[2] = new Array(0, 0, 1, 0, 0);
    212.         level[3] = new Array(0, 0, 0, 0, 0);
    213.         level[4] = new Array(0, 0, 0, 0, 0);
    214.         break;
    215.     }
    216.     _root.createEmptyMovieClip("bricks", 2);
    217.     bricks._x = 240-(80*ball_start_x);
    218.     bricks._y = 220-(80*ball_start_y);
    219.     for (y=0; y<=4; y++) {
    220.         for (x=0; x<=4; x++) {
    221.             if (level[y][x]>0) {
    222.                 depth = y*12+x;
    223.                 place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
    224.                 frame_to_stop = level[y][x];
    225.                 if (frame_to_stop>12000) {
    226.                     frame_to_stop = 12;
    227.                 }
    228.                 place_brick.gotoAndStop(frame_to_stop);
    229.             }
    230.         }
    231.     }
    232. }

    Let's comment the new lines:

    Line 3: Attaching the info_panel object (the panel that will show the messages when the ball rolls over it) and making it invisible

    Line 7: Creating a new variable to know if the player passed a checkpoint or not, and setting it to false by default

    Line 11: Making the info panel object invisible. This may seems redundant since I alredy set it as invisible at line 3, but consider that this line is inserted into a routine to be executed at every time (so it's redundant line 3...)

    Lines 17-20: To understand this code, you must know how did I manage message tiles. Message tiles are tiles at number 12, but in the level array I assign a value of 12000+x where x is the id of the message. As an example, if a value in the level array is 12045, it meas that it's a tile of type 12 (info tile) with the message 45. That's what is done with this set of lines: if a value is greater than 12000, then assign 12 to type_of_tile value and type_of_tile%12000 (even if type_of_tile-12000 would be better) to the message_to_show variable

    Lines 73-76: Code for the reverse controls tile (tile 11): simply multiplies power by -1

    Lines 77-81: Code for the info panel tile (tile 12). Setting the info panel to visibile and assigning the dynamic text

    Lines 82-87: Code for the checkpoint tile (tile 13): setting the checkpoint_passed variable to true and saving the current x and y tile position in save_x and save_y variables.

    Lines 140-141: Reset the speed when a level is initialized. This will prevent the ball to mantain its speed when the player passes the level

    Lines 157-159: Messages to display

    Lines 225-227: If the tile number is greater than 12000, then setting the frame to stop in the tiles movieclip to 12

    I am about to publish a complete game with a lot of more tiles, obviously I am releasing a full tutorial.

    Meanwhile, download the source of this one

    In the 4th part I am going to explain a feature that a race game must have: the laps

    Read steps 1, 2 and 3 before continuing

    Having laps in a track will result in a longer race.

    The bad thing is that if you don't design laps with some more actionscript than normally required, your players will cheat.

    Look at the picture:

    We have our track with 12 tiles with a clockwise direction. Assuming that you will start from 1, you should race through 1-2-3-4-5-6-7-8-9-A-B-C then 1 again in order to make a lap.

    So when the ball rolls over C, it's a new lap.

    Wrong.

    A cheater could move this way: 1-C-1-C-1 and he already completed 2 laps.

    At this point, you would put an intermediate lap, let's say at tile 7, and check that the intermediate lap has been passed before rolling over C. Now the player will have to drive through 1-2-3-4-5-6-7 but... let's say the second part of the track is hardest than the first... he could make 1-2-3-4-5-6-7-6-5-4-3-2-1-C completing a lap without passing over 8-9-10-A-B, the hard part of the track.

    To prevent this, you can put some "one way" tiles... if the tile 1 can be passed only from left to right, there is no way for the player to make 1-C because the game won't allow it... but in some cases I would need to make 1-C, maybe he needs more speed to pass a certain tile (let's say 3) and he founds himself at 2 without speed. He would need to make 2-1-C-B-C-1-2-3...

    If you try to solve the lap problem this way, the player won't be able to do 1-C to gain speed

    Well, what about placing another intermediate lap, let's say at A, so the player must pass over 7, then A and then C?

    This may work, unless the path from A to C is harder than A to 1... so you may place an intermediate lap on B... and you end with an intermediate lap at every tile.

    My solution allows to manage laps with only three tiles, one next to another. Let's say C-1-2

    The player will pass a lap when he rolls over C-1-2 but only if he never passed over tile 1 more than once. This means that a 1-C-1-2 does not count as a lap because he passed over the 1 twice.

    Let's see some actionscript: basically it's the same as Create a Flash ball game with visual from above tutorial part 3 so I will comment only the new lines

    PLAIN TEXT
    ACTIONSCRIPT:
    1. _root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
    2. _root.attachMovie("ball", "ball", 3, {_x:240, _y:220});
    3. _root.attachMovie("info_panel", "info_panel", 4, {_y:410, _alpha:50, _visible:false});
    4. _root.attachMovie("lap", "lap", 5);
    5. ball.texture.setMask(ball.ball_itself);
    6. yspeed = 0;
    7. xspeed = 0;
    8. checkpoint_passed = false;
    9. lev = 1;
    10. draw_level(lev);
    11. laps = 0;
    12. ball.onEnterFrame = function() {
    13.     info_panel._visible = false;
    14.     friction = 0.99;
    15.     power = 0.4;
    16.     brick_x = Math.floor((bricks._x-200)/80)*-1;
    17.     brick_y = Math.floor((bricks._y-180)/80)*-1;
    18.     type_of_tile = level[brick_y][brick_x];
    19.     if (type_of_tile>12000) {
    20.         message_to_show = messages[type_of_tile%12000];
    21.         type_of_tile = 12;
    22.     }
    23.     if (type_of_tile>10000) {
    24.         lap_sequence = type_of_tile-10000;
    25.         if ((lap_sequence == lap_to_go) and (lap_sequence == 1)) {
    26.             laps++;
    27.             lap.laptext.text = laps;
    28.         }
    29.         lap_to_go = lap_sequence%3+1;
    30.         type_of_tile = 1;
    31.     }
    32.     switch (type_of_tile) {
    33.     case 1 :
    34.         // normal tile
    35.         break;
    36.     case 2 :
    37.         // down spin tile
    38.         yspeed += 0.2;
    39.         break;
    40.     case 3 :
    41.         // up spin tile
    42.         yspeed -= 0.2;
    43.         break;
    44.     case 4 :
    45.         // left spin tile
    46.         xspeed -= 0.2;
    47.         break;
    48.     case 5 :
    49.         // right spin tile
    50.         xspeed += 0.2;
    51.         break;
    52.     case 6 :
    53.         // glass tile
    54.         depth = brick_y*12+brick_x;
    55.         bricks["brick_"+depth]._alpha--;
    56.         if (bricks["brick_"+depth]._alpha<1) {
    57.             level[brick_y][brick_x] = 0;
    58.         }
    59.         break;
    60.     case 7 :
    61.         // spin tile
    62.         xspeed *= 1.05;
    63.         yspeed *= 1.05;
    64.         break;
    65.     case 8 :
    66.         // slip tile
    67.         friction = 1;
    68.         power = 0;
    69.         break;
    70.     case 9 :
    71.         // beam
    72.         depth = brick_y*12+brick_x;
    73.         if (bricks["brick_"+depth].lava._currentframe>90) {
    74.             ball_die();
    75.         }
    76.         break;
    77.     case 10 :
    78.         // exit
    79.         checkpoint_passed = false;
    80.         lev++;
    81.         _root.removeMovieClip("bricks");
    82.         draw_level(lev);
    83.         break;
    84.     case 11 :
    85.         // reverse
    86.         power *= -1;
    87.         break;
    88.     case 12 :
    89.         // info
    90.         info_panel._visible = true;
    91.         info_panel.message_text.text = message_to_show;
    92.         break;
    93.     case 13 :
    94.         //checkpoint
    95.         checkpoint_passed = true;
    96.         save_x = brick_x;
    97.         save_y = brick_y;
    98.         break;
    99.     default :
    100.         // hole
    101.         ball_die();
    102.         break;
    103.     }
    104.     if (Key.isDown(Key.LEFT)) {
    105.         xspeed -= power;
    106.     }
    107.     if (Key.isDown(Key.RIGHT)) {
    108.         xspeed += power;
    109.     }
    110.     if (Key.isDown(Key.UP)) {
    111.         yspeed -= power;
    112.     }
    113.     if (Key.isDown(Key.DOWN)) {
    114.         yspeed += power;
    115.     }
    116.     xspeed *= friction;
    117.     yspeed *= friction;
    118.     if ((xspeed<0.1) and (xspeed>-0.1)) {
    119.         xspeed = 0;
    120.     }
    121.     if ((yspeed<0.1) and (yspeed>-0.1)) {
    122.         yspeed = 0;
    123.     }
    124.     bricks._y -= yspeed;
    125.     bricks._x -= xspeed;
    126.     starz._x = -20+((bricks._x-240)/10);
    127.     starz._y = -20+((bricks._y-220)/10);
    128.     this.texture._y += yspeed;
    129.     this.texture._x += xspeed;
    130.     if (this.texture._x>53) {
    131.         this.texture._x -= 63;
    132.     }
    133.     if (this.texture._x<-53) {
    134.         this.texture._x += 63;
    135.     }
    136.     if (this.texture._y>53) {
    137.         this.texture._y -= 63;
    138.     }
    139.     if (this.texture._y<-53) {
    140.         this.texture._y += 63;
    141.     }
    142. };
    143. function ball_die() {
    144.     bricks._x = 240-(80*_root.ball_start_x);
    145.     bricks._y = 220-(80*_root.ball_start_y);
    146.     xspeed = 0;
    147.     yspeed = 0;
    148.     lap_to_go = 2;
    149.     draw_level(lev);
    150. }
    151. function draw_level(number) {
    152.     yspeed = 0;
    153.     xspeed = 0;
    154.     level = new Array();
    155.     messages = new Array();
    156.     switch (number) {
    157.     case 1 :
    158.         _root.ball_start_x = 1;
    159.         _root.ball_start_y = 0;
    160.         if (checkpoint_passed) {
    161.             _root.ball_start_x = save_x;
    162.             _root.ball_start_y = save_y;
    163.         }
    164.         level[0] = new Array(1, 10001, 10002, 10003, 1);
    165.         level[1] = new Array(1, 0, 0, 0, 1);
    166.         level[2] = new Array(1, 0, 0, 0, 1);
    167.         level[3] = new Array(1, 0, 0, 0, 1);
    168.         level[4] = new Array(1, 1, 1, 1, 1);
    169.         messages[1] = "Welcome to the game";
    170.         messages[2] = "You are about to cross a checkpoint";
    171.         messages[3] = "Ok. Now suicide! You'll respawn on the checkpoint";
    172.         break;
    173.     case 2 :
    174.         _root.ball_start_x = 0;
    175.         _root.ball_start_y = 0;
    176.         level[0] = new Array(1, 4, 4, 5, 0);
    177.         level[1] = new Array(0, 0, 0, 1, 0);
    178.         level[2] = new Array(0, 0, 0, 1, 0);
    179.         level[3] = new Array(0, 0, 0, 10, 0);
    180.         level[4] = new Array(0, 0, 0, 0, 0);
    181.         break;
    182.     case 3 :
    183.         _root.ball_start_x = 0;
    184.         _root.ball_start_y = 0;
    185.         level[0] = new Array(1, 6, 6, 4, 0);
    186.         level[1] = new Array(0, 0, 0, 6, 0);
    187.         level[2] = new Array(6, 5, 5, 6, 0);
    188.         level[3] = new Array(6, 0, 0, 0, 0);
    189.         level[4] = new Array(1, 1, 10, 0, 0);
    190.         break;
    191.     case 4 :
    192.         _root.ball_start_x = 0;
    193.         _root.ball_start_y = 0;
    194.         level[0] = new Array(1, 7, 0, 0, 0);
    195.         level[1] = new Array(0, 7, 0, 7, 10);
    196.         level[2] = new Array(1, 3, 0, 1, 0);
    197.         level[3] = new Array(1, 0, 0, 1, 0);
    198.         level[4] = new Array(1, 1, 1, 7, 0);
    199.         break;
    200.     case 5 :
    201.         _root.ball_start_x = 4;
    202.         _root.ball_start_y = 2;
    203.         level[0] = new Array(7, 8, 8, 8, 10);
    204.         level[1] = new Array(1, 0, 0, 0, 0);
    205.         level[2] = new Array(1, 8, 8, 3, 1);
    206.         level[3] = new Array(0, 0, 0, 0, 0);
    207.         level[4] = new Array(0, 0, 0, 0, 0);
    208.         break;
    209.     case 6 :
    210.         _root.ball_start_x = 2;
    211.         _root.ball_start_y = 2;
    212.         level[0] = new Array(2, 8, 9, 8, 9);
    213.         level[1] = new Array(9, 0, 0, 0, 1);
    214.         level[2] = new Array(2, 8, 1, 0, 3);
    215.         level[3] = new Array(0, 0, 0, 0, 4);
    216.         level[4] = new Array(10, 9, 9, 8, 6);
    217.         break;
    218.     case 7 :
    219.         _root.ball_start_x = 2;
    220.         _root.ball_start_y = 2;
    221.         level[0] = new Array(0, 0, 0, 0, 0);
    222.         level[1] = new Array(0, 0, 0, 0, 0);
    223.         level[2] = new Array(0, 0, 1, 0, 0);
    224.         level[3] = new Array(0, 0, 0, 0, 0);
    225.         level[4] = new Array(0, 0, 0, 0, 0);
    226.         break;
    227.     }
    228.     _root.createEmptyMovieClip("bricks", 2);
    229.     bricks._x = 240-(80*ball_start_x);
    230.     bricks._y = 220-(80*ball_start_y);
    231.     for (y=0; y<=4; y++) {
    232.         for (x=0; x<=4; x++) {
    233.             if (level[y][x]>0) {
    234.                 depth = y*12+x;
    235.                 place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
    236.                 frame_to_stop = level[y][x];
    237.                 if (frame_to_stop>10000) {
    238.                     frame_to_stop = 1;
    239.                 }
    240.                 if (frame_to_stop>12000) {
    241.                     frame_to_stop = 12;
    242.                 }
    243.                 place_brick.gotoAndStop(frame_to_stop);
    244.             }
    245.         }
    246.     }
    247. }

    Line 4: Attaching a movieclip to display laps

    Line 11: Variable counting the number of laps

    Line 23: Checking if the type of tile is greater than 10000. In my game, lap tiles are 10001, 10002 and 10003

    Line 24: Obtaining the lap sequence: 1, 2 or 3, according on which tile the ball is rolling on

    Line 25: If the lap sequence is equal to a variable called lap_to_go (it stores the next lap sequence to go in order to complete the lap as you will see later) and its value is 1 (the 10001 tile, the one that represents the start)

    Line 26: Increase the number of laps

    Line 27: Display the number of laps

    Line 29: Calculating the value of the next tile in order to make a correct lap

    Line 30: Defining the type of tile (a normal one)

    Line 164: Level design of lap tiles

    Lines 237-239: Showing the default tile if its number is greater than 10000

    As you can see, now you have laps!

    Now you have a lot more gamplay options with this engine... download the source code and create the ultimate game!

    discuss this topic to forum

    relation tutorial

    No relevant information

    Category

      3D (20)
      Math Physics (14)
      3rd Party (5)
      Navigation (60)
      Actionscripting (26)
      Optimization (16)
      Animation (32)
      Projector (9)
      Audio (46)
      Special Effects (112)
      Backend (25)
      Text Effects (65)
      Drawing (18)
      Tips and Techniques (41)
      Dynamic Content (25)
      Tricks (6)
      Games (74)
      Utilities (21)
      Getting Started (91)
      Video (24)
      Interactivity (43)
      Web Design (29)

    New

    Hot