所以,我已经创建了一个基于"匹配3"在ActionScript游戏中,有几种不同类型的图块,主图块只是字母图块,然后就像炸弹一样有特殊的图块,每个图块都有相似的功能,但每个图块都有特殊的功能。
现在,我只有一个Tile类来处理所有无法实现的功能。我认为装饰师课程是实施它的最佳途径,我遇到了问题。
以下是我如何构建它,我将如何处理存储在Vector中的图块?我将如何添加到舞台?
目前,我将瓷砖存储在Vector中。(我有一个Tile类可以处理所有丑陋的类型)。如果我要转移到装饰模式,似乎我将存储一个ITile的Vector,我将如何添加" Itiles"这些基本上是LetterTiles和BombTiles来进行演出?我在尝试时遇到了类型强制错误。
此外,装饰器模式似乎基本上是一个接口,所有类型都只是实现,所以例如,如果我在舞台上采取现有的LetterTile并说它需要转换为BombTile,我将如何如何将当前的瓷砖更改或更新为Bomb瓷砖?
示例:
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
答案 0 :(得分:2)
就像我在评论中所说,这不是decorator pattern,它只是一个抽象类BaseTile
。
要回答您的问题,无论您使用装饰器还是基类:您需要使用强制转换。具体做法是:
我如何处理将图块存储在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";
}
}
我将如何添加到舞台?
如果您有ITile
,则必须转换为显示对象:
stage.addChild(tile as DisplayObject);
如果你有一个BaseTile
它已经扩展Sprite
,那么就不需要进行转换。
如果我在舞台上拍摄现有的LetterTile并说它需要 转换为BombTile,我将如何更改或更新 当前的瓷砖变成炸弹瓷砖?
这实际上取决于你想要做什么。您无法将对象更改为另一个对象,但您当然可以通过各种方式替换它:
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);
答案 1 :(得分:1)
如果您只想使用装饰器,您可以将其视为使您的瓷砖与数据对象不同的东西,然后使用提供功能的“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. }
但老实说,你不需要单独的课程来装饰它们,使它们看起来都一样。您可以只使用一种数据对象类型加载数据以满足您的需求。
编辑:我喜欢Aaron如何概述您的问题并说出他的代码如何回答它。我要去偷它。
我如何添加基本上是LetterTiles和BombTiles的“Itiles”?
如图所示的Tile类扩展了Sprite,因此您可以将它添加到舞台上。
如果我要在舞台上使用现有的LetterTile并说它需要转换为BombTile,我该如何将当前的瓷砖更改或更新为Bomb瓷砖?
在上面的代码中,我将ITileData作为构造函数参数传递,但您可以通过使getter / setter对设置tileData来轻松更改tile的类型。您需要删除旧图形并在触发设置器时替换它。
specialEvent会告诉你的父类当用户与磁贴进行交互时发生了什么,而父类将负责处理炸弹事件或触发的字母事件的结果。