Bio Game - ActionScript Overview

/BioGameLaunch.as

/BioGame.as

/com/biogame/AI.as

/com/biogame/BuyCow.as

/com/biogame/BuyFood.as

/com/biogame/Cow.as

/com/biogame/Cursor.as

/com/biogame/Doors.as

/com/biogame/Element.as

/com/biogame/Game.as

/com/biogame/Grass.as

/com/biogame/InteractiveElement.as

/com/biogame/Popup.as

/com/biogame/PopupAdjuster.as

/com/biogame/PopupButton.as

/com/biogame/Sack.as

/com/biogame/Silo.as

/com/biogame/Sounds.as

/com/biogame/Tractor.as

/com/biogame/Tree.as

/com/biogame/Truck.as

/BioGameLaunch.as

/**
*
*BioGameLaunch.as (Document Class)
*
*Preloader klasse, laadt de gespecificeerde SWF
*
*@ extendsMovieClip
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package {

import flash.text.TextField;
import flash.display.MovieClip;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.events.Event;

public class BioGameLaunch extends MovieClip {

private var mURL:String = './Bio Game.swf';
private var mLoader:Loader;

/**
*
*BioGameLaunch
*
*Constructor voor de preloader klasse
*
*@ params(Geen)
*
*/

public function BioGameLaunch():void {
mLoader = new Loader();
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingComplete);
mLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loading);
mLoader.load(new URLRequest('./Bio Game.swf'));
}

/**
*
*loading
*
*Event handler als er weer een stukje gedownload is van de te laden SWF
*
*@ paraminProgressEvent[ProgressEvent]Het progress event waarop gereageerd wordt, in dit geval van de te laden SWF
*
*/

private function loading(inProgressEvent:ProgressEvent):void {
var loaded = mLoader.contentLoaderInfo.bytesLoaded;
var total = mLoader.contentLoaderInfo.bytesTotal;
text.text = Math.round((loaded / total) * 100) + '%';
}

/**
*
*loadingComplete
*
*Aangeroepen wanneer de SWF klaar is met preloaden. Toevoegen aan de display list en gaan met die banaan
*
*@ paraminEvent[Event]Het event waarop gereageerd wordt, in dit geval van de te laden SWF
*
*/

private function loadingComplete(inEvent:Event):void {
removeChild(text);
removeChild(tile);
addChild(mLoader);
}

}

}

/BioGame.as

/**
*
*BioGame.as (Document Class)
*
*Aansturende klasse, maakt twee game instanties aan, die onafhankelijk van elkaar kunnen opereren
*
*@ extendsMovieClip
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package {

import com.biogame.*;
import flash.text.TextField;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.ui.Mouse;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.filters.GlowFilter;
import flash.filters.BitmapFilterQuality;
import flash.media.Sound;
import flash.media.SoundChannel;

import com.exanimo.*;

public class BioGame extends MovieClip {

private var mGameLength:Number = 365;
private var mGameLengthCurrent:Number = mGameLength;
private var mGameTick:Number = 900;
public var mTimer:Timer;
public var mGamePlayer:Game;
public var mGameOpponent:Game;
public var mPaused:Boolean = false;

public var mHighlight:GlowFilter = new GlowFilter();

public var mName:String = '';

private var mFPS:Number = 0;
private var mFPSTimer:Timer;

private var mCount:Number = 0;

/**
*
*BioGame
*
*Constructor voor de aansturende klasse. Als de game wordt ingeladen of geplaatst op de stage, initialize()
*
*@ params(Geen)
*
*/

public function BioGame():void {
addEventListener(Event.ADDED_TO_STAGE, initialize);
stop();
}

/**
*
*initialize
*
*Initialiseert de main klasse ivm wrapping preloader. Verstopt de muis, zet de scaling en start onze game
*
*@ params(Geen)
*
*/

public function initialize(inEvent:Event):void {
Mouse.hide();
Sounds.play(new SndBackground());
stage.scaleMode = StageScaleMode.EXACT_FIT;
launch();
}

/**
*
*launch
*
*Stelt de highlights in, maakt twee game instanties aan, start de game timer, start de FPS timer, stelt de cursor updates in
*Verplaatst enkele elementen naar de top van de display list, stelt de AI in, controls voor de speler, en laat een start popup zien
*
*@ params(Geen)
*
*/

public function launch():void {
setupHighlight();
mGameOpponent = new Game(false);
addChild(mGameOpponent);
mGamePlayer = new Game(true);
addChild(mGamePlayer);
mFPSTimer = new Timer(1000, 0);
mFPSTimer.addEventListener(TimerEvent.TIMER, fpsUpdate);
mFPSTimer.start();
stage.addEventListener(Event.ENTER_FRAME, fpsTick);
mTimer = new Timer(mGameTick, mGameLength);
mTimer.addEventListener(TimerEvent.TIMER, tick);
mTimer.addEventListener(TimerEvent.TIMER_COMPLETE, gameDone);
mTimer.start();
stage.addEventListener(MouseEvent.MOUSE_MOVE, mCursor.update);
moveChildToTop(mPopup);
moveChildToTop(mPauser);
moveChildToTop(mCursor);
stage.addEventListener(KeyboardEvent.KEY_UP, handle);
AI.initialize(mGameOpponent);
setupPositions();
//
mGameOpponent.initialize(mTxtOpponentMoney, mTxtOpponentFood, mTxtOpponentCows, mTxtOpponentSlaughter);
mGamePlayer.initialize(mTxtPlayerMoney, mTxtPlayerFood, mTxtPlayerCows, mTxtPlayerSlaughter);
mGamePlayer.setupControls();
//
mPopup.initialize();
mPopup.show(Popup.PERSON, new Array());
}

/**
*
*setupHighlight
*
*Genereert een highlight die door alle elementen gebruikt wordt om een highlight weer te geven
*
*@ params(Geen)
*
*/

private function setupHighlight():void {
// mHighlight.color = 0x25325E;
mHighlight.color = 0xFFFFFF;
mHighlight.alpha = 1.0;
mHighlight.blurX = 10;
mHighlight.blurY = 10;
mHighlight.quality = BitmapFilterQuality.MEDIUM;
}

/**
*
*setupPositions
*
*Maakt een lijst met gras en koe elementen, vanaf de voorgeplaatste plekken in de FLA
*Dit om ervoor te zorgen dat we deze makkelijk kunnen verplaatsen zonder de code hoeven aan te passen
*
*@ params(Geen)
*
*/

private function setupPositions():void {
var currentIndex:Number = 0;
var removed:Number = 0;
var looping:Boolean = true;

while(looping) {
var child = getChildAt(currentIndex);
if(child is Grass || child is Cow) {
if(child.x < 500) {
mGameOpponent.setupPosition(child, currentIndex + removed);
}else{
mGamePlayer.setupPosition(child, currentIndex + removed);
}
removeChild(child);
removed++;
}else{
currentIndex++;
}
if(currentIndex > (numChildren-1)) {
looping = false;
}
}
}

/**
*
*moveChildToTop
*
*Verplaatst een display element naar voren (naar de top van de display list)
*
*@ paraminChild [DisplayObject]Het te verplaatsen element
*
*/

private function moveChildToTop(inChild:DisplayObject):void {
setChildIndex(inChild, numChildren-1);
}

/**
*
*handle
*
*Vangt keyboard input af; Op dit moment wordt alleen spatiebalk (pauzeren) benut
*
*@ paraminKeyboardEvent [KeyboardEvent]Het keyboard-event waarop gereageerd wordt
*
*/

private function handle(inKeyboardEvent:KeyboardEvent):void {
switch(inKeyboardEvent.keyCode) {
case Keyboard.SPACE:
spaceToggle();
break;
}
}

/**
*
*spaceToggle
*
*Zorgt ervoor dat het spel te pauzeren of te hervatten is. Hangt af van de huidige pauzeer stand en van een eventuele popup
*
*@ params(Geen)
*
*/

private function spaceToggle():void {
if(mPaused && !mPopup.mActive) {
resume();
}else{
pause();
}
}

/**
*
*pause
*
*Pauzeert het spel als het nog niet gepauzeerd is. Laat het pauzeer icoon zien, pauzeert de AI, de game timer, en beide instanties
*
*@ params(Geen)
*
*/

public function pause():void {
if(!mPaused) {
mPaused = true;
//
mPauser.gotoAndPlay('paused');
AI.pause();
mTimer.stop();
mGamePlayer.pause();
mGameOpponent.pause();
}
}

/**
*
*resume
*
*Hervat het spel als het gepauzeerd is. Laat het play icoon zien, hervat de AI, de game timer indien nodig, en beide instanties
*
*@ params(Geen)
*
*/

public function resume():void {
if(mPaused) {
mPaused = false;
//
mPauser.gotoAndPlay('resume');
AI.resume();
if(mTimer.currentCount != mGameLength) {
mTimer.start();
}
mGamePlayer.resume();
mGameOpponent.resume();
}
}

/**
*
*fpsTick
*
*Bij ieder enter frame event wordt de FPS counter met eentje opgehoogd om de frames per second bij te houden
*
*@ paraminEvent [Event]Het event waarop gereageerd wordt. In dit geval een enter frame event
*
*/

private function fpsTick(inEvent:Event):void {
mFPS++;
}

/**
*
*fpsUpdate
*
*We zijn een seconde verder. Update de FPS meter, en zet de FPS counter weer op 0
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt. In dit geval iedere seconde
*
*/

private function fpsUpdate(inTimerEvent:TimerEvent):void {
mTxtFPS.text = String(mFPS) + ' FPS';
mFPS = 0;
}

/**
*
*tick
*
*Iedere tick representeert een dag in onze game. Op dit moment is dit iedere seconde
*Opmerking: De reden waarom dit apart zit van de fpsUpdate is omdat we dit wellicht nog willen wijzigen qua game snelheid
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt. In dit geval iedere seconde
*
*/

private function tick(inTimerEvent:TimerEvent):void {
mGameLengthCurrent--;
mTxtTimer.text = String(mGameLengthCurrent);
}

/**
*
*gameDone
*
*Aan het einde van de periode van een jaar, laten we de end game popup zien
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt. In dit geval na 365 seconden
*
*/

private function gameDone(inTimerEvent:TimerEvent):void {
mPopup.show(Popup.END, new Array());
}

}

}

/com/biogame/AI.as

/**
*
*AI.as
*
*Aansturende klasse voor de 'Artificial Intelligence' van de macro-boer
*
*@ staticJa (Geen directe instantie)
*@ extends(None)
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.TimerEvent;
import flash.utils.Timer;

public class AI {

private static var mGame:Game;

private static var mTimers:Object = new Object();
private static var mBuyCow:Boolean = false;

/**
*
*initialize
*
*Initialiseert de AI en start verscheidene timers om dit te bewerkstelligen
*
*@ paraminGame [Game]Referentie aan de game instantie, die van de tegenstander in dit geval
*
*/

