Moving stuff around, nothing to see here
git-svn-id: https://aklabs.dyndns.org/svn/aklabs/trunk/games/wilysays@50 eb184899-6090-47d4-a65b-558f62f6ea1c
292
AC_RunActiveContent.js
Executable file
@@ -0,0 +1,292 @@
|
|||||||
|
//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;
|
||||||
|
}
|
||||||
909
Game.as
Executable file
@@ -0,0 +1,909 @@
|
|||||||
|
/*
|
||||||
|
* 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()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
game.html
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
<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>
|
||||||
BIN
gfx/EXCLAMATION.png
Executable file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
gfx/FORGIVENESS.png
Executable file
|
After Width: | Height: | Size: 11 KiB |
BIN
gfx/LIFE.png
Executable file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
gfx/POINTDOUBLER.png
Executable file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
gfx/SHORTCIRCUIT.png
Executable file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
gfx/SLOWDOWN.png
Executable file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
gfx/SPEEDUP.png
Executable file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
gfx/blue-dark.png
Executable file
|
After Width: | Height: | Size: 18 KiB |
BIN
gfx/blue-light.png
Executable file
|
After Width: | Height: | Size: 19 KiB |
BIN
gfx/brushed-steel-lg.jpg
Executable file
|
After Width: | Height: | Size: 28 KiB |
BIN
gfx/circuitboard.jpg
Executable file
|
After Width: | Height: | Size: 722 KiB |
BIN
gfx/circuitboard.png
Executable file
|
After Width: | Height: | Size: 791 KiB |
BIN
gfx/cutscenes/difficultychooser.swf
Executable file
BIN
gfx/cutscenes/endscreen.swf
Executable file
BIN
gfx/cutscenes/highscore.swf
Executable file
BIN
gfx/cutscenes/intro-menu.swf
Executable file
BIN
gfx/cutscenes/tutorial.swf
Executable file
BIN
gfx/explosion.fla
Executable file
BIN
gfx/explosion.swf
Executable file
BIN
gfx/game_background.png
Executable file
|
After Width: | Height: | Size: 139 KiB |
BIN
gfx/green-dark.png
Executable file
|
After Width: | Height: | Size: 15 KiB |
BIN
gfx/green-light.png
Executable file
|
After Width: | Height: | Size: 16 KiB |
BIN
gfx/megaman_leaderboard.png
Executable file
|
After Width: | Height: | Size: 221 KiB |
BIN
gfx/progress_green.png
Executable file
|
After Width: | Height: | Size: 875 B |
BIN
gfx/progress_red.png
Executable file
|
After Width: | Height: | Size: 872 B |
BIN
gfx/red-dark.png
Executable file
|
After Width: | Height: | Size: 18 KiB |
BIN
gfx/red-light.png
Executable file
|
After Width: | Height: | Size: 20 KiB |
BIN
gfx/whole.png
Executable file
|
After Width: | Height: | Size: 129 KiB |
BIN
gfx/yellow-dark.png
Executable file
|
After Width: | Height: | Size: 19 KiB |
BIN
gfx/yellow-light.png
Executable file
|
After Width: | Height: | Size: 21 KiB |
145
help.html
Executable file
@@ -0,0 +1,145 @@
|
|||||||
|
<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>
|
||||||
|
|
||||||
|
|
||||||
BIN
help1.png
Executable file
|
After Width: | Height: | Size: 84 KiB |
BIN
help2.png
Executable file
|
After Width: | Height: | Size: 452 KiB |
134
index.php
Executable file
@@ -0,0 +1,134 @@
|
|||||||
|
<?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>
|
||||||
92
leaderboard.php
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
<?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>
|
||||||
|
</center>
|
||||||
|
<table cols=3 width=800 align="center" >
|
||||||
|
<tr>
|
||||||
|
<td valign="top" width="171" ><img src="megaman.png"/></td>
|
||||||
|
<td valign="top" >
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$totalRows = 0;
|
||||||
|
$curPage = 0;
|
||||||
|
$rowsPerPage = 5;
|
||||||
|
|
||||||
|
if ( isset($_REQUEST["perpage"]) ) {
|
||||||
|
$rowsPerPage = (int)$_REQUEST["perpage"];
|
||||||
|
}
|
||||||
|
if ( isset($_REQUEST["start"]) ) {
|
||||||
|
$curPage = ((int)$_REQUEST["start"])/$rowsPerPage
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalPages = $totalRows/$rowsPerPage;
|
||||||
|
|
||||||
|
$query = "SELECT COUNT(*) AS count FROM wilysays_highscores;"
|
||||||
|
$res = mysql_query($query, $db);
|
||||||
|
if ( $res ) {
|
||||||
|
$row = mysql_fetch_row_assoc($res);
|
||||||
|
$totalRows = $row["count"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SELECT * FROM wilysays_highscores ORDER BY score, maxpattern, dtime, name ASC LIMIT " . $rowsPerPage . " OFFSET " . ($curPage*$rowsPerPage) . ";";
|
||||||
|
|
||||||
|
///printf($query);
|
||||||
|
|
||||||
|
$res = mysql_query($query, $db);
|
||||||
|
if ( $res ) {
|
||||||
|
printf("\t\t\t<table align=center cols=4 width=379 border=1>\n");
|
||||||
|
printf("\t\t\t\t<tr><td><b>Player<br/>Name</b></td><td><b>Total<br/>Score</b></td><td><b>Longest<br/>Pattern</b></td><td><b>When<br/>Recorded</b></td></tr>\n");
|
||||||
|
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("\t\t\t</table>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td valign="top" ><img src="wily.png"/></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ( $curPage < ($totalPages-1) ) {
|
||||||
|
echo "<tr>";
|
||||||
|
echo " <td colspan=2><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=" . $rowsPerPage ."&start=". $curPage ."\"><< PREVIOUS</td>";
|
||||||
|
echo " <td colspan=2><a href=\"http://www.aklabs.net/~akesterson/wilysays/index.php?perpage=" . $rowsPerPage ."&start=". $curPage ."\">NEXT >></a></td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
megaman.png
Executable file
|
After Width: | Height: | Size: 77 KiB |
34
net/aklabs/demo/simonsays/LoadingObject.as
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
package net.aklabs.demo.simonsays {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class LoadingObject
|
||||||
|
*
|
||||||
|
* This class is used to represent a content asset while it is going through the process of being loaded
|
||||||
|
* by the Preloader class.
|
||||||
|
*/
|
||||||
|
public class LoadingObject {
|
||||||
|
public static var STATE_READY:Number = 0; // Object has been loaded and is ready
|
||||||
|
public static var STATE_LOADING:Number = 1; // Object is currently loading, not ready yet
|
||||||
|
public static var STATE_NOTFOUND:Number = 2; // Object wasn't found in the cache
|
||||||
|
public var handle:String; // Text handle for this object
|
||||||
|
public var state:Number; // State value
|
||||||
|
public var bytesRead:Number; // the amount of bytes currently read in to this object over the net
|
||||||
|
public var bytesTotal:Number; // the total byte size of this object
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LoadingObject()
|
||||||
|
*
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* arguments : none
|
||||||
|
*
|
||||||
|
* Returns : LoadingObject
|
||||||
|
*/
|
||||||
|
public function LoadingObject() {
|
||||||
|
this.handle = "";
|
||||||
|
this.state = LoadingObject.STATE_NOTFOUND;
|
||||||
|
this.bytesRead = 0;
|
||||||
|
this.bytesTotal = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
176
net/aklabs/demo/simonsays/Mastermind.as
Executable file
@@ -0,0 +1,176 @@
|
|||||||
|
package net.aklabs.demo.simonsays
|
||||||
|
{
|
||||||
|
|
||||||
|
import flash.utils.Timer;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import flash.events.TimerEvent;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import net.aklabs.demo.simonsays.Preloader;
|
||||||
|
import net.aklabs.demo.simonsays.SimonButton;
|
||||||
|
import net.aklabs.demo.simonsays.MastermindEvent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: Mastermind
|
||||||
|
*
|
||||||
|
* This class defines our "Simon Says", "Wily Lok", "Mastermind", whatever you want to call it.
|
||||||
|
* (I called it 3 or 4 different things during the course of development.)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Mastermind extends Sprite
|
||||||
|
{
|
||||||
|
protected var lightOutTimer:Timer; // timer that fires when it's time to turn off the lights
|
||||||
|
protected var lightButtons:Array; // array of custom SimonButtons that exists in Pattern.COLOR_XXX order
|
||||||
|
public var isLit:Boolean; // is the device currently lit?
|
||||||
|
|
||||||
|
public function Mastermind()
|
||||||
|
{
|
||||||
|
var preloader = Preloader.getInstance();
|
||||||
|
var lightPositions = new Array();
|
||||||
|
// this array holds pairs of (x,y) coordinates at which to place the dark/light colored
|
||||||
|
// Simon Says buttons, since they're meant to cover the existing buttons on the original graphic.
|
||||||
|
// These are hard-coded; in a better implementation, they would come from an XML or would be
|
||||||
|
// individual frames of an SWF which could be fired individually, etc. But this works.
|
||||||
|
// array idx 0: Blue, 1: Green, 2: Red, 3: Yellow
|
||||||
|
|
||||||
|
lightPositions.push( new Array(183, 187)); // blue
|
||||||
|
lightPositions.push( new Array(18, 17)); // green
|
||||||
|
lightPositions.push( new Array(185, 17)); // red
|
||||||
|
lightPositions.push( new Array(18, 186)); // yellow
|
||||||
|
|
||||||
|
// this array holds the button objects for the visible simon says buttons ...
|
||||||
|
this.lightButtons = new Array();
|
||||||
|
// just a temporary array for which images to fetch for creating the down/up button images
|
||||||
|
var fetchArray = new Array( new Array("gfx_btn_darkblue", "gfx_btn_lightblue"),
|
||||||
|
new Array("gfx_btn_darkgreen", "gfx_btn_lightgreen"),
|
||||||
|
new Array("gfx_btn_darkred", "gfx_btn_lightred"),
|
||||||
|
new Array("gfx_btn_darkyellow", "gfx_btn_lightyellow") );
|
||||||
|
// Simon Says body
|
||||||
|
var whole = preloader.getObject("gfx_mastermind");
|
||||||
|
this.addChild(whole);
|
||||||
|
|
||||||
|
for ( var i = 0; i < fetchArray.length ; i++ ) {
|
||||||
|
var btn:SimonButton = new SimonButton(preloader.getObject(fetchArray[i][1]), preloader.getObject(fetchArray[i][0]));
|
||||||
|
btn.x = lightPositions[i][0];
|
||||||
|
btn.y = lightPositions[i][1];
|
||||||
|
this.lightButtons.push(btn);
|
||||||
|
this.addChild(btn);
|
||||||
|
btn.addEventListener(MouseEvent.CLICK, this.onMouseClick); // for some reason, MouseEvent.CLICK never actually does anything?
|
||||||
|
//btn.addEventListener(MouseEvent.MOUSE_UP, this.onMouseClick);
|
||||||
|
}
|
||||||
|
this.lightOutTimer = new Timer(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flashAll(length)
|
||||||
|
*
|
||||||
|
* This function lights all the lights on the Mastermind for the given length of time
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @length:Number, the time in milliseconds for which the Mastermind should stay lit
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function flashAll(length:Number)
|
||||||
|
{
|
||||||
|
this.lightOutTimer.delay = length;
|
||||||
|
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
|
||||||
|
this.lightOutTimer.reset();
|
||||||
|
this.lightOutTimer.start();
|
||||||
|
for (var i = 0 ; i < 4 ; i++) {
|
||||||
|
// fake mouse event to light it up
|
||||||
|
this.lightButtons[i].onMouseDown(null);
|
||||||
|
}
|
||||||
|
this.isLit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lightButton(btn, activeTime)
|
||||||
|
*
|
||||||
|
* This function lights up a given button on the Mastermind. Mostly used by the Pattern when it's replaying itself.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @btn:Number, the Pattern.COLOR_XXX button that should light
|
||||||
|
* @activeTime:Number, the amount of milliseconds for which the button should stay lit
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function lightButton(btn:Number, activeTime:Number = 0 )
|
||||||
|
{
|
||||||
|
if ( btn < 4 ) {
|
||||||
|
this.lightButtons[btn].onMouseDown(null);
|
||||||
|
this.isLit = true;
|
||||||
|
}
|
||||||
|
if ( activeTime != 0 ) {
|
||||||
|
this.lightOutTimer.delay = activeTime;
|
||||||
|
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
|
||||||
|
this.lightOutTimer.reset();
|
||||||
|
this.lightOutTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* blackout()
|
||||||
|
*
|
||||||
|
* This function makes sure that all lights on the Mastermind are extinguished
|
||||||
|
*
|
||||||
|
* arguments : none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function blackout()
|
||||||
|
{
|
||||||
|
if ( this.lightButtons.length <= 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for ( var i = 0 ; i < this.lightButtons.length ; i++ ){
|
||||||
|
this.lightButtons[i].onMouseUp(null);
|
||||||
|
}
|
||||||
|
this.isLit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onTimer(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever the lightOutTimer fires, telling the lights to shut off
|
||||||
|
*
|
||||||
|
* arguments :
|
||||||
|
* @evt:Event, the event that's firing this function
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function onTimer(evt:TimerEvent)
|
||||||
|
{
|
||||||
|
if ( evt.target != this.lightOutTimer )
|
||||||
|
return;
|
||||||
|
this.lightOutTimer.removeEventListener(TimerEvent.TIMER, this.onTimer);
|
||||||
|
this.lightOutTimer.stop();
|
||||||
|
this.lightOutTimer.reset();
|
||||||
|
this.blackout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onMouseClick()
|
||||||
|
*
|
||||||
|
* This function is fired whenever the user clicks one of the Mastermind's buttons
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:Event, the event firing this function
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function onMouseClick(evt:MouseEvent)
|
||||||
|
{
|
||||||
|
// we don't do any processing here, as the SimonButton has already checked for
|
||||||
|
// per-pixel accuracy w/ the click on our abnormally shaped buttons. We just propagate
|
||||||
|
// out a new MastermindEvent for the game to catch.
|
||||||
|
for ( var i:Number = 0; i < this.lightButtons.length ; i++ ) {
|
||||||
|
if ( evt.target == this.lightButtons[i] ) {
|
||||||
|
var newEvt:MastermindEvent = new MastermindEvent(MastermindEvent.BTN_CLICKED);
|
||||||
|
newEvt.colorClicked = i;
|
||||||
|
this.dispatchEvent(newEvt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
net/aklabs/demo/simonsays/MastermindEvent.as
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
package net.aklabs.demo.simonsays
|
||||||
|
{
|
||||||
|
import flash.events.Event;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class : MastermindEvent
|
||||||
|
*
|
||||||
|
* This class basically just defines a custom event that will let the mastermind send up
|
||||||
|
* a clicked event w/ a color.
|
||||||
|
*/
|
||||||
|
public class MastermindEvent extends Event
|
||||||
|
{
|
||||||
|
public static var BTN_CLICKED:String = "MASTERMIND_BUTTON_CLICKED";
|
||||||
|
public var colorClicked:Number;
|
||||||
|
|
||||||
|
public function MastermindEvent(evtType:String)
|
||||||
|
{
|
||||||
|
super(evtType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
393
net/aklabs/demo/simonsays/Pattern.as
Executable file
@@ -0,0 +1,393 @@
|
|||||||
|
package net.aklabs.demo.simonsays
|
||||||
|
{
|
||||||
|
import flash.utils.Timer;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.TimerEvent;
|
||||||
|
import flash.events.EventDispatcher;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.display.Bitmap;
|
||||||
|
import net.aklabs.demo.simonsays.Mastermind;
|
||||||
|
import net.aklabs.demo.simonsays.Powerup;
|
||||||
|
import net.aklabs.demo.simonsays.PowerupEvent;
|
||||||
|
import net.aklabs.demo.simonsays.Preloader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class Pattern
|
||||||
|
*
|
||||||
|
* This class defines a "pattern", which is where most of the game challenge exists.
|
||||||
|
* It just defines the pattern currently being traced out on the Simon Says/Mastermind/etc
|
||||||
|
*
|
||||||
|
* In addition to doing processing, this class also does some graphical representation,
|
||||||
|
* in the way of a series of red/green lights to show how far along the player is inside the
|
||||||
|
* pattern. The image is 16 pixels wide, and (16*maxSize) pixels tall.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Pattern extends Sprite
|
||||||
|
{
|
||||||
|
public static var COLOR_BLUE:Number = 0;
|
||||||
|
public static var COLOR_GREEN:Number = 1;
|
||||||
|
public static var COLOR_RED:Number = 2;
|
||||||
|
public static var COLOR_YELLOW:Number = 3;
|
||||||
|
|
||||||
|
protected var patternTimer:Timer; // timer that fires to check pattern logic independently of game timer
|
||||||
|
protected var curIndex:Number; // amount of the pattern currently finished
|
||||||
|
protected var pattern:Array; // the array of colors that make up the actual pattern
|
||||||
|
protected var simon:Mastermind; // A link back up to the parent Mastermind (put here because I didn't want to assume that this.parent would always be correct)
|
||||||
|
protected var delay:Number; // The number of milliseconds that should pass before the logic timer fires
|
||||||
|
protected var playCount:Number; // The number of times this pattern has been played through (via Forgiveness). Not currently used for anything.
|
||||||
|
public var clearTime:Number; // the amount of time the player has (in milliseconds) to finish the pattern
|
||||||
|
public var state:Number; // state of the pattern at current
|
||||||
|
public static var STATE_RUNNING = 0; // STATE : pattern is currently "running" - e.g., waiting for input from the player and checking logic
|
||||||
|
public static var STATE_DEMO = 1; // STATE : pattern is currently "demoing", e.g., flashing the lights up to this.curIndex of the pattern
|
||||||
|
public static var STATE_FAILED = 2; // STATE : pattern is stopped and the player screwed up
|
||||||
|
public static var STATE_CORRECT = 3; // STATE : pattern is stopped and the player got the last iteration correct
|
||||||
|
public static var STATE_STOPPED = 4; // STATE : pattern is just stopped w/ no further info
|
||||||
|
public static var STATE_COMPLETE = 5; // STATE : pattern is stopped because the player has finished all iterations of this pattern
|
||||||
|
public var score:Number; // Score currently built up in this pattern
|
||||||
|
protected var maxSize:Number; // Maximum length of the pattern
|
||||||
|
public var patternPowerups:Array; // array of powerups assigned to any given button on this pattern
|
||||||
|
protected var scoreMultiplier:Number; // Set by powerup, the multiplier for current score (default x1)
|
||||||
|
protected var clearDecrement:Number; // Set by powerup, defines how quickly the pattern's timer runs
|
||||||
|
protected var progressLights:Array; // An array of bitmaps equal in length to the pattern; all the lights up to this.curIndex will be green, the rest are red
|
||||||
|
protected var level:Number; // The level of pattern which this is (mainly used for calculating pattern length, could probly be scrapped)
|
||||||
|
protected var difficulty:Number; // The difficulty of the pattern (used in calculating timer speed)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pattern()
|
||||||
|
*
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @levelNumber:Number, the level number for which this pattern is being made
|
||||||
|
* @simon:Mastermind, the Mastermind object to which this pattern is to be applied (default null)
|
||||||
|
* @difficulty:Number, the difficulty level for this pattern (default 1)
|
||||||
|
*
|
||||||
|
* Returns: Pattern
|
||||||
|
*/
|
||||||
|
public function Pattern(levelNumber:Number, simon:Mastermind = null, difficulty:Number = 1)
|
||||||
|
{
|
||||||
|
this.state = 0;
|
||||||
|
this.simon = simon;
|
||||||
|
this.level = levelNumber;
|
||||||
|
this.difficulty = difficulty;
|
||||||
|
this.curIndex = -1;
|
||||||
|
this.maxSize = 2+levelNumber; // smallest pattern will never be less than 3 lights total
|
||||||
|
this.pattern = new Array();
|
||||||
|
this.patternPowerups = new Array();
|
||||||
|
this.progressLights = new Array();
|
||||||
|
this.patternTimer = null;
|
||||||
|
this.delay = 1000;
|
||||||
|
this.playCount = 0;
|
||||||
|
this.clearTime = 0;
|
||||||
|
this.score = 0;
|
||||||
|
this.scoreMultiplier = 1;
|
||||||
|
this.clearDecrement = 0;
|
||||||
|
this.patternTimer = new Timer(0);
|
||||||
|
|
||||||
|
this.addEventListener(PowerupEvent.USED_POWERUP, this.onUsedPowerup);
|
||||||
|
|
||||||
|
var preloader:Preloader = Preloader.getInstance();
|
||||||
|
var newLight:Bitmap;
|
||||||
|
// populate all the red lights for this pattern that will turn green as the player goes on
|
||||||
|
for ( var i:Number = 0; i < this.maxSize ; i++ ) {
|
||||||
|
newLight = preloader.getBitmap("gfx_progress_red");
|
||||||
|
newLight.x = 0;
|
||||||
|
newLight.y = i*16;
|
||||||
|
if ( i > 15 ) {
|
||||||
|
newLight.x += 20;
|
||||||
|
newLight.y = (i-15)*16;
|
||||||
|
}
|
||||||
|
this.progressLights.push(newLight);
|
||||||
|
this.addChild(newLight);
|
||||||
|
}
|
||||||
|
this.complexify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* patternLength()
|
||||||
|
*
|
||||||
|
* Just a getter for the length of the pattern
|
||||||
|
*
|
||||||
|
* arguments : none
|
||||||
|
*
|
||||||
|
* Returns : Number
|
||||||
|
*/
|
||||||
|
public function patternLength():Number
|
||||||
|
{
|
||||||
|
return this.pattern.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* forceState()
|
||||||
|
*
|
||||||
|
* Forces a given state onto the pattern
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function forceState(state:Number)
|
||||||
|
{
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* complexify()
|
||||||
|
*
|
||||||
|
* This function adds another element to the pattern, so that it becomes a longer pattern, up until the maximum length of the pattern
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function complexify()
|
||||||
|
{
|
||||||
|
// we're complete if we're beyond the maximum size
|
||||||
|
if ( this.pattern.length >= this.maxSize ) {
|
||||||
|
this.stop();
|
||||||
|
this.state = Pattern.STATE_COMPLETE;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// reset the score multiplier and such 'cause complexify only gets called at the end of a round
|
||||||
|
this.scoreMultiplier = 1;
|
||||||
|
this.state = Pattern.STATE_STOPPED;
|
||||||
|
this.stop(); // -- wtf why did I call stop on myself? ...
|
||||||
|
var newcolor = (Math.round(int(Math.random()*4)));
|
||||||
|
this.pattern.push(newcolor);
|
||||||
|
// create a new powerup ~20% of the time that complexify is ran
|
||||||
|
if ( Math.random() < 0.20 ) {
|
||||||
|
var powerup = new Powerup();
|
||||||
|
powerup.pType = (Math.round(int(Math.random()*Powerup.PTYPE_MAXVALUE)));
|
||||||
|
powerup.imgHandle = Powerup.POWERUP_IMAGES[powerup.pType];
|
||||||
|
powerup.sndHandle = Powerup.POWERUP_SOUNDS[powerup.pType];
|
||||||
|
this.patternPowerups.push(powerup);
|
||||||
|
} else {
|
||||||
|
this.patternPowerups.push(null);
|
||||||
|
}
|
||||||
|
this.clearTime = 2000 * ( this.pattern.length );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* play(lightSimon)
|
||||||
|
*
|
||||||
|
* This function tells the pattern to start playback in one of two modes; demo, or running. Demo mode
|
||||||
|
* just has the pattern playing itself back via the lights on the Mastermind. The running mode doesn't
|
||||||
|
* do any playback, it just checks logic.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @lightSimon:Boolean, set this to True to run in Demo mode (default false)
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function play(lightSimon:Boolean = false)
|
||||||
|
{
|
||||||
|
if ( this.patternTimer ) {
|
||||||
|
this.patternTimer.reset()
|
||||||
|
} else {
|
||||||
|
this.patternTimer = new Timer( this.delay );
|
||||||
|
}
|
||||||
|
if ( lightSimon ){
|
||||||
|
this.state = Pattern.STATE_DEMO;
|
||||||
|
this.patternTimer.delay = 1000;
|
||||||
|
this.patternTimer.addEventListener(TimerEvent.TIMER, this.onDemoTimer);
|
||||||
|
} else {
|
||||||
|
this.state = Pattern.STATE_RUNNING;
|
||||||
|
this.patternTimer.delay = 25;
|
||||||
|
this.clearDecrement = this.patternTimer.delay + (this.level*(this.difficulty));
|
||||||
|
this.patternTimer.addEventListener(TimerEvent.TIMER, this.onRunningTimer);
|
||||||
|
}
|
||||||
|
this.patternTimer.start();
|
||||||
|
this.playCount += 1;
|
||||||
|
this.curIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stop()
|
||||||
|
*
|
||||||
|
* Stop all logic/running status on the pattern
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function stop()
|
||||||
|
{
|
||||||
|
if ( this.patternTimer ) {
|
||||||
|
this.patternTimer.removeEventListener(TimerEvent.TIMER, this.onDemoTimer);
|
||||||
|
this.patternTimer.removeEventListener(TimerEvent.TIMER, this.onRunningTimer);
|
||||||
|
}
|
||||||
|
this.curIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getIndex()
|
||||||
|
*
|
||||||
|
* Gets the current value is curIndex
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function getIndex()
|
||||||
|
{
|
||||||
|
return this.curIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getActive()
|
||||||
|
*
|
||||||
|
* OBSOLETE - gets the currecntly active color. This isn't as useful since the input checking method changed around v0.12.
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
* Returns : Number, -1 on failure, >= 0 on success
|
||||||
|
*/
|
||||||
|
public function getActive()
|
||||||
|
{
|
||||||
|
if ( (this.curIndex < this.pattern.length) && (this.curIndex >= 0) ) {
|
||||||
|
return this.pattern[this.curIndex];
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resetLights()
|
||||||
|
*
|
||||||
|
* This function makes sure the ratio of red:green lights in the progress lights is correct
|
||||||
|
* according to the value of curIndex
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function resetLights()
|
||||||
|
{
|
||||||
|
var preloader:Preloader = Preloader.getInstance();
|
||||||
|
var newLight:Bitmap;
|
||||||
|
for ( var i:Number = 0; i <= this.curIndex ; i++ ) {
|
||||||
|
// remove any existing red lights and replace them with green lights
|
||||||
|
// if they're at an index < curIndex
|
||||||
|
this.removeChild(this.progressLights[i]);
|
||||||
|
newLight = preloader.getBitmap("gfx_progress_green");
|
||||||
|
newLight.x = this.progressLights[i].x;
|
||||||
|
newLight.y = this.progressLights[i].y;
|
||||||
|
this.progressLights[i] = newLight;
|
||||||
|
this.addChild(this.progressLights[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* colorActive(color)
|
||||||
|
*
|
||||||
|
* Checks to see if the given color is the one currently active on the pattern.
|
||||||
|
* Also updates the current index, modifies state, etc, depending on the result.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @color:Number, the Pattern.COLOR_XXX color you want checked
|
||||||
|
*
|
||||||
|
* Returns: Boolean (Always returns false on a stopped pattern)
|
||||||
|
*/
|
||||||
|
public function colorActive(color:Number):Boolean
|
||||||
|
{
|
||||||
|
if ( this.curIndex == -1 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( (this.curIndex < this.pattern.length) && (this.pattern[this.curIndex] == color) ) {
|
||||||
|
// dispatch a PowerupEvent if there is a powerup in this spot at the pattern
|
||||||
|
if ( this.patternPowerups[this.curIndex] != null ) {
|
||||||
|
this.dispatchEvent(new PowerupEvent(PowerupEvent.GOT_POWERUP, this.patternPowerups[this.curIndex]));
|
||||||
|
this.patternPowerups[this.curIndex] = null;
|
||||||
|
}
|
||||||
|
this.resetLights();
|
||||||
|
this.curIndex += 1;
|
||||||
|
this.score += 5;
|
||||||
|
if ( this.curIndex >= this.pattern.length ) {
|
||||||
|
this.curIndex = -1;
|
||||||
|
this.state = Pattern.STATE_CORRECT;
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.state = Pattern.STATE_FAILED;
|
||||||
|
this.stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onRunningTimer(evt)
|
||||||
|
*
|
||||||
|
* Fires along w/ the runningTimer to check pattern logic
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:Event, event firing this function
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function onRunningTimer(evt:TimerEvent)
|
||||||
|
{
|
||||||
|
if ( (!evt) || (evt.target != this.patternTimer) )
|
||||||
|
return;
|
||||||
|
this.clearTime -= this.clearDecrement;
|
||||||
|
if ( this.clearTime < 0 ) {
|
||||||
|
this.clearTime = 0;
|
||||||
|
this.state = Pattern.STATE_FAILED;
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onDemoTimer(evt)
|
||||||
|
*
|
||||||
|
* Runs every time the Demo timer fires, lighting the buttons in sequence at the right times
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:Event, the event firing this function
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function onDemoTimer(evt:TimerEvent)
|
||||||
|
{
|
||||||
|
if ( (!evt) || (evt.target != this.patternTimer) || (!this.simon) )
|
||||||
|
return;
|
||||||
|
if ( this.curIndex >= this.pattern.length ) {
|
||||||
|
this.state = Pattern.STATE_STOPPED;
|
||||||
|
this.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.simon.lightButton(this.pattern[curIndex], this.patternTimer.delay/2);
|
||||||
|
this.curIndex += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onUsedPowerup(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever a PowerupEvent filters down from the Mastermind, which originally
|
||||||
|
* filtered up from the Player. It processes and applies the effects of any powerups used by the player.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:PowerupEvent, the event firing this function
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function onUsedPowerup(evt:PowerupEvent)
|
||||||
|
{
|
||||||
|
var pwup:Powerup = evt.pwup;
|
||||||
|
if ( pwup.pType == Powerup.PTYPE_FORGIVENESS ) {
|
||||||
|
// we don't actually have to *do* anything with a forgiveness ...
|
||||||
|
return;
|
||||||
|
} else if ( pwup.pType == Powerup.PTYPE_SLOWDOWN ) {
|
||||||
|
this.clearDecrement = 1;
|
||||||
|
} else if ( pwup.pType == Powerup.PTYPE_SKIP ) {
|
||||||
|
this.state = Pattern.STATE_CORRECT;
|
||||||
|
this.stop();
|
||||||
|
this.resetLights();
|
||||||
|
} else if ( pwup.pType == Powerup.PTYPE_DOUBLE ) {
|
||||||
|
this.scoreMultiplier = 2;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
228
net/aklabs/demo/simonsays/Player.as
Executable file
@@ -0,0 +1,228 @@
|
|||||||
|
package net.aklabs.demo.simonsays
|
||||||
|
{
|
||||||
|
import net.aklabs.demo.simonsays.PowerupEvent;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import net.aklabs.demo.simonsays.Preloader;
|
||||||
|
import flash.display.Bitmap;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class Player
|
||||||
|
*
|
||||||
|
* This class represents the player in the game.
|
||||||
|
*
|
||||||
|
* The class has two displayable objects in it: the Player object itself,
|
||||||
|
* and Player.lifeDisplay. The Player object displays the inventory (64 pixels high, up to (64*5) pixels wide)
|
||||||
|
* The Player.lifeDisplay object displays the remaining number of lives (64 pixels high, up to 64*3 pixels wide)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Player extends Sprite {
|
||||||
|
public var score:Number; // the player's current score
|
||||||
|
public var lives:Number; // the number of lives the player currently has
|
||||||
|
public var maxPattern:Number; // the largest pattern the player has completed
|
||||||
|
public var inventory:Array; // the player's inventory
|
||||||
|
public var lifeDisplay:Sprite; /* the parent sprite to which all the player life sprites are attached (number of remaining lives) ..
|
||||||
|
we have this parenting the rest of the images, so the Game class can just add this single child object, rather than tracking
|
||||||
|
and removing all the images in the individual lifeImages array */
|
||||||
|
protected var lifeImages:Array; // an array of images holding all the images showing up in the player's life array
|
||||||
|
protected var headExplosion;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Player()
|
||||||
|
*
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* arguments : none
|
||||||
|
*
|
||||||
|
* Returns : none
|
||||||
|
*/
|
||||||
|
public function Player()
|
||||||
|
{
|
||||||
|
this.score = 0;
|
||||||
|
this.lives = 3;
|
||||||
|
this.maxPattern = 0;
|
||||||
|
this.inventory = new Array();
|
||||||
|
this.lifeDisplay = new Sprite();
|
||||||
|
this.lifeImages = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addPowerup(pwup)
|
||||||
|
*
|
||||||
|
* Adds a new powerup to the player's inventory
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @pwup:Powerup, the powerup to be added
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function addPowerup(pwup:Powerup)
|
||||||
|
{
|
||||||
|
if ( this.inventory.length >= 5 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.inventory.push(pwup);
|
||||||
|
this.resetPowerupPositions();
|
||||||
|
this.addChild(pwup);
|
||||||
|
pwup.addEventListener(MouseEvent.MOUSE_UP, this.onPowerupClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resetPowerupPositions()
|
||||||
|
*
|
||||||
|
* This function goes through the player's inventory and makes sure the positions line up (mostly) with the background graphic for their slot
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
protected function resetPowerupPositions()
|
||||||
|
{
|
||||||
|
for ( var i = 0; i < this.inventory.length ; i++ ) {
|
||||||
|
var pwup:Powerup = this.inventory[i];
|
||||||
|
pwup.x = 2+(70*i);
|
||||||
|
pwup.y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* die()
|
||||||
|
*
|
||||||
|
* This function is called whenever the player should die - lose a life
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function die()
|
||||||
|
{
|
||||||
|
// lose a life, and do it in style
|
||||||
|
var preloader:Preloader = Preloader.getInstance();
|
||||||
|
this.headExplosion = preloader.getMovieClip("movie_explosion");
|
||||||
|
this.headExplosion.addEventListener(Event.ENTER_FRAME, this.stopExplosion);
|
||||||
|
this.headExplosion.x = (this.lives * 64)-32;
|
||||||
|
this.headExplosion.y = 32;
|
||||||
|
this.lifeDisplay.addChild(this.headExplosion);
|
||||||
|
this.headExplosion.play();
|
||||||
|
preloader.playSound("sfx_explosion");
|
||||||
|
this.lives -= 1;
|
||||||
|
this.resetLifePositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stopExplosion(evt)
|
||||||
|
*
|
||||||
|
* This stops the head explosion animation from looping (much like Game.onNonLoopEnterFrame)
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:Event, the event firing this function
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function stopExplosion(evt:Event)
|
||||||
|
{
|
||||||
|
if ( evt.target.currentFrame == evt.target.totalFrames ) {
|
||||||
|
this.headExplosion.stop();
|
||||||
|
this.lifeDisplay.removeChild(this.headExplosion);
|
||||||
|
this.headExplosion.removeEventListener(Event.ENTER_FRAME, this.stopExplosion);
|
||||||
|
this.headExplosion = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resetLifePositions()
|
||||||
|
*
|
||||||
|
* This function arranges the images representing the number of remaining lives the player has
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* returns : none
|
||||||
|
*/
|
||||||
|
public function resetLifePositions()
|
||||||
|
{
|
||||||
|
var i:Number = 0;
|
||||||
|
var preloader:Preloader = Preloader.getInstance();
|
||||||
|
if ( this.lifeImages.length < this.lives ) {
|
||||||
|
for ( i = this.lifeImages.length; i < this.lives; i++ ) {
|
||||||
|
var img:Bitmap = preloader.getBitmap("gfx_pwup_freelife");
|
||||||
|
img.x = 64*i;
|
||||||
|
img.y = 0;
|
||||||
|
this.lifeImages.push(img);
|
||||||
|
this.lifeDisplay.addChild(img);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ( var i = 0; i < this.lifeImages.length ; i++ ) {
|
||||||
|
if ( i >= this.lives ) {
|
||||||
|
this.lifeDisplay.removeChild(this.lifeImages[i]);
|
||||||
|
this.lifeImages.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( var i = 0; i < this.lifeImages.length ; i++ ) {
|
||||||
|
this.lifeImages[i].x = 64*i;
|
||||||
|
this.lifeImages[i].y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* usePowerupAt(index)
|
||||||
|
*
|
||||||
|
* See if there is a powerup at index 'index' in the inventory, use it, fire off any sounds associated with it,
|
||||||
|
* and dispatch a new PowerupEvent for it
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @index:Number, the index in inventory from which the powerup should be drawn
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function usePowerupAt(index:Number)
|
||||||
|
{
|
||||||
|
if ( index < this.inventory.length ) {
|
||||||
|
this.removeChild(this.inventory[index]);
|
||||||
|
var preloader:Preloader = Preloader.getInstance();
|
||||||
|
preloader.playSound(this.inventory[index].sndHandle);
|
||||||
|
this.resetPowerupPositions();
|
||||||
|
this.dispatchEvent(new PowerupEvent(PowerupEvent.USED_POWERUP, this.inventory[index]));
|
||||||
|
this.inventory[index].removeEventListener(MouseEvent.MOUSE_UP, this.onPowerupClicked);
|
||||||
|
this.inventory.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onPowerupClicked(evt)
|
||||||
|
*
|
||||||
|
* This function is fired whenever the player clicks the mouse on a powerup owned by the player
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:MouseEvent, the event firing this function
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function onPowerupClicked(evt:MouseEvent)
|
||||||
|
{
|
||||||
|
for ( var i:Number = 0 ; i < this.inventory.length ; i++ ) {
|
||||||
|
if ( this.inventory[i] == evt.target ) {
|
||||||
|
this.usePowerupAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clearInventory()
|
||||||
|
*
|
||||||
|
* Fairly obvious, this function just clears out the inventory
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function clearInventory()
|
||||||
|
{
|
||||||
|
for ( var i:Number = 0; i < this.inventory.length ; i++ ) {
|
||||||
|
this.removeChild(this.inventory[i]);
|
||||||
|
this.inventory.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
net/aklabs/demo/simonsays/Powerup.as
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
package net.aklabs.demo.simonsays {
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import net.aklabs.demo.simonsays.PowerupEvent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class Powerup
|
||||||
|
*
|
||||||
|
* This class just represents a powerup in the game.
|
||||||
|
* This is more a data structure than a class, but I don't think
|
||||||
|
* AS 3.0 has just bare structures. Silly ECMA language...
|
||||||
|
*/
|
||||||
|
public class Powerup extends Sprite
|
||||||
|
{
|
||||||
|
public static var PTYPE_SLOWDOWN:Number = 0; /* SLOWDOWN - Slows the pattern timer to a much lower rate */
|
||||||
|
public static var PTYPE_FORGIVENESS:Number = 1; /* FORGIVENESS - If you have FORGIVENESSS in your inventory and you miss a pattern, it doesn't stop you */
|
||||||
|
public static var PTYPE_SKIP:Number = 2; /* SKIP - Lets you "skip" a given pattern iteration, and you still get all the score for it. */
|
||||||
|
public static var PTYPE_DOUBLE:Number = 3; /* DOUBLE - Score double points for the pattern on which you use this powerup. */
|
||||||
|
public static var PTYPE_MAXVALUE:Number = 4;
|
||||||
|
// POWERUP_IMAGES - these are the image handles (stored in an array where idx => PTYPE_XXX) for each of the powerup types
|
||||||
|
public static var POWERUP_IMAGES = new Array("gfx_pwup_slowdown", "gfx_pwup_forgiveness", "gfx_pwup_exclamation", "gfx_pwup_pointdoubler");
|
||||||
|
// POWERUP_SOUNDS - these are the sound handles (stored in an array where idx => PTYPE_XXX) for each of the powerup types
|
||||||
|
public static var POWERUP_SOUNDS = new Array("sfx_slowdown", "sfx_forgiveness", "sfx_exclamation", "sfx_pointdoubler");
|
||||||
|
public var imgHandle:String; // the handle for the image of this specific powerup
|
||||||
|
public var sndHandle:String; // the handle for the sound of this specific powerup
|
||||||
|
public var pType:Number; // the PTYPE_XXX of this powerup
|
||||||
|
}
|
||||||
|
}
|
||||||
32
net/aklabs/demo/simonsays/PowerupEvent.as
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
package net.aklabs.demo.simonsays {
|
||||||
|
import flash.events.Event;
|
||||||
|
import net.aklabs.demo.simonsays.Powerup;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class PowerupEvent
|
||||||
|
*
|
||||||
|
* An event specifically made for actions taken regarding powerups
|
||||||
|
*/
|
||||||
|
public class PowerupEvent extends Event {
|
||||||
|
public static var GOT_POWERUP:String = "SIMONSAYS_GOT_POWERUP"; // Type for events when a powerup was received
|
||||||
|
public static var USED_POWERUP:String = "SIMONSAYS_USED_POWERUP"; // Type for events when a powerup was used
|
||||||
|
public var pwup:Powerup; // the powerup (rather than the target) of this event
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PowerupEvent()
|
||||||
|
*
|
||||||
|
* Default Constructor
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evtType:String, the type of this event (GOT_POWERUP or USED_POWERUP)
|
||||||
|
* @tgt:Powerup, the Powerup object that's being affected by this event
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function PowerupEvent(evtType:String, tgt:Powerup = null)
|
||||||
|
{
|
||||||
|
super(evtType);
|
||||||
|
this.pwup = tgt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
529
net/aklabs/demo/simonsays/Preloader.as
Executable file
@@ -0,0 +1,529 @@
|
|||||||
|
package net.aklabs.demo.simonsays {
|
||||||
|
|
||||||
|
import net.aklabs.demo.simonsays.LoadingObject;
|
||||||
|
import flash.utils.Dictionary;
|
||||||
|
import flash.net.URLRequest;
|
||||||
|
import flash.display.Loader;
|
||||||
|
import flash.display.LoaderInfo;
|
||||||
|
import flash.display.Bitmap;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
import flash.text.TextField;
|
||||||
|
import flash.text.TextFormat;
|
||||||
|
import flash.text.TextFieldAutoSize;
|
||||||
|
import flash.media.Sound;
|
||||||
|
import flash.display.MovieClip;
|
||||||
|
import flash.events.IOErrorEvent;
|
||||||
|
import flash.events.SecurityErrorEvent;
|
||||||
|
import flash.events.ProgressEvent;
|
||||||
|
import flash.events.Event;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class Preloader
|
||||||
|
*
|
||||||
|
* This class is what loads and manages the cache of media assets for the game
|
||||||
|
* This class is a singleton, which was annoyingly difficulty to implement in
|
||||||
|
* Actionscript 3 because it doesn't support private constructors.
|
||||||
|
*
|
||||||
|
* Be careful subclassing this, because of the way the singleton mechanism was implemented,
|
||||||
|
* it may break.
|
||||||
|
*
|
||||||
|
* This class can be added as a child asset, and it will display a pair of progress
|
||||||
|
* bars as it loads all the assets. The top bar is the progress on the current file,
|
||||||
|
* the bottom bar is the progress on the total set of assets. You don't have to display the
|
||||||
|
* preloader, but if you do, make sure to load via the assets array, rather than calling loadImage()
|
||||||
|
* and such manually, as the progress bars will act funky.
|
||||||
|
*
|
||||||
|
* When the preloader has loaded all of the assets, it will dispatch a COMPLETE event that should be handled
|
||||||
|
* by whatever higher game class, as a signal that all assets are ready and cached.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Preloader extends Sprite {
|
||||||
|
protected var objects:Dictionary; // this contains all loaded objects, keyed by their handle
|
||||||
|
protected var loading_by_instance:Dictionary; // this contains the [handle, bytes read, bytes total] of all objects that are currently loading, keyed by their instance
|
||||||
|
protected var loading_by_handle:Dictionary; // this contains the [instance, bytes read, bytes total] of all objects that are currently loading, keyed by their handle
|
||||||
|
protected static var instance:Preloader = null; // the singleton instance
|
||||||
|
protected var curAsset:Number; // the index of the asset (in the assets array) currently being loaded
|
||||||
|
|
||||||
|
protected var assets:Array; // the array of all the assets to be loaded
|
||||||
|
/* format of the 'assets' array:
|
||||||
|
[ ASSET_ARRAY, ASSET_ARRAY ...]
|
||||||
|
|
||||||
|
each ASSET_ARRAY is...
|
||||||
|
|
||||||
|
["images"|"sounds"|"movies", "TEXT HANDLE", "URI", "CLASS NAME"]
|
||||||
|
|
||||||
|
... The "images"|"sounds"|"movies" serves an obvious purpose; it says what kind of asset we're loading,
|
||||||
|
as the mechanism for loading images/sounds/movies are different.
|
||||||
|
|
||||||
|
The TEXT HANDLE is a text handle that can be used when referencing this asset in the preloader
|
||||||
|
|
||||||
|
The URI is just that, the URI where this object can be found. Usual security restrictions apply.
|
||||||
|
|
||||||
|
The CLASS NAME is only important for exported SWF movies, and must equal whatever the class name is
|
||||||
|
that you set for that SWF when telling Flash to export it for Actionscript. If this is wrong, or you
|
||||||
|
don't export your SWFs for actionscript, you won't be able to instantiate new MovieClip/Sprites of them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected var loadingLabel:TextField; // just a text label that says "Please wait; loading"
|
||||||
|
protected var progressSpinner:Array = new Array("-", "\\", "|", "/"); // an array of characters that creates a spinner for the loading label
|
||||||
|
protected var progSpin:Number = 0; // the current index in the progressSpinner array
|
||||||
|
protected var classDefs:Dictionary; // classDefs holds the class definitions for each of the given objects (if supplied), keyed by text handle
|
||||||
|
protected var classNames:Dictionary; // classNames holds the name of the classes for each of the given objects (if supplied), keyed by text handle
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getInstance()
|
||||||
|
*
|
||||||
|
* Returns the instance of the singleton
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* Returns: Preloader
|
||||||
|
*/
|
||||||
|
public static function getInstance():Preloader
|
||||||
|
{
|
||||||
|
if ( Preloader.instance == null )
|
||||||
|
Preloader.instance = new Preloader();
|
||||||
|
return Preloader.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Preloader(assets)
|
||||||
|
*
|
||||||
|
* Default constructor for Preloader
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @assets:Array, the asset array to be loaded (default null)
|
||||||
|
*
|
||||||
|
* Returns: none
|
||||||
|
*/
|
||||||
|
public function Preloader(assets:Array = null)
|
||||||
|
{
|
||||||
|
if ( Preloader.instance != null )
|
||||||
|
throw("Don't use (new Preloader()) directly, use Preloader.getInstance() to prevent duplication of this singleton class.");
|
||||||
|
this.objects = new Dictionary();
|
||||||
|
this.loading_by_instance = new Dictionary();
|
||||||
|
this.loading_by_handle = new Dictionary();
|
||||||
|
Preloader.instance = this;
|
||||||
|
this.curAsset = 0;
|
||||||
|
if ( assets != null)
|
||||||
|
this.assets = assets;
|
||||||
|
var labelFormat = new TextFormat();
|
||||||
|
labelFormat.font = "Courier New";
|
||||||
|
labelFormat.bold = false;
|
||||||
|
labelFormat.color = 0xFFFFFF;
|
||||||
|
labelFormat.size = 12;;
|
||||||
|
this.loadingLabel = new TextField();
|
||||||
|
this.loadingLabel.background = false;
|
||||||
|
this.loadingLabel.autoSize = TextFieldAutoSize.LEFT;
|
||||||
|
this.loadingLabel.defaultTextFormat = labelFormat;
|
||||||
|
this.loadingLabel.text = "Please wait; loading |"
|
||||||
|
this.loadingLabel.x = 0;
|
||||||
|
this.loadingLabel.y = 0;
|
||||||
|
this.addChild(loadingLabel);
|
||||||
|
this.classDefs = new Dictionary();
|
||||||
|
this.classNames = new Dictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setAssets(assets)
|
||||||
|
*
|
||||||
|
* Set the asset array for the preloader
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @assets:Array, the array of assets
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function setAssets(assets:Array)
|
||||||
|
{
|
||||||
|
this.assets = assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loadAssets()
|
||||||
|
*
|
||||||
|
* Start loading all the assets
|
||||||
|
*
|
||||||
|
* arguments: none
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function loadAssets()
|
||||||
|
{
|
||||||
|
this.onLoadComplete(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getObject(handle)
|
||||||
|
*
|
||||||
|
* Get a generic Object referenced by the given handle
|
||||||
|
*
|
||||||
|
* argument:
|
||||||
|
* @handle:String, the text handle of the object you want
|
||||||
|
*
|
||||||
|
* returns: object you want, or null
|
||||||
|
*/
|
||||||
|
public function getObject(handle:String)
|
||||||
|
{
|
||||||
|
if ( this.objects[handle] )
|
||||||
|
return this.objects[handle];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getBitmap(handle:String)
|
||||||
|
*
|
||||||
|
* This function returns a CLONE of a Bitmap object in the preloader. Use this when
|
||||||
|
* you want a bitmap that you can use in more than one place, e.g., more like a sprite.
|
||||||
|
* All instances will reference the same bitmap data, however, so any modification to
|
||||||
|
* the core bitmap data will show up in all instances.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @handle:String, the text handle reference for the bitmap you want
|
||||||
|
*
|
||||||
|
* returns Bitmap on success, null on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function getBitmap(handle:String)
|
||||||
|
{
|
||||||
|
var obj = this.getObject(handle);
|
||||||
|
if ( (obj) && (obj is Bitmap) ) {
|
||||||
|
var bm = new Bitmap(obj.bitmapData);
|
||||||
|
return bm;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getBitmap(handle:String)
|
||||||
|
*
|
||||||
|
* This function returns a CLONE of a MovieClip object in the preloader. Use this when
|
||||||
|
* you want a MovieClip that you can use in more than one place, e.g., more like a sprite.
|
||||||
|
* All instances will reference the same frame data, however, so any modification to
|
||||||
|
* the core frame data will show up in all instances.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @handle:String, the text handle reference for the bitmap you want
|
||||||
|
*
|
||||||
|
* returns MovieClip on success, null on failure
|
||||||
|
*/
|
||||||
|
public function getMovieClip(handle:String):MovieClip
|
||||||
|
{
|
||||||
|
var obj = this.getObject(handle);
|
||||||
|
try {
|
||||||
|
var clip:Class = this.classDefs[handle];
|
||||||
|
if ( clip ) {
|
||||||
|
return new clip();
|
||||||
|
}
|
||||||
|
} catch (error:Error) {
|
||||||
|
trace(error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* startObject(obj, handle)
|
||||||
|
*
|
||||||
|
* Start loading the given object with the given handle. Sets up event handling for notifications on the event while it loads.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @obj:Loader|Sound, either a Loader or a Sound object, referencing the object which has already had its URI set and begun loading
|
||||||
|
* @handle:String, the text string by which this object should be referenced
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function startObject(obj, handle:String)
|
||||||
|
{
|
||||||
|
var toadd = obj;
|
||||||
|
if ( obj is Loader ) {
|
||||||
|
toadd = obj.contentLoaderInfo;
|
||||||
|
}
|
||||||
|
toadd.addEventListener(Event.COMPLETE, this.onLoadComplete);
|
||||||
|
toadd.addEventListener(ProgressEvent.PROGRESS, this.onProgressUpdate);
|
||||||
|
toadd.addEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
|
||||||
|
toadd.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onSecurityError);
|
||||||
|
this.loading_by_instance[toadd] = new Array(handle, 0, 0);
|
||||||
|
this.loading_by_handle[handle] = new Array(obj, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stopObject(obj)
|
||||||
|
*
|
||||||
|
* Stops loading on a given object, unhooks all the event listeners, etc
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @obj:Loader|Sound, the object on which loading should stop
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function stopObject(obj)
|
||||||
|
{
|
||||||
|
var obj_info = this.loading_by_instance[obj];
|
||||||
|
obj.removeEventListener(Event.COMPLETE, this.onLoadComplete);
|
||||||
|
obj.removeEventListener(ProgressEvent.PROGRESS, this.onProgressUpdate);
|
||||||
|
obj.removeEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
|
||||||
|
obj.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onSecurityError);
|
||||||
|
delete this.loading_by_handle[this.loading_by_instance[obj][0]];
|
||||||
|
delete this.loading_by_instance[obj];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getObjectStatus(handle)
|
||||||
|
*
|
||||||
|
* Returns a LoadingObject object that describes the current loading status of the object you're inquiring about
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @handle:String, the handle of the object you want to know about
|
||||||
|
*
|
||||||
|
* returns : LoadingObject
|
||||||
|
*/
|
||||||
|
public function getObjectStatus(handle:String):LoadingObject
|
||||||
|
{
|
||||||
|
var objStats = new LoadingObject();
|
||||||
|
objStats.handle = handle;
|
||||||
|
if ( this.objects[handle] ) {
|
||||||
|
objStats.state = LoadingObject.STATE_READY;
|
||||||
|
} else if ( this.loading_by_handle[handle] ) {
|
||||||
|
objStats.state = LoadingObject.STATE_LOADING;
|
||||||
|
objStats.bytesRead = this.loading_by_handle[handle][1];
|
||||||
|
objStats.bytesTotal = this.loading_by_handle[handle][2];
|
||||||
|
}
|
||||||
|
return objStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loadImage(uri, handle)
|
||||||
|
*
|
||||||
|
* Start loading the image at the given URI with the given handle
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @uri:String, the URI where the file lives
|
||||||
|
* @handle:String, the handle for the object
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function loadImage(uri:String, handle:String)
|
||||||
|
{
|
||||||
|
var request:URLRequest = new URLRequest(uri);
|
||||||
|
var img = new Loader();
|
||||||
|
img.load(request);
|
||||||
|
this.startObject(img, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loadMovie(uri, handle, className)
|
||||||
|
*
|
||||||
|
* Loads an external SWF object from URI and stores it as 'handle' and stores the class definition from it where the class name is className
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @uri:String, the URI where the file lives
|
||||||
|
* @handle:String, the handle for this object
|
||||||
|
* @className:String, the name of the SWF class when exported for Actionscript
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function loadMovie(uri:String, handle:String, className:String)
|
||||||
|
{
|
||||||
|
var request:URLRequest = new URLRequest(uri);
|
||||||
|
var movie = new Loader();
|
||||||
|
movie.load(request);
|
||||||
|
this.startObject(movie, handle);
|
||||||
|
this.classNames[handle] = className;
|
||||||
|
trace(this.classNames[handle]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* loadSound(uri, handle)
|
||||||
|
*
|
||||||
|
* Loads the given sound
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @uri:String, the URI from which to load the sound
|
||||||
|
* @handle:String, the handle to store the sound as
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
public function loadSound(uri:String, handle:String)
|
||||||
|
{
|
||||||
|
var request:URLRequest = new URLRequest(uri);
|
||||||
|
var snd = new Sound();
|
||||||
|
snd.load(request);
|
||||||
|
this.startObject(snd, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* playSound(handle)
|
||||||
|
*
|
||||||
|
* Locates the sound associated with the given handle, and plays it
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @handle:String, the text handle for the sound you want
|
||||||
|
*
|
||||||
|
* returns: Boolean (true on success, false on error)
|
||||||
|
*/
|
||||||
|
public function playSound(handle:String):Boolean
|
||||||
|
{
|
||||||
|
var snd = this.getObject(handle);
|
||||||
|
if ( !snd )
|
||||||
|
return false;
|
||||||
|
snd.play(); // we don't care about the channel it returns
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onIOError(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever there's an IO Error that prevents the object from finishing loading
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:IOErrorEvent, the event firing this function
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function onIOError(evt:IOErrorEvent)
|
||||||
|
{
|
||||||
|
var obj = evt.target;
|
||||||
|
var obj_info = this.loading_by_instance[obj];
|
||||||
|
var handle = obj_info[0];
|
||||||
|
var read = obj_info[1];
|
||||||
|
var total = obj_info[2];
|
||||||
|
this.stopObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onSecurityError(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever there's a security error that prevents the object from finishing loading
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:SecurityErrorEvent, the event firing this function
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function onSecurityError(evt:SecurityErrorEvent)
|
||||||
|
{
|
||||||
|
var obj = evt.target;
|
||||||
|
var obj_info = this.loading_by_instance[obj];
|
||||||
|
var handle = obj_info[0];
|
||||||
|
var read = obj_info[1];
|
||||||
|
var total = obj_info[2];
|
||||||
|
this.stopObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onProgressUpdate(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever there's a progress update on the object currently loading
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:ProgressEvent, the event firing this function
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function onProgressUpdate(evt:ProgressEvent)
|
||||||
|
{
|
||||||
|
var obj = evt.target;
|
||||||
|
var handle = this.loading_by_instance[obj][0];
|
||||||
|
this.loading_by_instance[obj][1] = this.loading_by_handle[handle][1] = evt.bytesLoaded;
|
||||||
|
this.loading_by_instance[obj][2] = this.loading_by_handle[handle][2] = evt.bytesTotal;
|
||||||
|
this.drawProgressMeters(evt);
|
||||||
|
this.progSpin += 1;
|
||||||
|
if ( this.progSpin >= this.progressSpinner.length ) {
|
||||||
|
this.progSpin = 0;
|
||||||
|
}
|
||||||
|
this.loadingLabel.text = "Please wait; loading ... " + this.progressSpinner[this.progSpin];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* onLoadComplete(evt)
|
||||||
|
*
|
||||||
|
* This function fires whenever a file finishes loading. You can call this, after setting the assets array, with a null event.
|
||||||
|
* In such a case, the loading process will simply be started.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:Event, the event firing this function (default null)
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function onLoadComplete(evt:Event = null)
|
||||||
|
{
|
||||||
|
if ( evt != null ) {
|
||||||
|
var obj = evt.target;
|
||||||
|
var handle = this.loading_by_instance[obj][0];
|
||||||
|
if ( obj is LoaderInfo ) {
|
||||||
|
this.objects[handle] = obj.content;
|
||||||
|
trace(this.classNames[handle]);
|
||||||
|
if ( (this.classNames[handle]) && (this.classNames[handle] != "") )
|
||||||
|
this.classDefs[handle] = obj.applicationDomain.getDefinition(this.classNames[handle]);
|
||||||
|
else
|
||||||
|
this.classDefs[handle] = null;
|
||||||
|
} else
|
||||||
|
this.objects[handle] = obj
|
||||||
|
this.stopObject(obj);
|
||||||
|
this.curAsset += 1;
|
||||||
|
}
|
||||||
|
if ( this.curAsset < this.assets.length ) {
|
||||||
|
var asset = this.assets[this.curAsset];
|
||||||
|
var asset_stat = this.getObjectStatus(asset[1]);
|
||||||
|
if ( asset_stat.state == LoadingObject.STATE_NOTFOUND ) {
|
||||||
|
if ( asset[0] == "sounds" ){
|
||||||
|
this.loadSound(asset[2], asset[1]);
|
||||||
|
} else if ( asset[0] == "images" ) {
|
||||||
|
this.loadImage(asset[2], asset[1]);
|
||||||
|
} else if ( asset[0] == "movies" ) {
|
||||||
|
this.loadMovie(asset[2], asset[1], asset[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( this.curAsset >= this.assets.length ) {
|
||||||
|
var evt = new Event(Event.COMPLETE);
|
||||||
|
this.dispatchEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* drawProgressMeters(evt)
|
||||||
|
*
|
||||||
|
* This function redraws the visible progress meters; it is generally called from inside of onProgressUpdate.
|
||||||
|
* It isn't fired by a timer, but it does need to have the event passed in to it so it can access the bytes read, etc.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @evt:ProgressEvent, the event firing this function (default null)
|
||||||
|
*
|
||||||
|
* returns: none
|
||||||
|
*/
|
||||||
|
protected function drawProgressMeters(evt:ProgressEvent)
|
||||||
|
{
|
||||||
|
this.graphics.clear();
|
||||||
|
// draw the file progress meter
|
||||||
|
// white box
|
||||||
|
this.graphics.lineStyle(1,0xFFFFFF);
|
||||||
|
this.graphics.beginFill(0xFFFFFF);
|
||||||
|
this.graphics.drawRoundRect(60, 30, 200, 15, 5);
|
||||||
|
this.graphics.endFill();
|
||||||
|
// blue bar
|
||||||
|
this.graphics.lineStyle(1,0x6E6BF4);
|
||||||
|
this.graphics.beginFill(0x6E6BF4);
|
||||||
|
this.graphics.drawRoundRect(60, 30, 200*(evt.bytesLoaded/evt.bytesTotal), 15, 5);
|
||||||
|
this.graphics.endFill();
|
||||||
|
// red box
|
||||||
|
this.graphics.lineStyle(3, 0xAC2626);
|
||||||
|
this.graphics.drawRoundRect(60, 30, 200, 15, 5);
|
||||||
|
// draw the total progress meter
|
||||||
|
// white box
|
||||||
|
this.graphics.lineStyle(1,0xFFFFFF);
|
||||||
|
this.graphics.beginFill(0xFFFFFF);
|
||||||
|
this.graphics.drawRoundRect(60, 60, 200, 15, 5);
|
||||||
|
this.graphics.endFill();
|
||||||
|
// blue bar
|
||||||
|
this.graphics.lineStyle(1,0x6E6BF4);
|
||||||
|
this.graphics.beginFill(0x6E6BF4);
|
||||||
|
this.graphics.drawRoundRect(60, 60, 200*(this.curAsset/this.assets.length), 15, 5);
|
||||||
|
this.graphics.endFill();
|
||||||
|
// red box
|
||||||
|
this.graphics.lineStyle(3, 0xAC2626);
|
||||||
|
this.graphics.drawRoundRect(60, 60, 200, 15, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
123
net/aklabs/demo/simonsays/SimonButton.as
Executable file
@@ -0,0 +1,123 @@
|
|||||||
|
package net.aklabs.demo.simonsays {
|
||||||
|
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import flash.display.Bitmap;
|
||||||
|
import flash.display.Sprite;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* class SimonButton
|
||||||
|
*
|
||||||
|
* This is just a custom button class that is pixel-accurate, because the Mastermin/Simon Says
|
||||||
|
* buttons are an extremely odd shape, so I needed something that could detect mouse hits in/
|
||||||
|
* outside of the alpha color areas.
|
||||||
|
*
|
||||||
|
* Most of this class is really self explanatory, so I'm not going to bother documenting all of it. Only the parts that don't make immediate sense.
|
||||||
|
*/
|
||||||
|
public class SimonButton extends Sprite
|
||||||
|
{
|
||||||
|
protected var imgDown:Bitmap; // bitmap for when the button is pressed
|
||||||
|
protected var imgUp:Bitmap; // bitmap for when the button is released
|
||||||
|
protected var curImg:Bitmap; // the bitmap currently being displayed on the button
|
||||||
|
protected var magicColor:Number; // the magic color (e.g. "magic pink"), if any (otherwise alpha is used for hit detection)
|
||||||
|
|
||||||
|
public function SimonButton(imgDown:Bitmap = null, imgUp:Bitmap = null, magicColor = 0x00000000)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.imgDown = imgDown;
|
||||||
|
this.imgUp = imgUp;
|
||||||
|
this.curImg = null;
|
||||||
|
this.magicColor = magicColor;
|
||||||
|
this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
|
||||||
|
this.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
|
||||||
|
this.addEventListener(MouseEvent.CLICK, this.onMouseClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMagicColor(color:Number)
|
||||||
|
{
|
||||||
|
this.magicColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBtnDown(obj:Bitmap)
|
||||||
|
{
|
||||||
|
if ( obj ) {
|
||||||
|
this.imgDown = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBtnUp(obj:Bitmap)
|
||||||
|
{
|
||||||
|
if ( obj ) {
|
||||||
|
this.imgUp = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onMouseDown(obj:MouseEvent)
|
||||||
|
{
|
||||||
|
if ( (obj) && (! this.hitTestPoint(obj.localX, obj.localY)) ) {
|
||||||
|
obj.stopImmediatePropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( this.curImg ) {
|
||||||
|
this.removeChild(this.curImg);
|
||||||
|
}
|
||||||
|
if ( this.imgDown ) {
|
||||||
|
this.addChild(this.imgDown);
|
||||||
|
this.curImg = this.imgDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onMouseUp(obj:MouseEvent)
|
||||||
|
{
|
||||||
|
if ( (obj) && (!this.hitTestPoint(obj.localX, obj.localY)) ) {
|
||||||
|
obj.stopImmediatePropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( this.curImg ) {
|
||||||
|
this.removeChild(this.curImg);
|
||||||
|
}
|
||||||
|
if ( this.imgUp ) {
|
||||||
|
this.addChild(this.imgUp);
|
||||||
|
this.curImg = this.imgUp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onMouseClick(obj:MouseEvent)
|
||||||
|
{
|
||||||
|
if ( ! this.hitTestPoint(obj.localX, obj.localY) ) {
|
||||||
|
obj.stopImmediatePropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hitTestPoint(x, y, shapeFlag)
|
||||||
|
*
|
||||||
|
* An overriden version of hitTestPoint that is pixel-accurate. If the value at (x, y) is either A: of the value
|
||||||
|
* in the "magic color", or B: containing an alpha value of zero, then the hit is POSITIVE. Otherwise it is false.
|
||||||
|
*
|
||||||
|
* arguments:
|
||||||
|
* @x:Number, the X location of the hit relative to the origin of the object
|
||||||
|
* @y:Number, the Y location of the hit relative to the origin of the object
|
||||||
|
* @shapeFlag:Boolean, not used, just here for compatibility
|
||||||
|
*
|
||||||
|
* returns: Boolean (true if the hit is positive, false if it's negative)
|
||||||
|
*/
|
||||||
|
public override function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
|
||||||
|
{
|
||||||
|
var color:uint;
|
||||||
|
var rgb:uint;
|
||||||
|
var a:uint;
|
||||||
|
|
||||||
|
if ( this.curImg && this.curImg.bitmapData ) {
|
||||||
|
color = this.curImg.bitmapData.getPixel32(x, y);
|
||||||
|
a = ((color >> 24) & 0xFF);
|
||||||
|
rgb = (color & 0xFFFFFF00);
|
||||||
|
//trace("Alpha : " + a + " RGB " + rgb + " magic color " + this.magicColor);
|
||||||
|
if ( this.magicColor == rgb || a == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
net/aklabs/demo/simonsays/SimonSays.as
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
package net.aklabs.demo.simonsays
|
||||||
|
{
|
||||||
|
|
||||||
|
import flash.utils.Timer;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.TimerEvent;
|
||||||
|
import net.aklabs.demo.simonsays.Preloader;
|
||||||
|
|
||||||
|
public class Mastermind
|
||||||
|
{
|
||||||
|
protected var lightOutTimer:Timer;
|
||||||
|
protected var lightBitmaps:Array;
|
||||||
|
|
||||||
|
public function Mastermind(preloader:Preloader, screenX:Number = 0, screenY:Number = 0)
|
||||||
|
{
|
||||||
|
// pass in a preloader so the class knows where to get its resources
|
||||||
|
var lightPositions = new Array();
|
||||||
|
// this array holds pairs of (x,y) coordinates at which to place the dark/light colored
|
||||||
|
// Simon Says buttons, since they're meant to cover the existing buttons on the original graphic.
|
||||||
|
// These are hard-coded; in a better implementation, they would come from an XML or would be
|
||||||
|
// individual frames of an SWF which could be fired individually, etc. But this works.
|
||||||
|
// array idx 0: Blue, 1: Green, 2: Red, 3: Yellow
|
||||||
|
lightPositions.push( new Array(screenX + 216, screenY + 220)); // blue
|
||||||
|
lightPositions.push( new Array(screenX + 22, screenY + 20)); // green
|
||||||
|
lightPositions.push( new Array(screenX + 218, screenY + 20)); // red
|
||||||
|
lightPositions.push( new Array(screenX + 22, screenY + 218)); // yellow
|
||||||
|
// this array holds the light/dark bitmaps for the simon says buttons ... each idx is an array which holds (dark, light) bitmap objects
|
||||||
|
// the indexes (0-3) correspond to the above for colors
|
||||||
|
this.lightBitmaps = new Array();
|
||||||
|
var fetchArray = new Array( new Array("gfx_btn_darkblue", "gfx_btn_lightblue"),
|
||||||
|
new Array("gfx_btn_darkgreen", "gfx_btn_lightgreen"),
|
||||||
|
new Array("gfx_btn_darkred", "gfx_btn_lightred"),
|
||||||
|
new Array("gfx_btn_darkyellow", "gfx_btn_lightyellow") );
|
||||||
|
for ( var i = 0; i < fetchArray.length ; i++ ) {
|
||||||
|
light = preloader.getObject(fetchArray[i][0]);
|
||||||
|
dark = preloader.getObject(fetchArray[i][1]);
|
||||||
|
light.x = lightPositions[i][0];
|
||||||
|
light.y = lightPositions[i][1];
|
||||||
|
dark.x = lightPositions[i][0];
|
||||||
|
dark.y = lightPositions[i][1];
|
||||||
|
// we don't check the return values here because the preloader shouldn't even fire
|
||||||
|
// the application up if resources are missing
|
||||||
|
this.lightBitmaps.push(new Array(light, dark));
|
||||||
|
// the dark buttons are always there, the lighted ones are just temporarily overlain on them for effect
|
||||||
|
addChild(dark);
|
||||||
|
}
|
||||||
|
whole = preloader.getObject("gfx_background");
|
||||||
|
whole.x = screenX;
|
||||||
|
whole.y = screenY;
|
||||||
|
addChild(whole);
|
||||||
|
|
||||||
|
this.lightOutTimer = Timer(1000);
|
||||||
|
this.lightOutTimer.addEventListener(TimerEvent.TIMER, this.onTimer);
|
||||||
|
this.lightOutTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function flashAll(length:Number)
|
||||||
|
{
|
||||||
|
this.lightOutTimer.reset();
|
||||||
|
this.lightOutTimer.delay(length);
|
||||||
|
this.lightOutTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lightButton(btn:Number, activeTime:Number)
|
||||||
|
{
|
||||||
|
if ( btn < 4 ) {
|
||||||
|
this.lightOutTimer.reset();
|
||||||
|
this.lightOutTimer.delay(activeTime);
|
||||||
|
addChild(this.lightBitmaps[btn][0]);
|
||||||
|
this.lightOutTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimer(evt:TimerEvent);
|
||||||
|
{
|
||||||
|
for ( i = 0 ; i < this.lightBitmaps.length ; i++ ){
|
||||||
|
removeChild(this.lightBitmaps[i][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
sfx/BACKGROUND.mp3
Executable file
BIN
sfx/BLUE.mp3
Executable file
BIN
sfx/BUZZER.mp3
Executable file
BIN
sfx/EXCLAMATION.mp3
Executable file
BIN
sfx/EXPLOSION.mp3
Executable file
BIN
sfx/FORGIVENESS.mp3
Executable file
BIN
sfx/GREEN.mp3
Executable file
BIN
sfx/POINTDOUBLER.mp3
Executable file
BIN
sfx/RED.mp3
Executable file
BIN
sfx/SHORTCIRCUIT.mp3
Executable file
BIN
sfx/SIMONFAIL.wav
Executable file
BIN
sfx/SIMONSTART.wav
Executable file
BIN
sfx/SIMONTAUNT_1.wav
Executable file
BIN
sfx/SIMONTAUNT_2.wav
Executable file
BIN
sfx/SIMONTAUNT_3.wav
Executable file
BIN
sfx/SIMONTAUNT_4.wav
Executable file
BIN
sfx/SIMONTAUNT_5.wav
Executable file
BIN
sfx/SLOWDOWN.mp3
Executable file
BIN
sfx/SPEEDUP.mp3
Executable file
BIN
sfx/YELLOW.mp3
Executable file
BIN
simon says.swf
Executable file
BIN
wily.png
Executable file
|
After Width: | Height: | Size: 130 KiB |
BIN
wilysays-src-Mar-02-2010.zip
Executable file
10
wilysays-src-Mar-02-2010/readme.txt
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
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.
|
||||||
909
wilysays-src-Mar-02-2010/src/Game.as
Executable file
@@ -0,0 +1,909 @@
|
|||||||
|
/*
|
||||||
|
* 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()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
wilysays-src-Mar-02-2010/src/gfx/EXCLAMATION.png
Executable file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/FORGIVENESS.png
Executable file
|
After Width: | Height: | Size: 11 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/LIFE.png
Executable file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/POINTDOUBLER.png
Executable file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/SHORTCIRCUIT.png
Executable file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/SLOWDOWN.png
Executable file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/blue-dark.png
Executable file
|
After Width: | Height: | Size: 18 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/blue-light.png
Executable file
|
After Width: | Height: | Size: 19 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/circuitboard.png
Executable file
|
After Width: | Height: | Size: 791 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/difficultychooser.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/difficultychooser.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/endscreen.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/endscreen.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/highscore.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/highscore.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/intro-menu.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/intro-menu.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/tutorial.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/cutscenes/tutorial.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/explosion.fla
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/explosion.swf
Executable file
BIN
wilysays-src-Mar-02-2010/src/gfx/game_background.png
Executable file
|
After Width: | Height: | Size: 139 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/green-dark.png
Executable file
|
After Width: | Height: | Size: 15 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/green-light.png
Executable file
|
After Width: | Height: | Size: 16 KiB |
BIN
wilysays-src-Mar-02-2010/src/gfx/progress_green.png
Executable file
|
After Width: | Height: | Size: 875 B |
BIN
wilysays-src-Mar-02-2010/src/gfx/progress_red.png
Executable file
|
After Width: | Height: | Size: 872 B |