Moving stuff around, nothing to see here

git-svn-id: https://aklabs.dyndns.org/svn/aklabs/trunk/games/wilysays@50 eb184899-6090-47d4-a65b-558f62f6ea1c
This commit is contained in:
andrew
2010-07-29 01:33:30 +00:00
commit c4ae376c8b
136 changed files with 6379 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
package net.aklabs.demo.simonsays {
/*
* Class LoadingObject
*
* This class is used to represent a content asset while it is going through the process of being loaded
* by the Preloader class.
*/
public class LoadingObject {
public static var STATE_READY:Number = 0; // Object has been loaded and is ready
public static var STATE_LOADING:Number = 1; // Object is currently loading, not ready yet
public static var STATE_NOTFOUND:Number = 2; // Object wasn't found in the cache
public var handle:String; // Text handle for this object
public var state:Number; // State value
public var bytesRead:Number; // the amount of bytes currently read in to this object over the net
public var bytesTotal:Number; // the total byte size of this object
/*
* LoadingObject()
*
* Default constructor
*
* arguments : none
*
* Returns : LoadingObject
*/
public function LoadingObject() {
this.handle = "";
this.state = LoadingObject.STATE_NOTFOUND;
this.bytesRead = 0;
this.bytesTotal = 0;
}
}
}

View File