public static function initialize(inGame):void {
mGame = inGame;
startTimers();
}

/**
*
*startTimers
*
*Dit zet het hele AI gebeuren in werking. Alle acties zijn gebaseerd op tijd intervallen
*
*@ params(Geen)
*
*/

private static function startTimers():void {
mTimers['food'] = new Timer(1500, 0);
mTimers['food'].addEventListener(TimerEvent.TIMER, actionFood);
mTimers['food'].start();

setupDoors(30000, 1);

mTimers['stats'] = new Timer(1000, 0);
mTimers['stats'].addEventListener(TimerEvent.TIMER, actionStats);
mTimers['stats'].start();
}

/**
*
*setupDoors
*
*Maakt een deuren timer aan, die in een bepaalde interval de koeien naar binnen en buiten stuurt
*
*@ paraminDelay[Number]De interval waarna deze timer een event dispatcht
*@ paraminRepeat [Number]Hoe vaak deze timer zich moet herhalen (In dit geval is het steeds een one-shot timer)
*
*/

private static function setupDoors(inDelay:Number, inRepeat:Number):void {
mTimers['doors'] = new Timer(inDelay, inRepeat);
mTimers['doors'].addEventListener(TimerEvent.TIMER, actionDoors);
mTimers['doors'].start();
}

/**
*
*actionDoors
*
*Stuurt de koeien naar binnen of buiten. Staan ze binnen, schakel de grasmaai timer in werking om het gras te gaan maaien
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval die van setupDoors()
*
*/

private static function actionDoors(inTimerEvent:TimerEvent):void {
mGame.actionDoors();
if(mGame.mInside) {
mTimers['mow'] = new Timer(2000, 1);
mTimers['mow'].addEventListener(TimerEvent.TIMER, actionMow);
mTimers['mow'].start();
setupDoors(14000, 1);
}else{
setupDoors(30000, 1);
}
}

/**
*
*actionFood
*
*Voedert de koe die het meeste honger heeft, mits de koeien niet binnen staan. Deze koe wordt uitgekozen dmv pickCow()
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval van de honger / voedsel timer
*
*/

private static function actionFood(inTimerEvent:TimerEvent):void {
if(!mGame.mInside && mGame.mCows > 0) {
mGame.actionFoodIndividually(pickCow());
}
}

/**
*
*actionMow
*
*Laat de tractor grasmaaien
*
*@ paraminTimerGame [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval van de grasmaaien timer
*
*/

private static function actionMow(inTimerEvent:TimerEvent):void {
mGame.actionMow();
}

/**
*
*actionStats
*
*De tegenstander moet uiteraard ook koeien en voedsel kopen, afhankelijk van de status en resources
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval die van de stats timer
*
*/

private static function actionStats(inTimerEvent:TimerEvent):void {
if(mBuyCow || mGame.mFood > 65) {
mBuyCow = false;
mGame.actionBuyCow();
}else{
mBuyCow = true;
mGame.actionBuyFood();
}
}

/**
*
*pickCow
*
*Zoekt de koe met de meeste honger
*
*@ params(Geen)
*@ returnCowDe koe met de meeste honger
*
*/

public static function pickCow():Cow {
var lowestCow:Cow;
var lowestAmount:Number = 100;
for each(var cow:Cow in mGame.mListCows) {
if(cow.mFood < lowestAmount && !cow.mRemoved) {
lowestAmount = cow.mFood;
lowestCow = cow;
}
}
return lowestCow;
}

/**
*
*pause
*
*Pauzeert alle AI timers
*
*@ params(Geen)
*
*/

public static function pause():void {
for each(var timer in mTimers) {
timer.stop();
}
}

/**
*
*resume
*
*Hervat alle AI timers
*
*@ params(Geen)
*
*/

public static function resume():void {
for each(var timer in mTimers) {
timer.start();
}
}

}

}

/com/biogame/BuyCow.as

/**
*
*BuyCow.as
*
*De knop voor het kopen van een nieuwe koe
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.MouseEvent;
import flash.display.MovieClip;

public class BuyCow extends InteractiveElement {

/**
*
*BuyCow
*
*Constructor voor de koop koe knop
*
*@ paraminGame [Game]Referentie aan de game instantie waarin deze koop koe knop wordt opgenomen
*
*/

public function BuyCow(inGame:Game):void {
mGame = inGame;
visible = mGame.mIsPlayer;
determineButtonMode();
if(!mGame.mIsPlayer) {
scaleX *= -1;
}
}

/**
*
*initialize
*
*Initialiseert deze koop koe knop
*
*@ params(Geen)
*
*/

public function initialize():void {
mInfo.visible = false;
draw();
}

override function interactionOver(inMouseEvent:MouseEvent):void {
super.interactionOver(inMouseEvent);
if(!mEnabled && !mPaused) {
mInfo.visible = true;
}
}

override function interactionOut(inMouseEvent:MouseEvent):void {
super.interactionOut(inMouseEvent);
mInfo.visible = false;
}

}

}

/com/biogame/BuyFood.as

/**
*
*BuyFood.as
*
*De knop voor het kopen van nieuw veevoer / voedsel
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.MouseEvent;
import flash.display.MovieClip;

public class BuyFood extends InteractiveElement {

/**
*
*BuyFood
*
*Constructor voor de koop voedsel knop
*
*@ paraminGame [Game]Referentie aan de game instantie waarin deze silo wordt opgenomen
*
*/

public function BuyFood(inGame:Game):void {
mGame = inGame;
visible = mGame.mIsPlayer;
determineButtonMode();
if(!mGame.mIsPlayer) {
scaleX *= -1;
}
}

/**
*
*initialize
*
*Initialiseert deze koop voedsel knop
*
*@ params(Geen)
*
*/

public function initialize():void {
mInfo.visible = false;
draw();
}

override function interactionOver(inMouseEvent:MouseEvent):void {
super.interactionOver(inMouseEvent);
if(!mEnabled && !mPaused) {
mInfo.visible = true;
}
}

override function interactionOut(inMouseEvent:MouseEvent):void {
super.interactionOut(inMouseEvent);
mInfo.visible = false;
}

}

}

/com/biogame/Cow.as

/**
*
*Cow.as
*
*Representeert een koe, met bijbehorende functies (honger, voederen, naar binnen / buiten etc.)
*
*@ helperFoodIndicator (zie onder Cow klasse)
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import fl.transitions.TweenEvent;
import flash.display.MovieClip;
import flash.geom.Point;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.utils.setTimeout;
import flash.utils.getTimer;

import com.exanimo.transitions.*;

public class Cow extends Element {

public var mSpot:Number;

private var mFoodMax:Number = 15;
private var mFoodChance:Number = 2;
public var mFood:Number = mFoodMax;

private var mLastFed:Number = -10000;

private var mFoodIndicator:FoodIndicator;

private var mInside:Boolean = false;
public var mDead:Boolean = false;
private var mSlaughtered:Boolean = false;

private var mTruck:Truck;

/**
*
*Cow
*
*Constructor voor een koetje
*
*@ params(Geen)
*
*/

public function Cow():void {
mPerspective = true;
}

/**
*
*initialize
*
*Initialiseert deze koe. Zorgt voor de juiste toestanden (kalf, koe, dikke koe & dikste koe) & start een honger timer
*
*@ params(Geen)
*
*/

public function initialize():void {
mStates.push('calf');
mStates.push('cow');
mStates.push('fatCow');
mStates.push('fattiestCow');
mStates.push('dead');
if(mGame.mIsPlayer) {
mFoodIndicator = new FoodIndicator(scaleX);
addChild(mFoodIndicator);
}
mTimers['food'] = new Timer(1000, 0);
mTimers['food'].addEventListener(TimerEvent.TIMER, foodDecrease);
mTimers['food'].start();
draw();
}

/**
*
*drawIndicator
*
*Update de weergave van de honger indicator die aangemaakt is bij initialize()
*
*@ params(Geen)
*
*/

public function drawIndicator():void {
if(mFoodIndicator) {
mFoodIndicator.update(mFood, mFoodMax);
}
}

/**
*
*showIndicator
*
*Afhankelijk van de parameter laat deze functie de honger indicator zien of verstopt deze
*
*@ paraminShow [Boolean]Indien true, laat de indicator zien; Indien false verstopt deze
*
*/

public function showIndicator(inShow:Boolean):void {
if(mFoodIndicator) {
mFoodIndicator.show(inShow);
}
}

/**
*
*foodNeeded
*
*Berekent hoeveel voedsel er nodig is om deze koe te voeden
*
*@ returnNumberHet aantal voedsel benodigd om deze koe compleet te voeden
*
*/

public function foodNeeded():Number {
var foodDifference:Number = mFoodMax - mFood;
return foodDifference;
}

/**
*
*feed
*
*Voedt deze koe. Indien te snel gevoed, een ziekte popup
*Indien deze koe voldoende is vetgemest start de slacht animatie via slaughterStart(), zo niet, verander de toestand van de koe
*
*@ paraminFood [Number]Het totaal aantal voedsel
*@ returnNumberHet totaal aantal voedsel wat overblijft nadat deze koe is gevoederd
*
*/

public function feed(inFood:Number):Number {
if(mSlaughtered || mInside || mDead) {
return inFood;
}
if(mGame.mIsPlayer) {
if(getTimer() < (mLastFed + 4000)) {
BioGame(root).mPopup.show(Popup.ILL, new Array());
return inFood;
}
}
if(inFood != 0) {
if(mCurrentState < mStates.length - 2) {
mLastFed = getTimer();
mCurrentState++;
draw();
showIndicator(true);
}else{
slaughterStart();
}
var foodNeeded:Number = foodNeeded();
if(foodNeeded > inFood) {
mFood += inFood;
inFood = 0;
}else{
mFood += foodNeeded;
inFood -= foodNeeded;
}
if(mGame.mIsPlayer) {
Sounds.play(new SndFood());
}
drawIndicator();
return inFood;
}else{
return 0;
}
}

/**
*
*slaughterStart
*
*Start de slacht animatie, maakt een slacht truck aan die de koe komt ophalen. Na 1 seconde verdwijnt de koe en rijdt de truck weg
*
*@ params(Geen)
*
*/

private function slaughterStart():void {
if(mSlaughtered) {
return;
}
showIndicator(false);
mSlaughtered = true;
mTruck = mGame.setupTruck(this);
mTimers['slaughter'] = new Timer(1000, 1);
mTimers['slaughter'].addEventListener(TimerEvent.TIMER_COMPLETE, slaughter);
mTimers['slaughter'].start();
}

/**
*
*slaughter
*
*De koe is opgehaald door de slacht truck, verwijder de koe en verander het aantal geslachte koeien
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt. In dit geval het event van slaughterStart()
*
*/

private function slaughter(inTimerEvent:TimerEvent):void {
mGame.mSlaughter++;
visible = false;
}

