ActionScript游戏,无法实现装饰器类

时间:2016-01-27 15:59:28

标签: actionscript-3 flash design-patterns

所以,我已经创建了一个基于"匹配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

2 个答案:

答案 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会告诉你的父类当用户与磁贴进行交互时发生了什么,而父类将负责处理炸弹事件或触发的字母事件的结果。