1

最初に、アプリの存続期間全体を通して実際には存在しないシングルトンを使用していることを述べます。これは、ユーザーから何が起こっているかをカプセル化する方法です。

InGameやMainMenuなどのいくつかのGameStateがあり、これらには非常によく似た関数呼び出しがあるため、継承を使用してコピー/貼り付けを停止することを考えました。次のコードは私が持っているものですが、意図したとおりに機能しません。ここにあります:

BaseState.cs

abstract class BaseState
{
    protected static BaseState mHandle = null;

    protected static BaseState Handle
    {
        get
        {
            return mHandle;
        }
        set
        {
            mHandle = value;
        }
    }

    public static GameState UpdateState(GameTime gameTime)
    {
        GameState g = GameState.MainMenu;

        try
        {
            Handle.Update(gameTime);
        }
        catch (Exception e)
        {

        }

        return g;
    }

    public static void DrawState(GameTime gameTime, SpriteBatch spriteBatch)
    {
        Handle.Draw(gameTime, spriteBatch);
    }

    public static void Release()
    {
        mHandle = null;
    }

    protected abstract GameState Update(GameTime gameTime);
    protected abstract void Draw(GameTime gameTime, SpriteBatch spriteBatch);
}

InGame.cs

class InGame : BaseState
{
    private InGame()
    {

    }

    protected static new BaseState Handle
    {
        get
        {
            if (mHandle == null)
            {
                mHandle = new InGame();
            }

            return mHandle;
        }
        set
        {
            mHandle = value;
        }
    }

    protected override GameState Update(GameTime gameTime)
    {
        return GameState.Quit;
    }

    protected override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {

    }
}

getおそらく、とsetを使用できるようにしたいのでInGameBaseStateHandle.Update()を呼び出すだけで、InGameやMenuから呼び出した場合でも、使用するコードがわかっている場合でも、を使用できるようになります。

明らかに、私は自分のOOスキルを磨く必要があります。しかし、誰かがこれを私がやりたいことをするための方法を提案したり、それについて別の方法を提案したりすることができれば、私は感謝するでしょう。ありがとう。

4

2 に答える 2

3

達成しようとしていることはシングルトンを必要としません。以下を参照してください。

public abstract class BaseState
{
    public GameState UpdateState(GameTime gameTime)
    {
        GameState g = GameState.MainMenu;

        try
        {
            g = Update(gameTime); // Update returns a new state
        }
        catch (Exception e)
        {

        }

        return g;
    }

    protected abstract GameState Update(GameTime gameTime);
    protected abstract void Draw(GameTime gameTime, SpriteBatch spriteBatch);
}

public class InGame : BaseState
{
    public InGame()
    {

    }

    protected override GameState Update(GameTime gameTime)
    {
        return GameState.Quit;
    }

    protected override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        // Draw game
    }
}

public class InMenu : BaseState
{
    public InMenu()
    {

    }

    protected override GameState Update(GameTime gameTime)
    {
        return GameState.Pause;
    }

    protected override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        // Draw menu
    }
}

public void Foo()
{
    List<BaseState> states = new List<BaseState>();
    states.Add(new InGame());
    states.Add(new InMenu());

    // Calls InGame.Update(...)
    states[0].UpdateState(...);

    // Calls InMenu.Update(...)
    states[1].UpdateState(...);
}
于 2012-05-28T22:31:05.550 に答える
2

静的メンバーをオーバーライドすることはできないので、ここでのアプローチは間違っていると思います。現在のゲーム状態にアクセスできるファクトリクラスまたはマネージャークラス(必要に応じて、シングルトンを使用して現在のインスタンスにアクセスできます)を使用することをお勧めします。

public class GameStateManager
{
    private static GameStateManager _instance = new GameStateManager();

    public static GameStateManager Instance { get { return _instance; } }

    public BaseState Current { get; private set; }

    public GameStateManager()
    {
         Current = new InGame();
    }

    public void ChangeState(GameState state, GameTime gameTime)
    {
         // change your current state here, I'm not really sure about your logic here
         Current.UpdateState(gameTime);

         switch(state)
         {
            case GameState.Menu:
              Current = new MainMenu();
            // etc.
            default:
               throw new NotImplementedException(string.Formatted("The state {0} is not implemented.", state));
         }
    }
}

を使用してシングルトンにアクセスできますGameStateManager.Instance

于 2012-05-28T22:29:26.657 に答える