/**
*
*foodDecrease
*
*Onze koe heeft wellicht honger afhankelijk van de kansbereking. Als de koe teveel honger heeft, gaat deze dood via dieStart()
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt. In dit geval het event van de honger timer
*
*/

private function foodDecrease(inTimerEvent:TimerEvent):void {
if(mInside || mDead || mSlaughtered) {
return;
}
if(Math.round(Math.random() * mFoodChance) == 0) {
mFood--;
}
if(mFood <= 0) {
dieStart();
}else{
if((mFood == 2 || mFood == 5) && mGame.mIsPlayer) {
if(Math.round(Math.random()) == 0) {
Sounds.play(new SndCow2(), this);
}else{
Sounds.play(new SndCow1(), this);
}
}
drawIndicator();
}
}

/**
*
*dieStart
*
*Start de dood animatie (Hopelijk een opstijgende engel-koe! Haha ;o)
*
*@ params(Geen)
*
*/

private function dieStart():void {
mDead = true;
mCurrentState = 4;
showIndicator(false);
draw();
stop();
mTweens['y'] = new GCSafeTween(this, 'y', Strong.easeIn, y, -200, 2, true);
mTweens['y'].addEventListener(TweenEvent.MOTION_FINISH, dieEnd);
}

/**
*
*dieEnd
*
*Onze dood animatie is afgelopen, verwijder de koe
*
*@ paraminTweenEvent [TweenEvent]Het tween event waarop gereageerd wordt. In dit geval die van dieStart()
*
*/

private function dieEnd(inTweenEvent:TweenEvent):void {
if(mGame.mIsPlayer) {
BioGame(root).mPopup.show(Popup.DEAD, new Array());
}
remove();
}

/**
*
*pause
*
*Pauzeert de slacht truck mocht deze er zijn & overige pauzeer functies
*
*@ params(Geen)
*@ overrideElement:Pause()
*
*/

override function pause():void {
if(mTruck) {
mTruck.pause();
}
super.pause();
}

/**
*
*resume
*
*Hervat de slacht truck mocht deze er zijn & overige hervat functies
*
*@ params(Geen)
*@ overrideElement:resume()
*
*/

override function resume():void {
if(mTruck) {
mTruck.resume();
}
super.resume();
}

/**
*
*remove
*
*Zorgt dat de koe-positie vrij komt om een nieuwe koe te kopen via de game instantie & verwijdert de koe
*
*@ params(Geen)
*@ overrideElement:remove()
*
*/

override function remove():void {
mGame.removeCow(mSpot);
super.remove();
}

/**
*
*walk
*
*Laat de koe naar binnen of buiten lopen. Op dit moment staan de animaties uit, ze faden
*
*@ params(Geen)
*
*/

public function walk():void {
if(mDead) {
return;
}
var duration:Number = 2;
if(mInside) {
/*
mTweens['x'] = new GCSafeTween(this, 'x', Strong.easeInOut, x, mPosition.x, duration + Math.floor(Math.random()), true);
mTweens['y'] = new GCSafeTween(this, 'y', Strong.easeInOut, y, mPosition.y, duration, true);
*/

mTweens['alpha'] = new GCSafeTween(this, 'alpha', Regular.easeInOut, alpha, 1.0, duration, true);
}else{
/*
mTweens['x'] = new GCSafeTween(this, 'x', Strong.easeInOut, x, mGame.mInsidePoint.x, duration, true);
mTweens['y'] = new GCSafeTween(this, 'y', Strong.easeInOut, y, mGame.mInsidePoint.y, duration + Math.floor(Math.random()), true);
*/

mTweens['alpha'] = new GCSafeTween(this, 'alpha', Regular.easeInOut, alpha, 0.0, duration, true);
if(mFoodIndicator) {
mFoodIndicator.show(false);
}
}
mInside = !mInside;
mTweens['alpha'].addEventListener(TweenEvent.MOTION_FINISH, walkFinished, false, 0, true);
}

/**
*
*walkFinished
*
*De koe is klaar met zijn loop animatie. Als de koe niet binnen staat, laat de honger indicator weer zien
*
*@ paraminTweenEvent [TweenEvent]Het tween event waarop gereageerd wordt. In dit geval die van walk()
*
*/

public function walkFinished(inTweenEvent:TweenEvent):void {
if(!mInside) {
showIndicator(true);
}
}

}

}

/**
*
*Representeert een voedsel / honger indicator, die verandert naar mate de koe meer honger krijgt of gevoederd wordt
*
*@ extendsSprite
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


import flash.display.Sprite;
import flash.events.MouseEvent;

class FoodIndicator extends Sprite {

private var mWidth:Number = 220;
private var mHeight:Number = 30;
private var mRoundness:Number = 30;
private var mAdjustment:Number = 8;

/**
*
*FoodIndicator
*
*Constructor voor deze honger indicator. Laat een volledig volle indicator zien als deze wordt aangemaakt
*
*@ paraminScale [Number]De schaling van de koe, ivm de mogelijke random spiegeling van de koe
*
*/

function FoodIndicator(inScale:Number):void {
alpha = 1.0;
if(inScale < 0) {
scaleX *= -1;
x = 70;
}else{
x = -160;
}
y -= 80;
update(1, 1);
}

/**
*
*show
*
*Afhankelijk van de parameter, laat dit de indicator wel of niet zien. Indien true, verplaatst de indicator ook naar voren
*
*@ paraminShow [Boolean]Indien true, laat de indicator zien; Indien false, verstopt deze
*
*/

function show(inShow:Boolean):void {
visible = inShow;
if(inShow) {
parent.setChildIndex(this, parent.numChildren-1);
}
}

/**
*
*update
*
*Tekent een mooie rounded rectangle die langzaam afneemt en van kleur veranderd afhankelijk van kritieke status
*
*@ paraminFood[Number]Het huidige aantal voedsel (of honger) van de koe
*@ paraminFoodMax[Number]Het maximaal aantal voedsel van de koe (geen honger)
*
*/

function update(inFood:Number, inFoodMax:Number):void {
graphics.clear();
graphics.beginFill(0xF0EED8, 0.8);
graphics.drawRoundRect(0, 0, mWidth, mHeight, mRoundness, mRoundness);
graphics.endFill();

var color:uint = 0x990000;
var percentage:Number = Math.ceil(inFood / inFoodMax * 100);
if(percentage > 60) {
color = 0x00C102;
}else if(percentage <= 60 && percentage > 40) {
color = 0xE1B602;
}

var doubleAdjustment = mAdjustment * 2;

graphics.beginFill(color, 1.0);
graphics.drawRoundRect(mAdjustment, mAdjustment, (percentage / 100 * mWidth) - doubleAdjustment, mHeight - doubleAdjustment, mRoundness - doubleAdjustment, mRoundness - doubleAdjustment);
graphics.endFill();

}

}

/com/biogame/Cursor.as

/**
*
*Cursor.as
*
*Vervangt de muis met een custom cursor en reageert op andere interactieve elementen
*
*@ extendsElementeClip
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.MouseEvent;

public class Cursor extends Element {

private var mAreaTrigger:Boolean = false;

/**
*
*Cursor
*
*Constructor voor deze custom cursor
*
*@ params(Geen)
*
*/

public function Cursor():void {
cacheAsBitmap = true;
mStates.push('normal');
mStates.push('interactive');
mStates.push('disabled');
}

/**
*
*update
*
*Zorgt ervoor dat onze cursor de muis positie volgt. De cursor springt op de disabled cursor mocht je bij je tegenstander komen
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt. In dit geval een mouse move event
*
*/

public function update(inMouseEvent:MouseEvent):void {
x = inMouseEvent.stageX + 2;
y = inMouseEvent.stageY + 2;
if(!mAreaTrigger && x < 500 && !BioGame(root).mPaused) {
mCurrentState = 2;
draw();
mAreaTrigger = true;
}else if(mAreaTrigger && x >= 500) {
mCurrentState = 0;
draw();
mAreaTrigger = false;
}
inMouseEvent.updateAfterEvent();
}

}

}

/com/biogame/Doors.as

/**
*
*Doors.as
*
*Deur om de koeien naar binnen of buiten te verplaatsen
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class Doors extends InteractiveElement {

private var mDuration:Number = 2;

/**
*
*Doors
*
*Constructor voor de deurtjes
*
*@ paraminGame [Game]Referentie aan de game instantie waarin deze silo wordt opgenomen
*
*/

public function Doors(inGame:Game):void {
mGame = inGame;
determineButtonMode();
if(!mGame.mIsPlayer) {
visible = false;
}
}

/**
*
*initialize
*
*Initialiseert de deuren. Voegt daarnaast de 'toggle' toestand toe (Wanneer de deuren gebruikt worden)
*
*@ params(Geen)
*
*/

public function initialize():void {
mStates.push('toggle');
}

/**
*
*toggle
*
*Dit wordt aangeroepen wanneer de deuren gebruikt worden. Er zit een timer op die uiteindelijk toggleEnd() aanroept
*
*@ params(Geen)
*
*/

public function toggle():void {
if(mEnabled && !mPaused) {
disable();
mTimers['toggle'] = new Timer(mDuration * 1000, 1);
mTimers['toggle'].addEventListener(TimerEvent.TIMER_COMPLETE, toggleEnd);
mTimers['toggle'].start();
}
}

/**
*
*toggleEnd
*
*Als de deuren hun toggle() animatie hebben afgerond en de tractor is niet meer aan het maaien, de deuren weer bruikbaar maken
*
*@ paraminTimerEvent [Game]Het timer-event waarop gereageerd wordt, zie toggle()
*
*/

public function toggleEnd(inTimerEvent:TimerEvent):void {
if(!mGame.mElementTractor.mMowing) {
enable();
}
}

}

}

/com/biogame/Element.as

/**
*
*Element.as
*
*Basis klasse voor alle dynamische elementen in de game
*
*@ extendsMovieClip
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.geom.Point;
import flash.events.Event;

public class Element extends MovieClip {

public var mGame:Game;

public var mTimers:Object = new Object();
public var mTweens:Object = new Object();
public var mCurrentState:Number = 0;
public var mStates:Array = new Array();

public var mHighlighted:Boolean = false;

public var mPosition:Point;

public var mRemoved:Boolean = false;
public var mPaused:Boolean = false;

public var mPerspective:Boolean = false;
public var mPerspectiveMin:Number = 0.15;

/**
*
*Element
*
*Constructor voor een nieuw dynamisch element
*
*@ params(Geen)
*
*/

public function Element():void {
cacheAsBitmap = true;
stop();
}

/**
*
*setState
*
*Stelt een nieuwe toestand voor een dynamisch element in en roept draw() aan
*
*@ paraminState[int]Identificatie van de nieuwe toestand
*
*/

public function setState(inState:int):void {
mCurrentState = inState;
draw();
}

/**
*
*draw
*
*Update een element naar zijn nieuwe toestand afhankelijk van mCurrentState en of deze toestand bestaat
*
*@ params(Geen)
*
*/

