Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Plants Vs Zombies game, Actionscript 3, Flash and Game development.

In the second part of the series, it’s time to raise money to buy a plant.

Also, we should add a smooth animation to falling suns, fix a bug which made them appear only on certain tiles and make them disappear if they aren’t picked up after a given amount of time.

Fixing the bug on newSun function

As reported by some readers, newSun function had a bug which did not allow to make the sun appear on every tile. It can be fixed assigning the x property this way:

sun.x=52+sunCol*65;

but since we are featuring smooth animation to falling sun, the entire newSun function can be changed this way:

private function newSun(e:TimerEvent):void {
	var sunRow:uint=Math.floor(Math.random()*5);
	var sunCol:uint=Math.floor(Math.random()*9);
	sun = new sunMc();
	sun.buttonMode=true;
	sunContainer.addChild(sun);
	sun.x=52+sunCol*65;
	sun.destinationY=130+sunRow*75;
	sun.y=-20;
	sun.addEventListener(MouseEvent.CLICK,sunClicked);
}

Now y property is set at -20 to make the sun appear outside the visible area, and its final y destination is saved in a variable called destinationY. We’ll see later what to do with it. Also notice the buttonMode property to make the mouse pointer change shape when it’s over the sun.

Collecting suns to raise money

First, we need a new variable to store the amount of player’s money, then we need a text field to display it somewhere. We also need Event and TextField classes to handle frame events and create on the fly text fields.

So these are the libraries we need to import in the package:

import flash.display.Sprite;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.TextField;

and these are the class level variables used in the prototype:

private var gameField:Array;
private var flowersTimer:Timer=new Timer(5000);
private var sun:sunMc;
private var sunContainer:Sprite=new Sprite();
private var money:uint=0;
private var moneyText:TextField=new TextField;

money will store player’s money while moneyText is the dynamic text field to be created.

At this time, let’s take a look at the complete code and discuss new features:

