Talking about Ball Game game, Flash and Game development.
January 16th update: 4th part released
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:
_root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
_root.attachMovie("ball", "ball", 3, {_x:240, _y:220});
_root.attachMovie("info_panel", "info_panel", 4, {_y:410, _alpha:50, _visible:false});
ball.texture.setMask(ball.ball_itself);
yspeed = 0;
xspeed = 0;
checkpoint_passed = false;
lev = 1;
draw_level(lev);
ball.onEnterFrame = function() {
info_panel._visible = false;
friction = 0.99;
power = 0.4;
brick_x = Math.floor((bricks._x-200)/80)*-1;
brick_y = Math.floor((bricks._y-180)/80)*-1;
type_of_tile = level[brick_y][brick_x];
if (type_of_tile>12000) {
message_to_show = messages[type_of_tile%12000];
type_of_tile = 12;
}
switch (type_of_tile) {
case 1 :
// normal tile
break;
case 2 :
// down spin tile
yspeed += 0.2;
break;
case 3 :
// up spin tile
yspeed -= 0.2;
break;
case 4 :
// left spin tile
xspeed -= 0.2;
break;
case 5 :
// right spin tile
xspeed += 0.2;
break;
case 6 :
// glass tile
depth = brick_y*12+brick_x;
bricks["brick_"+depth]._alpha--;
if (bricks["brick_"+depth]._alpha<1) {
level[brick_y][brick_x] = 0;
}
break;
case 7 :
// spin tile
xspeed *= 1.05;
yspeed *= 1.05;
break;
case 8 :
// slip tile
friction = 1;
power = 0;
break;
case 9 :
// beam
depth = brick_y*12+brick_x;
if (bricks["brick_"+depth].lava._currentframe>90) {
ball_die();
}
break;
case 10 :
// exit
checkpoint_passed = false;
lev++;
_root.removeMovieClip("bricks");
draw_level(lev);
break;
case 11 :
// reverse
power *= -1;
break;
case 12 :
// info
info_panel._visible = true;
info_panel.message_text.text = message_to_show;
break;
case 13 :
//checkpoint
checkpoint_passed = true;
save_x = brick_x;
save_y = brick_y;
break;
default :
// hole
ball_die();
break;
}
if (Key.isDown(Key.LEFT)) {
xspeed -= power;
}
if (Key.isDown(Key.RIGHT)) {
xspeed += power;
}
if (Key.isDown(Key.UP)) {
yspeed -= power;
}
if (Key.isDown(Key.DOWN)) {
yspeed += power;
}
xspeed *= friction;
yspeed *= friction;
if ((xspeed<0.1) and (xspeed>-0.1)) {
xspeed = 0;
}
if ((yspeed<0.1) and (yspeed>-0.1)) {
yspeed = 0;
}
bricks._y -= yspeed;
bricks._x -= xspeed;
starz._x = -20+((bricks._x-240)/10);
starz._y = -20+((bricks._y-220)/10);
this.texture._y += yspeed;
this.texture._x += xspeed;
if (this.texture._x>53) {
this.texture._x -= 63;
}
if (this.texture._x<-53) {
this.texture._x += 63;
}
if (this.texture._y>53) {
this.texture._y -= 63;
}
if (this.texture._y<-53) {
this.texture._y += 63;
}
};
function ball_die() {
bricks._x = 240-(80*_root.ball_start_x);
bricks._y = 220-(80*_root.ball_start_y);
xspeed = 0;
yspeed = 0;
draw_level(lev);
}
function draw_level(number) {
yspeed = 0;
xspeed = 0;
level = new Array();
messages = new Array();
switch (number) {
case 1 :
_root.ball_start_x = 0;
_root.ball_start_y = 0;
if (checkpoint_passed) {
_root.ball_start_x = save_x;
_root.ball_start_y = save_y;
}
level[0] = new Array(12001, 11, 11, 11, 11);
level[1] = new Array(0, 0, 0, 0, 1);
level[2] = new Array(1, 1, 10, 0, 1);
level[3] = new Array(1, 0, 0, 0, 1);
level[4] = new Array(12003, 1, 1, 13, 12002);
messages[1] = "Welcome to the game";
messages[2] = "You are about to cross a checkpoint";
messages[3] = "Ok. Now suicide! You'll respawn on the checkpoint";
break;
case 2 :
_root.ball_start_x = 0;
_root.ball_start_y = 0;
level[0] = new Array(1, 4, 4, 5, 0);
level[1] = new Array(0, 0, 0, 1, 0);
level[2] = new Array(0, 0, 0, 1, 0);
level[3] = new Array(0, 0, 0, 10, 0);
level[4] = new Array(0, 0, 0, 0, 0);
break;
case 3 :
_root.ball_start_x = 0;
_root.ball_start_y = 0;
level[0] = new Array(1, 6, 6, 4, 0);
level[1] = new Array(0, 0, 0, 6, 0);
level[2] = new Array(6, 5, 5, 6, 0);
level[3] = new Array(6, 0, 0, 0, 0);
level[4] = new Array(1, 1, 10, 0, 0);
break;
case 4 :
_root.ball_start_x = 0;
_root.ball_start_y = 0;
level[0] = new Array(1, 7, 0, 0, 0);
level[1] = new Array(0, 7, 0, 7, 10);
level[2] = new Array(1, 3, 0, 1, 0);
level[3] = new Array(1, 0, 0, 1, 0);
level[4] = new Array(1, 1, 1, 7, 0);
break;
case 5 :
_root.ball_start_x = 4;
_root.ball_start_y = 2;
level[0] = new Array(7, 8, 8, 8, 10);
level[1] = new Array(1, 0, 0, 0, 0);
level[2] = new Array(1, 8, 8, 3, 1);
level[3] = new Array(0, 0, 0, 0, 0);
level[4] = new Array(0, 0, 0, 0, 0);
break;
case 6 :
_root.ball_start_x = 2;
_root.ball_start_y = 2;
level[0] = new Array(2, 8, 9, 8, 9);
level[1] = new Array(9, 0, 0, 0, 1);
level[2] = new Array(2, 8, 1, 0, 3);
level[3] = new Array(0, 0, 0, 0, 4);
level[4] = new Array(10, 9, 9, 8, 6);
break;
case 7 :
_root.ball_start_x = 2;
_root.ball_start_y = 2;
level[0] = new Array(0, 0, 0, 0, 0);
level[1] = new Array(0, 0, 0, 0, 0);
level[2] = new Array(0, 0, 1, 0, 0);
level[3] = new Array(0, 0, 0, 0, 0);
level[4] = new Array(0, 0, 0, 0, 0);
break;
}
_root.createEmptyMovieClip("bricks", 2);
bricks._x = 240-(80*ball_start_x);
bricks._y = 220-(80*ball_start_y);
for (y=0; y<=4; y++) {
for (x=0; x<=4; x++) {
if (level[y][x]>0) {
depth = y*12+x;
place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
frame_to_stop = level[y][x];
if (frame_to_stop>12000) {
frame_to_stop = 12;
}
place_brick.gotoAndStop(frame_to_stop);
}
}
}
}
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
And that’s it: the first level has the new features while the others are the same of part 2
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
Read 4th part released
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.