2011-08-11 63 views
4

所以我有许多物品都具有不同的属性(砖,玻璃等),并且每种物品都受到元素效果的不同影响。例如砖块材料会受到火或酸的影响,而不是水泥材料。当应用另一个燃烧/熔化效果时,正在燃烧或融化的砖块将受到不同的影响。游戏决策设计模式

在我的游戏中,我有一个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)); 

回答

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'); 
+0

不错。我想的方法不一定是压缩编写逻辑的工作,而是在这里很好地实现这种逻辑的表示。我会把问题保留一两天,但这绝对是一个改进。谢谢。 – Ilya

1

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

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

我希望我没有找错了树....如果你能提供更多的对位你想找的,我敢肯定有人比我聪明会跳;)

+1

+1这是一个完美的封装应用的例子。让一个Brick类处理与该砖相关的所有内容。让Bricks类处理所有的Brick对象。 –

+1

是的,我愿意。我正在编辑我的描述。意大利面条代码的数量和大量的功能创建虽然仍然很大。 – Ilya

+1

你正在忘记状态。如果你的Brick类保留了“火或其他”状态,那么你所需要的就是每个状态类中的一个函数。然后课程可以确定要做什么。而且你真的想要变得很光滑,那么只需要一个叫做statChange的函数或者其他东西,并且只需要传入状态。然后让班级确定要更改的状态。 –

1

简短的答案,因为我相信林奎斯特先生在解释它方面做得非常出色 - 但对我来说这听起来像是一份visitor pattern的工作。简而言之,你的元素(砖,混凝土等)都允许游客(火,冰,酸等)来“拜访”它们并应用它们的效果。

希望这会有所帮助!