Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Circle Chain game, Actionscript 3, Flash and Game development.

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.

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