Removed some cruft
@@ -1,10 +0,0 @@
|
||||
webapp/
|
||||
|
||||
this directory contains the PHP files that run the leaderboard.
|
||||
Really simple stuff. Also contains the help files and such.
|
||||
|
||||
src/
|
||||
|
||||
Contains the actual source files that the game was made from.
|
||||
|
||||
*SHOULD* load right up and run in Flash CS3.
|
||||
@@ -1,909 +0,0 @@
|
||||
/*
|
||||
* MEGA MAN : "Wily Says"
|
||||
* Demo for Zynga Games
|
||||
* (C) Andrew Kesterson 2010 andrew@aklabs.net
|
||||
*
|
||||
*/
|
||||
|
||||
// - TODO : Implement proper layering! Quit this *!@# of adding/removing children in the right order.
|
||||
|
||||
package {
|
||||
import flash.display.MovieClip;
|
||||
import flash.display.SimpleButton;
|
||||
import flash.text.TextField;
|
||||
import flash.text.TextFormat;
|
||||
import flash.text.TextFieldAutoSize;
|
||||
import flash.text.AntiAliasType;
|
||||
import flash.filters.GlowFilter;
|
||||
import flash.events.Event;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.events.KeyboardEvent;
|
||||
import flash.events.MouseEvent;
|
||||
import flash.utils.Timer;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.media.SoundChannel;
|
||||
import flash.net.*;
|
||||
import net.aklabs.demo.simonsays.Preloader;
|
||||
import net.aklabs.demo.simonsays.Pattern;
|
||||
import net.aklabs.demo.simonsays.Mastermind;
|
||||
import net.aklabs.demo.simonsays.LoadingObject;
|
||||
import net.aklabs.demo.simonsays.Player;
|
||||
import net.aklabs.demo.simonsays.Powerup;
|
||||
import net.aklabs.demo.simonsays.PowerupEvent;
|
||||
import net.aklabs.demo.simonsays.MastermindEvent;
|
||||
|
||||
/* Class : Game
|
||||
*
|
||||
* Main application class. Handles player input, logic, etc.
|
||||
*/
|
||||
|
||||
public class Game extends MovieClip {
|
||||
|
||||
protected var preloader:Preloader; // preloader content manager
|
||||
protected var gameTimer:Timer; // timer for the game logic
|
||||
protected var bgMusicChannel:SoundChannel; // channel on which background music is playing - TODO: Allow bgmusic/sfx turned ON/OFF
|
||||
protected var curLevel:Number; // the level of the current number, from 1-10
|
||||
protected var player:Player; // Object representing the player
|
||||
protected var curPattern:Pattern; // The currently active "Pattern" object being played out
|
||||
protected var simon:Mastermind; // The "Simon Says" ("Mastermind")
|
||||
protected var cutscenes:Dictionary; // A dictionary of instantiated and prepared SWF-cloned cutscenes
|
||||
protected var difficulty:Number; // An integer from 0-n setting the difficulty of the game
|
||||
public static var STATE_PLAYING:Number = 0; // STATE : Game is currently PLAYING (e.g., not in menu/cinematic/highscore/credits/etc)
|
||||
public static var STATE_MENU:Number = 1; // STATE: Game is currently sitting at the main menu waiting for player to start the game
|
||||
public static var STATE_HELP:Number = 2; // STATE : Game is currently on the HELP screen (currently unused) - TODO : Add "Help" screen beyond tutorial
|
||||
public static var STATE_PASSWORD:Number = 3; /* STATE : Game is currently on the password input screen to resume a game (currently unused)
|
||||
TODO : Get rid of this, password system was never implemented and doesn't make sense for this game */
|
||||
public static var STATE_GAMEOVER:Number = 4; // STATE : Player has lost the game and is dead
|
||||
public static var STATE_PLAYING_PLAYBACK:Number = 5; /* STATE : Substate of STATE_PLAYING. Used while the Mastermind is playing back the currently
|
||||
exposed portions of the currently playing pattern */
|
||||
public static var STATE_PLAYING_INPUT:Number = 6; // STATE : Substate of STATE_PLAYING. Used while the Mastermind is accepting input from the player.
|
||||
public static var STATE_PLAYING_FLASHING:Number = 7; // STATE : Substate of STATE_PLAYING. Used while the Mastermind is flashing all its lights for a second.
|
||||
public static var STATE_PLAYING_EXPLODING:Number = 8; // STATE : Substate of STATE_PLAYING. Used after the player loses, and while the screen is exploding.
|
||||
public static var STATE_PLAYING_WAITING:Number = 9; /* STATE : Substate of STATE_PLAYING. When the explosion timer has fired, this substate is used while
|
||||
waiting for the explosions to finish their animation before going to STATE_HIGHSCORE. */
|
||||
public static var STATE_PLAYING_WINLEVEL:Number = 10; /* STATE : Substate of STATE_PLAYING. Used when the player has completed all iterations of the
|
||||
current pattern. Implies that the level number is scrolling past, etc.*/
|
||||
public static var STATE_WINGAME:Number = 11; // STATE : Used when the player has completed all patterns and has won the game.
|
||||
public static var STATE_TUTORIAL = 12; // STATE : Game is currently running the tutorial/intro
|
||||
public static var STATE_HIGHSCORE = 13; // STATE : Game is currently awaiting input on the high score screen
|
||||
protected var primaryState:Number; // Stores the game's current primary state value
|
||||
protected var secondaryState:Number; // Stores any applicable substate for the game, if any
|
||||
protected var buttonSounds:Dictionary; // Stores references to the loaded sounds in the preloader for each of the Mastermind buttons
|
||||
protected var timerLabel:TextField; // Text label for the timer display (upper right)
|
||||
protected var scoreLabel:TextField; // Text label for the score display (upper left)
|
||||
protected var levelLabel:TextField; // Text label for the "LEVEL" that scrolls across the screen after beating a pattern
|
||||
protected var levelNumberLabel:TextField; // Text label for the level number (e.g., the "12" in "LEVEL 12") that scrolls after beating a pattern
|
||||
protected var explosionTimer:Timer; // Timer that runs long enough to generate a bunch of sparse explosions when the player loses.
|
||||
protected var explosions:Array; /* An array containing to references to all the currently running explosions on the screen
|
||||
(used so that they can all be safely cleaned up & removed from the screen after Game Over and before moving to the High Score screen) */
|
||||
protected var maxLevel:Number; // maximum level number achievable before winning the game
|
||||
protected var levelClearTime:Number; // The time in which a given pattern/level was cleared; currently unused. TODO - Implement this and put it in the high scores
|
||||
protected var labelPauseTimer:Timer; // the timer that lets the "Level X" label pause in the center of the screen briefly
|
||||
|
||||
public static var KEY_NUM1:Number = 97;
|
||||
public static var KEY_NUM3:Number = 99;
|
||||
public static var KEY_NUM7:Number = 103;
|
||||
public static var KEY_NUM9:Number = 105;
|
||||
public static var KEY_COMMA:Number = 188;
|
||||
public static var KEY_BACKSLASH:Number = 191;
|
||||
public static var KEY_K:Number = 75;
|
||||
public static var KEY_APOSTROPHE = 222;
|
||||
public static var KEY_0:Number = 48;
|
||||
public static var KEY_1:Number = 49;
|
||||
public static var KEY_2:Number = 50;
|
||||
public static var KEY_3:Number = 51;
|
||||
public static var KEY_4:Number = 52;
|
||||
public static var KEY_5:Number = 53;
|
||||
public static var KEY_6:Number = 54;
|
||||
public static var KEY_7:Number = 55;
|
||||
public static var KEY_8:Number = 56;
|
||||
public static var KEY_9:Number = 57;
|
||||
public static var KEY_SPACE:Number = 32;
|
||||
|
||||
/*
|
||||
* Game()
|
||||
*
|
||||
* Default constructor for Game class
|
||||
*
|
||||
* arguments: none
|
||||
*
|
||||
* returns : Game
|
||||
*/
|
||||
public function Game()
|
||||
{
|
||||
// -- setup the preloader and start it downloading
|
||||
var assets = new Array( new Array("sounds", "music_background", "sfx/BACKGROUND.mp3"),
|
||||
new Array("sounds", "sfx_explosion", "sfx/EXPLOSION.mp3"),
|
||||
new Array("sounds", "sfx_btn_blue", "sfx/BLUE.mp3"),
|
||||
new Array("sounds", "sfx_btn_green", "sfx/GREEN.mp3"),
|
||||
new Array("sounds", "sfx_btn_red", "sfx/RED.mp3"),
|
||||
new Array("sounds", "sfx_btn_yellow", "sfx/YELLOW.mp3"),
|
||||
new Array("sounds", "sfx_slowdown", "sfx/SLOWDOWN.mp3"),
|
||||
new Array("sounds", "sfx_shortcircuit", "sfx/SHORTCIRCUIT.mp3"),
|
||||
new Array("sounds", "sfx_pointdoubler", "sfx/POINTDOUBLER.mp3"),
|
||||
new Array("sounds", "sfx_exclamation", "sfx/EXCLAMATION.mp3"),
|
||||
new Array("sounds", "sfx_forgiveness", "sfx/FORGIVENESS.mp3"),
|
||||
new Array("images", "gfx_btn_darkblue", "gfx/blue-dark.png"),
|
||||
new Array("images", "gfx_btn_lightblue", "gfx/blue-light.png"),
|
||||
new Array("images", "gfx_btn_darkgreen", "gfx/green-dark.png"),
|
||||
new Array("images", "gfx_btn_lightgreen", "gfx/green-light.png"),
|
||||
new Array("images", "gfx_btn_darkred", "gfx/red-dark.png"),
|
||||
new Array("images", "gfx_btn_lightred", "gfx/red-light.png"),
|
||||
new Array("images", "gfx_btn_darkyellow", "gfx/yellow-dark.png"),
|
||||
new Array("images", "gfx_btn_lightyellow", "gfx/yellow-light.png"),
|
||||
new Array("images", "gfx_mastermind", "gfx/whole.png"),
|
||||
new Array("images", "gfx_background", "gfx/game_background.png"),
|
||||
new Array("images", "gfx_circuitboard", "gfx/circuitboard.png"),
|
||||
new Array("images", "gfx_pwup_exclamation", "gfx/EXCLAMATION.png"),
|
||||
new Array("images", "gfx_pwup_forgiveness", "gfx/FORGIVENESS.png"),
|
||||
new Array("images", "gfx_pwup_pointdoubler", "gfx/POINTDOUBLER.png"),
|
||||
new Array("images", "gfx_pwup_shortcircuit", "gfx/SHORTCIRCUIT.png"),
|
||||
new Array("images", "gfx_pwup_slowdown", "gfx/SLOWDOWN.png"),
|
||||
new Array("images", "gfx_progress_red", "gfx/progress_red.png"),
|
||||
new Array("images", "gfx_progress_green", "gfx/progress_green.png"),
|
||||
new Array("images", "gfx_pwup_freelife", "gfx/LIFE.png"),
|
||||
new Array("movies", "movie_endscreen", "gfx/cutscenes/endscreen.swf", ""),
|
||||
new Array("movies", "movie_intro_menu", "gfx/cutscenes/intro-menu.swf", ""),
|
||||
new Array("movies", "movie_tutorial", "gfx/cutscenes/tutorial.swf", ""),
|
||||
new Array("movies", "movie_highscore", "gfx/cutscenes/highscore.swf", ""),
|
||||
new Array("movies", "movie_difficultychooser", "gfx/cutscenes/difficultychooser.swf", ""),
|
||||
new Array("movies", "movie_explosion", "gfx/explosion.swf", "SmallExplosion") );
|
||||
this.preloader = new Preloader(assets);
|
||||
this.preloader.x = 200;
|
||||
this.preloader.y = 140;
|
||||
this.addChild(this.preloader);
|
||||
this.preloader.addEventListener(Event.COMPLETE, this.onPreloaderComplete);
|
||||
this.preloader.loadAssets();
|
||||
|
||||
this.buttonSounds = new Dictionary();
|
||||
this.buttonSounds[0] = "sfx_btn_blue";
|
||||
this.buttonSounds[1] = "sfx_btn_green";
|
||||
this.buttonSounds[2] = "sfx_btn_red";
|
||||
this.buttonSounds[3] = "sfx_btn_yellow";
|
||||
|
||||
// -- set up all the timers
|
||||
this.gameTimer = new Timer(25);
|
||||
this.gameTimer.start();
|
||||
this.explosionTimer = new Timer(5000);
|
||||
stage.addEventListener(KeyboardEvent.KEY_UP, this.onKeyUp);
|
||||
this.labelPauseTimer = new Timer(2000);
|
||||
|
||||
// -- miscellanious stuff
|
||||
this.player = new Player();
|
||||
this.cutscenes = new Dictionary();
|
||||
this.explosions = new Array();
|
||||
this.curLevel = 1;
|
||||
this.curPattern = null;
|
||||
this.difficulty = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* onNonLoopEnterFrame(evt)
|
||||
*
|
||||
* This function serves as a trigger on sprites which should not loop their animations. There may be
|
||||
* a simpler way to do this, but being pressed for time I knew this would stop it.
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event , event that triggered this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function onNonLoopEnterFrame(evt:Event)
|
||||
{
|
||||
if ( evt.target.currentFrame == evt.target.totalFrames ) {
|
||||
evt.target.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* onKeyUp(evt)
|
||||
*
|
||||
* This function grabs the player's keyboard input and passes it off to the Player, Pattern objects, etc
|
||||
*
|
||||
* arguments:
|
||||
* @evt: Event, event that triggered this function
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function onKeyUp(evt:KeyboardEvent)
|
||||
{
|
||||
var pwup:Powerup = null;
|
||||
|
||||
if ( this.primaryState == Game.STATE_PLAYING_INPUT ) {
|
||||
var colorPressed:Number = -1;
|
||||
if ( (( evt.keyCode == Game.KEY_NUM1) || (evt.keyCode == Game.KEY_COMMA)) ) {
|
||||
colorPressed = Pattern.COLOR_YELLOW;
|
||||
} else if ( (( evt.keyCode == Game.KEY_NUM3) || (evt.keyCode == Game.KEY_BACKSLASH)) ) {
|
||||
colorPressed = Pattern.COLOR_BLUE;
|
||||
} else if ( (( evt.keyCode == Game.KEY_NUM7) || (evt.keyCode == Game.KEY_K)) ) {
|
||||
colorPressed = Pattern.COLOR_GREEN;
|
||||
} else if ( (( evt.keyCode == Game.KEY_NUM9) || (evt.keyCode == Game.KEY_APOSTROPHE)) ) {
|
||||
colorPressed = Pattern.COLOR_RED;
|
||||
} else if ( ( evt.keyCode >= Game.KEY_0 && evt.keyCode <= Game.KEY_9) ) {
|
||||
if ( evt.keyCode == Game.KEY_0 )
|
||||
evt.keyCode = Game.KEY_0 + 10; // trust me it makes sense (Key 0 is the player's last inventory slot to the right
|
||||
// but it comes first in the keyCode sequence before 1, which is the far left, so we add 10 to it
|
||||
// because we're passing an index from 0 - 9 for the player's inventory)
|
||||
this.player.usePowerupAt(evt.keyCode - 49);
|
||||
}
|
||||
|
||||
if ( colorPressed != -1 )
|
||||
this.checkColorHit(colorPressed);
|
||||
} else if ( this.primaryState == Game.STATE_MENU ) {
|
||||
if ( evt.keyCode == Game.KEY_SPACE ) {
|
||||
this.addChild(cutscenes["difficultychooser"]);
|
||||
}
|
||||
} else if ( this.primaryState == Game.STATE_TUTORIAL ) {
|
||||
if ( evt.keyCode == Game.KEY_SPACE ) {
|
||||
this.newGame();
|
||||
}
|
||||
} else if ( this.primaryState == Game.STATE_WINGAME ) {
|
||||
if ( evt.keyCode == Game.KEY_SPACE ) {
|
||||
this.primaryState = Game.STATE_HIGHSCORE;
|
||||
this.secondaryState = Game.STATE_HIGHSCORE;
|
||||
this.removeChild(this.cutscenes["endscreen"]);
|
||||
this.addChild(this.cutscenes["highscores"]);
|
||||
this.cutscenes["highscores"].play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* onPreloaderComplete(evt)
|
||||
*
|
||||
* This function is fired whenever the Preloader fires an event signifying that all items
|
||||
* in the asset list have been successfully loaded.
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
|
||||
public function onPreloaderComplete(evt:Event)
|
||||
{
|
||||
if ( evt.target == this.preloader ){
|
||||
this.removeChild(this.preloader);
|
||||
// -- setup the cutscenes so they're ready to use
|
||||
this.cutscenes["intro_menu"] = this.preloader.getObject("movie_intro_menu");
|
||||
this.cutscenes["intro_menu"].x = 0;
|
||||
this.cutscenes["intro_menu"].y = 0;
|
||||
this.cutscenes["intro_menu"].addEventListener(Event.ENTER_FRAME, this.onNonLoopEnterFrame);
|
||||
this.cutscenes["tutorial"] = this.preloader.getObject("movie_tutorial");
|
||||
this.cutscenes["tutorial"].x = 0;
|
||||
this.cutscenes["tutorial"].y = 0;
|
||||
this.cutscenes["tutorial"].addEventListener(Event.ENTER_FRAME, this.onNonLoopEnterFrame);
|
||||
this.cutscenes["highscores"] = this.preloader.getObject("movie_highscore");
|
||||
this.cutscenes["highscores"].x = 0;
|
||||
this.cutscenes["highscores"].y = 0;
|
||||
this.cutscenes["highscores"].addEventListener(Event.ENTER_FRAME, this.onNonLoopEnterFrame);
|
||||
this.cutscenes["highscores"].highScorePostBtn.addEventListener(MouseEvent.CLICK, this.onHighScoreEntry);
|
||||
this.cutscenes["highscores"].highScoreCancelBtn.addEventListener(MouseEvent.CLICK, this.onHighScoreEntry);
|
||||
this.cutscenes["highscores"].viewScoreBtn.addEventListener(MouseEvent.CLICK, this.onHighScoreEntry);
|
||||
this.cutscenes["difficultychooser"] = this.preloader.getObject("movie_difficultychooser");
|
||||
this.cutscenes["difficultychooser"].x = 300;
|
||||
this.cutscenes["difficultychooser"].y = 200;
|
||||
this.cutscenes["difficultychooser"].easyBtn.addEventListener(MouseEvent.CLICK, this.onDifficultySelected);
|
||||
this.cutscenes["difficultychooser"].normalBtn.addEventListener(MouseEvent.CLICK, this.onDifficultySelected);
|
||||
this.cutscenes["difficultychooser"].hardBtn.addEventListener(MouseEvent.CLICK, this.onDifficultySelected);
|
||||
this.cutscenes["difficultychooser"].wilyBtn.addEventListener(MouseEvent.CLICK, this.onDifficultySelected);
|
||||
this.cutscenes["endscreen"] = this.preloader.getObject("movie_endscreen");
|
||||
this.cutscenes["endscreen"].x = 0;
|
||||
this.cutscenes["endscreen"].y = 0;
|
||||
|
||||
this.addChild(this.cutscenes["intro_menu"]);
|
||||
|
||||
this.gameTimer.removeEventListener(TimerEvent.TIMER, this.onPreloaderComplete);
|
||||
this.gameTimer.addEventListener(TimerEvent.TIMER, this.onGameTimer);
|
||||
|
||||
this.simon = new Mastermind();
|
||||
this.simon.x = (640-(this.simon.width))/2;
|
||||
this.simon.y = 20;
|
||||
this.simon.addEventListener(MastermindEvent.BTN_CLICKED, this.onMastermindClicked);
|
||||
|
||||
this.timerLabel = new TextField();
|
||||
this.timerLabel.background = false;
|
||||
this.timerLabel.autoSize = TextFieldAutoSize.LEFT;
|
||||
var timerLabelFormat = new TextFormat();
|
||||
timerLabelFormat.font = "Courier New";
|
||||
timerLabelFormat.bold = false;
|
||||
timerLabelFormat.color = 0xF12B2B;
|
||||
timerLabelFormat.size = 36;
|
||||
this.timerLabel.defaultTextFormat = timerLabelFormat;
|
||||
this.timerLabel.text = "00000";
|
||||
this.timerLabel.x = 504;
|
||||
this.timerLabel.y = 34;
|
||||
|
||||
this.scoreLabel = new TextField();
|
||||
this.scoreLabel.background = false;
|
||||
this.scoreLabel.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.scoreLabel.defaultTextFormat = timerLabelFormat;
|
||||
this.scoreLabel.text = "000000";
|
||||
this.scoreLabel.x = 12;
|
||||
this.scoreLabel.y = 34;
|
||||
|
||||
this.levelLabel = new TextField();
|
||||
this.levelLabel.background = false;
|
||||
this.levelLabel.autoSize = TextFieldAutoSize.LEFT;
|
||||
this.levelNumberLabel = new TextField();
|
||||
this.levelNumberLabel.background = false;
|
||||
this.levelNumberLabel.autoSize = TextFieldAutoSize.LEFT;
|
||||
var levelLabelFormat = new TextFormat();
|
||||
levelLabelFormat.font = "Helvetica";
|
||||
levelLabelFormat.bold = true;
|
||||
levelLabelFormat.color = 0xF12B2B;
|
||||
levelLabelFormat.size = 72;
|
||||
this.levelLabel.defaultTextFormat = levelLabelFormat;
|
||||
this.levelNumberLabel.defaultTextFormat = levelLabelFormat;
|
||||
this.levelLabel.antiAliasType = AntiAliasType.ADVANCED;
|
||||
this.levelNumberLabel.antiAliasType = AntiAliasType.ADVANCED;
|
||||
this.levelLabel.filters = [new GlowFilter(0x000000, 1.0, 4, 4, 300)];
|
||||
this.levelNumberLabel.filters = [new GlowFilter(0x000000, 1.0, 4, 4, 300)];
|
||||
this.levelLabel.x = 150;
|
||||
this.levelLabel.y = 500;
|
||||
this.levelNumberLabel.x = 400;
|
||||
this.levelNumberLabel.y = -150;
|
||||
this.levelLabel.text = "LEVEL";
|
||||
|
||||
this.player.addEventListener(PowerupEvent.USED_POWERUP, this.onUsedPowerup);
|
||||
this.playBackgroundMusic();
|
||||
this.primaryState = Game.STATE_MENU;
|
||||
this.secondaryState = Game.STATE_MENU;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* onBackgroundMusicFinished(evt)
|
||||
*
|
||||
* This function just makes sure that the background music loops forever
|
||||
*
|
||||
* arguments:
|
||||
* @evt: Event, event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function onBackgroundMusicFinished(evt:Event)
|
||||
{
|
||||
this.playBackgroundMusic();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* playBackgroundMusic()
|
||||
*
|
||||
* This function starts the background music playing
|
||||
*
|
||||
* arguments: none
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function playBackgroundMusic()
|
||||
{
|
||||
if ( this.bgMusicChannel )
|
||||
this.bgMusicChannel.stop();
|
||||
var bgmusic = this.preloader.getObject("music_background");
|
||||
if ( !bgmusic ) {
|
||||
return;
|
||||
}
|
||||
this.bgMusicChannel = bgmusic.play();
|
||||
this.bgMusicChannel.addEventListener(Event.SOUND_COMPLETE, this.onBackgroundMusicFinished);
|
||||
}
|
||||
|
||||
/*
|
||||
* onGetPowerup(evt)
|
||||
*
|
||||
* This function is fired whenever the Pattern is signifying that the player has gotten a powerup from the pattern
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function onGetPowerup(evt:PowerupEvent)
|
||||
{
|
||||
if ( evt.pwup != null ) {
|
||||
var pwup = evt.pwup;
|
||||
pwup.addChild(this.preloader.getBitmap(pwup.imgHandle));
|
||||
this.player.addPowerup(pwup);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* onGameTimer(evt)
|
||||
*
|
||||
* Fires once every 25 ms to run the core game logic
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
|
||||
public function onGameTimer(evt:TimerEvent)
|
||||
{
|
||||
var i:Number = 0;
|
||||
|
||||
/* This state machine got just a little bit too complex, and I think alot of it could be probably get
|
||||
done away with in favor of more events driving the show. However for right now, it works. The IF chains
|
||||
check the primary state first, then go in and check secondary states and ancillary conditions. */
|
||||
|
||||
if ( (this.primaryState == Game.STATE_PLAYING) && (this.curPattern.state == Pattern.STATE_STOPPED) ) {
|
||||
if ( this.secondaryState == Game.STATE_PLAYING_FLASHING && (!this.simon.isLit) ) {
|
||||
// we've flashed the Mastermind once, now let's play back the currently exposed portions of the pattern
|
||||
this.curPattern.play(true);
|
||||
this.primaryState = Game.STATE_PLAYING_PLAYBACK;
|
||||
this.secondaryState = Game.STATE_PLAYING_PLAYBACK;
|
||||
} else if ( this.secondaryState == Game.STATE_PLAYING_EXPLODING ) {
|
||||
// the player has died and we're still in the explosion timeframe, so blow some *!$% up
|
||||
if ( Math.random() < 0.25 ) {
|
||||
var explosion = this.preloader.getMovieClip("movie_explosion");
|
||||
explosion.addEventListener(Event.ENTER_FRAME, this.onNonLoopEnterFrame);
|
||||
explosion.x = Math.random()*640;
|
||||
explosion.y = Math.random()*480;
|
||||
explosion.play();
|
||||
this.preloader.playSound("sfx_explosion");
|
||||
this.addChild(explosion);
|
||||
this.explosions.push(explosion);
|
||||
}
|
||||
} else if ( this.secondaryState == Game.STATE_PLAYING_WINLEVEL ) {
|
||||
// player just beat the pattern; scroll "LEVEL" down from the top, and the level number up from the bottom
|
||||
this.levelNumberLabel.text = "" + this.curLevel;
|
||||
if ( this.levelLabel.y == 175 && (!this.labelPauseTimer.running)) {
|
||||
this.labelPauseTimer.addEventListener(TimerEvent.TIMER, this.onLabelPauseTimer);
|
||||
this.labelPauseTimer.reset();
|
||||
this.labelPauseTimer.start();
|
||||
} else if ( this.labelPauseTimer.running ) {
|
||||
// do nothing if the label pause timer is running
|
||||
} else if ( this.levelLabel.y <= -120 ) {
|
||||
this.secondaryState = Game.STATE_PLAYING;
|
||||
this.levelLabel.y = 500;
|
||||
this.levelNumberLabel.y = -150;
|
||||
} else {
|
||||
this.levelLabel.y -= 5;
|
||||
this.levelNumberLabel.y += 5;
|
||||
}
|
||||
} else if ( this.secondaryState == Game.STATE_PLAYING ){
|
||||
// flash the Mastermind once before playing back the portions currently exposed, so we have the player's
|
||||
// attention
|
||||
this.simon.flashAll(500);
|
||||
this.secondaryState = Game.STATE_PLAYING_FLASHING;
|
||||
}
|
||||
} else if ( (this.primaryState == Game.STATE_PLAYING_PLAYBACK) ) {
|
||||
if ( (this.secondaryState == Game.STATE_PLAYING_FLASHING ) && (!this.simon.isLit) ) {
|
||||
// okay we're done flashing around, let the player give input and start the timers
|
||||
this.curPattern.play(false);
|
||||
this.primaryState = Game.STATE_PLAYING_INPUT;
|
||||
this.secondaryState = Game.STATE_PLAYING;
|
||||
} else if ( this.secondaryState == Game.STATE_PLAYING_PLAYBACK && this.curPattern.state == Pattern.STATE_STOPPED ) {
|
||||
// flash the Mastermind a 2nd time to let the player know we're done running the pattern, and they need to start hitting buttons
|
||||
this.simon.flashAll(500);
|
||||
this.secondaryState = Game.STATE_PLAYING_FLASHING;
|
||||
}
|
||||
} else if ( (this.primaryState == Game.STATE_PLAYING_INPUT) && (this.curPattern.state != Pattern.STATE_RUNNING ) ) {
|
||||
if ( this.curPattern.state == Pattern.STATE_CORRECT ) {
|
||||
// player has repeated the pattern correctly
|
||||
this.player.score += this.curPattern.score;
|
||||
this.curPattern.complexify();
|
||||
if ( this.curPattern.patternLength() > this.player.maxPattern )
|
||||
this.player.maxPattern = this.curPattern.patternLength();
|
||||
// check the state again after complexifying it. If the player has reached the end of the pattern, we won't know
|
||||
// until we've ran .complexify() on it.
|
||||
if ( this.curPattern.state == Pattern.STATE_COMPLETE ) {
|
||||
this.nextLevel();
|
||||
if ( this.curLevel >= this.maxLevel ) {
|
||||
this.wonGame();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if ( this.curPattern.state == Pattern.STATE_FAILED ){
|
||||
// Player irrevocably missed the pattern; deduct a life and either start a new pattern, or game over.
|
||||
this.player.die();
|
||||
if ( this.player.lives <= 0 ) {
|
||||
this.curPattern.stop()
|
||||
this.primaryState = Game.STATE_PLAYING;
|
||||
this.secondaryState = Game.STATE_PLAYING_EXPLODING;
|
||||
this.explosionTimer.addEventListener(TimerEvent.TIMER, this.onExplosionTimer);
|
||||
this.explosionTimer.start();
|
||||
this.curPattern.forceState(Pattern.STATE_STOPPED);
|
||||
return;
|
||||
} else {
|
||||
this.newPattern();
|
||||
}
|
||||
}
|
||||
// if we haven't returned out from a previous condition, it's safe to reset the primary/secondary state
|
||||
// to STATE_PLAYING so we'll flash and run the pattern normally
|
||||
this.primaryState = Game.STATE_PLAYING;
|
||||
this.secondaryState = Game.STATE_PLAYING;
|
||||
this.timerLabel.text = "00000";
|
||||
} else if ( this.primaryState == Game.STATE_PLAYING_INPUT ) {
|
||||
// Player is running input, just update the timer text
|
||||
this.timerLabel.text = "" + this.curPattern.clearTime;
|
||||
}
|
||||
this.scoreLabel.text = "" + int(player.score);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* onLabelPauseTimer(evt)
|
||||
*
|
||||
* This function is called when the label pause timer is up, so the Level labels will start moving again
|
||||
*
|
||||
* arguments:
|
||||
* @evt:TimerEvent, the event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
|
||||
public function onLabelPauseTimer(evt:TimerEvent)
|
||||
{
|
||||
this.labelPauseTimer.removeEventListener(TimerEvent.TIMER, this.onLabelPauseTimer);
|
||||
this.labelPauseTimer.stop();
|
||||
// this bumps it past the pixel mark so we don't duplicate the onLabelPauseTimer call and it sits there forever
|
||||
this.levelLabel.y -= 5;
|
||||
this.levelNumberLabel.y == 5.
|
||||
}
|
||||
|
||||
/*
|
||||
* onDifficultySelected(evt)
|
||||
*
|
||||
* This function is called whenever the player selects a difficulty level from the main screen starting a new game
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function onDifficultySelected(evt:MouseEvent)
|
||||
{
|
||||
var mapping:Dictionary = new Dictionary;
|
||||
// -- this just saves me a long block of if () { ... } , and the use of one-line X ? Y : Z ...
|
||||
mapping[this.cutscenes["difficultychooser"].easyBtn] = 0;
|
||||
mapping[this.cutscenes["difficultychooser"].normalBtn] = 1;
|
||||
mapping[this.cutscenes["difficultychooser"].hardBtn] = 2;
|
||||
mapping[this.cutscenes["difficultychooser"].wilyBtn] = 3;
|
||||
this.difficulty = mapping[evt.target];
|
||||
|
||||
this.removeChild(this.cutscenes["difficultychooser"]);
|
||||
this.removeChild(this.cutscenes["intro_menu"]);
|
||||
this.primaryState = Game.STATE_TUTORIAL;
|
||||
this.secondaryState = Game.STATE_TUTORIAL;
|
||||
this.addChild(this.cutscenes["tutorial"]);
|
||||
this.cutscenes["tutorial"].play();
|
||||
}
|
||||
|
||||
/*
|
||||
* onHighScoreEntry(evt)
|
||||
*
|
||||
* This function fires whenever the user clicks any of the buttons on the High Score screen
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function onHighScoreEntry(evt:MouseEvent)
|
||||
{
|
||||
if ( evt.target == this.cutscenes["highscores"].highScorePostBtn ) {
|
||||
// post up the user's high score and spin off a new browser window to the high score area
|
||||
var request:URLRequest = new URLRequest("http://atlanta.aklabs.net/~akesterson/wilysays/index.php");
|
||||
request.method = URLRequestMethod.POST;
|
||||
var variables:URLVariables = new URLVariables();
|
||||
variables.op = "store";
|
||||
variables.name = this.cutscenes["highscores"].highScoreName.text;
|
||||
variables.score = this.player.score;
|
||||
variables.maxpattern = this.player.maxPattern;
|
||||
request.data = variables;
|
||||
sendToURL(request);
|
||||
var request:URLRequest = new URLRequest("http://atlanta.aklabs.net/~akesterson/wilysays/index.php");
|
||||
navigateToURL(request, "_blank");
|
||||
} else if ( evt.target == this.cutscenes["highscores"].viewScoreBtn) {
|
||||
// just send the user to the high scores and return, don't disable any of the buttons or change state
|
||||
var request:URLRequest = new URLRequest("http://atlanta.aklabs.net/~akesterson/wilysays/index.php");
|
||||
navigateToURL(request, "_blank");
|
||||
return;
|
||||
}
|
||||
// go back to the main menu
|
||||
this.removeChild(this.cutscenes["highscores"]);
|
||||
this.addChild(this.cutscenes["intro_menu"]);
|
||||
this.primaryState = Game.STATE_MENU;
|
||||
this.primaryState = Game.STATE_MENU;
|
||||
this.cutscenes["intro_menu"].gotoAndPlay(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* clearExplosions()
|
||||
*
|
||||
* This function is ran when the explosion timer is done, and right before the high score screen
|
||||
* is fixing to come up, to make sure that all the explosions are gone from the screen.
|
||||
*
|
||||
* arguments: none
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function clearExplosions()
|
||||
{
|
||||
var i:Number;
|
||||
for ( i = 0; i < this.explosions.length ; i++ ) {
|
||||
this.removeChild(this.explosions[i]);
|
||||
this.explosions[i].stop();
|
||||
this.explosions.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* clearGameScreen()
|
||||
*
|
||||
* This function clears the game screen of all play elements (inventory, lives, Mastermind, etc)
|
||||
*
|
||||
* arguments : none
|
||||
*
|
||||
* returns: none
|
||||
*/
|
||||
public function clearGameScreen()
|
||||
{
|
||||
this.removeChild(this.preloader.getObject("gfx_circuitboard"));
|
||||
this.removeChild(this.preloader.getObject("gfx_background"));
|
||||
this.removeChild(this.simon);
|
||||
this.removeChild(this.timerLabel);
|
||||
this.removeChild(this.scoreLabel);
|
||||
this.removeChild(this.levelLabel);
|
||||
this.removeChild(this.levelNumberLabel);
|
||||
if ( this.curPattern )
|
||||
this.removeChild(this.curPattern);
|
||||
this.removeChild(this.player);
|
||||
this.removeChild(this.player.lifeDisplay);
|
||||
|
||||
this.player.clearInventory();
|
||||
|
||||
this.explosionTimer.reset();
|
||||
this.explosionTimer.delay = 5000;
|
||||
this.explosionTimer.stop();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* wonGame()
|
||||
*
|
||||
* This function is called when the player has beaten all 10 levels and therefore won the game
|
||||
*
|
||||
* arguments: None
|
||||
*
|
||||
* Returns: None
|
||||
*
|
||||
*/
|
||||
|
||||
public function wonGame()
|
||||
{
|
||||
this.clearGameScreen();
|
||||
this.primaryState = Game.STATE_WINGAME;
|
||||
this.secondaryState = Game.STATE_WINGAME;
|
||||
this.addChild(this.cutscenes["endscreen"]);
|
||||
this.cutscenes["endscreen"].play();
|
||||
}
|
||||
|
||||
/* gameOver()
|
||||
*
|
||||
* This function is called whenever the player has lost all of their lives, and achieved Game Over
|
||||
*
|
||||
* arguments : None
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function gameOver()
|
||||
{
|
||||
this.clearGameScreen();
|
||||
this.primaryState = Game.STATE_HIGHSCORE;
|
||||
this.secondaryState = Game.STATE_HIGHSCORE;
|
||||
this.addChild(this.cutscenes["highscores"]);
|
||||
this.cutscenes["highscores"].play();
|
||||
}
|
||||
|
||||
/*
|
||||
* nextLevel()
|
||||
*
|
||||
* This function runs to setup the next level above the previous one
|
||||
*
|
||||
* arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function nextLevel()
|
||||
{
|
||||
this.curLevel += 1;
|
||||
this.levelLabel.y = 500;
|
||||
this.levelNumberLabel.y = -150;
|
||||
this.levelNumberLabel.text = "" + this.curLevel;
|
||||
this.primaryState = Game.STATE_PLAYING;
|
||||
this.secondaryState = Game.STATE_PLAYING_WINLEVEL;
|
||||
this.player.score += this.curPattern.score;
|
||||
this.timerLabel.text = "00000";
|
||||
this.scoreLabel.text = "" + int(player.score);
|
||||
this.newPattern();
|
||||
}
|
||||
|
||||
/*
|
||||
* newGame()
|
||||
*
|
||||
* This function sets up a new game when the player starts a game from the main menu
|
||||
*
|
||||
* arguments : none
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function newGame()
|
||||
{
|
||||
// difficulty just really changes how long the patterns are and how many levels you play
|
||||
if ( this.difficulty > 1 ) {
|
||||
this.curLevel = 3*this.difficulty;
|
||||
} else
|
||||
this.curLevel = 0;
|
||||
this.maxLevel = this.curLevel + (6+this.difficulty);
|
||||
this.player.score = 0;
|
||||
this.player.lives = 3;
|
||||
this.cutscenes["tutorial"].stop();
|
||||
this.cutscenes["highscores"].stop();
|
||||
this.cutscenes["intro_menu"].stop();
|
||||
|
||||
try {
|
||||
this.removeChild(this.cutscenes["tutorial"]);
|
||||
} catch (error:Error) {
|
||||
// do nothing, it wasn't a child for some reason.. (I ran into this a couple times but not sure why)
|
||||
}
|
||||
|
||||
this.addChild(this.preloader.getObject("gfx_circuitboard"));
|
||||
this.addChild(this.preloader.getObject("gfx_background"));
|
||||
this.addChild(this.simon);
|
||||
this.addChild(this.timerLabel);
|
||||
this.addChild(this.scoreLabel);
|
||||
this.addChild(player);
|
||||
this.addChild(player.lifeDisplay);
|
||||
this.addChild(this.levelLabel);
|
||||
this.addChild(this.levelNumberLabel);
|
||||
|
||||
this.player.x = 0;
|
||||
this.player.y = 480-64;
|
||||
player.lifeDisplay.x = 400;
|
||||
player.lifeDisplay.y = 480-64;
|
||||
this.player.resetLifePositions();
|
||||
|
||||
this.primaryState = Game.STATE_PLAYING;
|
||||
this.secondaryState = Game.STATE_PLAYING;
|
||||
|
||||
this.newPattern();
|
||||
this.nextLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
* onExplosionTimer(evt)
|
||||
*
|
||||
* This function fires when the explosion timeframe is up
|
||||
*
|
||||
* arguments :
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function onExplosionTimer(evt:TimerEvent)
|
||||
{
|
||||
this.primaryState = Game.STATE_PLAYING;
|
||||
this.secondaryState = Game.STATE_PLAYING_WAITING;
|
||||
for ( var i:Number = 0; i < this.explosions.length; i++ ) {
|
||||
if ( this.explosions[i].currentFrame != this.explosions[i].totalFrames ) {
|
||||
// some of the explosions aren't done yet, let them finish
|
||||
this.explosionTimer.delay = 1000;
|
||||
this.explosionTimer.start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.clearExplosions();
|
||||
this.gameOver();
|
||||
}
|
||||
|
||||
/*
|
||||
* onMastermindClicked(evt)
|
||||
*
|
||||
* This function fires whenever the player clicks the mouse on one of the mastermind buttons
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function onMastermindClicked(evt:MastermindEvent)
|
||||
{
|
||||
this.checkColorHit(evt.colorClicked);
|
||||
}
|
||||
|
||||
/*
|
||||
* autoForgiveness()
|
||||
*
|
||||
* This function checkes to see if the player has a Forgiveness powerup in his inventory,
|
||||
* and if it does, it uses it to stop the pattern from blowing out one of the players' lives
|
||||
*
|
||||
* arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*/
|
||||
public function autoForgiveness()
|
||||
{
|
||||
var pwup:Powerup = null;
|
||||
for ( var i:Number = 0; i < this.player.inventory.length ; i++ ) {
|
||||
pwup = this.player.inventory[i];
|
||||
if ( pwup.pType == Powerup.PTYPE_FORGIVENESS ) {
|
||||
this.curPattern.forceState(Pattern.STATE_STOPPED);
|
||||
this.player.usePowerupAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checkColorHit(colorPressed)
|
||||
*
|
||||
* arguments:
|
||||
* @colorPressed : Number, an integer (e.g. Pattern.COLOR_XXXX) specifying which color the player hit
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function checkColorHit(colorPressed:Number)
|
||||
{
|
||||
if ( this.curPattern.colorActive(colorPressed) == true ) {
|
||||
this.simon.lightButton(colorPressed, 100);
|
||||
this.preloader.playSound(this.buttonSounds[colorPressed]);
|
||||
} else {
|
||||
this.autoForgiveness();
|
||||
this.curPattern.stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* onUsedPowerup()
|
||||
*
|
||||
* Fired whenever the player uses a powerup
|
||||
*
|
||||
* arguments:
|
||||
* @evt : Event, the event firing this function
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function onUsedPowerup(evt:PowerupEvent)
|
||||
{
|
||||
// the only time we get a powerupevent for used powerups
|
||||
// is when it's the player dispatching one; we have to
|
||||
// then re-dispatch it so that the pattern will see it,
|
||||
// since it's in the opposite direction for bubbling (things bubble up,
|
||||
// never down). We never actually process them, all powerup handling is
|
||||
// handled between the player & pattern. We just dispatch.
|
||||
this.curPattern.onUsedPowerup(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
* newPattern()
|
||||
*
|
||||
* Creates a new pattern object to challenge the player.
|
||||
*
|
||||
* arguments: none
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
public function newPattern()
|
||||
{
|
||||
try {
|
||||
this.removeChild(this.curPattern);
|
||||
} catch (error:Error) {
|
||||
// do nothing, it wasn't in our child list yet
|
||||
}
|
||||
this.curPattern = new Pattern(this.curLevel, this.simon, this.difficulty);
|
||||
this.curPattern.addEventListener(PowerupEvent.GOT_POWERUP, this.onGetPowerup);
|
||||
this.curPattern.stop();
|
||||
this.curPattern.forceState(Pattern.STATE_STOPPED);
|
||||
this.curPattern.x = 602;
|
||||
this.curPattern.y = 138;
|
||||
this.addChild(this.curPattern);
|
||||
trace("Finished newPattern()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 791 KiB |
|
Before Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 875 B |
|
Before Width: | Height: | Size: 872 B |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,34 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,529 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
//v1.7
|
||||
// Flash Player Version Detection
|
||||
// Detect Client Browser type
|
||||
// Copyright 2005-2007 Adobe Systems Incorporated. All rights reserved.
|
||||
var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
|
||||
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
|
||||
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
|
||||
|
||||
function ControlVersion()
|
||||
{
|
||||
var version;
|
||||
var axo;
|
||||
var e;
|
||||
|
||||
// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
|
||||
|
||||
try {
|
||||
// version will be set for 7.X or greater players
|
||||
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
|
||||
version = axo.GetVariable("$version");
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!version)
|
||||
{
|
||||
try {
|
||||
// version will be set for 6.X players only
|
||||
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
|
||||
|
||||
// installed player is some revision of 6.0
|
||||
// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
|
||||
// so we have to be careful.
|
||||
|
||||
// default to the first public version
|
||||
version = "WIN 6,0,21,0";
|
||||
|
||||
// throws if AllowScripAccess does not exist (introduced in 6.0r47)
|
||||
axo.AllowScriptAccess = "always";
|
||||
|
||||
// safe to call for 6.0r47 or greater
|
||||
version = axo.GetVariable("$version");
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!version)
|
||||
{
|
||||
try {
|
||||
// version will be set for 4.X or 5.X player
|
||||
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||
version = axo.GetVariable("$version");
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!version)
|
||||
{
|
||||
try {
|
||||
// version will be set for 3.X player
|
||||
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||
version = "WIN 3,0,18,0";
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!version)
|
||||
{
|
||||
try {
|
||||
// version will be set for 2.X player
|
||||
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
|
||||
version = "WIN 2,0,0,11";
|
||||
} catch (e) {
|
||||
version = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
// JavaScript helper required to detect Flash Player PlugIn version information
|
||||
function GetSwfVer(){
|
||||
// NS/Opera version >= 3 check for Flash plugin in plugin array
|
||||
var flashVer = -1;
|
||||
|
||||
if (navigator.plugins != null && navigator.plugins.length > 0) {
|
||||
if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
|
||||
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
|
||||
var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
|
||||
var descArray = flashDescription.split(" ");
|
||||
var tempArrayMajor = descArray[2].split(".");
|
||||
var versionMajor = tempArrayMajor[0];
|
||||
var versionMinor = tempArrayMajor[1];
|
||||
var versionRevision = descArray[3];
|
||||
if (versionRevision == "") {
|
||||
versionRevision = descArray[4];
|
||||
}
|
||||
if (versionRevision[0] == "d") {
|
||||
versionRevision = versionRevision.substring(1);
|
||||
} else if (versionRevision[0] == "r") {
|
||||
versionRevision = versionRevision.substring(1);
|
||||
if (versionRevision.indexOf("d") > 0) {
|
||||
versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
|
||||
}
|
||||
}
|
||||
var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
|
||||
}
|
||||
}
|
||||
// MSN/WebTV 2.6 supports Flash 4
|
||||
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
|
||||
// WebTV 2.5 supports Flash 3
|
||||
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
|
||||
// older WebTV supports Flash 2
|
||||
else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
|
||||
else if ( isIE && isWin && !isOpera ) {
|
||||
flashVer = ControlVersion();
|
||||
}
|
||||
return flashVer;
|
||||
}
|
||||
|
||||
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
|
||||
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
|
||||
{
|
||||
versionStr = GetSwfVer();
|
||||
if (versionStr == -1 ) {
|
||||
return false;
|
||||
} else if (versionStr != 0) {
|
||||
if(isIE && isWin && !isOpera) {
|
||||
// Given "WIN 2,0,0,11"
|
||||
tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"]
|
||||
tempString = tempArray[1]; // "2,0,0,11"
|
||||
versionArray = tempString.split(","); // ['2', '0', '0', '11']
|
||||
} else {
|
||||
versionArray = versionStr.split(".");
|
||||
}
|
||||
var versionMajor = versionArray[0];
|
||||
var versionMinor = versionArray[1];
|
||||
var versionRevision = versionArray[2];
|
||||
|
||||
// is the major.revision >= requested major.revision AND the minor version >= requested minor
|
||||
if (versionMajor > parseFloat(reqMajorVer)) {
|
||||
return true;
|
||||
} else if (versionMajor == parseFloat(reqMajorVer)) {
|
||||
if (versionMinor > parseFloat(reqMinorVer))
|
||||
return true;
|
||||
else if (versionMinor == parseFloat(reqMinorVer)) {
|
||||
if (versionRevision >= parseFloat(reqRevision))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function AC_AddExtension(src, ext)
|
||||
{
|
||||
if (src.indexOf('?') != -1)
|
||||
return src.replace(/\?/, ext+'?');
|
||||
else
|
||||
return src + ext;
|
||||
}
|
||||
|
||||
function AC_Generateobj(objAttrs, params, embedAttrs)
|
||||
{
|
||||
var str = '';
|
||||
if (isIE && isWin && !isOpera)
|
||||
{
|
||||
str += '<object ';
|
||||
for (var i in objAttrs)
|
||||
{
|
||||
str += i + '="' + objAttrs[i] + '" ';
|
||||
}
|
||||
str += '>';
|
||||
for (var i in params)
|
||||
{
|
||||
str += '<param name="' + i + '" value="' + params[i] + '" /> ';
|
||||
}
|
||||
str += '</object>';
|
||||
}
|
||||
else
|
||||
{
|
||||
str += '<embed ';
|
||||
for (var i in embedAttrs)
|
||||
{
|
||||
str += i + '="' + embedAttrs[i] + '" ';
|
||||
}
|
||||
str += '> </embed>';
|
||||
}
|
||||
|
||||
document.write(str);
|
||||
}
|
||||
|
||||
function AC_FL_RunContent(){
|
||||
var ret =
|
||||
AC_GetArgs
|
||||
( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
|
||||
, "application/x-shockwave-flash"
|
||||
);
|
||||
AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
|
||||
}
|
||||
|
||||
function AC_SW_RunContent(){
|
||||
var ret =
|
||||
AC_GetArgs
|
||||
( arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
|
||||
, null
|
||||
);
|
||||
AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
|
||||
}
|
||||
|
||||
function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
|
||||
var ret = new Object();
|
||||
ret.embedAttrs = new Object();
|
||||
ret.params = new Object();
|
||||
ret.objAttrs = new Object();
|
||||
for (var i=0; i < args.length; i=i+2){
|
||||
var currArg = args[i].toLowerCase();
|
||||
|
||||
switch (currArg){
|
||||
case "classid":
|
||||
break;
|
||||
case "pluginspage":
|
||||
ret.embedAttrs[args[i]] = args[i+1];
|
||||
break;
|
||||
case "src":
|
||||
case "movie":
|
||||
args[i+1] = AC_AddExtension(args[i+1], ext);
|
||||
ret.embedAttrs["src"] = args[i+1];
|
||||
ret.params[srcParamName] = args[i+1];
|
||||
break;
|
||||
case "onafterupdate":
|
||||
case "onbeforeupdate":
|
||||
case "onblur":
|
||||
case "oncellchange":
|
||||
case "onclick":
|
||||
case "ondblclick":
|
||||
case "ondrag":
|
||||
case "ondragend":
|
||||
case "ondragenter":
|
||||
case "ondragleave":
|
||||
case "ondragover":
|
||||
case "ondrop":
|
||||
case "onfinish":
|
||||
case "onfocus":
|
||||
case "onhelp":
|
||||
case "onmousedown":
|
||||
case "onmouseup":
|
||||
case "onmouseover":
|
||||
case "onmousemove":
|
||||
case "onmouseout":
|
||||
case "onkeypress":
|
||||
case "onkeydown":
|
||||
case "onkeyup":
|
||||
case "onload":
|
||||
case "onlosecapture":
|
||||
case "onpropertychange":
|
||||
case "onreadystatechange":
|
||||
case "onrowsdelete":
|
||||
case "onrowenter":
|
||||
case "onrowexit":
|
||||
case "onrowsinserted":
|
||||
case "onstart":
|
||||
case "onscroll":
|
||||
case "onbeforeeditfocus":
|
||||
case "onactivate":
|
||||
case "onbeforedeactivate":
|
||||
case "ondeactivate":
|
||||
case "type":
|
||||
case "codebase":
|
||||
case "id":
|
||||
ret.objAttrs[args[i]] = args[i+1];
|
||||
break;
|
||||
case "width":
|
||||
case "height":
|
||||
case "align":
|
||||
case "vspace":
|
||||
case "hspace":
|
||||
case "class":
|
||||
case "title":
|
||||
case "accesskey":
|
||||
case "name":
|
||||
case "tabindex":
|
||||
ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
|
||||
break;
|
||||
default:
|
||||
ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
|
||||
}
|
||||
}
|
||||
ret.objAttrs["classid"] = classid;
|
||||
if (mimeType) ret.embedAttrs["type"] = mimeType;
|
||||
return ret;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>simon says</title>
|
||||
<script language="javascript">AC_FL_RunContent = 0;</script>
|
||||
<script src="AC_RunActiveContent.js" language="javascript"></script>
|
||||
</head>
|
||||
<body bgcolor="#000000" text="white">
|
||||
<!--url's used in the movie-->
|
||||
<!--text used in the movie-->
|
||||
<!-- saved from url=(0013)about:internet -->
|
||||
<center><h2>CLICK <a href="http://www.aklabs.net/~akesterson/wilysays/help.html">HERE</a> FOR HELP!</h2></center>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<script language="javascript">
|
||||
if (AC_FL_RunContent == 0) {
|
||||
alert("This page requires AC_RunActiveContent.js.");
|
||||
} else {
|
||||
AC_FL_RunContent(
|
||||
'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
|
||||
'width', '640',
|
||||
'height', '480',
|
||||
'src', 'simon says',
|
||||
'quality', 'high',
|
||||
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
|
||||
'align', 'middle',
|
||||
'play', 'true',
|
||||
'loop', 'true',
|
||||
'scale', 'showall',
|
||||
'wmode', 'window',
|
||||
'devicefont', 'false',
|
||||
'id', 'simon says',
|
||||
'bgcolor', '#000000',
|
||||
'name', 'simon says',
|
||||
'menu', 'true',
|
||||
'allowFullScreen', 'false',
|
||||
'allowScriptAccess','sameDomain',
|
||||
'movie', 'simon says',
|
||||
'salign', ''
|
||||
); //end AC code
|
||||
}
|
||||
</script>
|
||||
<noscript>
|
||||
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="640" height="480" id="simon says" align="middle">
|
||||
<param name="allowScriptAccess" value="sameDomain" />
|
||||
<param name="allowFullScreen" value="false" />
|
||||
<param name="movie" value="simon says.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#000000" /> <embed src="simon says.swf" quality="high" bgcolor="#000000" width="640" height="480" name="simon says" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
|
||||
</object>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,145 +0,0 @@
|
||||
<html>
|
||||
<body bgcolor="black" text="white">
|
||||
<center><h1>MEGA MAN: Wily Says!</h1>
|
||||
|
||||
<h2>HELP!</h2>
|
||||
</center>
|
||||
|
||||
This is the help information for Mega Man: Wily Says!, the smash-megahit
|
||||
game currently sweeping teh intarnets. Here's how to play the game.
|
||||
|
||||
<br/>
|
||||
|
||||
<center><img src="help1.png"></center>
|
||||
|
||||
<br/>
|
||||
|
||||
Once the game loads up, click inside the game window with your mouse to
|
||||
make sure it has focus. Then hit your SPACE BAR. Click on one of the
|
||||
difficulty setting buttons, to choose the difficulty. This determines
|
||||
how many levels you play, and how long the patterns you're challenged with,
|
||||
will be. Once you've done that, watch the intro; it'll give you a little
|
||||
bit of background story, and a little bit of information on how to play
|
||||
the game.
|
||||
|
||||
<center><h1>The interface</h1></center>
|
||||
<br/>
|
||||
<center><img src="help2.png"></center>
|
||||
|
||||
<br/>
|
||||
<ul>
|
||||
<li>The "SCORE" in the upper left corner of the window displays your current
|
||||
total score. Higher scores mean you're more awesome, therefore higher scores
|
||||
are better. You increase your score by completing more patterns.</li>
|
||||
<li>The "TIMER" in the upper right corner of the window displays the amount of
|
||||
time you have left to repeat the pattern. The timer may run faster or slower
|
||||
depending on what difficulty setting you chose, as well as any powerups
|
||||
you may or may not be using right then.</li>
|
||||
<li>The numbered slots on the bottom left are your powerup slots. Hidden
|
||||
inside the patterns are powerups; when you complete a pattern that has a
|
||||
powerup associated with it, you get the powerup, and it shows up in one
|
||||
of these numbered slots. To use one of the powerups, you can either click
|
||||
on the powerup, or press the number key on your keyboard (non-numeric keypad)
|
||||
above that powerup. Here are the powerups and what they do:
|
||||
|
||||
<br/><br/>
|
||||
<table cols=3 cellspacing = 5>
|
||||
<tr>
|
||||
<td><b>Powerup Icon</b></td>
|
||||
<td><b>Powerup Name</b></td>
|
||||
<td><b>Powerup Effect</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="gfx/EXCLAMATION.png"></td>
|
||||
<td valign=bottom>SKIP</td>
|
||||
<td valign=bottom>Skips the current pattern iteration you're on, and gives you all the score points for it</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="gfx/FORGIVENESS.png"></td>
|
||||
<td valign=bottom>FORGIVENESS</td>
|
||||
<td valign=bottom>If you have a FORGIVENESS in your inventory, and you mess up a pattern, then you don't have to start over on a new pattern; it's as if the mistake never happened.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="gfx/POINTDOUBLER.png"></td>
|
||||
<td valign=bottom>POINT DOUBLER</td>
|
||||
<td valign=bottom>When this powerup is used, the current pattern iteration will give you double the number of points it normally would have.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="gfx/SLOWDOWN.png"></td>
|
||||
<td valign=bottom>SLOW DOWN</td>
|
||||
<td valign=bottom>When this powerup is used, the timer runs at an incredibly slow speed, virtually stopping.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
<li> The "ATTEMPTS REMAINING" at the bottom right will show many lives
|
||||
you have left. Every time you miss a light on a pattern, you will
|
||||
lose one life. When you reach 0 lives, the lock will self-detonate,
|
||||
and you will experience the crushing failure that is Game Over.</li>
|
||||
<li>The red lights on the right side of the screen indicate the total
|
||||
number of lights in this pattern; for example, if there are 3
|
||||
red lights, then this pattern has 3 lights to its combination.
|
||||
Therefore you will have one iteration with one light, one
|
||||
iteration with 2 lights, and one iteration with 3 lights.
|
||||
We all remember how a Simon Says works, right?
|
||||
As you complete iterations, those iterations will turn lights
|
||||
from red to green, showing how far away you are from completing
|
||||
the lock/pattern and progressing to the next level.</li>
|
||||
<li>The thing that looks like a Simon Says in the middle of the screen
|
||||
isn't actually a simon says. Yeah, I know - I know, it looks
|
||||
like one, but it's *not*. It's called the WilyLok, "an ingenious
|
||||
pattern-based locking mechanism" designed to keep Mega Man
|
||||
out of Dr Wily's laboratory while he destroys the world.
|
||||
This is where most of the gameplay happens. All you have to do
|
||||
is press the lighted buttons in the same pattern that they
|
||||
flash. All 4 lights will flash once, and then the lights you
|
||||
need to press will light individually. Then all 4 lights
|
||||
will flash again, and the timer will start ticking.
|
||||
Now you have to click on the lights in the same pattern that
|
||||
you just watched. Failure to do so will explode your skull
|
||||
and you'll lose a life - and what's worse, you'll have to
|
||||
start over.</li>
|
||||
</ul>
|
||||
|
||||
Simple, right?
|
||||
|
||||
<center><h2>Credits</h2></center>
|
||||
|
||||
<pre>
|
||||
|
||||
Pre-formatting this because I'm lazy.
|
||||
|
||||
Most of this was assembled ad-hoc from various places around the internet
|
||||
for a game demo to accompany a resume, so it was never really intended for
|
||||
public consumption. But before the whole thing was over, it just became
|
||||
so ridiculous I couldn't possibly keep it to myself.
|
||||
|
||||
The theme music is a MIDI version of Depeche Mode's "Master and Servant". That's
|
||||
where the name "Mastermind" for the Simon Says came from.
|
||||
|
||||
The graphics were mostly stolen from mega man fansites around the internet.
|
||||
|
||||
The explosion graphic was lifted from someone. I forget who. It's the same
|
||||
one I used in my "HOLY *@#%! ALIENS!" space shooter demo.
|
||||
|
||||
The sound effects, again, were lifted from various free sites around the
|
||||
net. I honestly didn't keep track of them. I know they were all straight off
|
||||
Google links.
|
||||
|
||||
I'm solely responsible for this atrocity; if you want to send me hate mail,
|
||||
you're a megaman purist and you want to tear off my head, you think this was
|
||||
the most ridiculous idea for a game demo ever, or if you want to send me
|
||||
big buckets of money because I'm just so <i>goddamned AWESOME</i>, send mail
|
||||
to andrew@aklabs.net, or follow me on twitter (@akesterson). Thanks.
|
||||
|
||||
The entire demo was coded in ActionScript 3 on Adobe Flash CS3, graphics
|
||||
were chopped up with The GIMP, sounds composed/trimmed in Audacity. I think
|
||||
I spent about a total of 48 hours on this project, and that includes learning
|
||||
ActionScript 3. I'll release the source in a few days after an employer
|
||||
is done looking at it.
|
||||
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 452 KiB |
@@ -1,134 +0,0 @@
|
||||
<?php
|
||||
|
||||
$db = mysql_connect("localhost", "akesterson", "fadmin");
|
||||
if ( !$db ) {
|
||||
die("Unable to connect to mysql database");
|
||||
}
|
||||
|
||||
mysql_select_db("akesterson", $db);
|
||||
|
||||
if ( isset($_REQUEST["op"]) ) {
|
||||
if ( strcmp($_REQUEST["op"], "store") == 0 ) {
|
||||
$query = ("INSERT INTO wilysays_highscores (score, name, maxpattern, dtime) VALUES (" .
|
||||
(int)$_REQUEST["score"] . ", \"" . mysql_real_escape_string($_REQUEST["name"]) . "\", " . (int)$_REQUEST["maxpattern"] . ", NOW() );");
|
||||
//printf($query);
|
||||
$res = mysql_query($query, $db);
|
||||
if ( !$res )
|
||||
die("Unable to insert into the database - WTF?. " . mysql_error($db));
|
||||
printf("<html><body>\n<center>Groovy</center>\n</body></html>");
|
||||
}
|
||||
die();
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<body bgcolor="black" text="white">
|
||||
<center>
|
||||
<h1>MEGA MAN: Wily Says!</h1>
|
||||
<h3>Leaderboards</h3>
|
||||
<h4>Click <a href="http://www.aklabs.net/~akesterson/wilysays/game.html">HERE</a> to play the mega-hit game!</h4>
|
||||
<h4>Click <a href="http://www.aklabs.net/~akesterson/wilysays/help.html">HERE</a> for instructions on HOW to play the mega-hit game!</h4>
|
||||
</center>
|
||||
<table cols=3 align="center" >
|
||||
<tr>
|
||||
<td valign="top" width="171" ><img src="megaman.png"/></td>
|
||||
<td valign="top" >
|
||||
|
||||
<?php
|
||||
$totalRows = 0;
|
||||
$curPage = 0;
|
||||
$rowsPerPage = 5;
|
||||
$sortOrder = 1;
|
||||
|
||||
if ( isset($_REQUEST["perpage"]) ) {
|
||||
$rowsPerPage = (int)$_REQUEST["perpage"];
|
||||
}
|
||||
if ( isset($_REQUEST["start"]) ) {
|
||||
$curPage = ((int)$_REQUEST["start"])/$rowsPerPage;
|
||||
}
|
||||
if ( isset($_REQUEST["sort"]) ) {
|
||||
$sortOrder = (int)$_REQUEST["sort"];
|
||||
}
|
||||
|
||||
$totalPages = $totalRows/$rowsPerPage;
|
||||
|
||||
$query = "SELECT COUNT(*) AS count FROM wilysays_highscores;";
|
||||
$res = mysql_query($query, $db);
|
||||
if ( $res ) {
|
||||
$row = mysql_fetch_array($res);
|
||||
$totalRows = $row["count"];
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM wilysays_highscores";
|
||||
|
||||
if ( $sortOrder == 0 ) {
|
||||
$query .= " ORDER BY name ASC";
|
||||
} else if ( $sortOrder == 1 ) {
|
||||
$query .= " ORDER BY score DESC ";
|
||||
} else if ( $sortOrder == 2 ) {
|
||||
$query .= " ORDER BY maxpattern DESC ";
|
||||
} else if ( $sortOrder == 3 ) {
|
||||
$query .= " ORDER BY dtime DESC ";
|
||||
}
|
||||
|
||||
$query .= " LIMIT " . $rowsPerPage . " OFFSET " . ($curPage*$rowsPerPage) . ";";
|
||||
|
||||
///printf($query);
|
||||
|
||||
$res = mysql_query($query, $db);
|
||||
if ( $res ) {
|
||||
printf("\t\t\t<table align=center cols=4 width=440 border=1>\n");
|
||||
printf("<tr>\n");
|
||||
if ( $curPage > 0 )
|
||||
printf(" <td colspan=2 align=left><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=%d&start=%d\"><< PREVIOUS</td>\n", $rowsPerPage, (($curPage*$rowsPerPage)-$rowsPerPage));
|
||||
else
|
||||
printf(" <td colspan=2></td>\n");
|
||||
|
||||
if ( $totalRows > ($curPage * $rowsPerPage) )
|
||||
printf(" <td colspan=2 align=right><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=%d&start=%d\">NEXT >></a></td>\n", $rowsPerPage, (($curPage*$rowsPerPage)+$rowsPerPage));
|
||||
else
|
||||
printf(" <td colspan=2></td>\n");
|
||||
printf("</tr>\n");
|
||||
|
||||
printf("\t\t\t\t<tr><td><b><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?start=%d&sort=0\">Player<br/>Name</a></b></td><td><b><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?start=%d&sort=1\">Total<br/>Score</a></b></td><td><b><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?start=%d&sort=2\">Longest<br/>Pattern</a></b></td><td><b><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?start=%d&sort=3\">When<br/>Recorded</a></b></td></tr>\n",
|
||||
($curPage*$rowsPerPage), ($curPage*$rowsPerPage), ($curPage*$rowsPerPage), ($curPage*$rowsPerPage));
|
||||
while ( $row = mysql_fetch_array($res) ) {
|
||||
printf("\t\t\t\t<tr>\n");
|
||||
printf("\t\t\t\t\t<td>" . $row["name"] . "</td>\n");
|
||||
printf("\t\t\t\t\t<td>" . $row["score"] . "</td>\n");
|
||||
printf("\t\t\t\t\t<td>" . $row["maxpattern"] . "</td>\n");
|
||||
printf("\t\t\t\t\t<td>" . $row["dtime"] . "</td>\n");
|
||||
printf("\t\t\t\t</tr>\n");
|
||||
}
|
||||
printf("<tr>\n");
|
||||
if ( $curPage > 0 )
|
||||
printf(" <td colspan=2 align=left><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=%d&start=%d\"><< PREVIOUS</td>\n", $rowsPerPage, (($curPage*$rowsPerPage)-$rowsPerPage));
|
||||
else
|
||||
printf(" <td colspan=2></td>\n");
|
||||
|
||||
if ( $totalRows > ($curPage * $rowsPerPage) )
|
||||
printf(" <td colspan=2 align=right><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=%d&start=%d\">NEXT >></a></td>\n", $rowsPerPage, (($curPage*$rowsPerPage)+$rowsPerPage));
|
||||
else
|
||||
printf(" <td colspan=2></td>\n");
|
||||
printf("</tr>\n");
|
||||
|
||||
printf("\t\t\t</table>\n");
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</td>
|
||||
<td valign="top" ><img src="wily.png"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<center>
|
||||
<br/><br/><i>"A fabulous tour de force..." -- Game Misinformer Bragazine</i>
|
||||
<br/><br/><i>"Quite possibly the most important thing to happen to
|
||||
<br/>video games since Shigeru Miyamoto." -- Protendo Trading Cards</i>
|
||||
<br/><br/><i>"I believe we made the most beautiful thing in the world. Nobody
|
||||
<br/>would criticize a renowned architect's blueprint that the position
|
||||
<br/>of a gate is wrong. It's the same as that." --Ken Kutaragi</i>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||