Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Rebuild Chile game, Actionscript 3, Flash and Game development.

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?

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.