ActionScript 游戏,在实现装饰器时遇到问题 class
ActionScript game, having trouble implementing decorator class
所以,我在 ActionScript 中创建了一个基于方块的 "match 3" 游戏,其中有几种不同类型的方块,主要方块只是字母方块,还有特殊方块,例如炸弹每个磁贴都有相似的功能,但每个磁贴都有特殊的功能。
现在,我只有一个 Tile class 可以处理所有功能,这不是可行的方法。我认为装饰器 class 是最好的方法,但是实现它,我 运行 遇到了问题。
下面是我的结构,我将如何处理将图块存储在 Vector 中?我将如何添加到舞台上?
目前,我将图块存储在 Vector 中。(我有一个图块 class 可以处理所有丑陋的类型)。如果我要转向装饰器模式,似乎我将存储一个 ITile 向量,我将如何添加 "Itiles" ,它们本质上是 LetterTiles 和 BombTiles 到阶段?我在尝试时遇到类型强制错误。
此外,装饰器模式似乎基本上是一个接口,所有类型都会实现它,例如,如果我要在舞台上使用现有的 LetterTile 并说它需要转换为 BombTile,如何我会着手将当前图块更改或更新为炸弹图块吗?
示例:
public interface ITile
{
function create():void;
function remove():void;
}
和BaseTile.as
public class BaseTile extends Sprite
{
public function create():void
{
throw new IllegalOperationError("Must override in concrete class");
}
public class remove():void
{
throw new IllegalOperationError("Must override in concrete class");
}
}
LetterTile.as
public class LetterTile extends BaseTile implements ITile
{
public override function create():void
{
trace("Letter Tile Created");
}
public override function remove():void
{
trace("Letter Tile Removed");
}
}
BombTile.as
public class BombTile extends BaseTile implements ITile
{
public override function create():void
{
trace('Bomb tile created');
}
public override function remove():void
{
trace('Bomb tile removed');
doExplosion();
}
public function doExplosion():void
{
//This would do something different than regular letter tile.
}
}
希望这是有道理的,我需要在不创建 TL;DR 的情况下尽可能多地添加信息
如果您只想使用装饰器,您可以将其视为使您的图块与数据对象不同的东西,然后 "Decorate" 具有提供功能的 "shell" 的数据。
所以:
public class Bomb implements ITileData {
public function get tileName():String{
return 'bomb';
}
public function get specialEvent():Event{
return new BombEvent();//you'd write this class elsewhere
}
public function get displayClass():DisplayObject {
return BombSprite;
}
}
public class Tile extends Sprite {
protected var _tileData:ITileData;
public function Tile(tileData) {
_tileData = tileData;
}
public function create():void {
trace(_tileData.tileName, 'created');
addChild(new _tileData.displayClass();
}
public function interact():void {
dispatchEvent(_tileData.specialEvent);
}
//etc.
}
但老实说,您不需要单独的 class 装饰来使它们看起来都一样。您可以只拥有一种数据对象类型,您可以根据需要加载数据。
编辑:我喜欢 Aaron 如何内联您的问题并说明他的代码如何回答问题。我要偷了
how would I add "Itiles" which are essentially LetterTiles and BombTiles to stage?
如图所示的 Tile class 扩展了 Sprite,因此您可以将它添加到舞台上。
if I were to take an existing LetterTile on stage and say it needs to convert to a BombTile, How would I go about changing or updating the current tile into a Bomb tile?
在上面的代码中,我将 ITileData 作为构造函数参数传入,但您可以通过 getter/setter 对设置 tileData 来轻松更改图块的类型。您想要删除旧图形并在 setter 触发时替换它。
specialEvent 会告诉您的父级 class 当用户与磁贴交互时发生了什么,而父级 class 将负责处理炸弹事件或信件的结果事件触发。
正如我在评论中所说,这并不是真正的 decorator pattern,它只是一个抽象 class BaseTile
。
回答你是使用装饰器还是基础的问题class:你需要使用转换。具体来说:
how would I handle storing the tiles in a Vector?
var tiles:Vector.<ITile> = new <ITile>[];
tiles.push(new BombTile());
要检查向量中有哪些特定的图块类型,请使用 is
运算符,然后使用 as
运算符转换为特定的图块类型:
for each(var tile:ITile in tiles){
if(tile is BombTile){
var bombTile:BombTile = tile as BombTile;
bombTile.explode();
}else if(tile is LetterTile){
var letterTile:LetterTile = tile as LetterTile;
letterTile.letter = "A";
}
}
and how would I add to stage?
如果你有 ITile
,你必须强制转换为显示对象:
stage.addChild(tile as DisplayObject);
如果您有一个 BaseTile
,它已经扩展 Sprite
,所以不需要转换。
if I were to take an existing LetterTile on stage and say it needs to
convert to a BombTile, How would I go about changing or updating the
current tile into a Bomb tile?
这真的取决于你到底想做什么。您不能将一个对象更改为另一个对象,但您当然可以通过各种方式替换它:
var tiles:Vector.<ITile> = new <ITile>[];
tiles.push(new LetterTile(), new LetterTile(), ...etc);
function replaceTile(existingTile:ITile, replacementTile:ITile):void {
var index:int = tiles.indexOf(existingTile);
stage.removeChild(existingTile as DisplayObject);
tiles[index] = replacementTile;
stage.addChild(replacementTile as DisplayObject);
}
function changeTileType(tile:ITile, type:Class):void {
if( !(tile is type)){
replaceTile(tile, new type());
}
}
// Example:
changeTileType(tiles[0], BombTile);
所以,我在 ActionScript 中创建了一个基于方块的 "match 3" 游戏,其中有几种不同类型的方块,主要方块只是字母方块,还有特殊方块,例如炸弹每个磁贴都有相似的功能,但每个磁贴都有特殊的功能。
现在,我只有一个 Tile class 可以处理所有功能,这不是可行的方法。我认为装饰器 class 是最好的方法,但是实现它,我 运行 遇到了问题。
下面是我的结构,我将如何处理将图块存储在 Vector 中?我将如何添加到舞台上?
目前,我将图块存储在 Vector 中。(我有一个图块 class 可以处理所有丑陋的类型)。如果我要转向装饰器模式,似乎我将存储一个 ITile 向量,我将如何添加 "Itiles" ,它们本质上是 LetterTiles 和 BombTiles 到阶段?我在尝试时遇到类型强制错误。
此外,装饰器模式似乎基本上是一个接口,所有类型都会实现它,例如,如果我要在舞台上使用现有的 LetterTile 并说它需要转换为 BombTile,如何我会着手将当前图块更改或更新为炸弹图块吗?
示例:
public interface ITile
{
function create():void;
function remove():void;
}
和BaseTile.as
public class BaseTile extends Sprite
{
public function create():void
{
throw new IllegalOperationError("Must override in concrete class");
}
public class remove():void
{
throw new IllegalOperationError("Must override in concrete class");
}
}
LetterTile.as
public class LetterTile extends BaseTile implements ITile
{
public override function create():void
{
trace("Letter Tile Created");
}
public override function remove():void
{
trace("Letter Tile Removed");
}
}
BombTile.as
public class BombTile extends BaseTile implements ITile
{
public override function create():void
{
trace('Bomb tile created');
}
public override function remove():void
{
trace('Bomb tile removed');
doExplosion();
}
public function doExplosion():void
{
//This would do something different than regular letter tile.
}
}
希望这是有道理的,我需要在不创建 TL;DR 的情况下尽可能多地添加信息
如果您只想使用装饰器,您可以将其视为使您的图块与数据对象不同的东西,然后 "Decorate" 具有提供功能的 "shell" 的数据。
所以:
public class Bomb implements ITileData { public function get tileName():String{ return 'bomb'; } public function get specialEvent():Event{ return new BombEvent();//you'd write this class elsewhere } public function get displayClass():DisplayObject { return BombSprite; } }
public class Tile extends Sprite { protected var _tileData:ITileData; public function Tile(tileData) { _tileData = tileData; } public function create():void { trace(_tileData.tileName, 'created'); addChild(new _tileData.displayClass(); } public function interact():void { dispatchEvent(_tileData.specialEvent); } //etc. }
但老实说,您不需要单独的 class 装饰来使它们看起来都一样。您可以只拥有一种数据对象类型,您可以根据需要加载数据。
编辑:我喜欢 Aaron 如何内联您的问题并说明他的代码如何回答问题。我要偷了
how would I add "Itiles" which are essentially LetterTiles and BombTiles to stage?
如图所示的 Tile class 扩展了 Sprite,因此您可以将它添加到舞台上。
if I were to take an existing LetterTile on stage and say it needs to convert to a BombTile, How would I go about changing or updating the current tile into a Bomb tile?
在上面的代码中,我将 ITileData 作为构造函数参数传入,但您可以通过 getter/setter 对设置 tileData 来轻松更改图块的类型。您想要删除旧图形并在 setter 触发时替换它。
specialEvent 会告诉您的父级 class 当用户与磁贴交互时发生了什么,而父级 class 将负责处理炸弹事件或信件的结果事件触发。
正如我在评论中所说,这并不是真正的 decorator pattern,它只是一个抽象 class BaseTile
。
回答你是使用装饰器还是基础的问题class:你需要使用转换。具体来说:
how would I handle storing the tiles in a Vector?
var tiles:Vector.<ITile> = new <ITile>[];
tiles.push(new BombTile());
要检查向量中有哪些特定的图块类型,请使用 is
运算符,然后使用 as
运算符转换为特定的图块类型:
for each(var tile:ITile in tiles){
if(tile is BombTile){
var bombTile:BombTile = tile as BombTile;
bombTile.explode();
}else if(tile is LetterTile){
var letterTile:LetterTile = tile as LetterTile;
letterTile.letter = "A";
}
}
and how would I add to stage?
如果你有 ITile
,你必须强制转换为显示对象:
stage.addChild(tile as DisplayObject);
如果您有一个 BaseTile
,它已经扩展 Sprite
,所以不需要转换。
if I were to take an existing LetterTile on stage and say it needs to convert to a BombTile, How would I go about changing or updating the current tile into a Bomb tile?
这真的取决于你到底想做什么。您不能将一个对象更改为另一个对象,但您当然可以通过各种方式替换它:
var tiles:Vector.<ITile> = new <ITile>[];
tiles.push(new LetterTile(), new LetterTile(), ...etc);
function replaceTile(existingTile:ITile, replacementTile:ITile):void {
var index:int = tiles.indexOf(existingTile);
stage.removeChild(existingTile as DisplayObject);
tiles[index] = replacementTile;
stage.addChild(replacementTile as DisplayObject);
}
function changeTileType(tile:ITile, type:Class):void {
if( !(tile is type)){
replaceTile(tile, new type());
}
}
// Example:
changeTileType(tiles[0], BombTile);