package {
	import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	public class Main extends Sprite {
		private var gameField:Array;
		private var flowersTimer:Timer=new Timer(5000);
		private var sun:sunMc;
		private var sunContainer:Sprite=new Sprite();
		private var money:uint=0;
		private var moneyText:TextField=new TextField;
		public function Main():void {
			setupField();
			drawField();
			fallingSuns();
			addText();
			addEventListener(Event.ENTER_FRAME,onEnterFrm);
		}
		private function addText():void {
			addChild(moneyText);
			updateMoney();
			moneyText.textColor=0xFFFFFF;
			moneyText.height=20;
		}
		private function updateMoney():void {
			moneyText.text="Money: "+money.toString();
		}
		private function onEnterFrm(e:Event):void {
			for (var i:uint=0; i

Let's see what's new in this code

Line 19: calling addText function (lines 22-27), which simply creates a dynamic text field and thanks to updateMoney function (lines 28-30) called at line 24 displays the current amount of money.

Line 20: adding an ENTER_FRAME listener which calls onEnterFrm function (lines 31-44) at every frame.

Line 32: this for loop scans for all sunContainer's children, that is all suns. Every sun has one of these two states: falling or fallen.

A sun is falling when its y property is lower than its destinationY variable (line 34) and in this case it has to keep on falling increasing its y property (line 35).

A sun is fallen when it's not falling (line 36) and in this case it starts disappearing (line 37, playing with alpha property). Once it's completely transparent (line 38) the CLICK listener is removed (line 39) and the sun itself is removed from Display List (line 40).

The last modified function is sunClicked, now giving you 5 money for every collected sun (line 63) and updating the text field (line 64).

This is the game:

Collect suns to make money or leave them on the ground and watch them disappear.

Buying your first plant

To build the first plant, first we need two new symbols: one called plantMc which represents the plant, and one called selectorMc to make the player see where he's going to place the plant.

We also need five more class level variables:

private var plantContainer:Sprite=new Sprite();
private var plant:plantMc;
private var movingPlant:plantMc;
private var playerMoving:Boolean=false;
private var selector:selectorMc;

let's see their meanings:

plantContainer: the DisplayObject used as a container for all plants
plant: the plant itself
movingPlant: the plant the player will move around the game field once he bought it
playerMoving: a boolean value to determine whether the player is moving a plant or not
selector: the selector itself

this is the final source code:

package {
	import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	public class Main extends Sprite {
		private var gameField:Array;
		private var flowersTimer:Timer=new Timer(5000);
		private var sun:sunMc;
		private var sunContainer:Sprite=new Sprite();
		private var money:uint=0;
		private var moneyText:TextField=new TextField  ;
		private var plantContainer:Sprite=new Sprite();
		private var plant:plantMc;
		private var movingPlant:plantMc;
		private var playerMoving:Boolean=false;
		private var selector:selectorMc;
		public function Main():void {
			setupField();
			drawField();
			fallingSuns();
			addText();
			addPlants();
			addEventListener(Event.ENTER_FRAME,onEnterFrm);
		}
		private function onPlantClicked(e:MouseEvent):void {
			if (money>=10&&! playerMoving) {
				money-=10;
				updateMoney();
				selector=new selectorMc();
				selector.visible=false;
				plantContainer.addChild(selector);
				movingPlant=new plantMc() ;
				plantContainer.addChild(movingPlant);
				playerMoving=true;
			}
		}
		private function addPlants():void {
			addChild(plantContainer);
			plant=new plantMc();
			plantContainer.addChild(plant);
			plant.buttonMode=true;
			plant.x=90;
			plant.y=40;
			plant.addEventListener(MouseEvent.CLICK,onPlantClicked);
		}
		private function addText():void {
			addChild(moneyText);
			updateMoney();
			moneyText.textColor=0xFFFFFF;
			moneyText.height=20;
		}
		private function updateMoney():void {
			moneyText.text="Money: "+money.toString();
		}
		private function onEnterFrm(e:Event):void {
			for (var i:uint=0; i=0&&plantCol>=0&&plantRow<5&&plantCol<9) {
					selector.visible=true;
					selector.x=25+plantCol*65;
					selector.y=80+plantRow*75;
				} else {
					selector.visible=false;
				}
			}
		}
		private function fallingSuns():void {
			addChild(sunContainer);
			flowersTimer.start();
			flowersTimer.addEventListener(TimerEvent.TIMER, newSun);
		}
		private function newSun(e:TimerEvent):void {
			var sunRow:uint=Math.floor(Math.random()*5);
			var sunCol:uint=Math.floor(Math.random()*9);
			sun = new sunMc();
			sun.buttonMode=true;
			sunContainer.addChild(sun);
			sun.x=52+sunCol*65;
			sun.destinationY=130+sunRow*75;
			sun.y=-20;
			sun.addEventListener(MouseEvent.CLICK,sunClicked);
		}
		private function sunClicked(e:MouseEvent):void {
			e.currentTarget.removeEventListener(MouseEvent.CLICK,sunClicked);
			money+=5;
			updateMoney();
			var sunToRemove:sunMc=e.currentTarget as sunMc;
			sunContainer.removeChild(sunToRemove);
		}
		private function setupField():void {
			gameField=new Array();
			for (var i:uint=0; i<5; i++) {
				gameField[i]=new Array();
				for (var j:uint=0; j<9; j++) {
					gameField[i][j]=0;
				}
			}
		}
		private function drawField():void {
			var fieldSprite:Sprite=new Sprite();
			var randomGreen:Number;
			addChild(fieldSprite);
			fieldSprite.graphics.lineStyle(1,0xFFFFFF);
			for (var i:uint=0; i<5; i++) {
				for (var j:uint=0; j<9; j++) {
					randomGreen=(125+Math.floor(Math.random()*50))*256;
					fieldSprite.graphics.beginFill(randomGreen);
					fieldSprite.graphics.drawRect(25+65*j,80+75*i,65,75);
				}
			}
		}
	}
}

Let's see the new lines, as usual:

Line 25: Calling addPlants function (lines 40-48)which will add the plants toolbar. At the moment there is only one plant, and it's a green circle (remember we are playing at "Circles Vs Squares").

lines 40-48: addPlants function just adds to Display List the only type of plant we can buy and adds a CLICK listener (line 47) which calls onPlantClicked function (lines 28-39) which is the core of this script.

Let's see how does onPlantClicked function work:

Line 29: you can buy (click) a plant only if you have enough money and you aren't already placing a plant. In this case, the plant costs 10 money.

Lines 30-31: subtracting the plant cost to your money and updating the text field showing the money you own.

Lines 32-34: adding the selector to Display List, just keeping it invisible.

Lines 34-36: adding the plant to be placed on the game field

Line 37: setting playerMoving to true, to tell the script we are moving the plant.

What happens when playerMoving is true? Something changes in onEnterFrm.

Lines 71-83: this is what happens when playerMoving is true: the bought plant follows the mouse (lines 72-73) while we calculate which tile we are over (lines 74-75). If we are over a tile (line 76), then we show the selector highlighting the tile (lines 77-79), otherwise (line 80) we keep it invisible (line 81).

This is the result:

Collect at least 10 money, then purchase a plant and move it on the game field.

Download the source code. Next time, placing the plants and your first zombie encounter!!

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