Here we go with 3rd step of Plants Vs Zombies game. Now we will place the bought plant on the game field and let the zombies enter.
Adding a zombie is quite easy because we manage it in the same way we managed the sun. Just like suns appear out of the top of the stage and then fall down, Zombies appear out of the right edge of the stage and move left. They don’t interact with plants yet.
As for placing the plant, we have to make sure when the player presses the mouse while dragging the plant that the tile he wants to place the plant is free and it’s inside game area. Then the plant is placed, the selector and the listener are removed, and the routine starts again with the player collecting suns and selecting which plant (only one available at the moment) to place on the game field.
I commented line by line the whole code, to help you understanting what’s happening.
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 { // array to store game field information private var gameField:Array; // timer to make flowers fall down private var flowersTimer:Timer=new Timer(5000); // timer to make zombies come in private var zombieTimer:Timer=new Timer(5000); // container for all suns private var sunContainer:Sprite=new Sprite(); // container for all plants private var plantContainer:Sprite=new Sprite(); // container for all zombies private var zombieContainer:Sprite=new Sprite(); // the sun itself private var sun:sunMc; // plant on the plant bar private var plant:plantMc; // plant the player can drag on game field private var movingPlant:plantMc; // the selector square to show the playere where he's going to place the plant private var selector:selectorMc; // amout of money owned by the player private var money:uint=0; // dynamic text field where to show player's money private var moneyText:TextField=new TextField ; // boolean variable to tell us if the player is moving a plant (true) or not (false) private var playerMoving:Boolean=false; public function Main():void { // function to initialize the game field setupField(); // function to draw the game field itself drawField(); // function to handle falling suns fallingSuns(); // function to add all texts (only the amount of money at the moment) addText(); // function to add plants addPlants(); // function to add zombies addZombies(); // listener to ENTER_FRAME addEventListener(Event.ENTER_FRAME,onEnterFrm); } private function setupField():void { // creation of a 5 rows 9 columns matrix filled with zeros 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 addText():void { // adding a dynamic text field addChild(moneyText); updateMoney(); moneyText.textColor=0xFFFFFF; moneyText.height=20; } private function updateMoney():void { // writing the amount of money owned by the player moneyText.text="Money: "+money.toString(); } private function drawField():void { // drawing the game field, will be replaced when the game field will have real graphics 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); } } } private function addZombies():void { // adding the zombie container addChild(zombieContainer); // starting the timer to place zombies zombieTimer.start(); // listener to be triggered every time you have to place a new zombie zombieTimer.addEventListener(TimerEvent.TIMER,newZombie); } private function newZombie(e:TimerEvent):void { // constructing the zombie var zombie:zombieMc=new zombieMc(); // adding the zombie zombieContainer.addChild(zombie); // choosing a random row where to place the zombie var row:uint=Math.floor(Math.random()*5); // place the zombie on the board, outside the stage to the right zombie.x=660; zombie.y=row*75+115; } private function fallingSuns():void { // adding the suns container addChild(sunContainer); // starting the timer to make a new sun fall flowersTimer.start(); // listener ot be triggered every time you have to place a new sun flowersTimer.addEventListener(TimerEvent.TIMER, newSun); } private function newSun(e:TimerEvent):void { // choosing the destination row and column for the sun var sunRow:uint=Math.floor(Math.random()*5); var sunCol:uint=Math.floor(Math.random()*9); // constructing the sun sun = new sunMc(); // making the mouse change shape when over the plant sun.buttonMode=true; // adding the sun sunContainer.addChild(sun); // placing the sun in the proper column sun.x=52+sunCol*65; // definining the sun y destination point sun.destinationY=130+sunRow*75; // placing the sun out to the upper side of the stage sun.y=-20; // listener to be triggered when the sun is clicked sun.addEventListener(MouseEvent.CLICK,sunClicked); } private function sunClicked(e:MouseEvent):void { // removing the CLICK listener e.currentTarget.removeEventListener(MouseEvent.CLICK,sunClicked); // making the player earn money (5) money+=5; // updating money text updateMoney(); // defining which sun we need to remove var sunToRemove:sunMc=e.currentTarget as sunMc; // removing the sun sunContainer.removeChild(sunToRemove); } private function addPlants():void { // adding the plant container addChild(plantContainer); // constructing a new plant plant=new plantMc(); // adding the plant plantContainer.addChild(plant); // making the mouse change shape when over the plant plant.buttonMode=true; // placing the plant plant.x=90; plant.y=40; // listener to be triggered once the plant is clicked plant.addEventListener(MouseEvent.CLICK,onPlantClicked); } private function onPlantClicked(e:MouseEvent):void { // checking if the player has enough money (10) to afford the plant and isn't currently dragging a plant if (money>=10&&! playerMoving) { // paying the plant money-=10; // updating money text updateMoney(); // constructing a new selector selector=new selectorMc(); // make the selector invisible selector.visible=false; // adding the selector plantContainer.addChild(selector); // construcing a new moving plant movingPlant=new plantMc(); // lister to be triggered once the moving plant is clicked movingPlant.addEventListener(MouseEvent.CLICK,placePlant); // adding the moving plant plantContainer.addChild(movingPlant); // telling the script the player is actually moving a plant playerMoving=true; } } private function placePlant(e:MouseEvent):void { // looking in which tile the plant is going to be placed according to mouse position var plantRow:int=Math.floor((mouseY-80)/75); var plantCol:int=Math.floor((mouseX-25)/65); // checking if the tile is inside the game field and there isn't any other plant already placed in that tile if (plantRow>=0&&plantCol>=0&&plantRow<5&&plantCol<9&&gameField[plantRow][plantCol]==0) { // constructing the plan to be placed var placedPlant:plantMc=new plantMc(); // adding the plant plantContainer.addChild(placedPlant); // placing the plant placedPlant.x=plantCol*65+57; placedPlant.y=plantRow*75+115; //telling the script the player is no longer moving playerMoving=false; // removing the CLICK listener from the draggable plant movingPlant.removeEventListener(MouseEvent.CLICK,placePlant); // removing the selector plantContainer.removeChild(selector); // removing the plan itself plantContainer.removeChild(movingPlant); // updating game array adding the new plant gameField[plantRow][plantCol]=1; } } private function onEnterFrm(e:Event):void { // looping through all zombies for (var i:uint=0; i<zombieContainer.numChildren; i++) { var movingZombie:zombieMc=zombieContainer.getChildAt(i) as zombieMc; // moving each zombie left by 1/2 pixels movingZombie.x-=0.5; } // looping through all suns for (i=0; i<sunContainer.numChildren; i++) { var fallingSun:sunMc=sunContainer.getChildAt(i) as sunMc; // if the sun is still falling because it did not reach its destination... if (fallingSun.y<fallingSun.destinationY) { // move the sun down by one pixels fallingSun.y++; // if the sun is not falling anymore... } else { // make the sun fade away fallingSun.alpha-=0.01; // if the sun completely disappeared... if (fallingSun.alpha<0) { // remove the CLICK listener from the sun fallingSun.removeEventListener(MouseEvent.CLICK,sunClicked); // remove the sun sunContainer.removeChild(fallingSun); } } } // if the player is moving a plant... if (playerMoving) { // placing the plant under the mouse movingPlant.x=mouseX; movingPlant.y=mouseY; // determining which row and column the plany is over var plantRow:int=Math.floor((mouseY-80)/75); var plantCol:int=Math.floor((mouseX-25)/65); // if it's inside game field... if (plantRow>=0&&plantCol>=0&&plantRow<5&&plantCol<9) { // show the selector selector.visible=true; // place the selector over the selected tile selector.x=25+plantCol*65; selector.y=80+plantRow*75; } else { // hide the selector selector.visible=false; } } } } }
This is the result:
Collect suns and buy and place plants while zombies arrive.
Download the source code. Next time, we’ll fight the zombies.
Want to learn more? Learn by example!
Get the full commented source code of an actual commercial cross platform HTML5 game!!