Create a Flash ball game with visual from above tutorial part 3

Read all posts about "" game

January 16th update: 4th part released

In the third part of this tutorial I am going to fix a minor bug and introduce three new tiles:

info tile (displays a message when the ball rolls over it)
reverse control tile (reverses the controls of the ball)
checkpoint tile (makes you respawn at the checkpoint tile if you die)

Before continuing, I suggest you to read tutorials 1 and 2.

The actionscript of the last example has changed to:

_root.attachMovie("starz", "starz", 1, {_x:-20, _y:-20});
_root.attachMovie("ball", "ball", 3, {_x:240, _y:220});
_root.attachMovie("info_panel", "info_panel", 4, {_y:410, _alpha:50, _visible:false});
ball.texture.setMask(ball.ball_itself);
yspeed = 0;
xspeed = 0;
checkpoint_passed = false;
lev = 1;
draw_level(lev);
ball.onEnterFrame = function() {
	info_panel._visible = false;
	friction = 0.99;
	power = 0.4;
	brick_x = Math.floor((bricks._x-200)/80)*-1;
	brick_y = Math.floor((bricks._y-180)/80)*-1;
	type_of_tile = level[brick_y][brick_x];
	if (type_of_tile>12000) {
		message_to_show = messages[type_of_tile%12000];
		type_of_tile = 12;
	}
	switch (type_of_tile) {
	case 1 :
		// normal tile
		break;
	case 2 :
		// down spin tile
		yspeed += 0.2;
		break;
	case 3 :
		// up spin tile
		yspeed -= 0.2;
		break;
	case 4 :
		// left spin tile
		xspeed -= 0.2;
		break;
	case 5 :
		// right spin tile
		xspeed += 0.2;
		break;
	case 6 :
		// glass tile
		depth = brick_y*12+brick_x;
		bricks["brick_"+depth]._alpha--;
		if (bricks["brick_"+depth]._alpha<1) {
			level[brick_y][brick_x] = 0;
		}
		break;
	case 7 :
		// spin tile
		xspeed *= 1.05;
		yspeed *= 1.05;
		break;
	case 8 :
		// slip tile
		friction = 1;
		power = 0;
		break;
	case 9 :
		// beam
		depth = brick_y*12+brick_x;
		if (bricks["brick_"+depth].lava._currentframe>90) {
			ball_die();
		}
		break;
	case 10 :
		// exit
		checkpoint_passed = false;
		lev++;
		_root.removeMovieClip("bricks");
		draw_level(lev);
		break;
	case 11 :
		// reverse
		power *= -1;
		break;
	case 12 :
		// info
		info_panel._visible = true;
		info_panel.message_text.text = message_to_show;
		break;
	case 13 :
		//checkpoint
		checkpoint_passed = true;
		save_x = brick_x;
		save_y = brick_y;
		break;
	default :
		// hole
		ball_die();
		break;
	}
	if (Key.isDown(Key.LEFT)) {
		xspeed -= power;
	}
	if (Key.isDown(Key.RIGHT)) {
		xspeed += power;
	}
	if (Key.isDown(Key.UP)) {
		yspeed -= power;
	}
	if (Key.isDown(Key.DOWN)) {
		yspeed += power;
	}
	xspeed *= friction;
	yspeed *= friction;
	if ((xspeed<0.1) and (xspeed>-0.1)) {
		xspeed = 0;
	}
	if ((yspeed<0.1) and (yspeed>-0.1)) {
		yspeed = 0;
	}
	bricks._y -= yspeed;
	bricks._x -= xspeed;
	starz._x = -20+((bricks._x-240)/10);
	starz._y = -20+((bricks._y-220)/10);
	this.texture._y += yspeed;
	this.texture._x += xspeed;
	if (this.texture._x>53) {
		this.texture._x -= 63;
	}
	if (this.texture._x<-53) {
		this.texture._x += 63;
	}
	if (this.texture._y>53) {
		this.texture._y -= 63;
	}
	if (this.texture._y<-53) {
		this.texture._y += 63;
	}
};
function ball_die() {
	bricks._x = 240-(80*_root.ball_start_x);
	bricks._y = 220-(80*_root.ball_start_y);
	xspeed = 0;
	yspeed = 0;
	draw_level(lev);
}
function draw_level(number) {
	yspeed = 0;
	xspeed = 0;
	level = new Array();
	messages = new Array();
	switch (number) {
	case 1 :
		_root.ball_start_x = 0;
		_root.ball_start_y = 0;
		if (checkpoint_passed) {
			_root.ball_start_x = save_x;
			_root.ball_start_y = save_y;
		}
		level[0] = new Array(12001, 11, 11, 11, 11);
		level[1] = new Array(0, 0, 0, 0, 1);
		level[2] = new Array(1, 1, 10, 0, 1);
		level[3] = new Array(1, 0, 0, 0, 1);
		level[4] = new Array(12003, 1, 1, 13, 12002);
		messages[1] = "Welcome to the game";
		messages[2] = "You are about to cross a checkpoint";
		messages[3] = "Ok. Now suicide! You'll respawn on the checkpoint";
		break;
	case 2 :
		_root.ball_start_x = 0;
		_root.ball_start_y = 0;
		level[0] = new Array(1, 4, 4, 5, 0);
		level[1] = new Array(0, 0, 0, 1, 0);
		level[2] = new Array(0, 0, 0, 1, 0);
		level[3] = new Array(0, 0, 0, 10, 0);
		level[4] = new Array(0, 0, 0, 0, 0);
		break;
	case 3 :
		_root.ball_start_x = 0;
		_root.ball_start_y = 0;
		level[0] = new Array(1, 6, 6, 4, 0);
		level[1] = new Array(0, 0, 0, 6, 0);
		level[2] = new Array(6, 5, 5, 6, 0);
		level[3] = new Array(6, 0, 0, 0, 0);
		level[4] = new Array(1, 1, 10, 0, 0);
		break;
	case 4 :
		_root.ball_start_x = 0;
		_root.ball_start_y = 0;
		level[0] = new Array(1, 7, 0, 0, 0);
		level[1] = new Array(0, 7, 0, 7, 10);
		level[2] = new Array(1, 3, 0, 1, 0);
		level[3] = new Array(1, 0, 0, 1, 0);
		level[4] = new Array(1, 1, 1, 7, 0);
		break;
	case 5 :
		_root.ball_start_x = 4;
		_root.ball_start_y = 2;
		level[0] = new Array(7, 8, 8, 8, 10);
		level[1] = new Array(1, 0, 0, 0, 0);
		level[2] = new Array(1, 8, 8, 3, 1);
		level[3] = new Array(0, 0, 0, 0, 0);
		level[4] = new Array(0, 0, 0, 0, 0);
		break;
	case 6 :
		_root.ball_start_x = 2;
		_root.ball_start_y = 2;
		level[0] = new Array(2, 8, 9, 8, 9);
		level[1] = new Array(9, 0, 0, 0, 1);
		level[2] = new Array(2, 8, 1, 0, 3);
		level[3] = new Array(0, 0, 0, 0, 4);
		level[4] = new Array(10, 9, 9, 8, 6);
		break;
	case 7 :
		_root.ball_start_x = 2;
		_root.ball_start_y = 2;
		level[0] = new Array(0, 0, 0, 0, 0);
		level[1] = new Array(0, 0, 0, 0, 0);
		level[2] = new Array(0, 0, 1, 0, 0);
		level[3] = new Array(0, 0, 0, 0, 0);
		level[4] = new Array(0, 0, 0, 0, 0);
		break;
	}
	_root.createEmptyMovieClip("bricks", 2);
	bricks._x = 240-(80*ball_start_x);
	bricks._y = 220-(80*ball_start_y);
	for (y=0; y<=4; y++) {
		for (x=0; x<=4; x++) {
			if (level[y][x]>0) {
				depth = y*12+x;
				place_brick = bricks.attachMovie("brick", "brick_"+depth, bricks.getNextHighestDepth(), {_x:x*80, _y:y*80});
				frame_to_stop = level[y][x];
				if (frame_to_stop>12000) {
					frame_to_stop = 12;
				}
				place_brick.gotoAndStop(frame_to_stop);
			}
		}
	}
}