public function draw():void {
if(mCurrentState in mStates) {
gotoAndStop(mStates[mCurrentState]);
}else if(mStates.length > 0) {
gotoAndStop(mStates[0]);
}
}

/**
*
*setIndex
*
*Stelt een nieuwe diepte index voor de juiste weergave qua perspectief
*
*@ paraminIndex [Number]De nieuwe diepte index
*@ paraminField[Boolean]Of dit display object deel uit maakt van het veld ja of nee
*
*/

public function setIndex(inIndex:Number, inUseParent:Boolean=true):void {
if(parent) {
mGame.setIndex(this, inIndex, inUseParent);
}else{
trace('Incorrect parent relationship for ' + this);
}
}

/**
*
*getIndex
*
*Geeft de huidige diepte index van dit element terug
*
*@ params(Geen)
*@ returnNumberDe huidige diepte index
*
*/

public function getIndex():Number {
if(parent) {
return parent.getChildIndex(this);
}else{
return -1;
}
}

/**
*
*setRandomFlip
*
*Flipt een element horizontaal met een kans van vijftig (50) procent (Leuk om die koetjes te flippen)
*
*@ params(Geen)
*
*/

public function setRandomFlip():void {
if(Math.round(Math.random()) == 0) {
scaleX *= -1;
}
}

/**
*
*setPerspectiveInvoke
*
*Een event-response functie om het perspectief te updaten via setPerspective()
*
*@ params(Geen)
*
*/

public function setPerspectiveInvoke(inEvent:Event):void {
if(mPerspective) {
setPerspective();
}
}

/**
*
*setPerspective
*
*Update een element afhankelijk van de y-positie. Dit zorgt voor perspectief
*
*@ params(Geen)
*
*/

public function setPerspective():void {
if(!mPerspective) {
return;
}
var correctedY = y - 300;
if(correctedY < 1) {
correctedY = 1;
}
var newScale = correctedY / 400;
setScale(newScale);
}

/**
*
*setPosition
*
*Verplaatst een element naar zijn nieuwe positie, en slaat deze op als start-positie (Gebruikt in menig animatie)
*
*@ paraminX [Number]De nieuwe x-positie
*@ paraminY[Number]De nieuwe y-positie
*@ paraminMirrored [Boolean]Gebruikt om elementen mooi te spiegelen in het veld van de tegenstander
*
*/

public function setPosition(inX:Number, inY:Number, inMirrored:Boolean=false):void {
if(inMirrored && !mGame.mIsPlayer) {
inX = 500 - inX;
}
x = inX;
y = inY;
mPosition = new Point(x, y);
}

/**
*
*setScale
*
*Update een element naar zijn nieuwe schaal. Dit wordt gebruikt door oa setPerspective()
*
*@ paraminScale [Number]De nieuwe schaal
*
*/

public function setScale(inScale:Number):void {
if(inScale < mPerspectiveMin) {
inScale = mPerspectiveMin;
}
scaleX = (scaleX < 0) ? -1 * inScale : inScale;
scaleY = (scaleY < 0) ? -1 * inScale : inScale;
}

/**
*
*highlight
*
*Zorgt voor een highlight effect bij zowel interactieve elementen als bij droptargets
*
*@ paraminApply [Boolean]Om het effect juist toe te passen of te verwijderen
*
*/

public function highlight(inApply:Boolean):void {
if(inApply && !mRemoved && !mPaused) {
filters = [BioGame(root).mHighlight];
mHighlighted = true;
}else{
filters = new Array();
mHighlighted = false;
}
}

/**
*
*pause
*
*Pauzeert een element qua animaties en timers
*
*@ params(Geen)
*
*/

function pause():void {
if(mRemoved) {
return;
}
if(mPaused) {
return;
}
mPaused = true;
for each(var tween in mTweens) {
tween.stop();
}
for each(var timer in mTimers) {
timer.stop();
}
}

/**
*
*resume
*
*Hervat een element qua animaties en timers
*
*@ params(Geen)
*
*/

function resume():void {
if(mRemoved) {
return;
}
if(!mPaused) {
return;
}
mPaused = false;
for each(var tween in mTweens) {
tween.resume();
}
for each(var timer in mTimers) {
timer.start();
}
}

/**
*
*remove
*
*Verwijdert alle animaties, alle timers, alswel zichzelf van de display list
*
*@ params(Geen)
*
*/

function remove():void {
mRemoved = true;
for each(var tween in mTweens) {
tween.stop();
tween = null;
}
for each(var timer in mTimers) {
timer.stop();
timer = null;
}
if(parent) {
parent.removeChild(this);
}
}

/**
*
*debug
*
*Omdat Element de basis klasse is, is het makkelijk om een debug functie te hebben met informatie
*
*@ params(Geen)
*@ return[String]Een stuk tekst als representatie van dit Element object
*
*/

public function debug():String {
return this.name + ' ' + this + '; Paused: ' + mPaused + '; Removed: ' + mRemoved + '; Tweens: ' + mTweens + '; Timers: ' + mTimers + ';';
}

}

}

/com/biogame/Game.as

/**
*
*Game.as
*
*Game instantie waarin de boerderij zich bevindt met gebeurtenissen & handelingen
*
*@ extendsSprite
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.Sprite;
import flash.geom.Point;
import flash.text.TextField;
import flash.utils.Timer;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.utils.setTimeout;

public class Game extends Sprite {

private var mBioGame:BioGame;

public var mIsPlayer:Boolean = false;

public var mSlaughter:Number = 0;
public var mMoney:Number = 2000;
public var mFood:Number = 50;
public var mCowsMax:Number = 0;
public var mCows:Number = mCowsMax;

public var mPriceFood:Number = 40;
public var mPriceCow:Number = 200;

public var mTxtMoney:TextField;
public var mTxtFood:TextField;
public var mTxtCows:TextField;
public var mTxtSlaughter:TextField;

public var mElementSilo:Silo;
public var mElementDoors:Doors;
public var mElementTractor:Tractor;
public var mElementBuyFood:BuyFood;
public var mElementBuyCow:BuyCow;

public var mFieldCows:Sprite = new Sprite();
public var mFieldGrass:Sprite = new Sprite();
public var mListGrass:Array = new Array();
public var mListCows:Array = new Array();
public var mListSpawns:Array = new Array();
public var mListPositionsCows:Array = new Array();
public var mListPositionsGrass:Array = new Array();
public var mSack:Sack;

public var mInsidePoint:Point;
public var mInsideTimer:Timer;
public var mInside:Boolean = false;

/**
*
*Game
*
*Constructor voor een nieuwe game instantie
*
*@ paraminIsPlayer[Boolean]Bepaalt of dit de bestuurbare of tegenstander instantie van de game is
*
*/

public function Game(inIsPlayer:Boolean=false):void {
mIsPlayer = inIsPlayer;
if(!mIsPlayer) {
setupOpponent();
}
}


/**
*
*initialize
*
*Verzorgt het instellen van de tekstvelden in de HUD
*
*@ paraminTxtMoney[TextField]Tekstveld met daarin de hoeveelheid geld
*@ paraminTxtFood[TextField]Tekstveld met daarin de hoeveelheid zakken voedsel
*@ paraminTxtCows[TextField]Tekstveld met daarin het aantal koeien
*@ paraminTxtSlaughter[TextField]Tekstveld met daarin het aantal geslachte koeien
*
*/

public function initialize(inTxtMoney:TextField, inTxtFood:TextField, inTxtCows:TextField, inTxtSlaughter:TextField):void {
mBioGame = BioGame(parent);
mTxtMoney = inTxtMoney;
mTxtFood = inTxtFood;
mTxtCows = inTxtCows;
mTxtSlaughter = inTxtSlaughter;
if(mIsPlayer) {
x = 500;
mInsidePoint = new Point(62, -40);
}else{
x = 0;
mInsidePoint = new Point(238, -40);
}
y = 0;
setupElements();
setupGrass();
setupCows();
addChild(mFieldGrass);
addChild(mFieldCows);
update();
}

/**
*
*setupElements
*
*Voegt een aantal interactieve elementen toe, waaronder de silo, tractor, deuren en twee koop knoppen
*
*@ params(Geen)
*
*/

public function setupElements():void {
mElementSilo = new Silo(this);
mElementSilo.setPosition(280, 247, true);
addChild(mElementSilo);
mElementSilo.initialize();

mElementTractor = new Tractor(this);
mElementTractor.setPosition(60, 300, true);
addChild(mElementTractor);
mElementTractor.initialize();

mElementDoors = new Doors(this);
mElementDoors.setPosition(416, 242, true);
addChild(mElementDoors);
mElementDoors.initialize();

mElementBuyFood = new BuyFood(this);
mElementBuyFood.setPosition(270, 120, true);
addChild(mElementBuyFood);
mElementBuyFood.initialize();

mElementBuyCow = new BuyCow(this);
mElementBuyCow.setPosition(370, 120, true);
addChild(mElementBuyCow);
mElementBuyCow.initialize();
}

/**
*
*setupControls
*
*Zorgt voor event handlers bij de interactieve elementen, zie setupElements()
*
*@ params(Geen)
*
*/

public function setupControls():void {
mElementSilo.addEventListener(MouseEvent.MOUSE_DOWN, actionFoodInvoke);
mElementTractor.addEventListener(MouseEvent.CLICK, actionMowInvoke);
mElementDoors.addEventListener(MouseEvent.CLICK, actionDoorsInvoke);
mElementBuyFood.addEventListener(MouseEvent.CLICK, actionBuyFoodInvoke);
mElementBuyCow.addEventListener(MouseEvent.CLICK, actionBuyCowInvoke);
}

/**
*
*moveChildToTop
*
*Verplaatst een element in de display naar voren
*
*@ paraminChild [DisplayObject]Element om naar voren te verplaatsen
*
*/

private function moveChildToTop(inChild:DisplayObject):void {
setChildIndex(inChild, numChildren-1);
}

/**
*
*moveChildToBack
*
*Verplaatst een element in de display naar achteren
*
*@ paraminChild [DisplayObject]Element om naar achteren te verplaaatsen
*
*/

private function moveChildToBack(inChild:DisplayObject):void {
setChildIndex(inChild, 0);
}

/**
*
*update
*
*Dit update het merendeel van de tekstvelden bovenin, met daarin de huidige resources
*
*@ params(Geen)
*
*/

public function update():void {
mTxtMoney.text = '€' + String(mMoney);
mTxtFood.text = String(mFood);
mTxtCows.text = String(mCows);
mTxtSlaughter.text = String(mSlaughter);
if(mFood > 0 && !mInside) {
mElementSilo.enable();
}else{
mElementSilo.disable();
}
if(mMoney >= mPriceFood) {
mElementBuyFood.enable();
}else{
mElementBuyFood.disable();
}
if(mCows < mCowsMax && mMoney >= mPriceCow && !mInside) {
mElementBuyCow.enable();
}else{
mElementBuyCow.disable();
}
}

