游戏决策设计模式

时间:2011-08-11 15:46:13

标签: actionscript-3

所以我有许多物品,每种物品都具有不同的属性(砖块,玻璃等),每个物体都受到元素效应的不同影响。例如,砖材料受到火或酸的影响不同于水泥材料。当应用另一种燃烧/熔化效果时,燃烧或熔化的砖会受到不同的影响。

在我的游戏中,我有一个FSM,但它非常简单。如果我在砖上放下火元素,它将进入燃烧状态。然而,如果我然后在砖上放下一个水元素,我可能会想要灭火,采取/添加健康和更改纹理(或不取决于当前的组合)。

关键是,我有很多组合,它们之间没有共性,所以我不能创造统一的东西。有时我需要改变纹理,有时我不需要。有时会受到伤害,而其他时候会增加健康有时我需要在函数中什么都不做。在这一点上,我唯一能做的就是创建一个全局映射,例如:

FunctionMap [ObjectMaterial] [CurrentObjectState] [ElementBeingApplied]

(即

FunctionMap [砖] [燃烧] [酸]
FunctionMap [砖] [熔点] [酸]

问题在于,由于材料和效果类型可用的组合数量,这显然是一大堆功能。任何人都可以推荐一个采取或模式的路线来看待?

尽管与讨论并不完全相关,但这是在AS3和Away3D中进行的。

以下是我的一些示例:

public class Brick extends AbstractBlock implements IFireable
{
    public function Brick()
    {
        super(this);
        this.material = new BitmapMaterial(_spriteManager.GetBlockMaterial(BlockUtilities.GetMaterialMap["brick_new"]));
        _type = "Brick";
        /*
        RulesManager.StateMap["Brick"]["OnFire"]["Water"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Fire"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Acid"] = some function;
        RulesManager.StateMap["Brick"]["OnFire"]["Ice"] = some function;
        RulesManager.StateMap["Brick"]["OnWater"]["Water"] = some function;
        //and so on...there are nine different materials so I'm not liking this way
        */
    }

    public override function render():void
    {
        super.render();
    }
}   


public class OnFire extends AbstractDamage
{       

    protected var _timeStart:Number = 0;

    private var _damageAccumulated:Number = 0;

    public function OnFire(block:AbstractBlock,bombType:String) 
    {       
        super(block,bombType);                                      
    }

    public override function enter():void        
    {       
        super.enter();  
    }

    public override function exit():void         
    {       
        super.exit();                                       
    }

    public override function update(time:Number):void
    {
        super.update(time);

        if(_timeStart == 0)
            _timeStart = time;

        var time_delta:Number = (time - _timeStart)/_waitTime;

        var damageToSubtract:Number = (time_delta * _damageDone);

        _damageAccumulated += damageToSubtract;

        _self.Integrity = _self.Integrity - _damageAccumulated;


    }
}

}

因此,火元素可以应用于一堆应用。目前被冻结的那些块现在被击中,现在正在改变为OnFire状态。每个块都有自己的状态机,状态本身就是你可以看到的对象。

block.FSM.changeState(new OnFire(block));

3 个答案:

答案 0 :(得分:1)

您是否设置了自定义类?对我来说,这听起来像一个理想的解决方案。 一旦你绘制出每个类的属性和能力,对象管理应该是微不足道的。

即一个Brick类,当它与另一个类[水类]相互作用[碰撞]时,它具有某些状态[燃烧,熔化]并以不同的方式作出反应[函数调用]。

我希望我不会在错误的树上狂奔....​​..如果你能提供更多关于你所寻找的东西,我相信比我聪明的人会跳进去;)

答案 1 :(得分:1)

简短的回答是因为我相信Linquist先生在解释它方面做得很好 - 但听起来像是visitor pattern的工作。简而言之,你的元素(砖块,混凝土等)都允许访客(火,冰,酸等)来“访问”它们并应用它们的效果。

希望这有帮助!

答案 2 :(得分:1)

所以你的问题是你有9 * 5 * 4种效果组合,对吧?为每个人分别提供各种功能,管理起来并不好玩。但是,即使它是大量数据,你也需要它。我会尽可能简化数据,然后解析它。类似的东西:

var materialProperties = {
  brick: {
    fire: {
      normal: {damage: 10, image: 'brick_fire.jpg'},
    }
    water: {
      fire: {damage: 0, image: 'brick_smoking.jpg'}
    }
  },
  //... a lot more of this ...
}

class Material
{
  public var damage:int = 0;
  public var image:String = '';

  private var properties:Object;
  private var state:String;

  public function Material(properties)
  {
    this.properties = properties;
  }

  public function apply(effect:String):void
  {
    if(properties[effect])
    {
      if(properties[effect][state])
      {
        update(properties[effect][state]);
      }
      else if(properties[effect]['normal'])
      {
        update(properties[effect]['normal']);
      }
    }
    state = effect;
  }

  private function update(properties):void
  {
    damage += properties.damage;
    image = properties.image;
  }
}

var brick = new Material(materialProperties.brick);
brick.apply('fire');
brick.apply('water');