Let’s comment the new lines:

Line 3: Attaching the info_panel object (the panel that will show the messages when the ball rolls over it) and making it invisible

Line 7: Creating a new variable to know if the player passed a checkpoint or not, and setting it to false by default

Line 11: Making the info panel object invisible. This may seems redundant since I alredy set it as invisible at line 3, but consider that this line is inserted into a routine to be executed at every time (so it’s redundant line 3…)

Lines 17-20: To understand this code, you must know how did I manage message tiles. Message tiles are tiles at number 12, but in the level array I assign a value of 12000+x where x is the id of the message. As an example, if a value in the level array is 12045, it meas that it’s a tile of type 12 (info tile) with the message 45. That’s what is done with this set of lines: if a value is greater than 12000, then assign 12 to type_of_tile value and type_of_tile%12000 (even if type_of_tile-12000 would be better) to the message_to_show variable

Lines 73-76: Code for the reverse controls tile (tile 11): simply multiplies power by -1

Lines 77-81: Code for the info panel tile (tile 12). Setting the info panel to visibile and assigning the dynamic text

Lines 82-87: Code for the checkpoint tile (tile 13): setting the checkpoint_passed variable to true and saving the current x and y tile position in save_x and save_y variables.

Lines 140-141: Reset the speed when a level is initialized. This will prevent the ball to mantain its speed when the player passes the level

Lines 157-159: Messages to display

Lines 225-227: If the tile number is greater than 12000, then setting the frame to stop in the tiles movieclip to 12

And that’s it: the first level has the new features while the others are the same of part 2

I am about to publish a complete game with a lot of more tiles, obviously I am releasing a full tutorial.

Meanwhile, download the source of this one

Read 4th part released

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