Make a game like Lumines with Flash – part 3

Read all posts about "" game

Now it’s time to make bricks disappear if they group in a 2×2 square.

Read part 1 and 2 if you did not already.

It’s not difficult to check if bricks form a 2×2 square… and it’s not difficult to remove them from the stage.

The tricky part is making bricks fill the empty spaces left by disappeared bricks and managing combos (fallen bricks can make another 2×2 square, generating more falling bricks, and so on).

I preferred not to have an onEnterFrame on every brick to check if it’s over an empty space and eventually move it, so I created another array called bricks_in_field saving the depth of the brick in that position, so when I remove some bricks I just have to put in the moveable_bricks the depth found in the bricks_in_field array and the “engine” does the rest.

Here it is the actionscript:

// 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 bricks position
bricks_in_field = new Array();
// array containing the bricks I can move
moveable_bricks = new Array();
// initializing and drawing the play field and the bricks position fields
for (x=0; x0) {
						moveable_bricks.push(bricks_in_field[x][start_y+1]);
						start_y--;
					}
					start_y = y-1;
					while (field[x+1][start_y]>0) {
						moveable_bricks.push(bricks_in_field[x+1][start_y+1]);
						start_y--;
					}
					falling = true;
				}
			}
		}
		// place new bricks only if no bricks are falling
		if (!falling and moveable_bricks.length == 0) {
			place_bricks();
		}
		// 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_ 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
		moveable_bricks[x] = brk.getDepth();
	}
}

And this is the result:

Now wait for the next step to handle timing events.

Download the source.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers