Christmas Couples: the finished Poux prototype
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!
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 204 | 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("<u/*/u>");
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 ith to the ith+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!
They can be easily customized to meet the unique requirements of your project.

















(5 votes, average: 3.40 out of 5)









This post has 29 comments
Prototype of a Flash game like Poux : Emanuele Feronato - italian geek and PROgrammer
[...] 17th update: part 2 released November 22nd update: part 3 released November 28th update: Finished project [...]
Prototype of a Flash game like Poux - Part 2 : Emanuele Feronato - italian geek and PROgrammer
[...] 22nd update: part 3 released November 28th update: Finished project [...]
Prototype of a Flash game like Poux - Part 3 : Emanuele Feronato - italian geek and PROgrammer
[...] 28th update: Finished project [...]
Jhelle
Looks great emanuele!
Good luck with the monopolizing of it :D
I recently tried it too with the first game I ever made in flash (for a schoolproject even) after seeing your succes with Circle Chain. In my oppinion it is doing pretty well, I got 35.000 impressions and I only submitted it last friday :)
Kevin
Hi Emanuele,
Your new game looks great! I hope it will be a success.
By the way, I found your game’s graphic quite artistic. Did you draw them yourself? If yes, would you like to tell us some tips about drawing with flash? (As I can only draw straight lines, circles, squares using the standard tools. I can’t draw in flash using the mouse like drawing on papers using a pen. Therefore my flash game graphics are always very simple.)
bigbill
That’s cool however the high score doesn’t seem to work or is that just me?
Frederik J
Nice game Emanuele. :) It’s good and simple, and thanks for showing us, what you call a copycat game! Which im pretty sure of, is made fast, make good money, and of course, contains average graphic. Well done!
Robby
Really cool game :) love the graphics!! Keep doing what you’re doing Emanuele!
RJ
Good game, where did you find that music? It’s very good.
What’s your game, Jhelle?
[For Kevin] Graphics are from Zeus Box, as he said in part 3, have a look, it’s quite interesting.
Janaka
Hi,
I’m very glade to see some one doing this sort of work for free.
I have gained so much knowlege from you.
This problem is not about this lesson but I dont have any way to ask this sorry!
I’m developing a game these day’s and I was traped in a hole.. I mean I need to know how to code in flash to move a movie clip avoiding obstacles. I someone said to use recursion method but I can’t really figer it out.
I hope you can tell me a answere
Thanks a lot!
maciek
uhh… to do that you need a pathfindind algorithm. It is advanced stuff but if you really wanna do it search for A* algorithm
Jhelle
RJ:
My game is Agyta; http://www.newgrounds.com/portal/view/411650.
And Emanuele I’ve read your trying to find a sponsor for your new game, and someone posted a great site for that on the mochiads forums a few days ago. It is like a auction site for flash games sponsorships!
here is the url http://www.fantasticchoice.com/
Vixin
AAAAAARRRRRRRRRRGGGGGGGGGGG! I can`t believe I was so addicted to this game, FINALY got a score of 2300 and I Know I typed in `Vixin` rather than Santa Claus – AND ITS NOT ON YOUR HIGH SCORE LIST!
I want this game updated to Valentines day icons! And Fix The Score List! :p
Emanuele Feronato
Great idea! “Valentine Couples” will be out very soon, with some improvements and a better highscore table
Vixin
K well in the mean time I`m 16th on the all time facebook board at 2343! Woot! Hope you can do the new game in time!
Lynne Sargent
Hi Emanuele,
I am addicted to this little game!! (Started playing it on Facebook, & then searched for your site.) Only problem is, I can’t input my scores so the high score feature is pretty much useless.:(
Nathan
It says ‘two OF more’, shouldn’t it be ‘two OR more’. Otherwise, great game!!
Summer Couples: a game made in an airplane : Emanuele Feronato - italian geek and PROgrammer
[...] result is the “sequel” of Christmas Couples called Summer [...]
ИнÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð¿Ð¾ монетизации флÑш игр | terbooter
[...] ЕÑли интереÑно узнать больше об Ñтих играх, прочтите поÑты:Circle Сhain, Christmas Couples, [...]
Ten Million Plays Club membership : Emanuele Feronato
[...] second Flash game, Christmas Couples, a game released almost a year ago, reached 10,000,000 [...]
Fifteen Million Plays Club membership : Emanuele Feronato
[...] months ago, my second game, Christmas Couples, joined the Ten Millions Plays [...]
Guest
did you release the code?…
About season games : Emanuele Feronato
[...] they are classic games with a season theme, just like my two ones, Christmas Couples and Halloween [...]
Marketing influences game revenue three times more than high scores : Emanuele Feronato
[...] Christmas Couples really sucks, but I submitted it everywhere, and was one of the first games to include the MindJolt API. With its 17,596,730 views it was an incredible success. [...]
Milestone: reached $100 with MochiAds : Emanuele Feronato - italian geek and PROgrammer
[...] game is Christmas Couples and is having a second (third) youth since it’s Christmas… I always said season games [...]
vice
hi, are gonna still release the code? thx
Dan
Sweet!
Moccads
Nice game, I will try to put in my website!
Pat Means
I love the christmas couples game but I get so frustrated because the total score doesn’t register. This can happen several times, so I have to get back to my games, select it again, and play it again. Sometimes it accepts the score but most of the time it doesn’t. I hope there is some way you can fix it. Thanks