Talking about Flash and Game development.
This is the last step of the prototype of a Flash game likePoux. Read steps 1, 2 and 3 before continuing.
As said, I finished the game. I called it Christmas Couples
Let’s see its features:
* Fancy graphics
* Improved scoring system
* Cool sound loop
* Highscores
As you can see, graphics, sound and highscores are developed from third parts, so I focused only on coding and gameplay.
This is a pretty good example of a copycat game. It’s coded with 204 lines and it took about 6 hours to be completed… and now I am going to explain line by line how it’s made.
Ok.. time to show you some actionscript… obviously all in the 1st (2nd to tell the truth…) frame!
stop();
import ab3.rankz.*;
field = Array();
_root.attachMovie("splash","splash",_root.getNextHighestDepth());
_root.attachMovie("playbutton","playbutton",_root.getNextHighestDepth());
_root.attachMovie("soundbutton","soundbutton",_root.getNextHighestDepth());
playbutton._x = 280;
playbutton._y = 285;
soundbutton._x = 430;
soundbutton._y = 335;
music = new Sound(this);
music.attachSound("music");
music.start(0,10000);
playing_the_game = false;
function __rankz_send__(par1, par2, par3, par4) {
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
xxxxx.onLoad = function(success) {
if (success) {
rankz_t10_receive = new LoadVars();
// cannot show you this line or you may hack highscores
// cannot show you this line or you may hack highscores
rankz_t10_receive.onLoad = function(success) {
if (success) {
_rankz_ar_ = rankz_t10_receive.top10.split("");
for (i=0; i<_rankz_ar_.length; i++) {
tempv = _rankz_ar_[i].split("*/>");
ohno["rankz_n"+(i+1)].text = tempv[0];
ohno["rankz_v"+(i+1)].text = tempv[1];
}
}
};
rankz_t10_send.sendAndLoad("http://rankz.armorbot.com/get/top10.php",rankz_t10_receive,"POST");
}
else {
// cannot show you this line or you may hack highscores
}
};
}
function game_init() {
removed = 0;
score = 0;
interval = 250;
x2_horiz_pos = 0;
mult = 1;
game_over = 0;
turns = 0;
tiles_placed = 0;
for (x=0; x<10; x++) {
field[x] = Array();
for (y=0; y<10; y++) {
field[x][y] = 0;
}
}
_root.createEmptyMovieClip("things",_root.getNextHighestDepth());
score_obj.score.text = "Score: "+score;
place_line();
}
playbutton.onPress = function() {
player_name = splash.your_name.text;
playing_the_game = true;
_root.attachMovie("bg","bg",_root.getNextHighestDepth());
_root.attachMovie("x2_horiz","x2_horiz",_root.getNextHighestDepth(),{_x:10});
_root.createEmptyMovieClip("bar",_root.getNextHighestDepth());
_root.attachMovie("score","score_obj",_root.getNextHighestDepth(),{_x:340, _y:10});
game_init();
splash.removeMovieClip();
_root.soundbutton._y = 10000;
this._y=10000;
};
soundbutton.onPress = function() {
music.stop();
};
function place_line() {
for (x=0; x<10; x++) {
tiles_placed++;
if (field[x][0] != 0) {
push_blocks(x);
}
tile = things.attachMovie("tile", "tile_"+tiles_placed, tiles_placed, {_x:10+32*x, _y:300});
num = Math.floor(Math.random()*6)+1;
tile.gotoAndStop(num);
field[x][0] = tiles_placed;
}
}
_root.onEnterFrame = function() {
if (!game_over) {
interval--;
if (interval == 0) {
turns++;
interval = 250-turns;
place_line();
x2_horiz_pos = Math.floor(Math.random()*10);
x2_horiz._y = 300-x2_horiz_pos*32;
}
bar.clear();
bar.lineStyle(6,0xfff153);
bar.moveTo(10,350);
bar.lineTo(328,350);
bar.lineStyle(4,0xea8400);
bar.moveTo(10,350);
bar.lineTo(10+318*interval/(250-turns),350);
}
};
function push_blocks(col_number) {
for (i=9; i>=0; i--) {
if (!game_over) {
if (field[col_number][i] != 0) {
if (i != 9) {
field[col_number][i+1] = field[col_number][i];
things["tile_"+field[col_number][i]]._y -= 32;
}
else {
things._alpha = 50;
game_over = 1;
bXlnYW1lX25hbWVfdmFyaWFibGU = player_name;
bXlnYW1lX3Njb3JlX3ZhcmlhYmxl = score;
__rankz_send__("MTk0MWolZSVhJW4lcw==","cHltcFpTaGI=",bXlnYW1lX25hbWVfdmFyaWFibGU,bXlnYW1lX3Njb3JlX3ZhcmlhYmxl);
rankz_t10_send = new LoadVars();
_root.attachMovie("ohno","ohno",_root.getNextHighestDepth(),{_x:75, _y:5});
again_button = ohno.attachMovie("playagain", "playagain", _root.getNextHighestDepth());
again_button._x = 100;
again_button._y = 300;
again_button.onPress = function() {
things.removeMovieClip();
game_init();
ohno.removeMovieClip();
};
}
}
}
}
}
onMouseDown = function () {
if (playing_the_game) {
if (!game_over) {
x_tile_clicked = Math.floor((_root._xmouse-10)/32);
y_tile_clicked = -Math.floor((_root._ymouse-300)/32);
if ((x_tile_clicked>=0) and (x_tile_clicked<=9) and (y_tile_clicked>=0) and (y_tile_clicked<=9)) {
if (field[x_tile_clicked][y_tile_clicked] != 0) {
remove_tiles(x_tile_clicked,y_tile_clicked,1);
update_field();
for (i=1; i<=removed; i++) {
score += (i*mult);
}
score_obj.score.text = "Score: "+score;
removed = 0;
mult = 1;
}
}
}
}
};
function remove_tiles(tx, ty, clicked) {
tile_type = things["tile_"+field[tx][ty]]._currentframe;
if (!clicked) {
things["tile_"+field[tx][ty]].onEnterFrame = function() {
this._y++;
this._alpha--;
if (this._alpha == 0) {
this.removeMovieClip();
}
};
field[tx][ty] = 0;
removed++;
if (ty == x2_horiz_pos) {
mult = 2;
}
}
if ((field[tx+1][ty] != 0) and (things["tile_"+field[tx+1][ty]]._currentframe == tile_type)) {
remove_tiles(tx+1,ty);
}
if ((field[tx-1][ty] != 0) and (things["tile_"+field[tx-1][ty]]._currentframe == tile_type)) {
remove_tiles(tx-1,ty);
}
if ((field[tx][ty+1] != 0) and (things["tile_"+field[tx][ty+1]]._currentframe == tile_type)) {
remove_tiles(tx,ty+1);
}
if ((field[tx][ty-1] != 0) and (things["tile_"+field[tx][ty-1]]._currentframe == tile_type)) {
remove_tiles(tx,ty-1);
}
}
function update_field() {
for (i=0; i<10; i++) {
for (j=1; j<10; j++) {
if ((field[i][j] != 0) and (field[i][j-1] == 0)) {
falling = j-1;
while ((field[i][falling] == 0) and (falling>=0)) {
field[i][falling] = field[i][falling+1];
things["tile_"+field[i][falling+1]]._y += 32;
field[i][falling+1] = 0;
falling--;
}
}
}
}
}
Line 1: Have to stop in this frame because I installed MochiAds and MochiBot on the previuos frame. Yes, I am going to (try to) monetize this game too…
Line 2: This is a mandatory line if you want to use highscores feature provided by ArmorBot
Line 3: Array containing the game field
Line 4: Attaching the splash
movieclip. It contains the splash screen, the one you see when you start the game
Line 5: Attaching the play button
Line 6: Attaching the “Stop Sound” button
Lines 7-10: Adjusting play button and sound button positions.
Line 11: Creating a new sound variable
Line 12: Attaching the sound clip linked as music
Line 13: Playing the sound clip 10,000 time starting from second zero (the beginning)
Lines 15-46: Highscores management. This is the code provided by ArmorBot. I only made some changes to make result appear where I want them to appear and to show top 10 only after the last score was submitted.
Line 47: game_init
function. This function is called at every new play.
Line 48: Setting removed tiles to zero
Line 49: Setting the score to zero
Line 50: Setting the interval between two new row insertions to 250 (frames)
Line 51: Setting the initial position of the horizontal green bonus bar
Line 52: Setting multiplier bonus to 1
Line 53: Setting game_over
to zero (it’s not game over)
Line 54: Settings turns to zero
Line 55: Setting tile placed to zero
Lines 56-61: Initializing the game field with all zeros. Now the board is empty
Line 62: Creating the movieclip that will contain the objects
Line 63: Initializing the text variable that will display the current score (initially zero as seen on line 49)
Line 64: Calling the place_line function. This function will place a new line (line 81)
Line 66: This is the function to be executed when the player presses “play” on the splash screen
Line 67: Saving the name the player entered in the splash screen in a variable called player_name
Line 68: Setting a variable to tell we are actually playing the game
Line 69: Attaching the background of the game
Line 70: Attaching the horizontal green bonus bar
Line 71: Creating an empty movieclip that will contain the time bar
Line 72: Attaching the movieclip that will contain the score
Line 73: Calling the game_init function we saw at line 47
Line 74: Removing the splash screen
Line 75: Moving the Stop Sound button off the stage. I had to do in this way because removeMovieClip does not work on buttons
Line 76: Same thing with the play button itself
Line 78: Function to call if the player presses the Stop Sound button
Line 79: Stop the music
Line 81: Function to place a new line
Line 82: Counting from 1 to 10 (the number of columns)
Line 83: Increasing tiles_placed variable, to keep count of how many tiles we have placed so far
Line 84: If there is a tile in the spot where we should add a new tile…
Line 85: Call the function push_blocks. This function il push blocks from the bottom, to raise the stack of tiles
Line 87: Attaching the new tile
Line 88: Generation of a random number between 1 and 6 and saving it into num
Line 89: Stopping the tile movieclip at the num
-th frame. Obviously I have a different tile on each frame
Line 90: Saving tiles_placed
value in the field
array
Line 93: Function to be executed at every frame
Line 94: If it’s not game over…
Line 95: Decreasing interval
… time is passing…
Line 96: If interval
reaches zero…
Line 97: Increasing turns
variable
Line 98: Setting the new interval value to 250-turns
. This means new lines will be placed faster and faster. How faster? 1 frame faster than the last one
Line 99: Calling the function place_line
(line 81)
Line 100: Finding a new random position for the horizontal green bonus bar
Line 101: Moving the horizontal green bonus bar to its new position
Line 103: Clearing the bar movieclip
Line 104-109: Displaying the time bar by drawing two lines, one a bit thicker than another. To know more about Flash drawing routines refer to Create a flash draw game like Line Rider or others – part 1
Line 112: Function to push blocks (called at line 85)
Line 113: Scanning all vertical tiles in the col_number
column
Line 114: If it’s not game over…
Line 115: If the place we are scanning is not empty…
Line 116: If the row is not the top last row… (it’s very important because if I don’t have more space where to store tiles, it’s game over)
Lines 117-118: Bringing the tile at i
th to the i
th+1 position… both in the field array and physically
Line 120: If it was the top last row…
Line 121: Making tiles half transparent (it’s game over man…)
Line 122: Setting game_over to 1 (I told you it’s game over…)
Lines 123-126: Sending scores to the highscore table
Line 127: Attaching the game-over movieclip (the one with the highscores)
Lines 128-130: Placing the “play again” button
Line 131: Function to be executed when the player presses the Play again button
Line 132: Remove the movieclip with the tiles
Line 133: Calling game_init function to start a new game (line 47)
Line 134: Removing the game over movieclip
Line 141: Function ti be executed when the player clicks the mouse
Line 142: Checking if we are playing the game
Line 143: Checking if it’s not game over (I could merge this line with the above one with an and
)
Lines 144-145: Determining what tile did I click according to mouse coordinates
Line 146: Checking if it’s really a spot where it could be a tile
Line 147: Checking in the field array if there is a tile in the tile-space I clicked
Line 148: If all conditions are true, then call the remove_tiles
function you see at line 161
Line 149: Once the tiles have been removed, call update_field
function (line 190)
Lines 150-152: Calculating the score for the last move in this way: 2 tiles removed = 2+1= 3 points; 3 tiles removed = 3+2+1 = 6 points… and so on. Score is then multiplied by the multiplier
Line 153: Updating the score string
Line 154: Reset removed
variable to zero
Line 155: Reset mutliplier variable to 1
Line 161: Function remove_tiles called at line 148. Three arguments: the x position, the y position and a flag to determine if the tile to remove is the clicked one (that’s why I called with the last argument set to 1 at line 148)
Line 162: Determining which type of tile (star, snowflake, …) I am going to remove according to its current frame
Line 163: If the tile is not the clicked one
Line 164: Function to be executed at every frame for that tile
Line 165: Moving it down by 1 pixel
Line 166: Making it a bit more transparent
Lines 167-169: If it’s completely transparent, then remove it! This is the animation you see when you click a tile
Line 171: Setting its field position to zero… now there is an empty space
Line 172: Increasing remove
variable
Lines 173-175: If the tile was in the horizontal green bonus bar, then set the multiplier at 2
Lines 177-179: If there is a tile of the same type on the right of the tile just clicked (or remove) then recursively call remove_tiles
for that tile with the clicked
argument at zero
Lines 180-182: Same thing with the left tile
Lines 183-188: Same thing with the above and below tiles.
The clicked
flag is used to not remove the clicked tile if there aren’t adjacent tiles of the same type
Line 190: Beginning of the update_field
function (the last one!) called at line 149
Lines 191-192: Scanning the entire game field
Line 193: If there is an empty space under the field position we are looking at…
Line 194: Assign to falling
the vertical position of the tile that must fall down
Line 195: While there is an empty space under the falling tile and it hasn’t reached the “ground”…
Lines 196-198: Updating field array and physically moving down the tile
Line 199: The tile has moved down so falling
must decrease
And it’s over! This is the longest all-in-once explaination of this blog! I hope this will be useful
Now I am submitting the game to some portals, then I’ll release the source code.
Meanwhile… enjoy!
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.