/**
*
*actionFoodInvoke
*
*Event handler voor het voeden van koeien
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt, in dit geval een mouse down event op de silo
*
*/

private function actionFoodInvoke(inMouseEvent:MouseEvent):void {
actionFood(inMouseEvent);
}

/**
*
*actionMowInvoke
*
*Event handler voor het maaien van het grasveld
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt, in dit geval een mouse down event op de silo
*
*/

private function actionMowInvoke(inMouseEvent:MouseEvent):void {
actionMow();
}

/**
*
*actionDoorsInvoke
*
*Event handler voor het binnen of buiten zetten van koeien
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt, in dit geval een mouse down event op de silo
*
*/

private function actionDoorsInvoke(inMouseEvent:MouseEvent):void {
actionDoors();
}

/**
*
*actionBuyFoodInvoke
*
*Event handler voor het aanschaffen van voedsel
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt, in dit geval een mouse down event op de silo
*
*/

private function actionBuyFoodInvoke(inMouseEvent:MouseEvent):void {
actionBuyFood();
}

/**
*
*actionBuyCowInvoke
*
*Event handler voor het aanschaffen van een nieuwe koe
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt, in dit geval een mouse down event op de silo
*
*/

private function actionBuyCowInvoke(inMouseEvent:MouseEvent):void {
actionBuyCow();
}

/**
*
*actionFood
*
*Indien de silo actief is en niet gepauzeerd, een nieuwe voedsel zak genereren om te voederen, zie Sack
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt
*
*/

public function actionFood(inMouseEvent:MouseEvent):void {
if(mIsPlayer && mElementSilo.mEnabled && !mElementSilo.mPaused) {
var point:Point = globalToLocal(new Point(inMouseEvent.stageX, inMouseEvent.stageY));
mSack = new Sack(this, point.x, point.y);
mSack.initialize();
addChild(mSack);
}
}

/**
*
*actionFoodIndividually
*
*Voedt de gespecifeerde koe. De koe zal het totaal overgebleven bedrag aan voer teruggeven
*
*@ paraminCow [Cow]De koe om te voeden
*
*/

public function actionFoodIndividually(inCow:Cow):void {
mFood = Cow(inCow).feed(mFood);
update();
}

/**
*
*actionMow
*
*Indien de koeien binnen zitten, de tractor actief is & niet gepauzeerd is, begint met het maaien van het gras
*
*@ params(Geen)
*
*/

public function actionMow():void {
if(mInside && mElementTractor.mEnabled && !mElementTractor.mPaused) {
moveChildToTop(mElementTractor);
mElementDoors.disable();
mElementTractor.mowStart();
}
}

/**
*
*actionMowResult
*
*Het genereren van een popup voor het maai resultaat
*
*@ params(Geen)
*
*/

public function actionMowResult():void {
moveChildToBack(mElementTractor);
mElementTractor.scaleX *= -1;
var mowedAmount:Number = 0;
for each(var grass:Grass in mListGrass) {
mowedAmount += grass.mow();
}
mElementDoors.enable();
if(mIsPlayer) {
mBioGame.mPopup.show(Popup.MOW, new Array());
}else{
mMoney += 400;
}
}

/**
*
*actionInsideResult
*
*Het genereren van een popup voor het te lang binnen houden van de koeien
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval die van actionDoors()
*
*/

private function actionInsideResult(inTimerEvent:TimerEvent):void {
if(mCows > 0) {
mBioGame.mPopup.show(Popup.INSIDE, new Array());
}
}

/**
*
*actionDoors
*
*Het naar binnen en buiten verplaatsen van de koeien
*
*@ params(Geen)
*
*/

public function actionDoors():void {
if(mElementDoors.mEnabled && !mElementDoors.mPaused) {
Sounds.play(new SndDoor3());
mInside = !mInside;
if(mInside) {
if(mIsPlayer) {
mInsideTimer = new Timer(15000, 1);
mInsideTimer.addEventListener(TimerEvent.TIMER_COMPLETE, actionInsideResult);
mInsideTimer.start();
}
mElementSilo.disable();
mElementTractor.enable();
}else{
if(mIsPlayer) {
mInsideTimer.reset();
}
mElementSilo.enable();
mElementTractor.disable();
}
mElementDoors.toggle();
for each(var cow in mListCows) {
cow.walk();
}
update();
}
}

/**
*
*actionBuyFood
*
*Het kopen van wat extra voedsel
*
*@ params(Geen)
*
*/

public function actionBuyFood():void {
if(mElementBuyFood.mEnabled && !mElementBuyFood.mPaused && mMoney >= mPriceFood) {
if(mIsPlayer) {
Sounds.play(new SndKaChing());
}
mMoney -= mPriceFood;
mFood += 10;
update();
}
}

/**
*
*actionBuyCow
*
*Het kopen van een koe
*
*@ params(Geen)
*
*/

public function actionBuyCow():void {
if(mElementBuyCow.mEnabled && !mElementBuyCow.mPaused && mMoney >= mPriceCow) {
if(mIsPlayer) {
Sounds.play(new SndKaChing());
}
mMoney -= mPriceCow;
setupCow();
reorderIndices();
update();
}
}

/**
*
*pause
*
*Het pauzeren van deze game instantie, de interactieve elementen, timers, koeien en gras
*
*@ params(Geen)
*
*/

public function pause():void {
mElementTractor.pause();
mElementDoors.pause();
mElementSilo.pause();
mElementBuyFood.pause();
mElementBuyCow.pause();
if(mIsPlayer && mInsideTimer) {
mInsideTimer.stop();
}
for each(var cow in mListCows) {
cow.pause();
}
for each(var grass in mListGrass) {
grass.pause();
}
}

/**
*
*resume
*
*Het hervatten van deze game instantie, de interactieve elementen, timers, koeien en gras
*
*@ params(Geen)
*
*/

public function resume():void {
mElementTractor.resume();
mElementDoors.resume();
mElementSilo.resume();
mElementBuyFood.resume();
mElementBuyCow.resume();
if(mIsPlayer && mInside && mInsideTimer && mInsideTimer.currentCount < mInsideTimer.repeatCount) {
mInsideTimer.start();
}
for each(var cow in mListCows) {
cow.resume();
}
for each(var grass in mListGrass) {
grass.resume();
}
}

/**
*
*setIndex
*
*Instellen van een index voor een child object
*
*@ params(Geen)
*
*/

public function setIndex(inChild:DisplayObject, inIndex:Number, inUseParent:Boolean=true) {
if(inIndex < 0) {
inIndex = 0;
}
if(inUseParent) {
if(inIndex > inChild.parent.numChildren - 1) {
inIndex = inChild.parent.numChildren - 1;
}
inChild.parent.setChildIndex(inChild, inIndex);
}else{
if(inIndex > numChildren - 1) {
inIndex = numChildren - 1;
}
setChildIndex(inChild, inIndex);
}
}

/**
*
*reorderIndices
*
*Opnieuw instellen van de dieptes van de koeien en eventuele ophaal vrachtwagentjes
*
*@ params(Geen)
*
*/

public function reorderIndices():void {
var childArray:Array = new Array();
for(var i=0; i childArray.push(mFieldCows.getChildAt(i));
}
var sortedArray:Array = childArray.sortOn('y');
for(i=0; i setIndex(sortedArray[i], i);
}
}

/**
*
*setupOpponent
*
*De macro boer heeft het in het echte leven makkelijker dan de bio-boer. In onze game dus ook (verlaagde prijzen)
*
*@ params(Geen)
*
*/

private function setupOpponent():void {
mPriceCow = 100;
mPriceFood = 20;
}

/**
*
*removeCow
*
*Verwijderen van een koe, een nieuwe koe-positie toevoegen (om te kopen) en de HUD updaten
*
*@ paraminSpot [Number]Het nummertje (qua positie) van de koe die verwijderd wordt
*
*/

public function removeCow(inSpot:Number):void {
mListSpawns.push(inSpot);
mCows--;
update();
}

/**
*
*setupCow
*
*Toevoegen van een nieuwe koe op de eerste lege positie
*
*@ params(Geen)
*
*/

private function setupCow():void {
if(mListSpawns.length > 0) {
var position = mListSpawns.shift();
var array = mListPositionsCows[position] as Array;
var cow = new Cow();
cow.mGame = this;
cow.mSpot = position;
cow.setPosition(array[0], array[1]);
cow.setPerspective();
cow.setRandomFlip();
mListCows.push(cow);
mFieldCows.addChild(cow);
cow.setIndex(array[2]);
cow.initialize();
mCows++;
}
}

/**
*
*setupCows
*
*Aanmaken van de koeien voor zoveel er plekjes zijn (Verschilt dus per boer)
*
*@ params(Geen)
*
*/

private function setupCows():void {
mCowsMax = mListPositionsCows.length;
for(var i=0; i setupCow();
}
}

/**
*
*setupTruck
*
*Aanmaken van een vrachtwagentje die de koe komt ophalen
*
*@ paraminCow [Cow]De koe waarvoor een vrachtwagentje wordt aangemaakt
*
*/

public function setupTruck(inCow:Cow):Truck {
var truck:Truck = new Truck(this, inCow);
mFieldCows.addChild(truck);
var index:Number = inCow.getIndex();
truck.setIndex(index + 1, true);
return truck;
}

/**
*
*setupGrass
*
*Toevoegen van het gras
*
*@ params(Geen)
*
*/

private function setupGrass():void {
for each(var array in mListPositionsGrass) {
var grass = new Grass();
grass.mGame = this;
grass.setPosition(array[0], array[1]);
grass.setPerspective();
grass.setRandomFlip();
mListGrass.push(grass);
mFieldGrass.addChild(grass);
grass.setIndex(array[2]);
grass.initialize();
}
}

/**
*
*setupPosition
*
*Instellen van een display object op een bepaalde index (Gebruikt voor koeien & het gras)
*
*@ paraminChild [Object]Het display object om in te stellen
*@ paraminIndex [Number]De index qua diepte
*
*/

public function setupPosition(inChild:Object, inIndex:Number):void {
var inX = inChild.x;
if(mIsPlayer) {
inX -= 500;
}
var inY = inChild.y;
var inArray = new Array(inX, inY, inIndex);
if(inChild is Cow) {
mListSpawns.push(mListPositionsCows.length);
mListPositionsCows.push(inArray);
}else{
mListPositionsGrass.push(inArray);
}
}

}

}

/com/biogame/Grass.as

/**
*
*Grass.as
*
*Verzorgt een (1) stukje gras, zorgt voor groei functionaliteit en de mogelijkheid om dit stukje gras te maaien
*
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;

public class Grass extends Element {

private var mGrowthSpeed:Number = 15000;

/**
*
*Grass
*
*Constructor voor een stukje gras
*
*@ params(Geen)
*
*/

public function Grass():void {
cacheAsBitmap = true;
mPerspective = true;
mPerspectiveMin = 0.1;
}

