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

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!

ACTIONSCRIPT:
  1. stop();
  2. import ab3.rankz.*;
  3. field = Array();
  4. _root.attachMovie("splash","splash",_root.getNextHighestDepth());
  5. _root.attachMovie("playbutton","playbutton",_root.getNextHighestDepth());
  6. _root.attachMovie("soundbutton","soundbutton",_root.getNextHighestDepth());
  7. playbutton._x = 280;
  8. playbutton._y = 285;
  9. soundbutton._x = 430;
  10. soundbutton._y = 335;
  11. music = new Sound(this);
  12. music.attachSound("music");
  13. music.start(0,10000);
  14. playing_the_game = false;
  15. function __rankz_send__(par1, par2, par3, par4) {
  16.     // cannot show you this line or you may hack highscores
  17.     // cannot show you this line or you may hack highscores
  18.     // cannot show you this line or you may hack highscores
  19.     // cannot show you this line or you may hack highscores
  20.     // cannot show you this line or you may hack highscores
  21.     // cannot show you this line or you may hack highscores
  22.     // cannot show you this line or you may hack highscores
  23.     // cannot show you this line or you may hack highscores
  24.     // cannot show you this line or you may hack highscores
  25.     xxxxx.onLoad = function(success) {
  26.         if (success) {
  27.             rankz_t10_receive = new LoadVars();
  28.             // cannot show you this line or you may hack highscores
  29.             // cannot show you this line or you may hack highscores
  30.             rankz_t10_receive.onLoad = function(success) {
  31.                 if (success) {
  32.                     _rankz_ar_ = rankz_t10_receive.top10.split("<u/*/u>");
  33.                     for (i=0; i<_rankz_ar_.length; i++) {
  34.                         tempv = _rankz_ar_[i].split("</*/>");
  35.                         ohno["rankz_n"+(i+1)].text = tempv[0];
  36.                         ohno["rankz_v"+(i+1)].text = tempv[1];
  37.                     }
  38.                 }
  39.             };
  40.             rankz_t10_send.sendAndLoad("http://rankz.armorbot.com/get/top10.php",rankz_t10_receive,"POST");
  41.         }
  42.         else {
  43.             // cannot show you this line or you may hack highscores
  44.         }
  45.     };
  46. }
  47. function game_init() {
  48.     removed = 0;
  49.     score = 0;
  50.     interval = 250;
  51.     x2_horiz_pos = 0;
  52.     mult = 1;
  53.     game_over = 0;
  54.     turns = 0;
  55.     tiles_placed = 0;
  56.     for (x=0; x<10; x++) {
  57.         field[x] = Array();
  58.         for (y=0; y<10; y++) {
  59.             field[x][y] = 0;
  60.         }
  61.     }
  62.     _root.createEmptyMovieClip("things",_root.getNextHighestDepth());
  63.     score_obj.score.text = "Score: "+score;
  64.     place_line();
  65. }
  66. playbutton.onPress = function() {
  67.     player_name = splash.your_name.text;
  68.     playing_the_game = true;
  69.     _root.attachMovie("bg","bg",_root.getNextHighestDepth());
  70.     _root.attachMovie("x2_horiz","x2_horiz",_root.getNextHighestDepth(),{_x:10});
  71.     _root.createEmptyMovieClip("bar",_root.getNextHighestDepth());
  72.     _root.attachMovie("score","score_obj",_root.getNextHighestDepth(),{_x:340, _y:10});
  73.     game_init();
  74.     splash.removeMovieClip();
  75.     _root.soundbutton._y = 10000;
  76.     this._y=10000;
  77. };
  78. soundbutton.onPress = function() {
  79.     music.stop();
  80. };
  81. function place_line() {
  82.     for (x=0; x<10; x++) {
  83.         tiles_placed++;
  84.         if (field[x][0] != 0) {
  85.             push_blocks(x);
  86.         }
  87.         tile = things.attachMovie("tile", "tile_"+tiles_placed, tiles_placed, {_x:10+32*x, _y:300});
  88.         num = Math.floor(Math.random()*6)+1;
  89.         tile.gotoAndStop(num);
  90.         field[x][0] = tiles_placed;
  91.     }
  92. }
  93. _root.onEnterFrame = function() {
  94.     if (!game_over) {
  95.         interval--;
  96.         if (interval == 0) {
  97.             turns++;
  98.             interval = 250-turns;
  99.             place_line();
  100.             x2_horiz_pos = Math.floor(Math.random()*10);
  101.             x2_horiz._y = 300-x2_horiz_pos*32;
  102.         }
  103.         bar.clear();
  104.         bar.lineStyle(6,0xfff153);
  105.         bar.moveTo(10,350);
  106.         bar.lineTo(328,350);
  107.         bar.lineStyle(4,0xea8400);
  108.         bar.moveTo(10,350);
  109.         bar.lineTo(10+318*interval/(250-turns),350);
  110.     }
  111. };
  112. function push_blocks(col_number) {
  113.     for (i=9; i>=0; i--) {
  114.         if (!game_over) {
  115.             if (field[col_number][i] != 0) {
  116.                 if (i != 9) {
  117.                     field[col_number][i+1] = field[col_number][i];
  118.                     things["tile_"+field[col_number][i]]._y -= 32;
  119.                 }
  120.                 else {
  121.                     things._alpha = 50;
  122.                     game_over = 1;
  123.                     bXlnYW1lX25hbWVfdmFyaWFibGU = player_name;
  124.                     bXlnYW1lX3Njb3JlX3ZhcmlhYmxl = score;
  125.                     __rankz_send__("MTk0MWolZSVhJW4lcw==","cHltcFpTaGI=",bXlnYW1lX25hbWVfdmFyaWFibGU,bXlnYW1lX3Njb3JlX3ZhcmlhYmxl);
  126.                     rankz_t10_send = new LoadVars();
  127.                     _root.attachMovie("ohno","ohno",_root.getNextHighestDepth(),{_x:75, _y:5});
  128.                     again_button = ohno.attachMovie("playagain", "playagain", _root.getNextHighestDepth());
  129.                     again_button._x = 100;
  130.                     again_button._y = 300;
  131.                     again_button.onPress = function() {
  132.                         things.removeMovieClip();
  133.                         game_init();
  134.                         ohno.removeMovieClip();
  135.                     };
  136.                 }
  137.             }
  138.         }
  139.     }
  140. }
  141. onMouseDown = function () {
  142.     if (playing_the_game) {
  143.         if (!game_over) {
  144.             x_tile_clicked = Math.floor((_root._xmouse-10)/32);
  145.             y_tile_clicked = -Math.floor((_root._ymouse-300)/32);
  146.             if ((x_tile_clicked>=0) and (x_tile_clicked<=9) and (y_tile_clicked>=0) and (y_tile_clicked<=9)) {
  147.                 if (field[x_tile_clicked][y_tile_clicked] != 0) {
  148.                     remove_tiles(x_tile_clicked,y_tile_clicked,1);
  149.                     update_field();
  150.                     for (i=1; i<=removed; i++) {
  151.                         score += (i*mult);
  152.                     }
  153.                     score_obj.score.text = "Score: "+score;
  154.                     removed = 0;
  155.                     mult = 1;
  156.                 }
  157.             }
  158.         }
  159.     }
  160. };
  161. function remove_tiles(tx, ty, clicked) {
  162.     tile_type = things["tile_"+field[tx][ty]]._currentframe;
  163.     if (!clicked) {
  164.         things["tile_"+field[tx][ty]].onEnterFrame = function() {
  165.             this._y++;
  166.             this._alpha--;
  167.             if (this._alpha == 0) {
  168.                 this.removeMovieClip();
  169.             }
  170.         };
  171.         field[tx][ty] = 0;
  172.         removed++;
  173.         if (ty == x2_horiz_pos) {
  174.             mult = 2;
  175.         }
  176.     }
  177.     if ((field[tx+1][ty] != 0) and (things["tile_"+field[tx+1][ty]]._currentframe == tile_type)) {
  178.         remove_tiles(tx+1,ty);
  179.     }
  180.     if ((field[tx-1][ty] != 0) and (things["tile_"+field[tx-1][ty]]._currentframe == tile_type)) {
  181.         remove_tiles(tx-1,ty);
  182.     }
  183.     if ((field[tx][ty+1] != 0) and (things["tile_"+field[tx][ty+1]]._currentframe == tile_type)) {
  184.         remove_tiles(tx,ty+1);
  185.     }
  186.     if ((field[tx][ty-1] != 0) and (things["tile_"+field[tx][ty-1]]._currentframe == tile_type)) {
  187.         remove_tiles(tx,ty-1);
  188.     }
  189. }
  190. function update_field() {
  191.     for (i=0; i<10; i++) {
  192.         for (j=1; j<10; j++) {
  193.             if ((field[i][j] != 0) and (field[i][j-1] == 0)) {
  194.                 falling = j-1;
  195.                 while ((field[i][falling] == 0) and (falling>=0)) {
  196.                     field[i][falling] = field[i][falling+1];
  197.                     things["tile_"+field[i][falling+1]]._y += 32;
  198.                     field[i][falling+1] = 0;
  199.                     falling--;
  200.                 }
  201.             }
  202.         }
  203.     }
  204. }

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!

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

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

