Dungeon Raid iPhone game engine made with Flash and AS3

Read all posts about "" game

An iPhone game which I enjoyed a lot last year, a great twist in the “match three” genre, was Dungeon Raid.

Tracing a path and matching tiles you will be able to collect treasures, buy and upgrade weapons and defeat monsters.

In this post I am going to cover the part which traces a path along tiles. While it may seem easy, there are a couple of interesting things to consider:

1) Your path can be traced in diagonal, and this means you have to define hot spots on the tiles which must be smaller than the tile itself, or you surely touch adjacent horizontal and vertical tiles before you touch diagonal ones.

2) You can backtrack through the path, but you can’t walk over already other previously selected tiles. This will require a vector to be used as a stack to manage backtracking.

I made a fully commented script, where Tile and Path are the two movieclips representing respectively the tile (frame 1: unselected, frame 2: selected) and the path (frame 1 to 8: west, north-west, north, north-east and so on in clockwise order).

The darker circle inside tiles is the hot spot.

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	public class Main extends Sprite {
		private var fieldWidth:int=8;// field width, in tiles
		private var fieldHeight:int=6;// field height, in tiles
		private var tileSize:int=80;// tile size, in pixels
		private var tileVector:Vector.;
		private var visitedVector:Vector.;// vector to store all visited tiles, as Point as it's easy to store x and y coordinate
		public function Main() {
			// adding tiles on stage and initializing tile vector
			tileVector=new Vector.();
			for (var i:int=0; i();
				for (var j:int=0; j();
			visitedVector.push(new Point(i,j));
			// highlighting the tile and setting it as "taken";
			tileVector[i][j].tile.gotoAndStop(2);
			tileVector[i][j].taken=true;
			// updating listeners, removing mouse down, adding mouse move and mouse up;
			stage.removeEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,drawing);
			stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
		}
		private function drawing(e:MouseEvent):void {
			// getting tile
			var i:int=Math.floor(mouseX/tileSize);
			var j:int=Math.floor(mouseY/tileSize);
			// checking if we are inside the sensible area
			var distX:Number=mouseX-(i*tileSize+tileSize/2);
			var distY:Number=mouseY-(j*tileSize+tileSize/2);
			// 1225 is 35^2, where 35 is the radius of the sensible area
			if (distX*distX+distY*distY<1225) {
				// now checking if we moved from the last tile visited
				if (i!=visitedVector[visitedVector.length-1].x || j!=visitedVector[visitedVector.length-1].y) {
					// now, let's see if we moved to an adjacent tile. we don't want the player to jump here and there
					if (Math.abs(i-visitedVector[visitedVector.length-1].x)<=1 && Math.abs(j-visitedVector[visitedVector.length-1].y)<=1) {
						// ok we moved, now let's see if we are backtracking:
						if (visitedVector.length>1&&i==visitedVector[visitedVector.length-2].x&&j==visitedVector[visitedVector.length-2].y) {
							// we are backtracking, so we have to remove the last element from visitedVector and turn off the tile
							var backtrackPoint:Point=visitedVector.pop();
							tileVector[backtrackPoint.x][backtrackPoint.y].tile.gotoAndStop(1);
							tileVector[backtrackPoint.x][backtrackPoint.y].taken=false;
							removeChild(tileVector[backtrackPoint.x][backtrackPoint.y].path);
						}
						else {
							// we aren't backtracking, let's see if the new tile was already taken (illegal move)
							if (! tileVector[i][j].taken) {
								// it's a new tile, let's insert it into the vector and highlight it
								visitedVector.push(new Point(i,j));
								tileVector[i][j].tile.gotoAndStop(2);
								tileVector[i][j].taken=true;
								// then place the path movieclip
								tileVector[i][j].path=new Path();
								tileVector[i][j].path.x=visitedVector[visitedVector.length-2].x*tileSize+tileSize/2;
								tileVector[i][j].path.y=visitedVector[visitedVector.length-2].y*tileSize+tileSize/2;
								// showing the right frame
								var iDiff:int=i-visitedVector[visitedVector.length-2].x;
								var yDiff:int=j-visitedVector[visitedVector.length-2].y;
								switch (iDiff) {
									case -1 :
										tileVector[i][j].path.gotoAndStop(Math.abs(yDiff)*(4+3*yDiff)+1);
										break;
									case 0 :
										tileVector[i][j].path.gotoAndStop(5+2*yDiff);
										break;
									case 1 :
										tileVector[i][j].path.gotoAndStop(5+yDiff);
										break;
								}
								addChild(tileVector[i][j].path);
							}
							else {
								// invalid move, stop drawing
								stopDrawing(null);
							}
						}
					}
				}
			}
		}
		private function stopDrawing(e:MouseEvent):void {
			// updating listeners
			stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,drawing);
			stage.removeEventListener(MouseEvent.MOUSE_UP,stopDrawing);
			// turning off all tiles
			for (var i:int=0; i

Enjoy the result:

Select tiles and move the mouse to draw a path and eventually backtrack it.

Download the source code

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
// 2048
// Dots
// Maze
// Pool
// Poux
// Pudi
// qomp
// Turn
// Zhed