Create a Flash game like Rebuild Chile – Step 3: smooth movement

Read all posts about "" game

In this 3rd part I’ll cover a feature requested by some readers… smooth movement.

In step 1 and 2, the character and the debris move square by square.

This leads to a unplayable game, because the bulldozer moves too quickly.

We need a smoother movement.

Here is how will it work:

The bulldozer now has two states: moving and not moving

When the bulldozer is not moving, it simply waits for the player to press a key, like in previous steps.

When the bulldozer is moving, the player cannot interact with it (basically the player can’t stop it when is moving from one tile to another) and the bulldozer (and eventually the debris the bulldozer is pushing) moves by a certain amount of pixels, in this case just 10 pixels, until it completely moves to next tile. Then the bulldozer returns to a not moving state.

The interesting thing is we know the maximum number of moving objects is two: the bulldozer and eventually the debris.

This is the script:

package {
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	public class rebuild extends Sprite {
		public var map:Array=new Array();
		public var bulldozer_pos:Array= new Array();
		public var tree:tree_mc;
		public var debris:debris_mc;
		public var bulldozer:bulldozer_mc;
		public var key_pressed:int=0;
		public var bulldozer_is_moving:Boolean=false;
		public var bulldozer_x_dir:int=0;
		public var bulldozer_y_dir:int=0;
		public var debris_to_move:String="";
		public function rebuild():void {
			map=[[9,9,9,9,9,9,9,9,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]];
			bulldozer_pos=[7,3];
			draw_map();
			place_bulldozer();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, on_key_down);
			stage.addEventListener(KeyboardEvent.KEY_UP, on_key_up);
			stage.addEventListener(Event.ENTER_FRAME,on_enter_frame);
		}
		public function draw_map():void {
			for (var i:int=1; i<10; i++) {
				for (var j:int=1; j<10; j++) {
					switch (map[j][i]) {
						case 1 :
							tree = new tree_mc();
							tree.x=(i-1)*50;
							tree.y=(j-1)*50;
							addChild(tree);
							break;
						case 2 :
							debris=new debris_mc();
							debris.name="debris_"+j+"_"+i;
							debris.x=(i-1)*50;
							debris.y=(j-1)*50;
							addChild(debris);
							break;
					}
				}
			}
		}
		public function place_bulldozer():void {
			bulldozer = new bulldozer_mc();
			bulldozer.x=50*(bulldozer_pos[1]-1);
			bulldozer.y=50*(bulldozer_pos[0]-1);
			addChild(bulldozer);
		}
		public function on_key_down(e:KeyboardEvent):void {
			key_pressed=e.keyCode;
		}
		public function on_key_up(e:KeyboardEvent):void {
			if (e.keyCode==key_pressed) {
				key_pressed=0;
			}
		}
		public function on_enter_frame(e:Event):void {
			if (! bulldozer_is_moving) {
				switch (key_pressed) {
					case 37 :
						walk(-1,0);
						break;
					case 38 :
						walk(0,-1);
						break;
					case 39 :
						walk(1,0);
						break;
					case 40 :
						walk(0,1);
						break;
				}
			}
			if (bulldozer_is_moving) {
				bulldozer.x+=10*bulldozer_x_dir;
				bulldozer.y+=10*bulldozer_y_dir;
				if (debris_to_move!="") {
					with (getChildByName(debris_to_move)) {
						x+=10*bulldozer_x_dir;
						y+=10*bulldozer_y_dir;
					}
				}
				if ((bulldozer.x+bulldozer.y)%50==0) {
					bulldozer_is_moving=false;
					bulldozer_pos[0]+=bulldozer_y_dir;
					bulldozer_pos[1]+=bulldozer_x_dir;
					if (debris_to_move!="") {
						getChildByName(debris_to_move).name="debris_"+(bulldozer_pos[0]+1*bulldozer_y_dir)+"_"+(bulldozer_pos[1]+1*bulldozer_x_dir);
						debris_to_move="";
					}
				}
			}
		}
		function walk(px,py):void {
			var moved:Boolean=false;
			if (map[bulldozer_pos[0]+py][bulldozer_pos[1]+px]==0) {
				moved=true;
			} else {
				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]=2;
					map[bulldozer_pos[0]+py][bulldozer_pos[1]+px]=0;
					with (getChildByName("debris_"+(bulldozer_pos[0]+py)+"_"+(bulldozer_pos[1]+px))) {
						debris_to_move=name;
					}
					moved=true;
				}
			}
			if (moved) {
				bulldozer_is_moving=true;
				bulldozer_x_dir=px;
				bulldozer_y_dir=py;
			}
		}
	}
}

Let's see the new code

Line 12: variable to store whether the bulldozer is moving or not

Lines 13-14: variables to store bulldozer's x and y direction

Line 15: name of the debris we have to move (if any)

Line 61: as said, I check for user keyboard input only if the bulldozer is not moving

Line 77: if the bulldozer is moving... (notice there isn't an else to process the movement in the same frame the user pressed a key)

Lines 78-79: moving the bulldozer by 10 pixels (1/5 a tile) in the required direction

Lines 80-85: same thing with the debris, if I have to move it

Lines 86-94: when the bulldozer is on the tile, stop moving it, update the map and the debris name.

and this is the result:

first step with this one.

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