@@ -0,0 +1,176 @@
package net.aklabs.demo.simonsays
{
import flash.utils.Timer;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.display.Sprite;
import net.aklabs.demo.simonsays.Preloader;
import net.aklabs.demo.simonsays.SimonButton;
import net.aklabs.demo.simonsays.MastermindEvent;
/*
* Class: Mastermind
*
* This class defines our "Simon Says", "Wily Lok", "Mastermind", whatever you want to call it.
* (I called it 3 or 4 different things during the course of development.)
*
*/
public class Mastermind extends Sprite
{
protected var lightOutTimer:Timer; // timer that fires when it's time to turn off the lights
protected var lightButtons:Array; // array of custom SimonButtons that exists in Pattern.COLOR_XXX order
public var isLit:Boolean; // is the device currently lit?
public function Mastermind()
{
var preloader = Preloader.getInstance();
var lightPositions = new Array();
// this array holds pairs of (x,y) coordinates at which to place the dark/light colored
// Simon Says buttons, since they're meant to cover the existing buttons on the original graphic.
// These are hard-coded; in a better implementation, they would come from an XML or would be
// individual frames of an SWF which could be fired individually, etc. But this works.
// array idx 0: Blue, 1: Green, 2: Red, 3: Yellow
lightPositions.push( new Array(183, 187)); // blue
lightPositions.push( new Array(18, 17)); // green
lightPositions.push( new Array(185, 17)); // red
lightPositions.push( new Array(18, 186)); // yellow
// this array holds the button objects for the visible simon says buttons ...
this.lightButtons = new Array();
// just a temporary array for which images to fetch for creating the down/up button images
var fetchArray = new Array( new Array("gfx_btn_darkblue", "gfx_btn_lightblue"),
new Array("gfx_btn_darkgreen", "gfx_btn_lightgreen"),
new Array("gfx_btn_darkred", "gfx_btn_lightred"),
new Array("gfx_btn_darkyellow", "gfx_btn_lightyellow") );
// Simon Says body
var whole = preloader.getObject("gfx_mastermind");
this.addChild(whole);
for ( var i = 0; i < fetchArray.length ; i++ ) {
var btn:SimonButton = new SimonButton(preloader.getObject(fetchArray[i][1]), preloader.getObject(fetchArray[i][0]));
btn.x = lightPositions[i][0];
btn.y = lightPositions[i][1];
this.lightButtons.push(btn);
this.addChild(btn);
btn.addEventListener(MouseEvent.CLICK, this.onMouseClick); // for some reason, MouseEvent.CLICK never actually does anything?
//btn.addEventListener(MouseEvent.MOUSE_UP, this.onMouseClick);
}
this.lightOutTimer = new Timer(0);
}
/*
* flashAll(length)
*
* This function lights all the lights on the Mastermind for the given length of time
*
* arguments:
* @length:Number, the time in milliseconds for which the Mastermind should stay lit
*
* Returns : none
*/
public function flashAll(length:Number)
{
this.lightOutTimer.delay = length;
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
this.lightOutTimer.reset();
this.lightOutTimer.start();
for (var i = 0 ; i < 4 ; i++) {
// fake mouse event to light it up
this.lightButtons[i].onMouseDown(null);
}
this.isLit = true;
}
/*
* lightButton(btn, activeTime)
*
* This function lights up a given button on the Mastermind. Mostly used by the Pattern when it's replaying itself.
*
* arguments:
* @btn:Number, the Pattern.COLOR_XXX button that should light
* @activeTime:Number, the amount of milliseconds for which the button should stay lit
*
* Returns : none
*/
public function lightButton(btn:Number, activeTime:Number = 0 )
{
if ( btn < 4 ) {
this.lightButtons[btn].onMouseDown(null);
this.isLit = true;
}
if ( activeTime != 0 ) {
this.lightOutTimer.delay = activeTime;
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
this.lightOutTimer.reset();
this.lightOutTimer.start();
}
}
/*
* blackout()
*
* This function makes sure that all lights on the Mastermind are extinguished
*
* arguments : none
*
* Returns : none
*/
public function blackout()
{
if ( this.lightButtons.length <= 0 ) {
return;
}
for ( var i = 0 ; i < this.lightButtons.length ; i++ ){
this.lightButtons[i].onMouseUp(null);
}
this.isLit = false;
}
/*
* onTimer(evt)
*
* This function fires whenever the lightOutTimer fires, telling the lights to shut off
*
* arguments :
* @evt:Event, the event that's firing this function
*
* Returns : none
*/
public function onTimer(evt:TimerEvent)
{
if ( evt.target != this.lightOutTimer )
return;
this.lightOutTimer.removeEventListener(TimerEvent.TIMER, this.onTimer);
this.lightOutTimer.stop();
this.lightOutTimer.reset();
this.blackout();
}
/*
* onMouseClick()
*
* This function is fired whenever the user clicks one of the Mastermind's buttons
*
* arguments:
* @evt:Event, the event firing this function
*
* Returns : none
*/
public function onMouseClick(evt:MouseEvent)
{
// we don't do any processing here, as the SimonButton has already checked for
// per-pixel accuracy w/ the click on our abnormally shaped buttons. We just propagate
// out a new MastermindEvent for the game to catch.
for ( var i:Number = 0; i < this.lightButtons.length ; i++ ) {
if ( evt.target == this.lightButtons[i] ) {
var newEvt:MastermindEvent = new MastermindEvent(MastermindEvent.BTN_CLICKED);
newEvt.colorClicked = i;
this.dispatchEvent(newEvt);
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
package net.aklabs.demo.simonsays
{
import flash.events.Event;
/*
* Class : MastermindEvent
*
* This class basically just defines a custom event that will let the mastermind send up
* a clicked event w/ a color.
*/
public class MastermindEvent extends Event
{
public static var BTN_CLICKED:String = "MASTERMIND_BUTTON_CLICKED";
public var colorClicked:Number;
public function MastermindEvent(evtType:String)
{
super(evtType);
}
}
}

View File

@@ -0,0 +1,393 @@
package net.aklabs.demo.simonsays
{
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.EventDispatcher;
import flash.display.Sprite;
import flash.display.Bitmap;
import net.aklabs.demo.simonsays.Mastermind;
import net.aklabs.demo.simonsays.Powerup;
import net.aklabs.demo.simonsays.PowerupEvent;
import net.aklabs.demo.simonsays.Preloader;
/*
* Class Pattern
*
* This class defines a "pattern", which is where most of the game challenge exists.
* It just defines the pattern currently being traced out on the Simon Says/Mastermind/etc
*
* In addition to doing processing, this class also does some graphical representation,
* in the way of a series of red/green lights to show how far along the player is inside the
* pattern. The image is 16 pixels wide, and (16*maxSize) pixels tall.
*
*/
public class Pattern extends Sprite
{
public static var COLOR_BLUE:Number = 0;
public static var COLOR_GREEN:Number = 1;
public static var COLOR_RED:Number = 2;
public static var COLOR_YELLOW:Number = 3;
protected var patternTimer:Timer; // timer that fires to check pattern logic independently of game timer
protected var curIndex:Number; // amount of the pattern currently finished
protected var pattern:Array; // the array of colors that make up the actual pattern
protected var simon:Mastermind; // A link back up to the parent Mastermind (put here because I didn't want to assume that this.parent would always be correct)
protected var delay:Number; // The number of milliseconds that should pass before the logic timer fires
protected var playCount:Number; // The number of times this pattern has been played through (via Forgiveness). Not currently used for anything.
public var clearTime:Number; // the amount of time the player has (in milliseconds) to finish the pattern
public var state:Number; // state of the pattern at current
public static var STATE_RUNNING = 0; // STATE : pattern is currently "running" - e.g., waiting for input from the player and checking logic
public static var STATE_DEMO = 1; // STATE : pattern is currently "demoing", e.g., flashing the lights up to this.curIndex of the pattern
public static var STATE_FAILED = 2; // STATE : pattern is stopped and the player screwed up
public static var STATE_CORRECT = 3; // STATE : pattern is stopped and the player got the last iteration correct
public static var STATE_STOPPED = 4; // STATE : pattern is just stopped w/ no further info
public static var STATE_COMPLETE = 5; // STATE : pattern is stopped because the player has finished all iterations of this pattern
public var score:Number; // Score currently built up in this pattern
protected var maxSize:Number; // Maximum length of the pattern
public var patternPowerups:Array; // array of powerups assigned to any given button on this pattern
protected var scoreMultiplier:Number; // Set by powerup, the multiplier for current score (default x1)
protected var clearDecrement:Number; // Set by powerup, defines how quickly the pattern's timer runs
protected var progressLights:Array; // An array of bitmaps equal in length to the pattern; all the lights up to this.curIndex will be green, the rest are red
protected var level:Number; // The level of pattern which this is (mainly used for calculating pattern length, could probly be scrapped)
protected var difficulty:Number; // The difficulty of the pattern (used in calculating timer speed)
/*
* Pattern()
*
* Default constructor
*
* arguments:
* @levelNumber:Number, the level number for which this pattern is being made
* @simon:Mastermind, the Mastermind object to which this pattern is to be applied (default null)
* @difficulty:Number, the difficulty level for this pattern (default 1)
*
* Returns: Pattern
*/
public function Pattern(levelNumber:Number, simon:Mastermind = null, difficulty:Number = 1)
{
this.state = 0;
this.simon = simon;
this.level = levelNumber;
this.difficulty = difficulty;
this.curIndex = -1;
this.maxSize = 2+levelNumber; // smallest pattern will never be less than 3 lights total
this.pattern = new Array();
this.patternPowerups = new Array();
this.progressLights = new Array();
this.patternTimer = null;
this.delay = 1000;
this.playCount = 0;
this.clearTime = 0;
this.score = 0;
this.scoreMultiplier = 1;
this.clearDecrement = 0;
this.patternTimer = new Timer(0);
this.addEventListener(PowerupEvent.USED_POWERUP, this.onUsedPowerup);
var preloader:Preloader = Preloader.getInstance();
var newLight:Bitmap;
// populate all the red lights for this pattern that will turn green as the player goes on
for ( var i:Number = 0; i < this.maxSize ; i++ ) {
newLight = preloader.getBitmap("gfx_progress_red");
newLight.x = 0;
newLight.y = i*16;
if ( i > 15 ) {
newLight.x += 20;
newLight.y = (i-15)*16;
}
this.progressLights.push(newLight);
this.addChild(newLight);
}
this.complexify();
}
/*
* patternLength()
*
* Just a getter for the length of the pattern
*
* arguments : none
*
* Returns : Number
*/
public function patternLength():Number
{
return this.pattern.length;
}
/*
* forceState()
*
* Forces a given state onto the pattern
*
* arguments: none
*
* Returns : none
*/
public function forceState(state:Number)
{
this.state = state;
}
/*
* complexify()
*
* This function adds another element to the pattern, so that it becomes a longer pattern, up until the maximum length of the pattern
*
* arguments: none
*
* Returns : none
*/
public function complexify()
{
// we're complete if we're beyond the maximum size
if ( this.pattern.length >= this.maxSize ) {
this.stop();
this.state = Pattern.STATE_COMPLETE;
return null;
}
// reset the score multiplier and such 'cause complexify only gets called at the end of a round
this.scoreMultiplier = 1;
this.state = Pattern.STATE_STOPPED;
this.stop(); // -- wtf why did I call stop on myself? ...
var newcolor = (Math.round(int(Math.random()*4)));
this.pattern.push(newcolor);
// create a new powerup ~20% of the time that complexify is ran
if ( Math.random() < 0.20 ) {
var powerup = new Powerup();
powerup.pType = (Math.round(int(Math.random()*Powerup.PTYPE_MAXVALUE)));
powerup.imgHandle = Powerup.POWERUP_IMAGES[powerup.pType];
powerup.sndHandle = Powerup.POWERUP_SOUNDS[powerup.pType];
this.patternPowerups.push(powerup);
} else {
this.patternPowerups.push(null);
}
this.clearTime = 2000 * ( this.pattern.length );
}
/*
* play(lightSimon)
*
* This function tells the pattern to start playback in one of two modes; demo, or running. Demo mode
* just has the pattern playing itself back via the lights on the Mastermind. The running mode doesn't
* do any playback, it just checks logic.
*
* arguments:
* @lightSimon:Boolean, set this to True to run in Demo mode (default false)
*
* Returns : none
*/
public function play(lightSimon:Boolean = false)
{
if ( this.patternTimer ) {
this.patternTimer.reset()
} else {
this.patternTimer = new Timer( this.delay );
}
if ( lightSimon ){
this.state = Pattern.STATE_DEMO;
this.patternTimer.delay = 1000;
this.patternTimer.addEventListener(TimerEvent.TIMER, this.onDemoTimer);
} else {
this.state = Pattern.STATE_RUNNING;
this.patternTimer.delay = 25;
this.clearDecrement = this.patternTimer.delay + (this.level*(this.difficulty));
this.patternTimer.addEventListener(TimerEvent.TIMER, this.onRunningTimer);
}
this.patternTimer.start();
this.playCount += 1;
this.curIndex = 0;
}
/*
* stop()
*
* Stop all logic/running status on the pattern
*
* arguments: none
*
* Returns : none
*/
public function stop()
{
if ( this.patternTimer ) {
this.patternTimer.removeEventListener(TimerEvent.TIMER, this.onDemoTimer);
this.patternTimer.removeEventListener(TimerEvent.TIMER, this.onRunningTimer);
}
this.curIndex = -1;
}
/*
* getIndex()
*
* Gets the current value is curIndex
*
* arguments: none
*
* Returns : none
*/
public function getIndex()
{
return this.curIndex;
}
/*
* getActive()
*
* OBSOLETE - gets the currecntly active color. This isn't as useful since the input checking method changed around v0.12.
*
* arguments: none
* Returns : Number, -1 on failure, >= 0 on success
*/
public function getActive()
{
if ( (this.curIndex < this.pattern.length) && (this.curIndex >= 0) ) {
return this.pattern[this.curIndex];
}
return -1;
}
/*
* resetLights()
*
* This function makes sure the ratio of red:green lights in the progress lights is correct
* according to the value of curIndex
*
* arguments: none
*
* Returns: none
*/
public function resetLights()
{
var preloader:Preloader = Preloader.getInstance();
var newLight:Bitmap;
for ( var i:Number = 0; i <= this.curIndex ; i++ ) {
// remove any existing red lights and replace them with green lights
// if they're at an index < curIndex
this.removeChild(this.progressLights[i]);
newLight = preloader.getBitmap("gfx_progress_green");
newLight.x = this.progressLights[i].x;
newLight.y = this.progressLights[i].y;
this.progressLights[i] = newLight;
this.addChild(this.progressLights[i]);
}
}
/*
* colorActive(color)
*
* Checks to see if the given color is the one currently active on the pattern.
* Also updates the current index, modifies state, etc, depending on the result.
*
* arguments:
* @color:Number, the Pattern.COLOR_XXX color you want checked
*
* Returns: Boolean (Always returns false on a stopped pattern)
*/
public function colorActive(color:Number):Boolean
{
if ( this.curIndex == -1 ) {
return false;
}
if ( (this.curIndex < this.pattern.length) && (this.pattern[this.curIndex] == color) ) {
// dispatch a PowerupEvent if there is a powerup in this spot at the pattern
if ( this.patternPowerups[this.curIndex] != null ) {
this.dispatchEvent(new PowerupEvent(PowerupEvent.GOT_POWERUP, this.patternPowerups[this.curIndex]));
this.patternPowerups[this.curIndex] = null;
}
this.resetLights();
this.curIndex += 1;
this.score += 5;
if ( this.curIndex >= this.pattern.length ) {
this.curIndex = -1;
this.state = Pattern.STATE_CORRECT;
this.stop();
}
return true;
}
this.state = Pattern.STATE_FAILED;
this.stop();
return false;
}
/*
* onRunningTimer(evt)
*
* Fires along w/ the runningTimer to check pattern logic
*
* arguments:
* @evt:Event, event firing this function
*
* Returns : none
*/
public function onRunningTimer(evt:TimerEvent)
{
if ( (!evt) || (evt.target != this.patternTimer) )
return;
this.clearTime -= this.clearDecrement;
if ( this.clearTime < 0 ) {
this.clearTime = 0;
this.state = Pattern.STATE_FAILED;
this.stop();
}
}
/*
* onDemoTimer(evt)
*
* Runs every time the Demo timer fires, lighting the buttons in sequence at the right times
*
* arguments:
* @evt:Event, the event firing this function
*
* Returns : none
*/
public function onDemoTimer(evt:TimerEvent)
{
if ( (!evt) || (evt.target != this.patternTimer) || (!this.simon) )
return;
if ( this.curIndex >= this.pattern.length ) {
this.state = Pattern.STATE_STOPPED;
this.stop();
return;
}
this.simon.lightButton(this.pattern[curIndex], this.patternTimer.delay/2);
this.curIndex += 1;
}
/*
* onUsedPowerup(evt)
*
* This function fires whenever a PowerupEvent filters down from the Mastermind, which originally
* filtered up from the Player. It processes and applies the effects of any powerups used by the player.
*
* arguments:
* @evt:PowerupEvent, the event firing this function
*
* Returns: none
*/
public function onUsedPowerup(evt:PowerupEvent)
{
var pwup:Powerup = evt.pwup;
if ( pwup.pType == Powerup.PTYPE_FORGIVENESS ) {
// we don't actually have to *do* anything with a forgiveness ...
return;
} else if ( pwup.pType == Powerup.PTYPE_SLOWDOWN ) {
this.clearDecrement = 1;
} else if ( pwup.pType == Powerup.PTYPE_SKIP ) {
this.state = Pattern.STATE_CORRECT;
this.stop();
this.resetLights();
} else if ( pwup.pType == Powerup.PTYPE_DOUBLE ) {
this.scoreMultiplier = 2;
}
return;
}
}
}

View File

@@ -0,0 +1,228 @@
package net.aklabs.demo.simonsays
{
import net.aklabs.demo.simonsays.PowerupEvent;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import net.aklabs.demo.simonsays.Preloader;
import flash.display.Bitmap;
/*
* Class Player
*
* This class represents the player in the game.
*
* The class has two displayable objects in it: the Player object itself,
* and Player.lifeDisplay. The Player object displays the inventory (64 pixels high, up to (64*5) pixels wide)
* The Player.lifeDisplay object displays the remaining number of lives (64 pixels high, up to 64*3 pixels wide)
*
*/
public class Player extends Sprite {
public var score:Number; // the player's current score
public var lives:Number; // the number of lives the player currently has
public var maxPattern:Number; // the largest pattern the player has completed
public var inventory:Array; // the player's inventory
public var lifeDisplay:Sprite; /* the parent sprite to which all the player life sprites are attached (number of remaining lives) ..
we have this parenting the rest of the images, so the Game class can just add this single child object, rather than tracking
and removing all the images in the individual lifeImages array */
protected var lifeImages:Array; // an array of images holding all the images showing up in the player's life array
protected var headExplosion;
/*
* Player()
*
* Default constructor
*
* arguments : none
*
* Returns : none
*/
public function Player()
{
this.score = 0;
this.lives = 3;
this.maxPattern = 0;
this.inventory = new Array();
this.lifeDisplay = new Sprite();
this.lifeImages = new Array();
}
/*
* addPowerup(pwup)
*
* Adds a new powerup to the player's inventory
*
* arguments:
* @pwup:Powerup, the powerup to be added
*
* Returns: none
*/
public function addPowerup(pwup:Powerup)
{
if ( this.inventory.length >= 5 ) {
return;
}
this.inventory.push(pwup);
this.resetPowerupPositions();
this.addChild(pwup);
pwup.addEventListener(MouseEvent.MOUSE_UP, this.onPowerupClicked);
}
/*
* resetPowerupPositions()
*
* This function goes through the player's inventory and makes sure the positions line up (mostly) with the background graphic for their slot
*
* arguments: none
*
* Returns: none
*/
protected function resetPowerupPositions()
{
for ( var i = 0; i < this.inventory.length ; i++ ) {
var pwup:Powerup = this.inventory[i];
pwup.x = 2+(70*i);
pwup.y = 0;
}
}
/*
* die()
*
* This function is called whenever the player should die - lose a life
*
* arguments: none
*
* Returns: none
*/
public function die()
{
// lose a life, and do it in style
var preloader:Preloader = Preloader.getInstance();
this.headExplosion = preloader.getMovieClip("movie_explosion");
this.headExplosion.addEventListener(Event.ENTER_FRAME, this.stopExplosion);
this.headExplosion.x = (this.lives * 64)-32;
this.headExplosion.y = 32;
this.lifeDisplay.addChild(this.headExplosion);
this.headExplosion.play();
preloader.playSound("sfx_explosion");
this.lives -= 1;
this.resetLifePositions();
}
/*
* stopExplosion(evt)
*
* This stops the head explosion animation from looping (much like Game.onNonLoopEnterFrame)
*
* arguments:
* @evt:Event, the event firing this function
*
* Returns: none
*/
public function stopExplosion(evt:Event)
{
if ( evt.target.currentFrame == evt.target.totalFrames ) {
this.headExplosion.stop();
this.lifeDisplay.removeChild(this.headExplosion);
this.headExplosion.removeEventListener(Event.ENTER_FRAME, this.stopExplosion);
this.headExplosion = null;
}
}
/*
* resetLifePositions()
*
* This function arranges the images representing the number of remaining lives the player has
*
* arguments: none
*
* returns : none
*/
public function resetLifePositions()
{
var i:Number = 0;
var preloader:Preloader = Preloader.getInstance();
if ( this.lifeImages.length < this.lives ) {
for ( i = this.lifeImages.length; i < this.lives; i++ ) {
var img:Bitmap = preloader.getBitmap("gfx_pwup_freelife");
img.x = 64*i;
img.y = 0;
this.lifeImages.push(img);
this.lifeDisplay.addChild(img);
}
} else {
for ( var i = 0; i < this.lifeImages.length ; i++ ) {
if ( i >= this.lives ) {
this.lifeDisplay.removeChild(this.lifeImages[i]);
this.lifeImages.splice(i, 1);
}
}
}
for ( var i = 0; i < this.lifeImages.length ; i++ ) {
this.lifeImages[i].x = 64*i;
this.lifeImages[i].y = 0;
}
}
/*
* usePowerupAt(index)
*
* See if there is a powerup at index 'index' in the inventory, use it, fire off any sounds associated with it,
* and dispatch a new PowerupEvent for it
*
* arguments:
* @index:Number, the index in inventory from which the powerup should be drawn
*
* returns: none
*/
public function usePowerupAt(index:Number)
{
if ( index < this.inventory.length ) {
this.removeChild(this.inventory[index]);
var preloader:Preloader = Preloader.getInstance();
preloader.playSound(this.inventory[index].sndHandle);
this.resetPowerupPositions();
this.dispatchEvent(new PowerupEvent(PowerupEvent.USED_POWERUP, this.inventory[index]));
this.inventory[index].removeEventListener(MouseEvent.MOUSE_UP, this.onPowerupClicked);
this.inventory.splice(index, 1);
}
}
/*
* onPowerupClicked(evt)
*
* This function is fired whenever the player clicks the mouse on a powerup owned by the player
*
* arguments:
* @evt:MouseEvent, the event firing this function
*
* Returns: none
*/
public function onPowerupClicked(evt:MouseEvent)
{
for ( var i:Number = 0 ; i < this.inventory.length ; i++ ) {
if ( this.inventory[i] == evt.target ) {
this.usePowerupAt(i);
}
}
}
/*
* clearInventory()
*
* Fairly obvious, this function just clears out the inventory
*
* arguments: none
*
* returns: none
*/
public function clearInventory()
{
for ( var i:Number = 0; i < this.inventory.length ; i++ ) {
this.removeChild(this.inventory[i]);
this.inventory.splice(i, 1);
}
}
}
}

View File

@@ -0,0 +1,29 @@
package net.aklabs.demo.simonsays {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import net.aklabs.demo.simonsays.PowerupEvent;
/*
* Class Powerup
*
* This class just represents a powerup in the game.
* This is more a data structure than a class, but I don't think
* AS 3.0 has just bare structures. Silly ECMA language...
*/
public class Powerup extends Sprite
{
public static var PTYPE_SLOWDOWN:Number = 0; /* SLOWDOWN - Slows the pattern timer to a much lower rate */
public static var PTYPE_FORGIVENESS:Number = 1; /* FORGIVENESS - If you have FORGIVENESSS in your inventory and you miss a pattern, it doesn't stop you */
public static var PTYPE_SKIP:Number = 2; /* SKIP - Lets you "skip" a given pattern iteration, and you still get all the score for it. */
public static var PTYPE_DOUBLE:Number = 3; /* DOUBLE - Score double points for the pattern on which you use this powerup. */
public static var PTYPE_MAXVALUE:Number = 4;
// POWERUP_IMAGES - these are the image handles (stored in an array where idx => PTYPE_XXX) for each of the powerup types
public static var POWERUP_IMAGES = new Array("gfx_pwup_slowdown", "gfx_pwup_forgiveness", "gfx_pwup_exclamation", "gfx_pwup_pointdoubler");
// POWERUP_SOUNDS - these are the sound handles (stored in an array where idx => PTYPE_XXX) for each of the powerup types
public static var POWERUP_SOUNDS = new Array("sfx_slowdown", "sfx_forgiveness", "sfx_exclamation", "sfx_pointdoubler");
public var imgHandle:String; // the handle for the image of this specific powerup
public var sndHandle:String; // the handle for the sound of this specific powerup
public var pType:Number; // the PTYPE_XXX of this powerup
}
}

View File

@@ -0,0 +1,32 @@
package net.aklabs.demo.simonsays {
import flash.events.Event;
import net.aklabs.demo.simonsays.Powerup;
/*
* Class PowerupEvent
*
* An event specifically made for actions taken regarding powerups
*/
public class PowerupEvent extends Event {
public static var GOT_POWERUP:String = "SIMONSAYS_GOT_POWERUP"; // Type for events when a powerup was received
public static var USED_POWERUP:String = "SIMONSAYS_USED_POWERUP"; // Type for events when a powerup was used
public var pwup:Powerup; // the powerup (rather than the target) of this event
/*
* PowerupEvent()
*
* Default Constructor
*
* arguments:
* @evtType:String, the type of this event (GOT_POWERUP or USED_POWERUP)
* @tgt:Powerup, the Powerup object that's being affected by this event
*
* returns: none
*/
public function PowerupEvent(evtType:String, tgt:Powerup = null)
{
super(evtType);
this.pwup = tgt;
}
}
}

View File

@@ -0,0 +1,529 @@
package net.aklabs.demo.simonsays {
import net.aklabs.demo.simonsays.LoadingObject;
import flash.utils.Dictionary;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.media.Sound;
import flash.display.MovieClip;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ProgressEvent;
import flash.events.Event;
/*
* Class Preloader
*
* This class is what loads and manages the cache of media assets for the game
* This class is a singleton, which was annoyingly difficulty to implement in
* Actionscript 3 because it doesn't support private constructors.
*
* Be careful subclassing this, because of the way the singleton mechanism was implemented,
* it may break.
*
* This class can be added as a child asset, and it will display a pair of progress
* bars as it loads all the assets. The top bar is the progress on the current file,
* the bottom bar is the progress on the total set of assets. You don't have to display the
* preloader, but if you do, make sure to load via the assets array, rather than calling loadImage()
* and such manually, as the progress bars will act funky.
*
* When the preloader has loaded all of the assets, it will dispatch a COMPLETE event that should be handled
* by whatever higher game class, as a signal that all assets are ready and cached.
*/
public class Preloader extends Sprite {
protected var objects:Dictionary; // this contains all loaded objects, keyed by their handle
protected var loading_by_instance:Dictionary; // this contains the [handle, bytes read, bytes total] of all objects that are currently loading, keyed by their instance
protected var loading_by_handle:Dictionary; // this contains the [instance, bytes read, bytes total] of all objects that are currently loading, keyed by their handle
protected static var instance:Preloader = null; // the singleton instance
protected var curAsset:Number; // the index of the asset (in the assets array) currently being loaded
protected var assets:Array; // the array of all the assets to be loaded
/* format of the 'assets' array:
[ ASSET_ARRAY, ASSET_ARRAY ...]
each ASSET_ARRAY is...
["images"|"sounds"|"movies", "TEXT HANDLE", "URI", "CLASS NAME"]
... The "images"|"sounds"|"movies" serves an obvious purpose; it says what kind of asset we're loading,
as the mechanism for loading images/sounds/movies are different.
The TEXT HANDLE is a text handle that can be used when referencing this asset in the preloader
The URI is just that, the URI where this object can be found. Usual security restrictions apply.
The CLASS NAME is only important for exported SWF movies, and must equal whatever the class name is
that you set for that SWF when telling Flash to export it for Actionscript. If this is wrong, or you
don't export your SWFs for actionscript, you won't be able to instantiate new MovieClip/Sprites of them.
*/
protected var loadingLabel:TextField; // just a text label that says "Please wait; loading"
protected var progressSpinner:Array = new Array("-", "\\", "|", "/"); // an array of characters that creates a spinner for the loading label
protected var progSpin:Number = 0; // the current index in the progressSpinner array
protected var classDefs:Dictionary; // classDefs holds the class definitions for each of the given objects (if supplied), keyed by text handle
protected var classNames:Dictionary; // classNames holds the name of the classes for each of the given objects (if supplied), keyed by text handle
/*
* getInstance()
*
* Returns the instance of the singleton
*
* arguments: none
*
* Returns: Preloader
*/
public static function getInstance():Preloader
{
if ( Preloader.instance == null )
Preloader.instance = new Preloader();
return Preloader.instance;
}
/*
* Preloader(assets)
*
* Default constructor for Preloader
*
* arguments:
* @assets:Array, the asset array to be loaded (default null)
*
* Returns: none
*/
public function Preloader(assets:Array = null)
{
if ( Preloader.instance != null )
throw("Don't use (new Preloader()) directly, use Preloader.getInstance() to prevent duplication of this singleton class.");
this.objects = new Dictionary();
this.loading_by_instance = new Dictionary();
this.loading_by_handle = new Dictionary();
Preloader.instance = this;
this.curAsset = 0;
if ( assets != null)
this.assets = assets;
var labelFormat = new TextFormat();
labelFormat.font = "Courier New";
labelFormat.bold = false;
labelFormat.color = 0xFFFFFF;
labelFormat.size = 12;;
this.loadingLabel = new TextField();
this.loadingLabel.background = false;
this.loadingLabel.autoSize = TextFieldAutoSize.LEFT;
this.loadingLabel.defaultTextFormat = labelFormat;
this.loadingLabel.text = "Please wait; loading |"
this.loadingLabel.x = 0;
this.loadingLabel.y = 0;
this.addChild(loadingLabel);
this.classDefs = new Dictionary();
this.classNames = new Dictionary();
}
/*
* setAssets(assets)
*
* Set the asset array for the preloader
*
* arguments:
* @assets:Array, the array of assets
*
* returns: none
*/
public function setAssets(assets:Array)
{
this.assets = assets;
}
/*
* loadAssets()
*
* Start loading all the assets
*
* arguments: none
*
* returns: none
*/
public function loadAssets()
{
this.onLoadComplete(null);
}
/*
* getObject(handle)
*
* Get a generic Object referenced by the given handle
*
* argument:
* @handle:String, the text handle of the object you want
*
* returns: object you want, or null
*/
public function getObject(handle:String)
{
if ( this.objects[handle] )
return this.objects[handle];
return null;
}
/*
* getBitmap(handle:String)
*
* This function returns a CLONE of a Bitmap object in the preloader. Use this when
* you want a bitmap that you can use in more than one place, e.g., more like a sprite.
* All instances will reference the same bitmap data, however, so any modification to
* the core bitmap data will show up in all instances.
*
* arguments:
* @handle:String, the text handle reference for the bitmap you want
*
* returns Bitmap on success, null on failure
*/
public function getBitmap(handle:String)
{
var obj = this.getObject(handle);
if ( (obj) && (obj is Bitmap) ) {
var bm = new Bitmap(obj.bitmapData);
return bm;
}
return obj;
}
/*
* getBitmap(handle:String)
*
* This function returns a CLONE of a MovieClip object in the preloader. Use this when
* you want a MovieClip that you can use in more than one place, e.g., more like a sprite.
* All instances will reference the same frame data, however, so any modification to
* the core frame data will show up in all instances.
*
* arguments:
* @handle:String, the text handle reference for the bitmap you want
*
* returns MovieClip on success, null on failure
*/
public function getMovieClip(handle:String):MovieClip
{
var obj = this.getObject(handle);
try {
var clip:Class = this.classDefs[handle];
if ( clip ) {
return new clip();
}
} catch (error:Error) {
trace(error);
return null;
}
return null;
}
/*
* startObject(obj, handle)
*
* Start loading the given object with the given handle. Sets up event handling for notifications on the event while it loads.
*
* arguments:
* @obj:Loader|Sound, either a Loader or a Sound object, referencing the object which has already had its URI set and begun loading
* @handle:String, the text string by which this object should be referenced
*
* returns: none
*/
protected function startObject(obj, handle:String)
{
var toadd = obj;
if ( obj is Loader ) {
toadd = obj.contentLoaderInfo;
}
toadd.addEventListener(Event.COMPLETE, this.onLoadComplete);
toadd.addEventListener(ProgressEvent.PROGRESS, this.onProgressUpdate);
toadd.addEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
toadd.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onSecurityError);
this.loading_by_instance[toadd] = new Array(handle, 0, 0);
this.loading_by_handle[handle] = new Array(obj, 0, 0);
}
/*
* stopObject(obj)
*
* Stops loading on a given object, unhooks all the event listeners, etc
*
* arguments:
* @obj:Loader|Sound, the object on which loading should stop
*
* returns: none
*/
protected function stopObject(obj)
{
var obj_info = this.loading_by_instance[obj];
obj.removeEventListener(Event.COMPLETE, this.onLoadComplete);
obj.removeEventListener(ProgressEvent.PROGRESS, this.onProgressUpdate);
obj.removeEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
obj.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onSecurityError);
delete this.loading_by_handle[this.loading_by_instance[obj][0]];
delete this.loading_by_instance[obj];
}
/*
* getObjectStatus(handle)
*
* Returns a LoadingObject object that describes the current loading status of the object you're inquiring about
*
* arguments:
* @handle:String, the handle of the object you want to know about
*
* returns : LoadingObject
*/
public function getObjectStatus(handle:String):LoadingObject
{
var objStats = new LoadingObject();
objStats.handle = handle;
if ( this.objects[handle] ) {
objStats.state = LoadingObject.STATE_READY;
} else if ( this.loading_by_handle[handle] ) {
objStats.state = LoadingObject.STATE_LOADING;
objStats.bytesRead = this.loading_by_handle[handle][1];
objStats.bytesTotal = this.loading_by_handle[handle][2];
}
return objStats;
}
/*
* loadImage(uri, handle)
*
* Start loading the image at the given URI with the given handle
*
* arguments:
* @uri:String, the URI where the file lives
* @handle:String, the handle for the object
*
* returns: none
*/
public function loadImage(uri:String, handle:String)
{
var request:URLRequest = new URLRequest(uri);
var img = new Loader();
img.load(request);
this.startObject(img, handle);
}
/*
* loadMovie(uri, handle, className)
*
* Loads an external SWF object from URI and stores it as 'handle' and stores the class definition from it where the class name is className
*
* arguments:
* @uri:String, the URI where the file lives
* @handle:String, the handle for this object
* @className:String, the name of the SWF class when exported for Actionscript
*
* returns: none
*/
public function loadMovie(uri:String, handle:String, className:String)
{
var request:URLRequest = new URLRequest(uri);
var movie = new Loader();
movie.load(request);
this.startObject(movie, handle);
this.classNames[handle] = className;
trace(this.classNames[handle]);
}
/*
* loadSound(uri, handle)
*
* Loads the given sound
*
* arguments:
* @uri:String, the URI from which to load the sound
* @handle:String, the handle to store the sound as
*
* returns: none
*/
public function loadSound(uri:String, handle:String)
{
var request:URLRequest = new URLRequest(uri);
var snd = new Sound();
snd.load(request);
this.startObject(snd, handle);
}
/*
* playSound(handle)
*
* Locates the sound associated with the given handle, and plays it
*
* arguments:
* @handle:String, the text handle for the sound you want
*
* returns: Boolean (true on success, false on error)
*/
public function playSound(handle:String):Boolean
{
var snd = this.getObject(handle);
if ( !snd )
return false;
snd.play(); // we don't care about the channel it returns
return true;
}
/*
* onIOError(evt)
*
* This function fires whenever there's an IO Error that prevents the object from finishing loading
*
* arguments:
* @evt:IOErrorEvent, the event firing this function
*
* returns: none
*/
protected function onIOError(evt:IOErrorEvent)
{
var obj = evt.target;
var obj_info = this.loading_by_instance[obj];
var handle = obj_info[0];
var read = obj_info[1];
var total = obj_info[2];
this.stopObject(obj);
}
/*
* onSecurityError(evt)
*
* This function fires whenever there's a security error that prevents the object from finishing loading
*
* arguments:
* @evt:SecurityErrorEvent, the event firing this function
*
* returns: none
*/
protected function onSecurityError(evt:SecurityErrorEvent)
{
var obj = evt.target;
var obj_info = this.loading_by_instance[obj];
var handle = obj_info[0];
var read = obj_info[1];
var total = obj_info[2];
this.stopObject(obj);
}
/*
* onProgressUpdate(evt)
*
* This function fires whenever there's a progress update on the object currently loading
*
* arguments:
* @evt:ProgressEvent, the event firing this function
*
* returns: none
*/
protected function onProgressUpdate(evt:ProgressEvent)
{
var obj = evt.target;
var handle = this.loading_by_instance[obj][0];
this.loading_by_instance[obj][1] = this.loading_by_handle[handle][1] = evt.bytesLoaded;
this.loading_by_instance[obj][2] = this.loading_by_handle[handle][2] = evt.bytesTotal;
this.drawProgressMeters(evt);
this.progSpin += 1;
if ( this.progSpin >= this.progressSpinner.length ) {
this.progSpin = 0;
}
this.loadingLabel.text = "Please wait; loading ... " + this.progressSpinner[this.progSpin];
}
/*
* onLoadComplete(evt)
*
* This function fires whenever a file finishes loading. You can call this, after setting the assets array, with a null event.
* In such a case, the loading process will simply be started.
*
* arguments:
* @evt:Event, the event firing this function (default null)
*
* returns: none
*/
protected function onLoadComplete(evt:Event = null)
{
if ( evt != null ) {
var obj = evt.target;
var handle = this.loading_by_instance[obj][0];
if ( obj is LoaderInfo ) {
this.objects[handle] = obj.content;
trace(this.classNames[handle]);
if ( (this.classNames[handle]) && (this.classNames[handle] != "") )
this.classDefs[handle] = obj.applicationDomain.getDefinition(this.classNames[handle]);
else
this.classDefs[handle] = null;
} else
this.objects[handle] = obj
this.stopObject(obj);
this.curAsset += 1;
}
if ( this.curAsset < this.assets.length ) {
var asset = this.assets[this.curAsset];
var asset_stat = this.getObjectStatus(asset[1]);
if ( asset_stat.state == LoadingObject.STATE_NOTFOUND ) {
if ( asset[0] == "sounds" ){
this.loadSound(asset[2], asset[1]);
} else if ( asset[0] == "images" ) {
this.loadImage(asset[2], asset[1]);
} else if ( asset[0] == "movies" ) {
this.loadMovie(asset[2], asset[1], asset[3]);
}
}
} else if ( this.curAsset >= this.assets.length ) {
var evt = new Event(Event.COMPLETE);
this.dispatchEvent(evt);
}
}
/*
* drawProgressMeters(evt)
*
* This function redraws the visible progress meters; it is generally called from inside of onProgressUpdate.
* It isn't fired by a timer, but it does need to have the event passed in to it so it can access the bytes read, etc.
*
* arguments:
* @evt:ProgressEvent, the event firing this function (default null)
*
* returns: none
*/
protected function drawProgressMeters(evt:ProgressEvent)
{
this.graphics.clear();
// draw the file progress meter
// white box
this.graphics.lineStyle(1,0xFFFFFF);
this.graphics.beginFill(0xFFFFFF);
this.graphics.drawRoundRect(60, 30, 200, 15, 5);
this.graphics.endFill();
// blue bar
this.graphics.lineStyle(1,0x6E6BF4);
this.graphics.beginFill(0x6E6BF4);
this.graphics.drawRoundRect(60, 30, 200*(evt.bytesLoaded/evt.bytesTotal), 15, 5);
this.graphics.endFill();
// red box
this.graphics.lineStyle(3, 0xAC2626);
this.graphics.drawRoundRect(60, 30, 200, 15, 5);
// draw the total progress meter
// white box
this.graphics.lineStyle(1,0xFFFFFF);
this.graphics.beginFill(0xFFFFFF);
this.graphics.drawRoundRect(60, 60, 200, 15, 5);
this.graphics.endFill();
// blue bar
this.graphics.lineStyle(1,0x6E6BF4);
this.graphics.beginFill(0x6E6BF4);
this.graphics.drawRoundRect(60, 60, 200*(this.curAsset/this.assets.length), 15, 5);
this.graphics.endFill();
// red box
this.graphics.lineStyle(3, 0xAC2626);
this.graphics.drawRoundRect(60, 60, 200, 15, 5);
}
}
}

View File

@@ -0,0 +1,123 @@
package net.aklabs.demo.simonsays {
import flash.events.MouseEvent;
import flash.display.Bitmap;
import flash.display.Sprite;
/*
* class SimonButton
*
* This is just a custom button class that is pixel-accurate, because the Mastermin/Simon Says
* buttons are an extremely odd shape, so I needed something that could detect mouse hits in/
* outside of the alpha color areas.
*
* Most of this class is really self explanatory, so I'm not going to bother documenting all of it. Only the parts that don't make immediate sense.
*/
public class SimonButton extends Sprite
{
protected var imgDown:Bitmap; // bitmap for when the button is pressed
protected var imgUp:Bitmap; // bitmap for when the button is released
protected var curImg:Bitmap; // the bitmap currently being displayed on the button
protected var magicColor:Number; // the magic color (e.g. "magic pink"), if any (otherwise alpha is used for hit detection)
public function SimonButton(imgDown:Bitmap = null, imgUp:Bitmap = null, magicColor = 0x00000000)
{
super();
this.imgDown = imgDown;
this.imgUp = imgUp;
this.curImg = null;
this.magicColor = magicColor;
this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
this.addEventListener(MouseEvent.CLICK, this.onMouseClick);
}
public function setMagicColor(color:Number)
{
this.magicColor = color;
}
public function setBtnDown(obj:Bitmap)
{
if ( obj ) {
this.imgDown = obj;
}
}
public function setBtnUp(obj:Bitmap)
{
if ( obj ) {
this.imgUp = obj;
}
}
public function onMouseDown(obj:MouseEvent)
{
if ( (obj) && (! this.hitTestPoint(obj.localX, obj.localY)) ) {
obj.stopImmediatePropagation();
return;
}
if ( this.curImg ) {
this.removeChild(this.curImg);
}
if ( this.imgDown ) {
this.addChild(this.imgDown);
this.curImg = this.imgDown;
}
}
public function onMouseUp(obj:MouseEvent)
{
if ( (obj) && (!this.hitTestPoint(obj.localX, obj.localY)) ) {
obj.stopImmediatePropagation();
return;
}
if ( this.curImg ) {
this.removeChild(this.curImg);
}
if ( this.imgUp ) {
this.addChild(this.imgUp);
this.curImg = this.imgUp;
}
}
public function onMouseClick(obj:MouseEvent)
{
if ( ! this.hitTestPoint(obj.localX, obj.localY) ) {
obj.stopImmediatePropagation();
}
}
/*
* hitTestPoint(x, y, shapeFlag)
*
* An overriden version of hitTestPoint that is pixel-accurate. If the value at (x, y) is either A: of the value
* in the "magic color", or B: containing an alpha value of zero, then the hit is POSITIVE. Otherwise it is false.
*
* arguments:
* @x:Number, the X location of the hit relative to the origin of the object
* @y:Number, the Y location of the hit relative to the origin of the object
* @shapeFlag:Boolean, not used, just here for compatibility
*
* returns: Boolean (true if the hit is positive, false if it's negative)
*/
public override function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
{
var color:uint;
var rgb:uint;
var a:uint;
if ( this.curImg && this.curImg.bitmapData ) {
color = this.curImg.bitmapData.getPixel32(x, y);
a = ((color >> 24) & 0xFF);
rgb = (color & 0xFFFFFF00);
//trace("Alpha : " + a + " RGB " + rgb + " magic color " + this.magicColor);
if ( this.magicColor == rgb || a == 0 ) {
return false;
}
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,81 @@
package net.aklabs.demo.simonsays
{
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
import net.aklabs.demo.simonsays.Preloader;
public class Mastermind
{
protected var lightOutTimer:Timer;
protected var lightBitmaps:Array;
public function Mastermind(preloader:Preloader, screenX:Number = 0, screenY:Number = 0)
{
// pass in a preloader so the class knows where to get its resources
var lightPositions = new Array();
// this array holds pairs of (x,y) coordinates at which to place the dark/light colored
// Simon Says buttons, since they're meant to cover the existing buttons on the original graphic.
// These are hard-coded; in a better implementation, they would come from an XML or would be
// individual frames of an SWF which could be fired individually, etc. But this works.
// array idx 0: Blue, 1: Green, 2: Red, 3: Yellow
lightPositions.push( new Array(screenX + 216, screenY + 220)); // blue
lightPositions.push( new Array(screenX + 22, screenY + 20)); // green
lightPositions.push( new Array(screenX + 218, screenY + 20)); // red
lightPositions.push( new Array(screenX + 22, screenY + 218)); // yellow
// this array holds the light/dark bitmaps for the simon says buttons ... each idx is an array which holds (dark, light) bitmap objects
// the indexes (0-3) correspond to the above for colors
this.lightBitmaps = new Array();
var fetchArray = new Array( new Array("gfx_btn_darkblue", "gfx_btn_lightblue"),
new Array("gfx_btn_darkgreen", "gfx_btn_lightgreen"),
new Array("gfx_btn_darkred", "gfx_btn_lightred"),
new Array("gfx_btn_darkyellow", "gfx_btn_lightyellow") );
for ( var i = 0; i < fetchArray.length ; i++ ) {
light = preloader.getObject(fetchArray[i][0]);
dark = preloader.getObject(fetchArray[i][1]);
light.x = lightPositions[i][0];
light.y = lightPositions[i][1];
dark.x = lightPositions[i][0];
dark.y = lightPositions[i][1];
// we don't check the return values here because the preloader shouldn't even fire
// the application up if resources are missing
this.lightBitmaps.push(new Array(light, dark));
// the dark buttons are always there, the lighted ones are just temporarily overlain on them for effect
addChild(dark);
}
whole = preloader.getObject("gfx_background");
whole.x = screenX;
whole.y = screenY;
addChild(whole);
this.lightOutTimer = Timer(1000);
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
this.lightOutTimer.start();
}
public function flashAll(length:Number)
{
this.lightOutTimer.reset();
this.lightOutTimer.delay(length);
this.lightOutTimer.start();
}
public function lightButton(btn:Number, activeTime:Number)
{
if ( btn < 4 ) {
this.lightOutTimer.reset();
this.lightOutTimer.delay(activeTime);
addChild(this.lightBitmaps[btn][0]);
this.lightOutTimer.start();
}
}
public function onTimer(evt:TimerEvent);
{
for ( i = 0 ; i < this.lightBitmaps.length ; i++ ){
removeChild(this.lightBitmaps[i][0]);
}
}
}
}