Class XNA如何使用游戏组件组织代码(管理器)

Class XNA如何使用游戏组件组织代码(管理器),class,components,xna,Class,Components,Xna,新华社 如果我有一个button类,我有一个buttonManager类,它根据当前游戏状态(主菜单、游戏中等)管理要绘制到屏幕上的按钮,那么我如何组织代码,以便当我单击按钮时,它将用户带到不同的屏幕。(例如,选项菜单,ingame)。 更具体地说,如果我检查用户是否单击buttonManager中的按钮,我将如何切换游戏并运行实际的游戏(这是一个完全不同的类) 主要游戏类 buttonManager游戏组件(添加按钮) 按钮类 一种方法是使用代理。另一种方法是拥有一个所有类都用来确定状态的全

新华社 如果我有一个button类,我有一个buttonManager类,它根据当前游戏状态(主菜单、游戏中等)管理要绘制到屏幕上的按钮,那么我如何组织代码,以便当我单击按钮时,它将用户带到不同的屏幕。(例如,选项菜单,ingame)。 更具体地说,如果我检查用户是否单击buttonManager中的按钮,我将如何切换游戏并运行实际的游戏(这是一个完全不同的类)

  • 主要游戏类
  • buttonManager游戏组件(添加按钮)
  • 按钮类

一种方法是使用代理。另一种方法是拥有一个所有类都用来确定状态的全局类

如果你不熟悉游戏状态的概念,我在我的网站上有一个教程,可以帮助你了解基本知识(该教程中的最后一个示例也使用了代理!)

您的屏幕类(菜单屏幕、选项屏幕、游戏屏幕等)需要为其显示的每个按钮保留功能。例如:

//in optionsScreen class' update method:
if(input.gamepad.Buttons.A == ButtonState.Pressed && cursorSpriteRect.Intersects(button[0].Rect)
{
  //begin transition into gameplay screen... or whatever
} 

您的游戏必须具有或能够获得对按钮管理器的引用。通常您的游戏将创建并拥有buttonManager

class Game
{
   ButtonManager m_buttonManager;

   ...
}  
您的按钮管理器可以公开类似OnButtonClicked的事件

class ButtonManager
{
   private Button m_playGameButton;

   // delegate to define the type of the event handler
   public delegate void ButtonClickedEventHandler(ButtonId buttonId);

   // event object matching the type of the event handler
   public event ButtonClickedEventHandler OnButtonClicked;

   void Update()
   {
      ...

      if (m_playGameButton.Clicked)
      {
         // Launch the event when appropriate if there are any subscribers
         if (OnButtonClicked != null)
         {
            OnButtonClicked(ButtonId.PlayGame)
         }
      }
   }
}
然后,游戏类可以订阅事件并提供处理程序方法

class Game
{
    ...

    void Initialise()
    {
        m_buttonManager += ButtonClicked;
    }

    void ButtonClicked(ButtonId buttonId)
    {
        switch (buttonId)
        {
            case ButtonId.PlayGame:
                PlayGame();
                break;

            case ButtonId.OptionsMenu:
                OptionsMenu();
                break;
        }
    }

    ...
}
或者,游戏类可以轮询按钮管理器

class Game
{
   ...

   void Update()
   {
      if (m_buttonManager.IsPlayGameButtonHit)
      {
         PlayGame();
      }
      else if (m_buttonManager.IsOptionsMenuButtonHit)
      {
         OptionsMenu();
      }
   }

   ...
}

+1:我就是这样做的,这意味着我可以重复使用我的引擎,而不必在其中硬编码值。