/**
*
*initialize
*
*Initialiseerd een stukje gras met de zes (6) standen gras. Laat het gras ook groeien dmv growTimer()
*
*@ params(Geen)
*
*/

public function initialize():void {
mStates.push('grass0');
mStates.push('grass1');
mStates.push('grass2');
mStates.push('grass3');
mStates.push('grass4');
growTimer();
draw();
}

/**
*
*mow
*
*Maait een stukje gras en bepaald hoeveel gras het oplevert om te gebruiken
*
*@ params(Geen)
*@ returnNumberHet aantal gras dat deze maai actie heeft opgeleverd
*
*/

public function mow():Number {
if(mCurrentState >= 2) {
var returnState:Number = mCurrentState;
shrink();
return returnState;
}else{
return 0;
}
}

/**
*
*growTimer
*
*Genereert een groei timer, met een minimale tijdsduur van 3 seconden. Als deze timer afloopt, zie growing()
*
*@ params(Geen)
*
*/

private function growTimer():void {
if(mTimers['growth']) {
mTimers['growth'].removeEventListener(TimerEvent.TIMER_COMPLETE, growing);
}
mTimers['growh'] = new Timer(3000 + Math.random() * mGrowthSpeed, 1);
mTimers['growh'].addEventListener(TimerEvent.TIMER_COMPLETE, growing);
mTimers['growh'].start();
}

/**
*
*growing
*
*Event-handler als de groei timer afloopt. Laat ons gras een stukje groeien, zie grow()
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt, in dit geval die van growTimer()
*
*/

private function growing(inTimerEvent:TimerEvent):void {
grow();
}

/**
*
*grow
*
*Als ons gras nog kan groeien, laat het een stukje groeien (visueel) en start een nieuwe groei timer, zie growTimer()
*
*@ params(Geen)
*
*/

private function grow():void {
if(mCurrentState < mStates.length - 1) {
mCurrentState++;
draw();
}
growTimer();
}

/**
*
*shrink
*
*Zet het gras weer terug op zijn fijngesneden visuele toestand
*
*@ params(Geen)
*
*/

private function shrink():void {
mCurrentState = 0;
draw();
}

}

}

/com/biogame/InteractiveElement.as

/**
*
*InteractiveElement.as
*
*Basis klasse van alle interactieve elementen in de game
*
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.MouseEvent;

public class InteractiveElement extends Element {

public var mEnabled:Boolean = true;

/**
*
*InteractiveElement
*
*Constructor voor alle interactieve elementen. Voegt standaard hover, enabled en disabled toestanden toe
*
*@ params(Geen)
*
*/

public function InteractiveElement():void {
mStates.push('enabled');
mStates.push('disabled');
}

/**
*
*enableButtonMode
*
*Zorgt ervoor dat het element een 'handje' cursor laat zien en highlight voor de juiste gebruikers feedback
*
*@ params(Geen)
*
*/

public function enableButtonMode():void {
buttonMode = true;
addEventListener(MouseEvent.MOUSE_OVER, interactionOver);
addEventListener(MouseEvent.MOUSE_OUT, interactionOut);
}

/**
*
*determineButtonMode
*
*Roept enableButtonMode() aan indien het om een interactief element van de speler gaat
*
*@ params(Geen)
*
*/

public function determineButtonMode():void {
if(mGame.mIsPlayer) {
enableButtonMode();
}else{
buttonMode = false;
}
}

/**
*
*interactionOver
*
*Als dit interactieve element aan staat en niet gepauzeerd is, laat een highlight en een andere cursor zien
*
*@ paraminMouseEvent [MouseEvent]Het mouse-over event waarop gereageerd wordt
*
*/

function interactionOver(inMouseEvent:MouseEvent):void {
if(!BioGame(root)) {
return;
}
if(mEnabled && !mPaused) {
BioGame(root).mCursor.setState(1);
highlight(true);
}else{
BioGame(root).mCursor.setState(2);
highlight(false);
}
}

/**
*
*interactionOut
*
*Zet de cursor weer terug naar een normale cursor en haal de highlight weg
*
*@ paraminMouseEvent [MouseEvent]Het mouse-out event waarop gereageerd wordt
*
*/

function interactionOut(inMouseEvent:MouseEvent):void {
if(!BioGame(root)) {
return;
}
BioGame(root).mCursor.setState(0);
highlight(false);
}

/**
*
*resume
*
*Hervat dit interactieve element en maak het ook weer bruikbaar als het gepauzeerd was tijdens die periode
*
*@ params(Geen)
*
*/

override function resume():void {
super.resume();
if(mEnabled) {
enable();
}
}

/**
*
*enable
*
*Het bruikbaar maken van een interactief element en de toestand daarna updaten
*
*@ params(Geen)
*
*/

function enable():void {
mEnabled = true;
mCurrentState = 0;
enabled = true;
draw();
}

/**
*
*disable
*
*Het onbruikbaar maken van een interactief element en de toestand daarna updaten
*
*@ params(Geen)
*
*/

function disable():void {
mEnabled = false;
mCurrentState = 1;
if(mHighlighted) {
highlight(false);
BioGame(root).mCursor.setState(2);
}
enabled = false;
draw();
}

}

}

/com/biogame/Popup.as

/**
*
*Popup.as
*
*Maakt & verzorgd correct functionerende popups voor verscheidene events (Start, Informatie, Maaien, Ziekte, Beweging & End)
*
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.transitions.easing.*;

import com.exanimo.transitions.GCSafeTween;

public class Popup extends Element {

public static const PERSON:Class = PopupPerson;
public static const MISSION:Class = PopupMission;
public static const START:Class = PopupStart;
public static const INTRO:Class = PopupIntro;

public static const INFO:Class = PopupInfo;
public static const DEAD:Class = PopupDead;
public static const MOW:Class = PopupMow;
public static const ILL:Class = PopupIll;
public static const INSIDE:Class = PopupInside;

public static const END:Class = PopupEnd;
public static const MEAT:Class = PopupMeat;

private var mTimer:Timer;
private var mStarted:Boolean = false;

public var mActive:Boolean = false;
private var mOptions:Array;

private var mPopup:MovieClip;
private var mOverlay:Sprite;
private var mOverlayTween:GCSafeTween;

private var mOpponentCows:Number;
private var mOpponentPrice:Number;
private var mOpponentSum:Number;

private var mPlayerCows:Number;
private var mPlayerPrice:Number;
private var mPlayerSum:Number;

/**
*
*Popup
*
*Constructor voor een popup
*
*@ params(Geen)
*
*/

public function Popup():void {
visible = false;
}

/**
*
*initialize
*
*Tekent een mooie grijze overlay om de speelomgeving wat uit te faden indien er een popup te voorschijn komt
*Deze popup staat standaard helemaal ingefade
*
*@ params(Geen)
*
*/

public function initialize():void {
mOverlay = new Sprite();
mOverlay.graphics.beginFill(0xF0EED8, 1.0);
mOverlay.graphics.drawRect(-0.5 * 1000, -0.5 * 706, 1000, 706);
mOverlay.graphics.endFill();
mOverlay.alpha = 1.0;
addChild(mOverlay);
}

/**
*
*fadeIn
*
*Zorgt voor een fade in als er een popup tevoorschijn komt
*
*@ params(Geen)
*
*/

private function fadeIn():void {

mOverlayTween = new GCSafeTween(mOverlay, 'alpha', Regular.easeIn, mOverlay.alpha, 0.6, 1, true);
}

/**
*
*fadeOut
*
*Zorgt voor een fade out als de popup verdwijnt (Op dit moment disabled)
*
*@ params(Geen)
*
*/

private function fadeOut():void {
// mOverlayTween = new GCSafeTween(mOverlay, 'alpha', Regular.easeIn, mOverlay.alpha, 0.0, 1, true);
}

/**
*
*person
*
*Event handler voor de naam-invoeren popup. Slaat de naam van de speler op en verstopt de popup weer
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function person(inMouseEvent:MouseEvent):void {
BioGame(root).mName = mPopup.mName.text;
show(MISSION, new Array());
}

/**
*
*personEmpty
*
*Event handler voor de naam-invoeren popup. Zorgt ervoor dat 'Voornaam' verdwijnt als je er op klikt
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op het voornaam veld
*
*/

private function personEmpty(inMouseEvent:MouseEvent):void {
if(mPopup.mName.text == 'Voornaam') {
mPopup.mName.text = '';
}
}

/**
*
*fillInName
*
*Vervangt ### door de naam van de speler (Dynamisch effect)
*
*@ paraminString [String]String te vervangen
*@ returnStringString met daarin de naam vervangen
*
*/

private function fillInName(inString:String):String {
var pattern:RegExp = /###/;
return inString.replace(pattern, BioGame(root).mName);
}

/**
*
*mission
*
*Event handler voor de missie popup. Geeft de missie weer
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function mission(inMouseEvent:MouseEvent):void {
show(INTRO, new Array());
}

/**
*
*intro
*
*Event handler voor de intro popup. Geeft de introductie animatie weer
*
*@ paraminTimerEvent [TimerEvent]Het timer-event waarop gereageerd wordt bij het aflopen van de intro animatie
*
*/

private function intro(inTimerEvent:TimerEvent):void {
introNext();
}

/**
*
*introSkip
*
*Event handler voor de intro popup. Skipt de intro, zie introNext()
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het skippen van de intro animatie
*
*/

public function introSkip(inMouseEvent:MouseEvent):void {
introNext();
}

/**
*
*introNext
*
*Event handler voor de intro popup. Switcht naar het start scherm
*
*@ params(Geen)
*
*/

private function introNext():void {
if(!mStarted) {
mStarted = true;
stage.frameRate = 59;
show(START, new Array());
}
}

/**
*
*start
*
*Event handler voor de start popup. Geeft uitleg & start het spel
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function start(inMouseEvent:MouseEvent):void {
hide();
}

/**
*
*mowFood
*
*Event handler voor de maaien popup na een keuze van voedsel. Geeft de speler het opgeleverde bedrag aan voedsel
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function mowFood(inMouseEvent:MouseEvent):void {
Sounds.play(new SndFood());
BioGame(root).mGamePlayer.mFood += 28;
BioGame(root).mGamePlayer.update();
hide();
}

/**
*
*mowMoney
*
*Event handler voor de maaien popup na een keuze van geld. Geeft de speler het opgeleverde bedrag aan geld
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function mowMoney(inMouseEvent:MouseEvent):void {
Sounds.play(new SndKaChing());
BioGame(root).mGamePlayer.mMoney += 300;
BioGame(root).mGamePlayer.update();
hide();
}

/**
*
*ill
*
*Event handler voor de ziekte popup als je te snel je koeien voert. Int de boete
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function ill(inMouseEvent:MouseEvent):void {
BioGame(root).mGamePlayer.mMoney -= 100;
Sounds.play(new SndKaChing());
if(BioGame(root).mGamePlayer.mMoney < 0) {
BioGame(root).mGamePlayer.mMoney = 0;
}
BioGame(root).mGamePlayer.update();
hide();
}

/**
*
*mowMoney
*
*Event handler voor de maaien popup na een keuze van geld. Geeft de speler het opgeleverde bedrag aan geld
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function dead(inMouseEvent:MouseEvent):void {
BioGame(root).mGamePlayer.mMoney -= 300;
Sounds.play(new SndKaChing());
if(BioGame(root).mGamePlayer.mMoney < 0) {
BioGame(root).mGamePlayer.mMoney = 0;
}
BioGame(root).mGamePlayer.update();
hide();
}

/**
*
*inside
*
*Event handler voor de inside popup als de koeien te lang binnen staan. Int de boete
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function inside(inMouseEvent:MouseEvent):void {
BioGame(root).mGamePlayer.mMoney -= 200;
Sounds.play(new SndKaChing());
if(BioGame(root).mGamePlayer.mMoney < 0) {
BioGame(root).mGamePlayer.mMoney = 0;
}
hide();
}

/**
*
*end
*
*Event handler voor de end-game popup. Laat het einde van het spel zien, het verschijnen van het stukje vlees
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de popup-knop
*
*/

