Circle Chain ported to AS3 with commented source code available. Ready to jump to the iPhone

Read all posts about "" game

If you are a long time reader, you know Circle Chain was my first Flash game released to start experimenting how to monetize Flash games.

More than four years have passed, and I ported my old AS2 game to AS3, giving you the commented source code of a complete game.

But it’s not over… since it was my first Flash game, it will also be my first iPhone game. While you are reading this post, I am porting it to iPhone using Air for Flash. I will keep you updated about the making and the submission of the game in the App Store.

This is the AS3 game, with the same flaws as the original:

and this is the source code, keep in mind my library is made this way:

BackGroundImage: the background image

BlueMob: the blue circle (for some reason I used “mob” rather than “circle”)

CongratzScreen: the congratulations screen you see when you complete the game

GameMusic: the music

GameTitle: the splash screen

GreenBullet: the green bullet

GreenMob: the green circle

HowMany: contains a dynamic text field called howManyText

LevelIntro: contains two dynamic text fields called levelName and levelNotes

PlayerBullet: the player bullet

PlayerCircle: the circle controlled by the player

PurpleBullet: the purple bullet

PurpleMob: the purple circle

YellowBullet: the yellow bullet

YellowMob: the yellow circle

And here we go:

package {
	import flash.display.Sprite;
	import flash.ui.Mouse;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.media.SoundChannel;
	import flash.utils.getQualifiedClassName;
	public class Main extends Sprite {
		/* LEVEL DESIGN VARIABLES */
		// green mobs per level
		private var greenMobs=new Array(5,10,15,20,6,10,7,25,5,10,0,10,2,1,10,0,5,0,25,2,0);
		// blue mobs per level
		private var blueMobs=new Array(0,0,0,0,1,2,6,0,0,1,15,0,1,1,0,1,0,6,0,1,0);
		// yellow mobs per level
		private var yellowMobs=new Array(0,0,0,0,0,0,0,0,5,4,1,10,1,1,10,0,5,0,20,2,0);
		// purple mobs per level
		private var purpleMobs=new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,5,5,1,5,2,0);
		// mobs to destroy to pass the level
		private var mobsToDestroy=new Array(2,5,10,15,3,4,1,24,3,5,1,18,3,3,30,1,13,1,50,5,0);
		// levels description array
		private var levelDescription=new Array();
		/* GAME LOGIC VARIABLES */
		// are we playing the game?
		private var playingGame:Boolean=false;
		// level to play, from 0 to 19 = 20 levels
		private var levelToPlay:Number=0;
		// destroyed mobs counter
		private var mobsDestroyed:Number;
		// Boolean variable to determine if the player exploded
		private var playerExploded:Boolean=false;
		// Boolean variable to determine if the player started the level
		private var playerStarted:Boolean=false;
		// Boolean variable to know if the level shouldn't be considered completed anyway
		private var dieAnyway:Boolean;
		// Vector of mobs on screen
		private var mobVector:Vector.=new Vector.();
		// Vector of bullet on screen
		private var bulletVector:Vector.=new Vector.();
		/* SPRITES INSTANCES */
		// the circle controlled by the player. It's you!!
		private var playerCircle:PlayerCircle=new PlayerCircle();
		// game title splash screen
		private var gameTitle:GameTitle=new GameTitle();
		// sprite container where to play the game
		private var battleField:Sprite;
		// level intro, the big box with instructions 
		private var levelIntro:LevelIntro;
		// text showing how many mobs you destroyed so far
		private var howMany:HowMany=new HowMany();
		public function Main() {
			// adding the music
			var gameMusic:GameMusic = new GameMusic();
			var soundChannel:SoundChannel=gameMusic.play(0,10000);
			// initializing level descriptions
			levelDescription[0]="This is the first level.\nJust move the red circle with the mouse\nand click to start the chain reaction\nand explode other cirlces\n\nClick anywhere to begin";
			levelDescription[1]="If you can see this message,\nyou are on level 2.\n\nYou have to destroy as many circles as\nreported in the upper left corner to\nadvance levels\n\nClick anywhere to begin";
			levelDescription[2]="Well done\n\nYou can proceed\nThis is the last time I tell you that...\n\nyou have to press mouse anywhere\nto begin";
			levelDescription[3]="Ok\n\nYou managed the game.\n\nThis is the last normal stage";
			levelDescription[4]="Ok\n\nLet's make things harder.\n\nYou can't touch blue circles";
			levelDescription[5]="Hmmmm\n\nLet me see if you can save TWO blues";
			levelDescription[6]="If your boss knew you are\ntrying to save all those blues...";
			levelDescription[7]="Now a bit of mess, then you'll meet\na new circle type";
			levelDescription[8]="Yellow circles explode in a different way";
			levelDescription[9]="All 3 colors together";
			levelDescription[10]="Feeling blue?";
			levelDescription[11]="Destroy them all! (well, almost)";
			levelDescription[12]="Easy?";
			levelDescription[13]="What!\n\nAnother kind of circle!\nHow does it work?";
			levelDescription[14]="Destroy them all! (this time 4 real)";
			levelDescription[15]="It sucks, I know...\n\nBut I just do not want you\nto pass this level";
			levelDescription[16]="There are 20 levels in this game\n\nBut the sequel is on its way!";
			levelDescription[17]="This is so bad...";
			levelDescription[18]="It's not a level.\n\nIt's a stress test!";
			levelDescription[19]="One last level and...\n\nBACK AT WORK!!";
			// adding the background image
			var backgroundImage:BackgroundImage=new BackgroundImage();
			addChild(backgroundImage);
			// adding game title
			addChild(gameTitle);
			// adding the player
			addChild(playerCircle);
			// hiding the mouse
			Mouse.hide();
			// listeners
			addEventListener(Event.ENTER_FRAME,updateGame);
			stage.addEventListener(MouseEvent.CLICK,mouseClicked);

		}
		/* FUNCTION TO BE EXECUTED AT EVERY FRAME */
		private function updateGame(e:Event):void {
			// adjusting circle position according to mouse position
			playerCircle.x=stage.mouseX;
			playerCircle.y=stage.mouseY;
			// looping through mobs Vector
			for (var i:Number=0; i500) {
					mobVector[i].theSprite.x-=500;
				}
				if (mobVector[i].theSprite.x<0) {
					mobVector[i].theSprite.x+=500;
				}
				if (mobVector[i].theSprite.y>500) {
					mobVector[i].theSprite.y-=500;
				}
				if (mobVector[i].theSprite.y<0) {
					mobVector[i].theSprite.y+=500;
				}
			}
			// looping through bullet Vector 
			for (i=0; i0) {
							i--;
						}
						if (j>0) {
							j--;
						}
						// incrementing the counter of destroyed mobs
						mobsDestroyed++;
						// updating the dynamic text showing the current destroyed/needed mob counters
						howMany.howManyText.text="Exploded: "+mobsDestroyed+"/"+mobsToDestroy[levelToPlay];
					}
				}
				// checking if the bullets are out of the stage
				if (bulletVector[i].theSprite.y>500||bulletVector[i].theSprite.y<0||bulletVector[i].theSprite.x>500||bulletVector[i].theSprite.x<0) {
					// removing bullets out of the stage
					battleField.removeChild(bulletVector[i].theSprite);
					bulletVector.splice(i,1);
					// if there aren't bullets on the stage...
					if (bulletVector.length==0) {
						// if we destroyed the required amount of mobs...
						if (mobsDestroyed>=mobsToDestroy[levelToPlay] && !dieAnyway) {
							// we are ready to play next level!!
							levelToPlay++;
						}
						// play a new level (or the current level if you did not pass it)
						playLevel();
					}
				}
			}
		}
		/* FUNCTION TO BE EXECUTED WHEN THE PLAYER CLICKS THE MOUSE */
		private function mouseClicked(e:MouseEvent):void {
			// if we aren't playing the game (we still are on the splash screen);
			if (! playingGame) {
				// now we are playing!!
				playingGame=true;
				// removing unnecessary assets
				removeChild(gameTitle);
				removeChild(playerCircle);
				// play the level
				playLevel();
			}
			// otherwise it means we are already playing
			else {
				// if we are playing AND we aren't exploded yet...
				if (playerStarted && !playerExploded) {
					// time to explode!!
					playerExploded=true;
					// let's create four red bullets
					for (var i:Number=1; i<=4; i++) {
						var theBullet:TheBullet=new TheBullet(new PlayerBullet(),playerCircle,Math.PI*i/2);
						bulletVector.push(theBullet);
						battleField.addChild(theBullet.theSprite);
					}
					// set player alpha to almost transparent
					playerCircle.alpha=0.25;
				}
				// otherwise it means we are on the level intro
				if (! playerStarted) {
					// removing level intro
					battleField.removeChild(levelIntro);
					// let's start
					playerStarted=true;
				}
			}
		}
		/* FUNCTION TO BUILD A LEVEL */
		private function playLevel():void {
			// if we are on level 20 (congratz screen since levels range from 0 to 19)
			if (levelToPlay==20) {
				// show the congratz screen
				var congratzScreen:CongratzScreen=new CongratzScreen();
				addChild(congratzScreen);
			}
			// otherwise let's get ready to play
			else {
				// the remaning lines just initialize variables and place mobs on screen
				// nothing interesting here
				dieAnyway=false;
				mobVector=new Vector.();
				bulletVector=new Vector.();
				playerStarted=false;
				playerExploded=false;
				if (battleField!=null) {
					removeChild(battleField);
				}
				battleField=new Sprite();
				addChild(battleField);
				var loseAnyway:Boolean=false;
				var numberOfMobs:Number=greenMobs[levelToPlay]+blueMobs[levelToPlay]+yellowMobs[levelToPlay]+purpleMobs[levelToPlay];
				mobsDestroyed=0;
				var collisionArray:Array= new Array();
				howMany=new HowMany();
				howMany.howManyText.text="Exploded: "+mobsDestroyed+"/"+mobsToDestroy[levelToPlay];
				battleField.addChild(howMany);
				levelIntro=new LevelIntro();
				levelIntro.x=250;
				levelIntro.y=250;
				levelIntro.levelName.text="Level "+(levelToPlay+1);
				levelIntro.levelNotes.text=levelDescription[levelToPlay];
				battleField.addChild(levelIntro);
				playerCircle=new PlayerCircle();
				battleField.addChild(playerCircle);
				for (var i:Number=0; i

This is the content of TheBullet class:

package  {
	import flash.display.Sprite;
	public class TheBullet extends Sprite{
		public var theSprite:Sprite;
		public var xSpeed:Number;
		public var ySpeed:Number;
		public function TheBullet(sprite:Sprite,father:Sprite,bulletDirection:Number) {
			theSprite=sprite;
			xSpeed=6*Math.cos(bulletDirection);
			ySpeed=6*Math.sin(bulletDirection);
			theSprite.x=father.x;
			theSprite.y=father.y;
		}
	}
}

And this is the content of TheMob class:

package {
	import flash.display.Sprite;
	public class TheMob extends Sprite {
		public var theSprite:Sprite;
		public var xSpeed:Number;
		public var ySpeed:Number;
		public function TheMob(sprite:Sprite) {
			theSprite=sprite;
			theSprite.x=Math.random()*500;
			theSprite.y=Math.random()*500;
			var randomDirection:Number=Math.random()*2*Math.PI;
			xSpeed=2*Math.cos(randomDirection);
			ySpeed=2*Math.sin(randomDirection);
		}
	}
}

Download the source code and see you soon in the App Store.

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