20 Responses to “Christmas Couples: the finished Poux prototype”

  1. Jhelle on November 28th, 2007 1:47 pm

    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 :)

  2. Kevin on November 28th, 2007 5:50 pm

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

  3. bigbill on November 28th, 2007 6:17 pm

    That’s cool however the high score doesn’t seem to work or is that just me?

  4. Frederik J on November 28th, 2007 8:30 pm

    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!

  5. Robby on November 28th, 2007 8:50 pm

    Really cool game :) love the graphics!! Keep doing what you’re doing Emanuele!

  6. RJ on November 28th, 2007 11:45 pm

    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.

  7. Janaka on November 29th, 2007 12:13 am

    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!

  8. maciek on November 30th, 2007 12:21 am

    uhh… to do that you need a pathfindind algorithm. It is advanced stuff but if you really wanna do it search for A* algorithm

  9. Jhelle on November 30th, 2007 11:26 am

    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/

  10. Vixin on January 23rd, 2008 4:46 pm

    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

  11. Emanuele Feronato on January 23rd, 2008 4:54 pm

    Great idea! “Valentine Couples” will be out very soon, with some improvements and a better highscore table

  12. Vixin on February 7th, 2008 4:29 am

    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!

  13. Lynne Sargent on April 9th, 2008 8:28 pm

    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.:(

  14. Nathan on April 26th, 2008 6:56 pm

    It says ‘two OF more’, shouldn’t it be ‘two OR more’. Otherwise, great game!!

Leave a Reply




Trackbacks

  1. Prototype of a Flash game like Poux : Emanuele Feronato - italian geek and PROgrammer on November 28th, 2007 12:11 pm

    [...] 17th update: part 2 released November 22nd update: part 3 released November 28th update: Finished project [...]

  2. Prototype of a Flash game like Poux - Part 2 : Emanuele Feronato - italian geek and PROgrammer on November 28th, 2007 12:12 pm

    [...] 22nd update: part 3 released November 28th update: Finished project [...]

  3. Prototype of a Flash game like Poux - Part 3 : Emanuele Feronato - italian geek and PROgrammer on November 28th, 2007 12:13 pm

    [...] 28th update: Finished project [...]

  4. Summer Couples: a game made in an airplane : Emanuele Feronato - italian geek and PROgrammer on July 8th, 2008 3:24 pm

    [...] result is the “sequel” of Christmas Couples called Summer [...]

  5. Инструкция по монетизации флэш игр | terbooter on October 29th, 2008 6:57 pm

    [...] Если интересно узнать больше об этих играх, прочтите посты:Circle Сhain, Christmas Couples, [...]

  6. Ten Million Plays Club membership : Emanuele Feronato on November 12th, 2008 1:32 pm

    [...] second Flash game, Christmas Couples, a game released almost a year ago, reached 10,000,000 [...]