private function end(inMouseEvent:MouseEvent):void {
if(mPopup.mButton.mEnabled) {
show(MEAT, new Array());
}
}

/**
*
*endPriceUp
*
*Event handler voor de end-game popup. Gooit de prijs van de speler omhoog
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de up-knop
*
*/

private function endPriceUp(inMouseEvent:MouseEvent):void {
Sounds.play(new SndKaChing());
mPlayerPrice++;
endPriceUpdate();
}

/**
*
*endPriceDown
*
*Event handler voor de end-game popup. Gooit de prijs van de speler omlaag
*
*@ paraminMouseEvent [MouseEvent]Het mouse-event waarop gereageerd wordt bij het klikken op de down-knop
*
*/

private function endPriceDown(inMouseEvent:MouseEvent):void {
if(mPlayerPrice > mOpponentPrice) {
Sounds.play(new SndKaChing());
mPlayerPrice--;
}
endPriceUpdate();
}

/**
*
*endPriceUpdate
*
*Update de prijs en het totaal voor de speler in de end-game popup
*
*@ params(Geen)
*
*/

private function endPriceUpdate():void {
if(mPlayerPrice <= mOpponentPrice) {
mPopup.mDown.disable();
}else{
mPopup.mDown.enable();
}
mPlayerSum = mPlayerPrice * mPlayerCows * 900;
if(mPlayerSum >= mOpponentSum) {
mPopup.mButton.enable();
}else{
mPopup.mButton.disable();
}
mPopup.mPlayerSum.text = '€' + mPlayerSum + ',00';
mPopup.mPlayerPrice.text = '€' + mPlayerPrice + ',00';
}

/**
*
*erase
*
*Verwijdert de popup. Dit wordt oa gebruikt direct voor het genereren van een nieuwe popup
*
*@ params(Geen)
*
*/

private function erase():void {
if(mPopup) {
BioGame(root).mCursor.setState(0);
removeChild(mPopup);
mPopup = null;
}
}

/**
*
*add
*
*Genereert een nieuwe popup zien, stelt de popup in afhankelijk van het type popup en voegt de popup toe aan de display list
*
*@ paraminClass [Class]De popup-classe die getoont moet worden (linkage via library)
*
*/

public function add(inClass:Class):void {
erase();
mPopup = new inClass();
switch(inClass) {
case PERSON:
mPopup.mName.addEventListener(MouseEvent.CLICK, personEmpty);
mPopup.mButton.set('Verder');
mPopup.mButton.addEventListener(MouseEvent.CLICK, person);
break;
case MISSION:
mPopup.mContent.text = fillInName(mPopup.mContent.text);
mPopup.mButton.set('Verder');
mPopup.mButton.addEventListener(MouseEvent.CLICK, mission);
break;
case INTRO:
mTimer = new Timer(48500, 1);
mTimer.addEventListener(TimerEvent.TIMER_COMPLETE, intro);
mTimer.start();
mPopup.play();
mPopup.mButton.set('Overslaan');
mPopup.mButton.addEventListener(MouseEvent.CLICK, introSkip);
stage.frameRate = 2;
break;
case START:
mPopup.mButton.set('Start');
mPopup.mButton.addEventListener(MouseEvent.CLICK, start);
break;
case DEAD:
mPopup.mButton.set('OK');
mPopup.mButton.addEventListener(MouseEvent.CLICK, dead);
break;
case MOW:
mPopup.mFoodButton.set('Voedsel');
mPopup.mFoodButton.addEventListener(MouseEvent.CLICK, mowFood);
mPopup.mMoneyButton.set('Geld');
mPopup.mMoneyButton.addEventListener(MouseEvent.CLICK, mowMoney);
break;
case ILL:
mPopup.mButton.set('OK');
mPopup.mButton.addEventListener(MouseEvent.CLICK, ill);
break;
case INSIDE:
mPopup.mButton.set('OK');
mPopup.mButton.addEventListener(MouseEvent.CLICK, inside);
break;
case END:
mOpponentCows = BioGame(root).mGameOpponent.mSlaughter;
if(mOpponentCows < 1) {
mOpponentCows = 1;
}
mOpponentPrice = 2;
mOpponentSum = mOpponentCows * 900 * mOpponentPrice;
mPopup.mOpponentCows.text = mOpponentCows;
mPopup.mOpponentMeat.text = mOpponentCows * 900;
mPopup.mOpponentPrice.text = '€' + mOpponentPrice + ',00';
mPopup.mOpponentSum.text = '€' + mOpponentSum + ',00';

mPlayerCows = BioGame(root).mGamePlayer.mSlaughter;
if(mPlayerCows < 1) {
mPlayerCows = 1;
}
mPlayerPrice = 2;
mPopup.mPlayerCows.text = mPlayerCows;
mPopup.mPlayerMeat.text = mPlayerCows * 900;

endPriceUpdate();

mPopup.mName.text = BioGame(root).mName;
mPopup.mUp.addEventListener(MouseEvent.CLICK, endPriceUp);
mPopup.mDown.addEventListener(MouseEvent.CLICK, endPriceDown);
mPopup.mButton.set('Vaststellen');
mPopup.mButton.addEventListener(MouseEvent.CLICK, end);
break;
case MEAT:
mPopup.mPrice.text = '€' + mPlayerPrice + ',00';
break;
}
addChild(mPopup);
}

/**
*
*show
*
*Fade de overlay, genereert een nieuwe popup, slaat de opties voor de popup op, laat deze zijn en pauzeert de complete game
*
*@ paraminClass[Class]Het type popup om te genereren en laten zien (linkage via library)
*@ paraminOptions[Array]Dynamische collectie aan opties / variablen per popup (verschilt per type popup)
*
*/

public function show(inClass:Class, inOptions:Array):void {
visible = true;
fadeIn();
add(inClass);
mOptions = inOptions;
mActive = true;
BioGame(root).pause();
}

/**
*
*hide
*
*Herstelt de cursor, verwijdert de laatste popup, verstopt de popup en hervat de complete game
*
*@ params(Geen)
*
*/

public function hide():void {
erase();
visible = false;
mActive = false;
mOverlay.alpha = 0.0;
BioGame(root).resume();
}

}

}

/com/biogame/PopupAdjuster.as

/**
*
*PopupAdjuster
*
*Verzorgt een up/down knop om een aantal te veranderen
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.text.TextField;

public class PopupAdjuster extends InteractiveElement {

/**
*
*PopupAdjuster
*
*//
*
*@ params(Geen)
*
*/

public function PopupAdjuster():void {
enableButtonMode();
}

}

}

/com/biogame/PopupButton.as

/**
*
*PopupButton
*
*Verzorgt een tekstuele popup knop (Wordt gebruikt in alle popup vensters)
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.text.TextField;

public class PopupButton extends InteractiveElement {

private var mSprite:Sprite;

/**
*
*PopupButton
*
*Constructor voor een popup button. Zorgt ook dmv een transparent vlak dat je ook op de tekst kan klikken (Flash bug?)
*
*@ params(Geen)
*
*/

public function PopupButton():void {
enableButtonMode();

mSprite = new Sprite();
mSprite.graphics.beginFill(0xFFFFFF, 0.01);
mSprite.graphics.drawRect(-1 * width / 2, -1 * height / 2, width, height);
mSprite.graphics.endFill();
addChild(mSprite);
}

/**
*
*set
*
*Gebruikt om de tekst van zo'n knop, dynamisch te veranderen
*
*@ paraminText [String]De nieuwe tekst voor deze knop
*
*/

public function set(inText:String):void {
mText.text = inText;
}

}

}

/com/biogame/Sack.as

/**
*
*Sack.as
*
*Zakje voedsel om te slepen op een koe (Wordt niet gebruikt door je tegenstander)
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.events.Event;

public class Sack extends InteractiveElement {

private var mMoved:Boolean = false;

/**
*
*Sack
*
*Constructor voor een drag-and-drop zak met voedsel
*
*@ paraminGame[Game]Referentie aan de game instantie waarin deze zak met voedsel wordt opgenomen
*@ paraminX[Number]De x-positie van de zak met voedsel (Dicht bij de silo waarschijnlijk)
*@ paraminY[Number]De y-positie van de zak met voedsel (Idem)
*
*/

public function Sack(inGame:Game, inX:Number, inY:Number):void {
mGame = inGame;
cacheAsBitmap = true;
x = inX;
y = inY;
mPerspectiveMin = 0.2;
mPerspective = true;
setPerspective();
}

/**
*
*initialize
*
*Initialiseert deze zak met voedsel om te kunnen slepen, maar ook drop functionaliteit
*
*/

public function initialize():void {
startDrag(true, new Rectangle(40, 195, 430, 480));
addEventListener(MouseEvent.MOUSE_MOVE, update);
addEventListener(MouseEvent.MOUSE_UP, drop);
draw();
}

/**
*
*removeHighlights
*
*Haalt de highlights bij koeien weg
*
*@ params(Geen)
*
*/

private function removeHighlights():void {
for each(var cow in mGame.mListCows) {
cow.highlight(false);
}
}

/**
*
*update
*
*Dit zorgt ervoor dat de zak in perspectief wordt geplaatst dat deze mooi over het veld heen beweegt
*Daarnaast wordt er gezorgd dat er eventueel een koe gehighlight wordt waar je overheen beweegt met de zak met voedsel
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt. In dit geval een mouse move event
*
*/

private function update(inMouseEvent:MouseEvent):void {
if(mRemoved) {
return;
}
mMoved = true;
var point:Point = mGame.localToGlobal(new Point(x, y));
var skipRest:Boolean = false;
for each(var cow in mGame.mListCows) {
if(!skipRest && !cow.mDead && cow.hitTestPoint(point.x, point.y, true)) {
cow.highlight(true);
skipRest = true;
}else{
cow.highlight(false);
}
}
setPerspective();
}

