2017-06-13 82 views
1

在一個典型的RPG設置中,我試圖製作一個可以處理來自角色能力的附加效果的事件設計。事件和多態設計

我的主要問題是使這樣的系統多態,所以我可以添加任何我想要的效果,而不用掙扎參數或返回類型的問題。

下面是我迄今所做的爲例:

public abstract class Character 
{ 
    public int CurrentMP { get; set; } 
    public List<ISkill> Moveset { get; protected set; } 
    // the rest doesn't matter i guess 
} 

public interface ISkill 
{ 
    string Name { get; set; } 
} 

public class Weaponskill : ISkill 
{ 
    public int Potency { get; protected set; } 
    public IEffects AdditionalEffect { get; set; } 
} 

public class Warrior : Character 
{ 
    public Warrior() 
    { 
     Moveset = new List<Move.ISkill>() 
     { 
      new Weaponskill("Sword Slash", 100, new ManaGain(this, 707)) 
     } 
    } 
} 

在另一個命名空間的事件。

namespace Additional_Effects 
{ 
    public delegate void EffectEventHandler(Character character, int gain); 

    public interface IEffects 
    { 
      event EffectEventHandler Event; 
    } 

    public class ManaGain : IEffects 
    { 
     public ManaGain(Character character, int gain) 
     { 
      Event += OnEffect; 
     } 

     public event EffectEventHandler Event; 

     protected virtual void OnEffect(Character character, int gain) 
     { 
      character.CurrentMP += gain; 
     } 

     public void Execute(Character character, int gain) 
     { 
      if (Event != null) 
       Event(character, gain); 
     } 
    } 
} 

我的主要問題是委託的參數類型和數量及其返回類型不靈活。我可能需要一個完全不同於另一個IEffects實現的代理。我怎樣才能改變我的事件系統來實現呢?

此外,在我作爲示例的IEffects實例的情況下,我不確定屬性CurrentMP是否實際上是在方法外部修改的,我對通過值或引用在這裏傳遞參數有疑問。

最後,我想我不能叫我從我的Weaponskill類Execute方法,因爲它知道IEffect而不是它的具體實現,但我不能有接口的執行方法,因爲我將不得不處處甚至實現它如果參數需求可能會在每個具體實現中發生變化

回答

0

對於委託,也許你可以使用不同的簽名喜歡這裏:C# - Is it possible to have multiple method signatures for an Action<>?

如果我記得很清楚,在C#中,只能從VALUETYPE得到的對象是按值傳遞。如果需要,您可以通過引用關鍵字ref來傳遞它們。但我不認爲這是性格的情況。

當然,你不能從IEffect調用execute,因爲Execute是Managain的一個函數。您必須編寫執行的簽名和您希望能夠從IEffect調用的每個函數。

+0

所以我的字符屬性實際上是更新?那很好。我知道我不能從IEffect調用Execute,但我也不想在每個子類中實現一個執行有用的只有一個。 我正在看你的鏈接,它看起來很有希望第一眼 –

+0

我不認爲有IEffect的其他方式。您也可以使用繼承,因爲只有母類才具有該功能,並且您仍然可以在某些子類中覆蓋它。但是如果你不想在每個類中實現一個函數,接口不是一個好的工作方式 – 2017-06-13 13:32:34