2011-08-11 64 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的工作。簡而言之,你的元素(磚,混凝土等)都允許遊客(火,冰,酸等)來「拜訪」它們並應用它們的效果。

希望這會有所幫助!