Make a game like Lumines with Flash – part 2
In the first part we managed to move and rotate a 2×2 square made (obviously) by 4 bricks.
Now we’ll see how to make them fall when we press SPACE key.
Notice that you move and rotate blocks by tapping arrow keys, but you make them fall by pressing SPACE.
This because timing is essential, and we want to make blocks fall as the player touches the spacebar.
The code does not have anything difficult, I just have to check if there are empty spaces under falling bricks.
No “game over” check at the moment, it will be covered later.
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 | // declaring some setup variables
// number of horizontal cells
grid_width = 16;
// number of vertical cells
grid_height = 10;
// size of the cell
tile_size = 30;
// offset in pixels fron the left side of the stage
x_offset = 10;
// offset in pixels from the top side of the stage
y_offset = 10;
// number of different colors that can be displayed in a brick
different_colors = 3;
// boolean values saying if I should wait for the left (or right, up...) key to be released
// this is used to make the player move bricks tapping arrow keys instead of just pressing them
wait_left = false;
wait_right = false;
wait_up = false;
wait_down = false;
// flag indicating if blocks are falling
falling = false;
// array containing the game field data
field = new Array();
// array containing the bricks I can move
moveable_bricks = new Array();
// initializing and drawing the play field
for (x=0; x<grid_width; x++) {
field[x] = Array();
for (y=0; y<grid_height; y++) {
field[x][y] = 0;
// look how I determine cells position according to tile size and offsets
cell = _root.attachMovie("brick", "brick_"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:x*tile_size+x_offset, _y:(y+2)*tile_size+y_offset});
// first frame = empty cell
cell.gotoAndStop(1);
}
}
// calling the function that will place four bricks on the stage
place_bricks();
// main function, to be executed at every frame
_root.onEnterFrame = function() {
// if blocks aren't falling
if (!falling) {
// this is how I detect if a key was tapped:
// when it's pressed, I wait for it to be released (in this case: not pressed)
// thanks to the wait_<direction> variable
if (Key.isDown(Key.LEFT)) {
wait_left = true;
} else {
if (wait_left) {
// if the left key has been tapped, move the four bricks on the left
for (x=0; x<4; x++) {
// this "if" is used to determine if the bricks are still inside the game field
if ((_root["brick_"+moveable_bricks[x]]._x-x_offset)/tile_size-_root["brick_"+moveable_bricks[x]].pos%2>0) {
_root["brick_"+moveable_bricks[x]]._x -= tile_size;
}
}
// reset variable, now I must wait again for a key to be pressed
wait_left = false;
}
}
// same routine for the right key
if (Key.isDown(Key.RIGHT)) {
wait_right = true;
} else {
if (wait_right) {
for (x=0; x<4; x++) {
if ((_root["brick_"+moveable_bricks[x]]._x-x_offset)/tile_size-_root["brick_"+moveable_bricks[x]].pos%2<14) {
_root["brick_"+moveable_bricks[x]]._x += tile_size;
}
}
wait_right = false;
}
}
// when the DOWN arrow is pressed, I must rotate the bricks clockwise
// block 0: moves to the right and becomes block 1
// block 1: moves down and becomes block 3
// block 2: moves up and becomes block 0
// block 3: moves to the left and becomes block 2
if (Key.isDown(Key.DOWN)) {
wait_down = true;
} else {
if (wait_down) {
for (x=0; x<4; x++) {
switch (_root["brick_"+moveable_bricks[x]].pos) {
case 0 :
_root["brick_"+moveable_bricks[x]].pos = 1;
_root["brick_"+moveable_bricks[x]]._x += tile_size;
break;
case 1 :
_root["brick_"+moveable_bricks[x]].pos = 3;
_root["brick_"+moveable_bricks[x]]._y += tile_size;
break;
case 2 :
_root["brick_"+moveable_bricks[x]].pos = 0;
_root["brick_"+moveable_bricks[x]]._y -= tile_size;
break;
case 3 :
_root["brick_"+moveable_bricks[x]].pos = 2;
_root["brick_"+moveable_bricks[x]]._x -= tile_size;
break;
}
}
wait_down = false;
}
}
// when the UP arrow is pressed, I must rotate the bricks counter-clockwise
// block 0: moves down the right and becomes block 2
// block 1: moves to the left and becomes block 0
// block 2: moves to the right and becomes block 3
// block 3: moves up and becomes block 1
if (Key.isDown(Key.UP)) {
wait_up = true;
} else {
if (wait_up) {
for (x=0; x<4; x++) {
switch (_root["brick_"+moveable_bricks[x]].pos) {
case 0 :
_root["brick_"+moveable_bricks[x]].pos = 2;
_root["brick_"+moveable_bricks[x]]._y += tile_size;
break;
case 1 :
_root["brick_"+moveable_bricks[x]].pos = 0;
_root["brick_"+moveable_bricks[x]]._x -= tile_size;
break;
case 2 :
_root["brick_"+moveable_bricks[x]].pos = 3;
_root["brick_"+moveable_bricks[x]]._x += tile_size;
break;
case 3 :
_root["brick_"+moveable_bricks[x]].pos = 1;
_root["brick_"+moveable_bricks[x]]._y -= tile_size;
break;
}
}
wait_up = false;
}
}
// when SPACE key is pressed, I don't wait for its release but I detect the key at once
if (Key.isDown(Key.SPACE)) {
// letìs made bricks fall...
falling = true;
}
} else {
//if the blocks are falling
// blocks_landed variable will count the number of bricks that already touched the ground
// or that cannot fall anymore because they are over other bricks
blocks_landed = 0;
for (x=0; x<4; x++) {
// calculating x and y position of the brick in the array
x_pos = (_root["brick_"+moveable_bricks[x]]._x-x_offset)/tile_size;
y_pos = (_root["brick_"+moveable_bricks[x]]._y-y_offset)/tile_size-1;
// determining if the block can fall. There are two conditions:
// 1: its position is less than zero. It means the block is outside the grid, in its starting position
// 2: its position is lower than the grid height and the tile under the block is empty
if ((y_pos<0) or ((y_pos<grid_height) and (field[x_pos][y_pos] == 0))) {
// updating field array
field[x_pos][y_pos] = _root["brick_"+moveable_bricks[x]]._currentframe;
field[x_pos][y_pos-1] = 0;
// physically moving the brick
_root["brick_"+moveable_bricks[x]]._y += tile_size;
} else {
// if the brick cannot move down, increase the number of blocks landed
blocks_landed++;
}
}
// if all four bricks landed successfully...
if (blocks_landed == 4) {
// reset variable to false
falling = false;
// place four more bricks
place_bricks();
}
}
};
// function to place four bricks on the stage
function place_bricks() {
// placing the four bricks
for (x=0; x<4; x++) {
// again, look how I determine bricks position according to tile size and offsets
brk = _root.attachMovie("brick", "brick_"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:(grid_width/2+(x%2))*tile_size+x_offset, _y:y_offset+tile_size*Math.floor(x/2)});
// setting a random color for the brick (frames 2 to different_colors+1)
brk.gotoAndStop(Math.floor(Math.random()*different_colors)+2);
// saving brick position
// 0: up left
// 1: up right
// 2: bottom left
// 3: bottom right
brk.pos = x;
// saving the depth of the brick into the moveable_bricks array
// if you look how did I assign brick names, you'll see that I can determine a brick name
// starting from its depth. It's simply "brick_"+<the_depth>
moveable_bricks[x] = brk.getDepth();
}
} |
And this is the result… arrow keys to move/rotate and SPACE to drop
They can be easily customized to meet the unique requirements of your project.















(32 votes, average: 4.00 out of 5)









This post has one comment
Make a game like Lumines with Flash - part 3 : Emanuele Feronato - italian geek and PROgrammer
[...] part 1 and 2 if you did not [...]