Create a game like Perfectionism with Flash – Step 4
4th step of the quickest game creation tutorial… in the last step we added elements to the game field… now we have to introduce real clicks
Real clicks
What is a real click? In Perfectionism game you can have only two buttons clicked at once: since it’s basically a “swap some elements” game, you can only click the “from” button and the “to” button.
Moreover, if you click a button on the horizontal row and then roll over a button on the vertical row, the button you clicked must become unclicked, and the same must happen when you click a button on the vertical row and then roll over a button on the horizontal one.
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 | _root.attachMovie("grid","grid",1,{_x:90, _y:90});
_root.createEmptyMovieClip("rays",2);
swapping = false;
horizontal_hover = new Array(0, 0, 0, 0, 0, 0, 0, 0);
vertical_hover = new Array(0, 0, 0, 0, 0, 0, 0, 0);
horizontal_click = new Array(0, 0, 0, 0, 0, 0, 0, 0);
vertical_click = new Array(0, 0, 0, 0, 0, 0, 0, 0);
level = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
for (x=0; x<64; x++) {
if (level[x] == 1) {
grid.attachMovie("cell","cell_"+x,grid.getNextHighestDepth(),{_x:(x%8)*40, _y:Math.floor(x/8)*40});
}
if (level[x] == 2) {
grid.attachMovie("atom","atom"+x,grid.getNextHighestDepth(),{_x:(x%8)*40, _y:Math.floor(x/8)*40});
}
}
for (x=1; x<=8; x++) {
hs = grid.attachMovie("hswapper", "hswapper_"+x, grid.getNextHighestDepth(), {_x:-20, _y:40*x-20});
hs.pos = x;
hs.onEnterFrame = function() {
if (!swapping) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.gotoAndStop(2);
horizontal_hover[this.pos-1] = 1;
for (x=0; x<8; x++) {
vertical_click[x] = 0;
}
}
else {
this.gotoAndStop(1);
horizontal_hover[this.pos-1] = 0;
}
if (horizontal_click[this.pos-1] == 1) {
(this.gotoAndStop(3));
}
}
};
vs = grid.attachMovie("vswapper", "vswapper_"+x, grid.getNextHighestDepth(), {_x:40*x-20, _y:-20});
vs.pos = x;
vs.onEnterFrame = function() {
if (!swapping) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.gotoAndStop(2);
vertical_hover[this.pos-1] = 1;
for (x=0; x<8; x++) {
horizontal_click[x] = 0;
}
}
else {
this.gotoAndStop(1);
vertical_hover[this.pos-1] = 0;
}
if (vertical_click[this.pos-1] == 1) {
(this.gotoAndStop(3));
}
}
};
}
rays.onEnterFrame = function() {
if (!swapping) {
this.clear();
clicks = 0;
this.lineStyle(2,0x00ff00);
for (x=0; x<8; x++) {
if ((horizontal_hover[x] == 1) or (horizontal_click[x] == 1)) {
this.moveTo(90,x*40+110);
this.lineTo(410,x*40+110);
if (horizontal_click[x] == 1) {
clicks++;
}
}
if ((vertical_hover[x] == 1) or (vertical_click[x] == 1)) {
this.moveTo(x*40+110,90);
this.lineTo(x*40+110,410);
if (vertical_click[x] == 1) {
clicks++;
}
}
}
if (clicks == 2) {
swapping = true;
}
}
};
_root.onMouseDown = function() {
for (x=0; x<8; x++) {
if (horizontal_hover[x] == 1) {
horizontal_click[x] = 1-horizontal_click[x];
}
if (vertical_hover[x] == 1) {
vertical_click[x] = 1-vertical_click[x];
}
}
}; |
Line 3: Creating a boolean variable called swapping that will be true if we are ready to swap elements (two buttons on the same row or column have been clicked) or false otherwise
Line 21: Now all operations on the horizontal buttons are performed only if we aren’t swapping elements
Lines 25-27: If we are rolling over an horizontal button, then set all vertical buttons to unclicked
Line 41: Now all operations on the vertical buttons are performed only if we aren’t swapping elements
Lines 45-47: If we are rolling over an vertical button, then set all horizontal buttons to unclicked
Line 60: Now all operations on rays are performed only if we aren’t swapping elements
Line 62: Setting a variable called clicks, that will store the number of buttons clicked, to zero
Lines 68-70: If the x-th element of the horizontal_click array is set to 1 (the button is clicked), then increment clicks value
Lines 75-77: Same thing with the vertical_click array
Line 80: If we have two buttons clicked (and we know they will be two horizontal buttons or two vertical buttons), then set swapping to true. We are now ready to swap elements
And here it is:
Now if you click an horizontal button and then roll over a vertical one, you will lose the clicked status on the horizontal button, and the same thing will happen if you click on the vertical one and then roll over an horizontal button
If you click two horizontal buttons, you’re ready to swap elements! The game freezes at this point, because there is no swapping code, but it’s exactly what we are going to make
Swapping elements
This is the hardest part of the game… once you click two horizontal or vertical buttons, we have to swap elements. Remember that only the squares can be moved, while the rings have to remain in the same position even if I try to swap them
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 | _root.attachMovie("grid", "grid", 1, {_x:90, _y:90});
_root.createEmptyMovieClip("rays", 2);
swapping = false;
from = -1;
to = -1;
horizontal_swap = false;
vertical_swap = false;
horizontal_hover = new Array(0, 0, 0, 0, 0, 0, 0, 0);
vertical_hover = new Array(0, 0, 0, 0, 0, 0, 0, 0);
horizontal_click = new Array(0, 0, 0, 0, 0, 0, 0, 0);
vertical_click = new Array(0, 0, 0, 0, 0, 0, 0, 0);
level = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
for (x=0; x<64; x++) {
if (level[x] == 1) {
grid.attachMovie("cell", "cell_"+x, grid.getNextHighestDepth(), {_x:(x%8)*40, _y:Math.floor(x/8)*40});
}
if (level[x] == 2) {
at = grid.attachMovie("atom", "atom_"+x, grid.getNextHighestDepth(), {_x:(x%8)*40, _y:Math.floor(x/8)*40});
at.pos = x;
at.moving = 0;
at.onEnterFrame = function() {
if (this.moving == 0) {
if (swapping) {
if (horizontal_swap) {
if ((this.pos>=from*8) and (this.pos<=from*8+7)) {
this.moving = (to-from)*40;
}
if ((this.pos>=to*8) and (this.pos<=to*8+7)) {
this.moving = (from-to)*40;
}
}
if (vertical_swap) {
for (x=0; x<8; x++) {
if (this.pos == x*8+from) {
this.moving = (to-from)*40;
}
}
for (x=0; x<8; x++) {
if (this.pos == x*8+to) {
this.moving = (from-to)*40;
}
}
}
}
} else {
if (this.moving>0) {
if (horizontal_swap) {
this._y += 10;
}
if (vertical_swap) {
this._x += 10;
}
this.moving -= 10;
}
if (this.moving<0) {
if (horizontal_swap) {
this._y -= 10;
}
if (vertical_swap) {
this._x -= 10;
}
this.moving += 10;
}
if (this.moving == 0) {
this.pos = Math.round(this._x/40)+Math.round(this._y/40)*8;
for (x=0; x<8; x++) {
horizontal_click[x] = 0;
vertical_click[x] = 0;
swapping = false;
}
}
}
};
}
}
for (x=1; x<=8; x++) {
hs = grid.attachMovie("hswapper", "hswapper_"+x, grid.getNextHighestDepth(), {_x:-20, _y:40*x-20});
hs.pos = x;
hs.onEnterFrame = function() {
if (!swapping) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.gotoAndStop(2);
horizontal_hover[this.pos-1] = 1;
for (x=0; x<8; x++) {
vertical_click[x] = 0;
}
} else {
this.gotoAndStop(1);
horizontal_hover[this.pos-1] = 0;
}
if (horizontal_click[this.pos-1] == 1) {
(this.gotoAndStop(3));
}
}
};
vs = grid.attachMovie("vswapper", "vswapper_"+x, grid.getNextHighestDepth(), {_x:40*x-20, _y:-20});
vs.pos = x;
vs.onEnterFrame = function() {
if (!swapping) {
if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
this.gotoAndStop(2);
vertical_hover[this.pos-1] = 1;
for (x=0; x<8; x++) {
horizontal_click[x] = 0;
}
} else {
this.gotoAndStop(1);
vertical_hover[this.pos-1] = 0;
}
if (vertical_click[this.pos-1] == 1) {
(this.gotoAndStop(3));
}
}
};
}
rays.onEnterFrame = function() {
if (!swapping) {
horizontal_swap = false;
vertical_swap = false;
this.clear();
clicks = 0;
this.lineStyle(2, 0x00ff00);
for (x=0; x<8; x++) {
if ((horizontal_hover[x] == 1) or (horizontal_click[x] == 1)) {
this.moveTo(90, x*40+110);
this.lineTo(410, x*40+110);
if (horizontal_click[x] == 1) {
clicks++;
horizontal_swap = true;
}
}
if ((vertical_hover[x] == 1) or (vertical_click[x] == 1)) {
this.moveTo(x*40+110, 90);
this.lineTo(x*40+110, 410);
if (vertical_click[x] == 1) {
clicks++;
vertical_swap = true;
}
}
}
if (clicks == 2) {
from = -1;
to = -1;
swapping = true;
if (horizontal_swap) {
for (x=0; x<8; x++) {
if (horizontal_click[x] == 1) {
if (from == -1) {
from = x;
} else {
to = x;
}
}
}
}
if (vertical_swap) {
for (x=0; x<8; x++) {
if (vertical_click[x] == 1) {
if (from == -1) {
from = x;
} else {
to = x;
}
}
}
}
}
}
};
_root.onMouseDown = function() {
for (x=0; x<8; x++) {
if (horizontal_hover[x] == 1) {
horizontal_click[x] = 1-horizontal_click[x];
}
if (vertical_hover[x] == 1) {
vertical_click[x] = 1-vertical_click[x];
}
}
}; |
Line 4: Declaring a from variable that will store the row (or column) to be swapped. -1 means no columns (or rows) to swap
Line 5: Same thing with the destination row (or column)
Line 6: Boolean flag that tells me if I should make an horizontal swap
Line 7: Boolean flag that tells me if I should make a vertical swap
Line 20: When I create the square movieclip, I assign it a moving variable that will tell me how many pixel the square has to move.
Line 22: If the square is not moving…
Line 23: If we must swap rows (or columns)…
Line 24: If we must perform an horizontal swap (we’ll see later in this code how to determine if it’s an horizontal or verticals swap)…
Line 25: If the square is in the starting row (we’ll see later in this code how to determine which row is the starting one)…
Line 26: Calculating the number of pixels the square has to move. This number is determined multiplying 40 (the side of one cell of the game field) by the difference between the ending and the starting rows
Lines 28-30: Same thing as lines 25-27, but I am checking if the square is on the destination row
Lines 32-43: Same thing as lines 24-31, just applied to vertical swapping
In a brief summary, if the square is not already moving and I know I have to swap two rows (or columns), first I check if I am going to swap rows or columns, then I check if the square lies on one of the rows (or columns) to be swapped and in this case I determine how many pixels the square has to move up/down/left/right according to its position in the swapping row/column
Line 45: If the square is moving…
Line 46: If the amount of pixels the square has to move is greater than zero (the square moves from left to right or from up to down)
Line 47: If it’s an horizontal swap…
Line 48: Move the square down by 10 pixels (an arbitrary speed I set)
Lines 50-52: Same thing for the vertical swap, just moving the square to the right by 10 pixels
Line 53: Since the square has moved by 10 pixels (no matter in which direction), I subtract 10 to moving variable
Lines 55-63: Same thing as lines 46-64, just managing movements when moving is less than zero
In a brief summary, if the square is moving, I determine the direction I will move the square, and move it by 10 pixels per frame, until I moved it for the same amount of pixels calculated at lines 26 or 29 or 35 or 40
Line 64: If moving is equal to zero (I just moved the square for the last 10 pixels step)
Line 65: Update pos value according to the physical position of the square in the stage
Lines 66-70: Now that columns/rows have been swapped, it’s time to clear the click status of all buttons. I don’t really know why I included line 69 inside the cycle… oh well…
Line 129: Setting horizontal_swap to true if an horizontal button has been clicked
Line 137: Same thing for the vertical_swap variable
Line 142: Now we have to manage the game when the player clicks on two buttons… first resetting from to -1…
Line 143: Then doing the same thing with to
Line 144: Set swapping to true, now we only need to know the couple of rows/columns to swap
Line 145: If it’s an horizontal swap…
Line 146: Cycle scanning all horizontal_click array elements
Line 147: If the x-th element is equal to 1 (the button has been clicked)…
Lines 148-152: I have to assign the from and the to variables. I want the from variable to store the upper (or leftmost) position on the field where the player clicked the button and the the to variable to store the lower (or rightmost) one. So, if from is at -1, it means this is the first clicked button I found, so I assign x value to from. If from is not -1, it means I already found a clicked button so this must be the second button, so I store x value to to variable
Lines 156-166: Same thing as lines 145-155, but for vertical swapping
And that’s it!! Now you can swap rows and columns, but the game still crashes if you try to swap empty rows/columns
Don’t be afraid of the complexity of this code because this was the hardest part.
You’ll see in next tutorial how things will get easier and easier now that the game is ready to be published
Download source codes and prepare yourself for next step
They can be easily customized to meet the unique requirements of your project.
3 Responses to “Create a game like Perfectionism with Flash – Step 4”
Leave a Reply
Trackbacks
-
Create a game like Perfectionism with Flash - Step 5 : Emanuele Feronato - italian geek and PROgrammer on
April 10th, 2008 5:12 pm
[...] this step we have to manage row/column swapping that in the previous step caused the game to crash if there was nothing to [...]
- Citrus Engine released for free for learning
- My epic fail with ClickBank
- Get up to $100,000 for your next Flash game with Mochi GAME Developer Fund
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines – 17 lines version
- Sell sitelocked version of your Flash games and even .fla sources to Free Online Games
- Protect your work from ActionScript code theft with SWF Protector
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines
- Understanding Box2D’s one-way platforms, aka CLOUDS
- Triqui MochiAds Arcade plugin for WordPress upgraded to 1.2
- Box2D Flash game creation tutorial – part 2
- Create a Lightbox effect only with CSS - no javascript needed
- Flash game creation tutorial - part 1
- Create a Flash Racing Game Tutorial
- Flash game creation tutorial - part 2
- Make a Flash game like Flash Element Tower Defense - Part 2
- Flash game creation tutorial - part 3
- Triqui MochiAds Arcade plugin for WordPress official page
- Make a Flash game like Flash Element Tower Defense - Part 1
- Create a flash draw game like Line Rider or others - part 1
- Create a flash artillery game - step 1
- Flash game creation tutorial – part 5.2 (4.88/5)
- Create a flash artillery game – step 1 (4.79/5)
- Create a Flash Racing Game Tutorial (4.76/5)
- Create a survival horror game in Flash tutorial – part 1 (4.74/5)
- Create a flash artillery game – step 2 (4.74/5)
- Creation of a Flash arcade site using WordPress – step 2 (4.73/5)
- Flash game creation tutorial – part 1 (4.71/5)
- Flash game creation tutorial – part 2 (4.71/5)
- Create a flash draw game like Line Rider or others – part 1 (4.69/5)
- Creation of a platform game with Flash – step 2 (4.68/5)





That was quick huh?
Need some graphs, just let me know.
Good stuff, the only thing missing is nice graphics, more gameplay, its not an easy game to both code and play from what I can tell. Good job so far !