Create a Flash game like Rebuild Chile – Step 4: removing debris

Read all posts about "" game

Time to see the feature that will allow you to complete a level: removing debris.

Debris can be removed in two ways:

1) Pushing them off the stage through an hole in the border walls

2) Calling an helicopter and removing them on the fly

Obviously pro players will prefer the first option.

First, we need two new tile types: border wall and hole in border wall. The border wall is unwalkable, while the hole in the border wall is still unwalkable but debris can be pushed on it. Once on this tile, the debris disappear.

Also, pressing “H” you can call an helicopter, select a debris with arrow keys and removing pressin SPACEBAR or trying to make it without the helicopter pressing “H” again.

This is the complete, fully commented code:

package {
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	public class rebuild extends Sprite {
		// array to store the map
		public var map:Array=new Array();
		// array to store bulldozer position
		public var bulldozer_pos:Array= new Array();
		// tree movieclip
		public var tree:tree_mc;
		// debris movieclip
		public var debris:debris_mc;
		// bulldozer movieclip
		public var bulldozer:bulldozer_mc;
		// external wall movieclip
		public var ext_wall:ext_wall_mc;
		// helicopter movieclip
		public var heli:heli_mc;
		// variable to store the last key pressed
		public var key_pressed:int=0;
		// flag to determine if the bulldozer is moving or not
		public var bulldozer_is_moving:Boolean=false;
		// bulldozer x and y direction
		public var bulldozer_x_dir:int=0;
		public var bulldozer_y_dir:int=0;
		// variable to determine which debris the helicopter is going to pick up
		public var heli_on_debris:int=1;
		// number of debris left to clear the screen
		public var debris_left:int=0;
		// variable to store the name of the debris we will move
		public var debris_to_move:String="";
		// main function
		public function rebuild():void {
			// initializing the map
			// 0: empty space (walkable)
			// 1: tree (unmovable object)
			// 2: debris (movable object)
			// 9: external wall (unmovable object)
			// 10: hole in external wall (unwalkable, but debris can be pushed on it)
			map=[[9,9,9,9,9,9,9,10,9,9,9],[9,0,0,2,0,0,0,0,0,0,9],[9,0,0,0,0,0,0,0,0,0,9],[9,1,1,1,1,1,0,1,0,0,9],[9,1,0,0,2,0,0,1,0,0,9],[9,1,0,0,0,0,0,1,0,0,9],[9,1,1,1,1,1,1,1,0,0,9],[9,0,0,0,0,2,0,0,0,0,9],[9,0,0,0,0,0,0,0,0,0,9],[9,0,0,0,0,0,0,0,0,0,9],[9,9,9,9,9,9,9,9,9,9,9]];
			// initializing bulldozer starting position
			bulldozer_pos=[7,3];
			// calling main functions
			draw_map();
			place_bulldozer();
			// adding listeners
			stage.addEventListener(KeyboardEvent.KEY_DOWN, on_key_down);
			stage.addEventListener(KeyboardEvent.KEY_UP, on_key_up);
			addEventListener(Event.ENTER_FRAME,on_enter_frame);
		}
		// function to draw the map
		public function draw_map():void {
			// looping though all map. What's that "11"? it's the map width/height
			for (var i:int=0; i<11; i++) {
				for (var j:int=0; j<11; j++) {
					switch (map[j][i]) {
							// I found a tree
						case 1 :
							// placing the tree
							tree = new tree_mc();
							// What's that "50"? it's the tile width/height
							// And the "25"? It's half a tile width/height
							// the whole game area is shifted by half a tile up and left
							// so that the external wall is only displayed at a half
							tree.x=i*50-25;
							tree.y=j*50-25;
							addChild(tree);
							break;
						case 2 :
							// placing a debris, same way as the tree
							debris=new debris_mc();
							debris.name="debris_"+j+"_"+i;
							debris.x=i*50-25;
							debris.y=j*50-25;
							addChild(debris);
							debris_left++;
							break;
						case 9 :
							// placing an external wall, same way as the tree
							ext_wall = new ext_wall_mc();
							ext_wall.x=i*50-25;
							ext_wall.y=j*50-25;
							addChild(ext_wall);
							break;
					}
				}
			}
		}
		// function to place the bulldozer, in the same way as the tree
		public function place_bulldozer():void {
			bulldozer = new bulldozer_mc();
			bulldozer.x=50*(bulldozer_pos[1])-25;
			bulldozer.y=50*(bulldozer_pos[0])-25;
			addChild(bulldozer);
		}
		// function to be executed every time a key is down
		public function on_key_down(e:KeyboardEvent):void {
			// storing key_pressed variable the keyCode of the latest key pressed
			key_pressed=e.keyCode;
		}
		// function to be executed every time a key is released
		public function on_key_up(e:KeyboardEvent):void {
			// if we are releasing the same key we pressed last time, then reset key_pressed variable
			// this way we allow to press only one key at time
			if (e.keyCode==key_pressed) {
				key_pressed=0;
			}
		}
		// function to be executed at every frame
		public function on_enter_frame(e:Event):void {
			// I am checking for keyboard input only if the bulldozer is not already moving
			// and there is at least one debris to remove
			if (! bulldozer_is_moving&&debris_left>0) {
				switch (key_pressed) {
						// right
					case 37 :
						walk(-1,0);
						break;
					case 38 :
						// up
						walk(0,-1);
						break;
					case 39 :
						//left
						walk(1,0);
						break;
					case 40 :
						//down
						walk(0,1);
						break;
					case 72 :
						// "H", calling the helicopter
						// resetting key_pressed
						key_pressed=0;
						// if the helicopter in not on stage...
						if (heli==null) {
							// place the helicopter on the first debris and don't remove the debris
							heli=new heli_mc();
							addChild(heli);
							place_heli(heli_on_debris,false);
						} else {
							// if the helicopter is already on stage, remove it and set the debris
							// to be picked up as the first one
							removeChild(heli);
							heli=null;
							heli_on_debris=1;
						}
						break;
					case 32 :
						// SPACEBAR, to remove selected debris
						// if the helicopter is on stage...
						if (heli!=null) {
							// remove the debris under the helicopter
							place_heli(heli_on_debris,true);
							// remove the helicopter itself
							removeChild(heli);
							heli=null;
							// set the debris to be picked up as the first one
							heli_on_debris=1;
						}
						break;
				}
			}
			// if the bulldozer is moving...
			if (bulldozer_is_moving) {
				// move the bulldozer one more step. One step = 10 pixels = 1/5 a tile
				bulldozer.x+=10*bulldozer_x_dir;
				bulldozer.y+=10*bulldozer_y_dir;
				// if there is a debris to move...
				if (debris_to_move!="") {
					// move the debris one more step
					with (getChildByName(debris_to_move)) {
						x+=10*bulldozer_x_dir;
						y+=10*bulldozer_y_dir;
					}
				}
				// if the bulldozer is completely on a tile...
				if ((bulldozer.x+bulldozer.y)%50==0) {
					// stop moving the bulldozer
					bulldozer_is_moving=false;
					// update bulldozer position
					bulldozer_pos[0]+=bulldozer_y_dir;
					bulldozer_pos[1]+=bulldozer_x_dir;
					// if there is a debris to move...
					if (debris_to_move!="") {
						// set the tile occupied by the debris BEFORE it moved to "0" (walkable)
						map[bulldozer_pos[0]][bulldozer_pos[1]]=0;
						// if the debris is on the map tile marked as "10" (hole in external wall)...
						if (map[bulldozer_pos[0]+bulldozer_y_dir][bulldozer_pos[1]+bulldozer_x_dir]==10) {
							// remove the debris
							removeChild(getChildByName(debris_to_move));
							// decrease number of remaining debris
							debris_left--;
						} else {
							// if it's not on a "10" map, then simply update debris name and the map
							getChildByName(debris_to_move).name="debris_"+(bulldozer_pos[0]+1*bulldozer_y_dir)+"_"+(bulldozer_pos[1]+1*bulldozer_x_dir);
							map[bulldozer_pos[0]+bulldozer_y_dir][bulldozer_pos[1]+bulldozer_x_dir]=2;
						}
						// set the debris_to_move variable as "no debris to move"
						debris_to_move="";
					}
				}
			}
		}
		// Function to move the bulldozer or the helicopter. px and py are the amount of tiles we want to move the bulldozer
		// Possible values passed:
		// 1,0: right
		// -1,0: left
		// 0,1: down
		// 0,-1: up
		public function walk(px:int,py:int):void {
			// if the helicopter is not on stage...
			if (heli==null) {
				// setting a "moved" flag as "false". It says the bulldozer did not move
				var moved:Boolean=false;
				// if the tile that the bulldozer should walk on is walkable...
				if (map[bulldozer_pos[0]+py][bulldozer_pos[1]+px]==0) {
					// the bulldozer moved
					moved=true;
				} else {
					// else, if the tile that the bulldozer should walk on is occupied by a debris and
					// the next one is a walkable tile or an hole in external wall...
					if (map[bulldozer_pos[0]+py][bulldozer_pos[1]+px]==2&&(map[bulldozer_pos[0]+2*py][bulldozer_pos[1]+2*px]==0||map[bulldozer_pos[0]+2*py][bulldozer_pos[1]+2*px]==10)) {
						// set which debris has to move
						debris_to_move=getChildByName("debris_"+(bulldozer_pos[0]+py)+"_"+(bulldozer_pos[1]+px)).name;
						// the bulldozer moved
						moved=true;
					}
				}
				// if the bulldozer moved...
				if (moved) {
					// setting variables to let it move and the direction it has to move
					bulldozer_is_moving=true;
					bulldozer_x_dir=px;
					bulldozer_y_dir=py;
				}
			} else {
				// if the helicopter is on stage...
				// reset key_pressed variable
				key_pressed=0;
				// increase heli_on_debris value by 1 if the direction is "down" or "right"
				// decrease it by 1 if the direction is "left" or "up"
				heli_on_debris+=px+py;
				// checking if we completely cycled through debris
				if (heli_on_debris<1) {
					heli_on_debris=debris_left;
				}
				if (heli_on_debris>debris_left) {
					heli_on_debris=1;
				}
				// place the helicopter on the selected debris and don't remove it
				place_heli(heli_on_debris,false);
			}
		}
		// function to place the helicopter on a debris and eventually remove it
		// n: n-th debris, starting from the upper left corner
		// del: if true, remove the debris
		public function place_heli(n:int,del:Boolean):void {
			// debris already found on the map
			var debris_found=0;
			// scanning the map...
			for (var i:int=1; i<10; i++) {
				for (var j:int=1; j<10; j++) {
					// if I found a debris...
					if (map[i][j]==2) {
						// increasing the number of debris I found
						debris_found++;
						// if I am on the right debris...
						if (debris_found==n) {
							// place the helicopter on the debris
							heli.x=j*50-25;
							heli.y=i*50-25;
							// if I have to remove the debris...
							if (del) {
								// update the map
								map[i][j]=0;
								// remove the debris
								removeChild(getChildByName("debris_"+i+"_"+j));
								// update remaining debris
								debris_left--;
							}
							// exit the cycle
							j=10;
							i=10;
						}
					}
				}
			}
		}
	}
}

And this is the result:

original game.

Download the source code.

I enjoyed the making of this prototype so much that I am planning a game based on it, maybe with more options such as more ways to remove debris, and a different theme.

Any idea?

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

214 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
// 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