1

首先,我将声明我使用的单例实际上不会在整个应用程序生命周期中出现。它更像是一种封装用户正在发生的事情的方式。

我有几个 GameState,例如 InGame 或 MainMenu,它们有一些非常相似的函数调用,所以我想使用继承来停止复制/粘贴。以下代码是我所拥有的,但它不能按我的意愿工作。这里是:

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)
    {

    }
}

您可能会说我希望能够在其中使用and getofset所以我可以简单地调用 Handle.Update() 并且无论我是从 InGame 还是 Menu 或任何它知道要使用哪个代码的地方调用它。InGameBaseState

显然,我需要提高我的 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 回答