Making a Flash game like Plants Vs Zombies – step 2

Read all posts about "" game

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!!

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