单身人士继承C#

时间:2012-05-28 22:15:35

标签: c# inheritance singleton

首先我要说明我使用的单身人士在整个应用程序生命周期中都不会出现。它更像是一种封装用户正在发生的事情的方式。

我有几个GameStates,例如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)
    {

    }
}

您可以说我希望能够使用get中的setInGame BaseState,因此我可以简单地调用Handle.Update()无论我是从InGame或菜单中调用它,还是知道使用哪种代码。

显然我需要提高我的OO技能。但是,如果有人可以建议一种方法来实现我想做的事情,或者提出一种不同的方式来实现它,我将不胜感激。感谢。

2 个答案:

答案 0 :(得分: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(...);
}

答案 1 :(得分: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访问单身人士。