Text Based Adventure Engine
The example game allows you to play a game of rock, paper, scissors, lizard, spock against Sheldon Cooper.
/**
* Copyright paulstamp1 ( http://wonderfl.net/user/paulstamp1 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/o7VJ
*/
/**
_____ _____ _____ __ _____ _____ _____ _____ _____
| _ | _ | | | | | __|_ _| _ | | _ |
| __| | | | |__ |__ | | | | | | | | __|
|__| |__|__|_____|_____| |_____| |_| |__|__|_|_|_|__|
@paulstamp
This project was created as part of a hack day.
I decided to create an engine for a Text Based Adventure Game.
Built in a web based IDE using nothing but cloud based tools.
TOOLS:
image editor: http://pixlr.com/editor/
ftp upload: http://www.ftplive.com/ftp.php?
code editor: http://wonderfl.net/
*/
package {
import flash.external.ExternalInterface;
import flash.system.Security;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
/**
*
* Use ':' in a description to allow text input
* USe '<thing>' to enter player data
*
*/
//setup
Security.allowDomain("*");
Security.allowInsecureDomain("*");
Security.allowDomain("http://www.paulstamp.co.uk/examples/tba");
//game
var tba:TextBasedAdventureGame = new TextBasedAdventureGame( this );
//assets
var asset_sheldon:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonFace.jpg");
var asset_sheldonXmen:Asset = new Asset( "http://paulstamp.co.uk/examples/tba/sheldonShirt.jpg" );
var asset_sheldonSat:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonSat.jpg" );
var asset_smug:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/bazinga.jpg" );
var asset_lost:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonGrump.jpg" );
var asset_angry:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/sheldonAngry.jpg");
var asset_spock:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/spock.jpg" );
var asset_liveLong:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/liveLong.jpg");
var scene1Asset:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/scene1.swf" );
var scene2Asset:Asset = new Asset( "http://www.paulstamp.co.uk/examples/tba/scene2.swf" );
//generic responses
tba.addGenericOption( new Option( [new NavigationOperation( tba, "offerGame")], ["game"] ));
//scenes
//ask name
var askName:Scene = new Scene( "askName", asset_sheldon);
askName.description = "Hello fellow Science lover. What is your name?:";
askName.addOption( new Option( [new CaptureInputOperation( tba, "playerName", tba.playerData, new NavigationOperation( tba, "areYouReady" ) )], [] ));
tba.addScene( askName );
//are you ready
var areYouReady:Scene = new Scene( "areYouReady", asset_sheldonSat);
areYouReady.description = "Greetings <playerName> did you know the X-men were named for the X in Charles Xavier. Since I am Sheldon Cooper, will you join my C-men?:";
areYouReady.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], ["yes", "ok", "no"] ));
tba.addScene( areYouReady );
//star trek
var likeStarTrek:Scene = new Scene( "likeStarTrek", asset_liveLong);
likeStarTrek.description = "Do you like Star Trek?:";
likeStarTrek.addOption( new Option( [new NavigationOperation( tba, "offerGame")], ["yes", "ok"] ));
likeStarTrek.addOption( new Option( [new NavigationOperation( tba, "offerGame")], ["no"] ));
tba.addScene( likeStarTrek );
//offer game
var offerGame:Scene = new Scene( "offerGame", asset_sheldon);
offerGame.description = "<playerName> how about a game of Rock, Paper, Scissors, Lizard, Spock?:";
offerGame.addOption( new Option( [new NavigationOperation( tba, "playGame")], ["yes", "ok", "sure"] ));
offerGame.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], ["no"] ));
tba.addScene( offerGame );
//play game
var playGame:Scene = new Scene( "playGame", asset_spock);
playGame.description = "good, as this is a Text Based Adventure you will have to enter either Rock, Paper, Lizard, Scissors or Spock:";
playGame.addOption( new Option( [new RockPaperScissorsOperation( tba, tba.playerData )], ["rock", "paper", "lizard", "scissors", "spock"] ));
tba.addScene( playGame );
//sheldon loses
var sheldonLoses:Scene = new Scene( "sheldonLoses", asset_angry);
sheldonLoses.description = "Drat. <playerName> you beat my <losingMove>. Would you like to play again:";
sheldonLoses.addOption( new Option( [new NavigationOperation( tba, "playGame")], ["yes", "ok"] ));
sheldonLoses.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], ["no"] ));
tba.addScene( sheldonLoses );
//sheldon wins
var sheldonWins:Scene = new Scene( "sheldonWins", asset_smug);
sheldonWins.description = "Bazinga I beat you <playerName> with an inspired <winningMove>. Would you like to play again:";
sheldonWins.addOption( new Option( [new NavigationOperation( tba, "playGame")], ["yes", "ok"] ));
sheldonWins.addOption( new Option( [new NavigationOperation( tba, "likeStarTrek")], ["no"] ));
tba.addScene( sheldonWins );
//start
tba.setScene( "askName" );
}
}
}
import flash.display.AVM1Movie;
import flash.system.SecurityDomain;
import flash.geom.Rectangle;
import flash.events.MouseEvent;
import flash.events.FocusEvent;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextField;
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ErrorEvent;
import flash.events.IOErrorEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
import flash.utils.Dictionary;
import flash.display.Scene;
import flash.events.KeyboardEvent;
import flash.events.TextEvent;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
import flash.display.DisplayObjectContainer;
class TextBasedAdventureGame extends Sprite {
private var _io:InputOutput;
private var _sceneManager:SceneManager;
private var _genericCommands:Array;
private var _image:ImageViewer;
private var _playerData:PlayerData;
public const SIZE:uint = 465;
public function TextBasedAdventureGame( parent:DisplayObjectContainer )
{
parent.addChild( this );
_genericCommands = [];
//image
_image = new ImageViewer( SIZE, SIZE );
addChild( _image );
//input
_io = new InputOutput( SIZE, SIZE, playerData );
_io.addEventListener( CommandEvent.COMMAND_ENTERED, handleCommand );
addChild( _io );
//scene manager
_sceneManager = new SceneManager( _image, _io );
_io.print( "Hello World >" );
}
public function addGenericOption( option:Option ):void
{
_genericCommands.push( option );
}
public function get playerData():PlayerData
{
return _playerData ||= new PlayerData();
}
public function addScene( value:Scene ):void
{
value.tba = this;
_sceneManager.addScene( value );
}
public function setScene( title:String ):void
{
_sceneManager.setScene( title );
}
private function handleCommand( event:CommandEvent ):void
{
if( !_sceneManager.currentScene )
return;
if( !_sceneManager.currentScene.handleCommand( event.command ))
{
handleGenericCommand( event );
}
}
public function displayFeedback( feedback:String ):void
{
_io.print( feedback );
}
private function handleGenericCommand( event:CommandEvent ):void
{
for each( var option:Option in _genericCommands )
{
if( option.hasCommand( event.command ))
{
option.run( event.command );
return;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.display.DisplayObject;
class ImageViewer extends Sprite {
public function ImageViewer( width:uint, heigt:uint )
{
this.graphics.beginFill( 0x000000 );
this.graphics.drawRect( 0,0, width, height );
this.graphics.endFill();
}
public function displayImage( image:Loader ):void
{
//prevent replacing same screen
if( this.numChildren > 0 && this.getChildAt(0)== image )
return;
if( this.numChildren > 0 )
{
for( var i:uint = 0; i < this.numChildren; i++)
{
TweenMax.to( this.getChildAt(i), 0.4, { alpha:0, x:-465, onComplete:this.getChildAt(i).parent.removeChild, onCompleteParams:[this.getChildAt(i)] });
}
image.alpha = 0;
image.x = 465;
addChild( image );
TweenMax.to( image, 0.2, { x:0, alpha:1 } );
}
else
{
addChild( image );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
import flash.display.Sprite;
import com.greensock.TweenMax;
class InputOutput extends Sprite {
private var _output:TextField;
private var _input:TextField;
private var _defaultHeight:uint = 40;
private var _gapAtSides:uint = 10;
private var _gapFromBottom:uint = 20;
private var _width:uint;
private var _height:uint;
private var _outputHeight:uint = 60;
private var _inputHeight:uint = 20;
private var _caret:Sprite;
private var _playerData:PlayerData;
public function InputOutput( width:uint, height:uint, playerData:PlayerData )
{
//position at the bottom of the screen and work in negatPlayerData
_playerData = playerData;
_width = width;
_height = height;
this.y = height;
var outputFormat:TextFormat = new TextFormat( "_sans", 12, 0x0eef24 );
_output = new TextField();
_output.defaultTextFormat = outputFormat;
_output.type = TextFieldType.DYNAMIC;
_output.width = _width - (_gapAtSides<<1);
_output.height = _defaultHeight;
_output.x = _gapAtSides;
_output.y = -(_outputHeight + _gapFromBottom);
_output.wordWrap = true;
_output.multiline = true;
_output.selectable = false;
addChild( _output );
var inputFormat:TextFormat = new TextFormat( "_sans", 12, 0x0eef24 );
_input = new TextField();
_input.defaultTextFormat = inputFormat;
_input.type = TextFieldType.INPUT;
_input.width = _width - (_gapAtSides<<1);
_input.height = _defaultHeight;
_input.addEventListener(KeyboardEvent.KEY_DOWN, onInput);
_input.addEventListener(FocusEvent.FOCUS_IN, onFocus);
_input.x = _gapAtSides;
_input.y = -(_inputHeight + _gapFromBottom);
_input.selectable = true;
addChild( _input );
_caret = new Sprite();
_caret.graphics.beginFill( 0x009900 );
_caret.graphics.drawRect( 0,0,4,17 );
_caret.graphics.endFill();
_caret.x = _gapAtSides + 10;
addChild( _caret );
TweenMax.to(_caret, 0.2, {tint:0x000000, repeat:-1, yoyo:true, repeatDelay:0.2});
drawBackground();
}
private function onFocus( event:FocusEvent ):void
{
_input.text = "";
_caret.visible = false;
}
public function clearText():void
{
_output.text = "";
_output.height = _defaultHeight;
_output.y = -(60 + _gapFromBottom);
drawBackground();
}
public function print( message:String):void
{
var lastChar:String = getLastCharInString(message);
//allow input
_input.visible = lastChar == ":";
if( lastChar == ":" )
{
message = message.slice( 0, -1 );
_input.visible = true;
_output.text = message;
}
else
{
_input.visible = false;
}
//display message
_output.text = insertUserData(message);
}
private function insertUserData( string:String ):String
{
var subs:Array = string.split( "<" );
var pos:int;
var sub:String;
var reform:String = "";
var s:String;
var r:String;
for( var i:uint; i < subs.length; i++ )
{
sub = subs[i];
pos = sub.indexOf(">");
if( pos > -1 )
{
s = sub.substr( 0, pos );
r = _playerData.getData(s);
sub = strReplace( sub, s+">", r );
subs[i] = sub;
}
reform += sub;
}
return reform;
}
private function strReplace(str:String, search:String, replace:String):String
{
return str.split(search).join(replace);
}
private function getLastCharInString( value:String):String
{
return value.substr(value.length-1, value.length);
}
private function drawBackground():void
{
this.graphics.clear();
this.graphics.beginFill( 0x111111, 0.9 );
this.graphics.drawRect( _gapAtSides, -(_outputHeight + _gapFromBottom), _width - (_gapAtSides<<1), _output.height );
this.graphics.endFill();
this.graphics.beginFill( 0x00000, 0.9 );
this.graphics.drawRect( _gapAtSides, -(_inputHeight + _gapFromBottom), _width - (_gapAtSides<<1), _input.height );
this.graphics.endFill();
_caret.y = _input.y;
_caret.x = _input.x + 2;
}
private function onInput( event:KeyboardEvent ):void
{
//detect enter key
if(event.charCode == 13)
{
//infom
this.dispatchEvent( new CommandEvent( _input.text ) );
//clear field
_input.text = "";
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class SceneManager {
private var _scenes:Dictionary;
private var _currentScene:Scene;
private var _imageView:ImageViewer;
private var _io:InputOutput;
public function SceneManager( imageView:ImageViewer, io:InputOutput )
{
_io = io;
_imageView = imageView;
_scenes = new Dictionary();
}
public function addScene( value:Scene ):void
{
_scenes[ value.title ] = value;
}
public function setScene( title:String):void
{
_currentScene = _scenes[ title ];
_currentScene.displayImage( _imageView );
_currentScene.displayDescription( _io);
}
public function get currentScene():Scene
{
return _currentScene;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Scene {
public var tba:TextBasedAdventureGame
public var description:String;
public var title:String;
public var image:Loader;
private var _options:Array;
private var _asset:Asset;
public function Scene( title:String, asset:Asset )
{
this.title = title;
_asset = asset;
_options = [];
}
public function displayImage( imageView:ImageViewer ):void
{
imageView.displayImage( _asset.load() );
}
public function displayDescription( io:InputOutput):void
{
io.print( description );
}
public function addOption( option:Option ):void
{
_options.push( option );
}
public function handleCommand( command:String ):Boolean
{
var ranCommand:Boolean;
for each( var option:Option in _options )
{
if( option.hasCommand( command ))
{
option.run( command );
ranCommand = true;
}
}
return ranCommand;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Asset {
public var image:Loader;
private var _imageURL:String;
private var _imageLoaded:Boolean;
public function Asset( contentURL:String )
{
image = new Loader();
image.contentLoaderInfo.addEventListener( Event.COMPLETE, imageLoadedHandler );
image.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, imageErrorHandler );
image.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, imageProgressHandler );
image.contentLoaderInfo.addEventListener( SecurityErrorEvent.SECURITY_ERROR, imageSecurityErrorHandler );
_imageURL = contentURL;
}
public function load():Loader
{
if( _imageLoaded )
return image;
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.checkPolicyFile = true;
loaderContext.allowCodeImport = true;
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
//loaderContext.securityDomain = SecurityDomain.currentDomain;
image.load(new URLRequest(_imageURL), loaderContext);
return image;
}
private function imageSecurityErrorHandler( event:SecurityErrorEvent ):void
{
throw new Error( "image security error" );
}
private function imageProgressHandler( event:ProgressEvent ):void
{
}
private function imageErrorHandler( event:IOErrorEvent ):void
{
throw new Error( "Failed to load image" );
}
private function imageLoadedHandler( event:Event ):void
{
image.contentLoaderInfo.removeEventListener( Event.COMPLETE, imageLoadedHandler );
_imageLoaded = true;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class Option {
private var _commands:Array;
private var _operations:Array;
private var _catchAll:Boolean;
public function Option( operations:Array, commands:Array )
{
_catchAll = commands.length == 0;
_operations = operations;
_commands = commands;
}
public function addOperation( operation:IOperation ):void
{
_operations.push( operation );
}
public function addCommand( value:String ):void
{
_commands.push( value );
}
public function hasCommand( value:String ):Boolean
{
if( _catchAll ) return true; //used to invoke operation on any command
//check for command similarity
for each( var command:String in _commands )
{
var sim:Number = similarity( value, command );
//throw new Error( sim + "," + command + "," + value );
if( sim > 10 )
{
return true;
}
}
return _commands.lastIndexOf( value ) != -1;
}
private function similarity(p_source:String, p_target:String):Number {
var ed:uint = editDistance(p_source, p_target);
var maxLen:uint = Math.max(p_source.length, p_target.length);
if (maxLen == 0) { return 100; }
else { return (1 - ed/maxLen) * 100; }
}
private function minimum(a:uint, b:uint, c:uint):uint
{
return Math.min(a, Math.min(b, Math.min(c,a)));
}
private function editDistance(p_source:String, p_target:String):uint {
var i:uint;
if (p_source == null) { p_source = ''; }
if (p_target == null) { p_target = ''; }
if (p_source == p_target) { return 0; }
var d:Array = new Array();
var cost:uint;
var n:uint = p_source.length;
var m:uint = p_target.length;
var j:uint;
if (n == 0) { return m; }
if (m == 0) { return n; }
for (i=0; i<=n; i++) { d[i] = new Array(); }
for (i=0; i<=n; i++) { d[i][0] = i; }
for (j=0; j<=m; j++) { d[0][j] = j; }
for (i=1; i<=n; i++) {
var s_i:String = p_source.charAt(i-1);
for (j=1; j<=m; j++) {
var t_j:String = p_target.charAt(j-1);
if (s_i == t_j) { cost = 0; }
else { cost = 1; }
d[i][j] = minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost);
}
}
return d[n][m];
}
public function run( command:String ):void
{
for each( var operation:IOperation in _operations )
{
operation.execute( command );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
interface IOperation {
function execute( command:String ):void;
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class CommandEvent extends Event{
public static const COMMAND_ENTERED:String = "CommandEntered";
private var _command:String;
public function CommandEvent( command:String ):void
{
_command = command;
super( COMMAND_ENTERED, false, false );
}
public function get command():String
{
return _command;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class NavigationOperation implements IOperation {
private var _title:String;
private var _tba:TextBasedAdventureGame;
public function NavigationOperation( tba:TextBasedAdventureGame, title:String )
{
_tba = tba;
_title = title;
}
public function execute( command:String ):void
{
//do some shit
_tba.setScene( _title );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class FeedbackOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _feedback:String;
public function FeedbackOperation( tba:TextBasedAdventureGame, feedback:String )
{
_tba = tba;
_feedback = feedback;
}
public function execute( command:String ):void
{
//do some shit
_tba.displayFeedback( _feedback );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class CaptureInputOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _playerData:PlayerData;
private var _storeDataWithName:String;
private var _onComplete:IOperation;
public function CaptureInputOperation( tba:TextBasedAdventureGame, storeDataWithName:String, playerData:PlayerData, onComplete:IOperation = null )
{
_storeDataWithName = storeDataWithName;
_playerData = playerData;
_tba = tba;
_onComplete = onComplete;
}
public function execute( command:String ):void
{
//command should be data to store
_playerData.store( _storeDataWithName, command );
if( _onComplete )
_onComplete.execute( command );
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class RockPaperScissorsOperation implements IOperation {
private var _tba:TextBasedAdventureGame;
private var _playerData:PlayerData;
private var _storeDataWithName:String;
private var _onComplete:IOperation;
private var _results:Array;
public function RockPaperScissorsOperation( tba:TextBasedAdventureGame, playerData:PlayerData )
{
_playerData = playerData;
_tba = tba;
var rock:RPS = new RPS( "rock" );
var paper:RPS = new RPS( "paper" );
var scissors:RPS = new RPS( "scissors" );
var lizard:RPS = new RPS( "lizard" );
var spock:RPS = new RPS( "spock" );
rock.beats( scissors );
rock.beats( lizard );
paper.beats( rock );
paper.beats( spock );
scissors.beats( paper );
scissors.beats( lizard );
lizard.beats( paper );
lizard.beats( spock );
spock.beats( scissors );
spock.beats( rock );
_results = [rock, paper, scissors, lizard, spock];
}
public function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
public function execute( command:String ):void
{
var command:String = command.toLowerCase();
_results.sort( randomize );
var response:RPS;
var entry:RPS;
for( var i:uint = 0; i < _results.length; i++)
{
var option:RPS = _results[i] as RPS;
//find option
if( option.type == command )
{
entry = option;
}
else
{
response = option;
}
if( entry && response )
break;
}
if( entry == null || response == null )
{
throw new Error( "no response" );
return;
}
var didSheldonWin:Boolean = response.doYouBeat( entry );
if( didSheldonWin )
{
_playerData.store( "winningMove", catipaliseFirstLetter(response.type) );
_tba.setScene( "sheldonWins" );
}
else
{
_playerData.store( "losingMove", catipaliseFirstLetter(response.type) );
_tba.setScene( "sheldonLoses" );
}
}
private function catipaliseFirstLetter($s:String):String {
return $s.substring(0, 1).toUpperCase() + $s.substr(1, $s.length-1);
}
private function randomizeArray(array:Array):Array{
var newArray:Array = new Array();
while(array.length > 0){
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class RPS{
public var type:String;
private var _losers:Array = [];
public function RPS( type:String )
{
this.type = type;
}
public function beats( rps:RPS ):void
{
_losers.push( rps );
}
public function doYouBeat( rps:RPS ):Boolean
{
for each( var option:RPS in _losers )
{
if( option.type == rps.type )
{
return true;
}
}
return false;
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class MultiOppOperation implements IOperation {
private var _args:Array;
public function MultiOppOperation( ...args )
{
_args = args
}
public function execute( command:String ):void
{
for each( var opp:IOperation in _args )
{
opp.execute( command );
}
}
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
class PlayerData {
private var _store:Dictionary = new Dictionary();
public function store( storeDataWithName:String, data:String ):void
{
_store[ storeDataWithName ] = data;
}
public function getData( storeDataWithName:String ):String
{
return _store[ storeDataWithName ];
}
}