2

次のコードを検討してください。

class GameEventsManager
{
    public void StartGameEvent(GameEvent TheGameEvent)
    {       
        SubscribeToGameEvent(TheGameEvent);
        TheGameEvent.Begin();
        UnsubscribeToGameEvent(TheGameEvent);
    }

    private void SubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound += OnPlaySound;
        TheGameEvent.OnShowWrittenItem += OnShowWrittenItem;
            ...
    }

    private void UnsubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound -= OnPlaySound;
        TheGameEvent.OnShowWrittenItem -= OnShowWrittenItem;
            ...
    }
}

GameEvent は、基本的にこれを行うクラスです。Begin() が呼び出されると、GameEventManager に渡されるイベントが発生し、ゲーム環境に適切な変更を「加える」ことができます (これは、イベントをさらにオブザーバー パターンのように、特定の各命令の実行を担当するオブジェクト)。

すべての InventoryItems (OnConsume、OnUse などのイベントをトリガーできる) は、特定のクラスの静的フィールドであることを考慮してください。これは端が少し荒いように見えるかもしれませんが、できることは次のとおりです。

AddItem(WrittenItems.NoteFromKing) //NoteFromKing is a static field in WrittenItems

非常に複雑なゲームに取り組んでいることを考えると、これは歓迎すべき光景です。

ただし、これにより、必要な場合に備えて、ゲームのすべてのアイテムをどこかにリストすることが非常に困難になります。それは私の質問に私たちをもたらします:

プレーヤーがレベル内の特定のアイテムを操作するときなどを管理する LevelManager は、必要に応じて特定の GameEvent を実行するように GameEventsManager に指示します。次に、GameEventsManager が GameEvent をサブスクライブし、開始してから、サブスクライブを解除します。このサブスクライブ/実行/サブスクライブ解除のパターンに従っていると、顕著なパフォーマンスの問題が発生すると予想できますか? 最終的に、マネージャーは GameEvent 内の約 20 のイベントをサブスクライブ/サブスクライブ解除する可能性があります。

サブスクライブ/サブスクライブ解除メカニズムが遅い場合は、ゲームの初期化時に実行される単一のサブスクライブ プロセスを作成できますが、それではすべてのアイテムを一覧表示するために余分な構造を構築する必要があります。

要するに、この種の実装によってかなりの速度低下が予想されるかどうかを知りたいのです。より正確には、約 20 のイベントをサブスクライブしてから、それらのサブスクライブを解除すると、かなり時間がかかります。

言語は C# で、Unity 4 で .NET 2.0 サブセットを使用しています。

4

1 に答える 1

0

ただし、これにより、ゲームのすべてのアイテムをどこかにリストするのが非常に難しくなります

なんでそうなの?ItemManager (シングルトン) を作成できます。

public class ItemManager
{
    private static volatile ItemManager _instance;
    private static object syncRoot = new Object();

    private ObservableCollection<ItemBase> _registeredItems = new ObservableCollection<ItemBase>();
    private ItemManager()
    {
    }

    public ItemManager Instance
    {
        get
        {
             if (instance == null) 
             {
                 lock (syncRoot) 
                 {
                     if (instance == null) 
                         instance = new ItemManager();
                 }
             } 
             return instance;
        }
    }

    public void RegisterItem(ItemBase item)
    {
        _registeredItems.Add(item);
        // Do some stuff here, subscribe events, etc.
    }

    public void UnregisterItem(item)
    {
        // Do some stuff here, unregister events, etc.
        _registeredItems.Remove(item)
    }

}

その後、すべてのアイテム クラスを「ItemBase」というクラスから派生させます。そして ItemBases コンストラクターでは、これを呼び出します:

ItemManager.Instance.RegisterItem(this);

したがって、すべての項目を手動で追加する必要はありません。シングルトン パターンの詳細については、http: //msdn.microsoft.com/en-us/library/ff650316.aspxを参照してください。

これには、GameManager と ItemManager の間の一般的な通信を実装できるという利点もあります。

于 2013-01-01T17:14:29.330 に答える