/**
*
*drop
*
*De zak met voedsel wordt gedropt, al dan niet op een koe. De potentiele koe wordt gevoederd, de zak verwijdert
*
*@ paraminMouseEvent [MouseEvent]Het mouse event waarop gereageerd wordt. In dit geval een mouse release event
*
*/

private function drop(inMouseEvent:MouseEvent):void {
if(!mMoved || mRemoved) {
return;
}
var point:Point = mGame.localToGlobal(new Point(x, y));
for each(var cow in mGame.mListCows) {
if(cow.hitTestPoint(point.x, point.y, true)) {
mGame.actionFoodIndividually(cow);
break;
}
}
mRemoved = true;
removeHighlights();
stopDrag();
if(parent) {
parent.removeChild(this);
}
}

}

}

/com/biogame/Silo.as

/**
*
*Silo.as
*
*Silo om de koeien te kunnen voeren
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

public class Silo extends InteractiveElement {

/**
*
*Silo
*
*Constructor voor de silo
*
*@ paraminGame [Game]Referentie aan de game instantie waarin deze silo wordt opgenomen
*
*/

public function Silo(inGame:Game):void {
mGame = inGame;
determineButtonMode();
if(!mGame.mIsPlayer) {
visible = false;
}
}

/**
*
*initialize
*
*Initialiseert deze silo
*
*@ params(Geen)
*
*/

public function initialize():void {
draw();
}

}

}

/com/biogame/Sounds.as

/**
*
*Sounds.as
*
*Aansturende klasse voor geluiden / muziek
*
*@ staticJa (Geen directe instantie)
*@ extends(None)
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.media.Sound;
import flash.media.SoundChannel;

public class Sounds {

private static var mSoundCounter:Number = 0;
private static var mSounds:Object = new Object();

/**
*
*play
*
*Speelt de gespecifeerde sound af en koppelt deze eventueel aan een object
*
*@ paraminSound[Sound]Sound om af te spelen
*@ paraminObject[Object]Eventueel het object om de sound aan te koppelen
*
*/

public static function play(inSound:Sound, inObject:Object=null):void {
var addedIndex:Object;
if(!inObject) {
mSoundCounter++;
addedIndex = mSoundCounter;
}else{
addedIndex = inObject.name;
if(mSounds[addedIndex]) {
stop(addedIndex);
}
}
mSounds[addedIndex] = inSound.play();
}

/**
*
*stop
*
*Stopt soundchannel voor gespecifieerde object
*
*@ paraminObject[Object]Het object om de sound voor te stoppen
*
*/

public static function stop(inObject:Object):void {
if(mSounds[inObject]) {
SoundChannel(mSounds[inObject]).stop();
}
}

}

}

/com/biogame/Tractor.as

/**
*
*Tractor.as
*
*Tractor om je gras te maaien als je koeien binnen staan
*
*@ extendsInteractiveElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;

import com.exanimo.transitions.GCSafeTween;

public class Tractor extends InteractiveElement {

public var mMowing:Boolean = false;
private var mMowingForward:Boolean = false;
private var mMowingDuration:Number = 1;
private var mMowingLines:Number = 8;
private var mMowingCurrentLine:Number = mMowingLines;

/**
*
*Tractor
*
*Constructor voor de tractor
*
*@ paraminGame [Game]Referentie aan de game instantie waarin deze tractor wordt opgenomen
*
*/

public function Tractor(inGame:Game):void {
mGame = inGame;
determineButtonMode();
mPerspective = true;
setPerspective();
if(mGame.mIsPlayer) {
scaleX *= -1;
}
disable();
}

/**
*
*initialize
*
*Initialiseert de tractor en verplaatst deze helemaal achteraan in de display list
*
*@ params(Geen)
*
*/

public function initialize():void {
parent.setChildIndex(this, 0);
draw();
}

/**
*
*mowStart
*
*Start de tractor met maaien indien deze nog niet aan het maaien is, aan staan en niet gepauzeerd is
*
*@ params(Geen)
*
*/

public function mowStart():void {
if(!mMowing && mEnabled && !mPaused) {
Sounds.play(new SndTractor());
mEnabled = false;
mMowing = true;
mow();
mAnimation.play();
}
}

/**
*
*mow
*
*Effectieve maaibeweging, van links naar rechts of van rechts naar links, afhankelijk van mMowingForward
*
*@ params(Geen)
*
*/

private function mow():void {
if(!mMowing) {
return;
}
var positionHedge:Number;
var positionEdge:Number;
if(mGame.mIsPlayer) {
positionHedge = Math.floor(width / 2) * 1.2;
positionEdge = 500 + width;
}else{
positionHedge = 500 - Math.floor(width / 2) * 1.4;
positionEdge = -1 * width;
}
if(mMowingForward) {
mTweens['x'] = new GCSafeTween(this, 'x', None.easeNone, x, positionHedge, mMowingDuration, true);
}else{
mTweens['x'] = new GCSafeTween(this, 'x', None.easeNone, x, positionEdge, mMowingDuration, true);
}
mTweens['x'].addEventListener(TweenEvent.MOTION_FINISH, mowRowFinished);
}

/**
*
*mowRowFinished
*
*Als we klaar zijn met een (1) rij, start een nieuwe rij om te maaien, anders stop met maaien in zijn totaliteit
*
*@ paraminTweenEvent [TweenEvent]Het tween-event waarop gereageerd wordt (Het maaien van een rij)
*
*/

private function mowRowFinished(inTweenEvent:TweenEvent):void {
if(!mMowing) {
return;
}
mMowingForward = !mMowingForward;
if(mMowingCurrentLine > 0) {
mMowingCurrentLine--;
y += (300 / mMowingLines);
setPerspective();
scaleX *= -1;
mow();
}else{
y = mPosition.y;
mMowingCurrentLine = mMowingLines;
mowFinished();
}
}

/**
*
*mowFinished
*
*De tractor is klaar met maaien, laat de game instantie het resultaat uitvoeren
*
*@ params(Geen)
*
*/

private function mowFinished():void {
if(mMowing) {
mAnimation.stop();
mMowingForward = !mMowingForward;
scaleX *= -1;
mEnabled = true;
setPerspective();
mTweens['x'] = new GCSafeTween(this, 'x', None.easeNone, x, mPosition.x, 1, true);
mMowing = false;
mGame.actionMowResult();
}
}

}

}

/com/biogame/Tree.as

/**
*
*Tree.as
*
*Verzorgt een (1) boompje die van seizoen kan verwisselen
*
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame {

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;

public class Tree extends Element {

/**
*
*Tree
*
*Constructor voor een boompje
*
*@ params(Geen)
*
*/

public function Tree():void {
cacheAsBitmap = true;
initialize();
}

/**
*
*initialize
*
*Initialiseerd een boompje met de vier (4) seizoenen
*
*@ params(Geen)
*
*/

public function initialize():void {
mStates.push('spring');
mStates.push('summer');
mStates.push('autumn');
mStates.push('winter');
seasonStart();
draw();
}

/**
*
*seasonStart
*
*Start de een timer als countdown voor de seizoene
*
*@ params(Geen)
*
*/

private function seasonStart():void {
mTimers['seasonStart'] = new Timer(50000, 1);
mTimers['seasonStart'].addEventListener(TimerEvent.TIMER_COMPLETE, seasonTimer);
mTimers['seasonStart'].start();
}

/**
*
*seasonTimer
*
*Dit start de eigenlijke seizoenen rotatie
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt
*
*/

private function seasonTimer(inTimerEvent:TimerEvent):void {
mTimers['seasonStart'] = null;
mTimers['season'] = new Timer(82000, 3);
mTimers['season'].addEventListener(TimerEvent.TIMER, seasonUpdate);
mTimers['season'].start();
}

/**
*
*seasonUpdate
*
*Een seizoen is voorbij, update naar het nieuwe seizoen als we niet aan het einde van het jaar zitten
*
*@ paraminTimerEvent [TimerEvent]Het timer event waarop gereageerd wordt
*
*/

private function seasonUpdate(inTimerEvent:TimerEvent):void {
if(mCurrentState < mStates.length - 1) {
mCurrentState++;
draw();
}
}

}

}

/com/biogame/Truck.as

/**
*
*Truck.as
*
*Representeert een slacht truck, die klaar-voor-de-slacht koeien op komt halen
*
*@ extendsElement
*@ groupCMD2 A1
*@ authorsTim Kurvers & Michel Lubbers
*
*/


package com.biogame{

import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
import flash.geom.Point;

import com.exanimo.transitions.*;

public class Truck extends Element {

private var mCow:Cow;
private var mCowPosition:Point;

/**
*
*Truck
*
*Constructor voor een slacht truck. Berekent de juiste positie van de truck buiten beeld & laat deze naar de koe rijden via moveToCow()
*
*@ paraminGame[Game]Referentie naar de game instantie waar deze truck deel van uit maakt
*@ paraminCow[Cow]De koe instantie die deze truck zal gaan ophalen
*
*/

public function Truck(inGame:Game, inCow:Cow):void {
mGame = inGame;
mCow = inCow;
y = inCow.y;
mPerspective = true;
setPerspective();
var newX;
if (mGame.mIsPlayer) {
newX = 1000 + width;
} else {
newX = 0 - width;
}
var newY = y;
setPosition(newX, newY);
if (mGame.mIsPlayer) {
scaleX *= -1;
mCowPosition = new Point(mCow.x + 30, y);
} else {
mCowPosition = new Point(mCow.x - 20, y);
}
moveToCow();
Sounds.play(new SndTruck());
}

/**
*
*moveToCow
*
*Laat de truck richting de koe rijden
*
*@ params(Geen)
*
*/

private function moveToCow():void {
mTweens['x'] = new GCSafeTween(this, 'x', Strong.easeOut, x, mCowPosition.x, 1, true);
mTweens['x'].addEventListener(TweenEvent.MOTION_FINISH, moveToButcher);
}

/**
*
*moveToButcher
*
*Laat de truck weer uit beeld verdwijnen; Zogenaamd richting de slagerij - zielig koetje :(
*
*@ paraminTweenEvent [TweenEvent]Het tween event waarop gereageerd wordt. In dit geval die van moveToCow()
*
*/

private function moveToButcher(inTweenEvent:TweenEvent):void {
mTweens['x'] = new GCSafeTween(this, 'x', Strong.easeIn, x, mPosition.x, 1, true);
mTweens['x'].addEventListener(TweenEvent.MOTION_FINISH, doneMoving);
}

/**
*
*doneMoving
*
*De truck is klaar met rijden, verwijder deze
*
*@ paraminTweenEvent [TweenEvent]Het tween event waarop gereageerd wordt. In dit geval die van moveToButcher()
*
*/

private function doneMoving(inTweenEvent:TweenEvent):void {
mCow.remove();
remove();
}
}

}