topical media & game development
actionscript-zoo-lib-VirtualPet.ax
actionscript-zoo-lib-VirtualPet.ax
[swf]
flex
package {
import flash.utils.*;
import flash.events.*;
// The @ax-actionscript-zoo-lib-VirtualPet class represents a pet in the zoo. It extends
// EventDispatcher so that it can be targeted by event dispatches.
public class @ax-actionscript-zoo-lib-VirtualPet extends EventDispatcher {
// ==STATIC CONSTANTS==
// @ax-actionscript-zoo-lib-VirtualPet-related event types (handled by the @fileView object
// that displays the pet on screen)
public static const NAME_CHANGE:String = "NAME_CHANGE";
public static const STATE_CHANGE:String = "STATE_CHANGE";
// States representing the pet's current physical condition
public static const PETSTATE_FULL:int = 0;
public static const PETSTATE_HUNGRY:int = 1;
public static const PETSTATE_STARVING:int = 2;
public static const PETSTATE_DEAD:int = 3;
// ==STATIC VARIABLES==
// The maximum length of a pet's name
private static var maxNameLength:int = 20;
// The maximum number of calories a pet can have
private static var maxCalories:int = 2000;
// The rate at which pets digest food
private static var caloriesPerSecond:int = 100;
// The default name for pets
private static var defaultName:String = "Unnamed Pet";
// ==INSTANCE VARIABLES==
// The pet's name
private var petName:String;
// The number of calories currently in the pet's "stomach".
private var currentCalories:int;
// The pet's current physical condition
private var petState:int;
// A timer for invoking digest() on a regular basis
private var digestTimer:Timer;
// Constructor
public function @ax-actionscript-zoo-lib-VirtualPet (name:String):void {
// Assign this pet's name
setName(name);
// Start this pet out with half the maximum calories (a
// half-full "stomach").
setCalories(@ax-actionscript-zoo-lib-VirtualPet.maxCalories/2);
}
// Starts the pet's life cycle
public function start ():void {
// Invoke digestTimerListener() once per second
digestTimer = new Timer(1000, 0);
digestTimer.addEventListener(TimerEvent.TIMER, digestTimerListener);
digestTimer.start();
}
// Pauses the pet's life cycle
public function stop ():void {
if (digestTimer != null) {
digestTimer.stop();
}
}
// Assigns the pet's name, and notifies listeners of the change
public function setName (newName:String):void {
// Throw an exception if the new name is not valid
if (newName.indexOf(" ") == 0) {
throw new @fileNameException();
} else if (newName == "") {
throw new @fileInsufficientDataException();
} else if (newName.length > @ax-actionscript-zoo-lib-VirtualPet.maxNameLength) {
throw new @fileExcessDataException();
}
// Assign the new name
petName = newName;
// Notify listeners that the name changed
dispatchEvent(new Event(@ax-actionscript-zoo-lib-VirtualPet.NAME_CHANGE));
}
// Returns the pet's name
public function getName ():String {
// If the pet has never been assigned a valid name...
if (petName == null) {
// ...return the default name
return @ax-actionscript-zoo-lib-VirtualPet.defaultName;
} else {
// ...otherwise, return the pet's name
return petName;
}
}
// Adds some calories to the pet's stomach, in the form of a Food object
public function eat (foodItem:actionscript_zoo_lib_Food):void {
// If the pet is dead, abort
if (petState == @ax-actionscript-zoo-lib-VirtualPet.PETSTATE_DEAD) {
trace(getName() + " is dead. You can't feed it.");
return;
}
// If the food item is an apple, check it for worms. If it has a worm,
// don't eat it.
if (foodItem is actionscript_zoo_lib_Apple) {
if (actionscript_zoo_lib_Apple(foodItem).hasWorm()) {
trace("The " + foodItem.getName() + " had a worm. " + getName()
+ " didn't eat it.");
return;
}
}
// Display a debugging message indicating what the pet ate
trace(getName() + " ate the " + foodItem.getName()
+ " (" + foodItem.getCalories() + " calories).");
// Add the calories from the food to the pet's "stomach"
setCalories(getCalories() + foodItem.getCalories());
}
// Assigns the pet a new number of calories, and changes the pet's
// state if necessary
private function setCalories (newCurrentCalories:int):void {
// Bring newCurrentCalories into the legal range, if necessary
if (newCurrentCalories > @ax-actionscript-zoo-lib-VirtualPet.maxCalories) {
currentCalories = @ax-actionscript-zoo-lib-VirtualPet.maxCalories;
} else if (newCurrentCalories < 0) {
currentCalories = 0;
} else {
currentCalories = newCurrentCalories;
}
// Calculate the number of calories in the pet's stomach, as a
// percentage of the maximum calories allowed
var caloriePercentage:int = Math.floor(getHunger()*100);
// Display a debugging message indicating how many calories the pet
// now has
trace(getName() + " has " + currentCalories + " calories"
+ " (" + caloriePercentage + "% of its food) remaining.");
// If necessary, set the pet's state based on the change in calories
if (caloriePercentage == 0) {
// The pet has no food left. So if the pet is not already dead...
if (getPetState() != @ax-actionscript-zoo-lib-VirtualPet.PETSTATE_DEAD) {
// ...deactivate it
die();
}
} else if (caloriePercentage < 20) {
// The pet needs food badly. Set its state to starving.
if (getPetState() != @ax-actionscript-zoo-lib-VirtualPet.PETSTATE_STARVING) {
setPetState(@ax-actionscript-zoo-lib-VirtualPet.PETSTATE_STARVING);
}
} else if (caloriePercentage < 50) {
// The pet needs food. Set its state to hungry.
if (getPetState() != @ax-actionscript-zoo-lib-VirtualPet.PETSTATE_HUNGRY) {
setPetState(@ax-actionscript-zoo-lib-VirtualPet.PETSTATE_HUNGRY);
}
} else {
// The pet doesn't need food. Set its state to full.
if (getPetState() != @ax-actionscript-zoo-lib-VirtualPet.PETSTATE_FULL) {
setPetState(@ax-actionscript-zoo-lib-VirtualPet.PETSTATE_FULL);
}
}
}
// Returns the number of calories in the pet's "stomach"
public function getCalories ():int {
return currentCalories;
}
// Returns a floating-point number describing the amount of food left
// in the pet's "stomach," as a percentage
public function getHunger ():Number {
return currentCalories / @ax-actionscript-zoo-lib-VirtualPet.maxCalories;
}
// Deactivates the pet
private function die ():void {
// Stop the pet's life cycle
stop();
// Put the pet in the "dead" state
setPetState(@ax-actionscript-zoo-lib-VirtualPet.PETSTATE_DEAD);
// Display a debugging message indicating that the pet died
trace(getName() + " has died.");
}
// Reduces the pet's calories according to the pet's digestion rate.
// This method is called automatically by digestTimer.
private function digest ():void {
trace(getName() + " is digesting...");
setCalories(getCalories() - @ax-actionscript-zoo-lib-VirtualPet.caloriesPerSecond);
}
// Assigns an integer representing the pet's current physical condition
private function setPetState (newState:int):void {
// If the pet has not changed state, abort
if (newState == petState) {
return;
}
// Assign the new state
petState = newState;
// Notify listeners that the pet's state changed
dispatchEvent(new Event(@ax-actionscript-zoo-lib-VirtualPet.STATE_CHANGE));
}
// Returns an integer representing the pet's current physical condition
public function getPetState ():int {
return petState;
}
// An event listener for the Timer object that governs digestion
private function digestTimerListener (e:TimerEvent):void {
// Digest some food
digest();
}
}
}
(C) Æliens
27/08/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.