XNA pressing keys

本文关键字:keys pressing XNA | 更新日期: 2023-09-27 18:06:07

我需要在游戏中制作一个菜单。我做到了,但如果我想进入"选项"部分,我不能回到主菜单。首先,我在屏幕上绘制基本图像(游戏邦注:如游戏、选项和退出),如果计数器为0,我将在另一张图像上方绘制另一张具有不同效果的图像。看这里(我没有重写所有的代码):

int count=0;
KeyboardState state=Keyboard.GetState();
if(count <6)//main menu
    {
        //if i press "UP" key count -- 
        //if I press "Down" key count++

        //and i did:
        if(count==0)//and I press "enter"
        {
        //Play
        }
        if(count==1)//and I press "enter"
        {
        // count =6 and go to the opstions
        }
        if(count==2)//and I press "enter"
        {
        //Exit
        }
        //This functions!
    }
        //now i am in Options section
        if(count>5)
        {
            //here I have some options including "back button" which is number 8
        if(count==8)
        {
            if(Keyboard.GetState().IsKeyDown(Keys.Enter) && state.IsKeyUp(Keys.Enter))
        {
            count=1;//and I should move in Main menu BUT IT DOESN'T FUNCTION!! WHY?
        }
         state=Keyboard.GtState();
        }
        }

XNA pressing keys

我有一些改进您的输入内容的建议,您可能会觉得有用。我正在运行的假设,这是一个更新功能,因为你似乎抓住状态,并在整个过程中使用它(请,让我知道如果我错了)。

要检查并查看一个键是否被按了一次(没有保持),您可以通过存储两个keyboardstate来实现,如下所示。

// You need to store these in your class, not locally
KeyboardState m_PreviousState;
KeyboardState m_CurrentState;

接下来你要把它放在你的更新函数中:

// At the start of the function, put this
m_CurrentState = Keyboard.GetState();
// do whatever your update function is supposed to do
// At the end of the function, put this
m_PreviousState = m_CurrentState;

它的作用是每帧获取当前状态,这样你就知道键盘当前的状态。通过在m_PreviousState中存储最后一帧的状态,你现在可以检查并查看是否按下了一个键。要做到这一点,您需要这样做:

if (m_CurrentState.IsKeyUp(Keys.Enter) && m_PreviousState.IsKeyDown(Keys.Enter))
{ /* Run whatever logic */ }

这将解决您的按键问题。至于你的菜单,我建议使用枚举来跟踪你在菜单上的进度。让我来布局一个基本的菜单,以及如何通过编程来实现它。

Play
Load Save
Options
  - Mute Sound
  - Mute Volume
  - Raise / Lower Volume
Quit

让我们假设这是您的菜单(请填写您的菜单)。我会存储主菜单(播放,加载保存,选项和退出)在它自己的枚举,我会存储的东西在选项子菜单(静音声音,静音音量,提高/降低音量)它是自己的枚举也是如此。这可以按照如下所示完成:

// Putting MAX and MIN in both of them will be useful later, just trust me
public enum MenuOptions
{
    MIN = -1,
    PLAY,
    LOAD_SAVE,
    OPTIONS,
    QUIT,
    MAX
}
public enum OptionsOptions // Yes, i know its not the best name
{
    MIN = -1,
    MUTE_SOUND,
    MUTE_VOLUME,
    RAISE_LOWER_VOLUME,
    MAX
}
// Create your variables in your class at the top
private MenuOptions m_CurrentMenuOption;
private OptionsOptions m_CurrentOptionsOption;
private Bool m_InOptions; // We will need this shortly

现在我们已经为每个菜单和子菜单以及用来存储它们的变量创建了枚举,现在我们有了一种易于阅读的方式来跟踪我们当前在每个菜单中的位置。现在是我们把它们组合起来的部分。

我通常使用事件处理程序进行键输入,以便它可以与更新函数分开运行,但我将假设您想要使用更新函数。你可以这样做:

// If Enter was just pressed, move into the submenu if it exists
if (m_CurrentState.IsKeyUp(Keys.Enter) && m_PreviousState.IsKeyDown(Keys.Enter))
{
    // If we are currently hovering over options, we should move into that submenu
    if (m_CurrentMenuOption == MenuOptions.OPTIONS)
    {
        // Make sure to reset all other bools like this if you have any to avoid
        // confusing bugs later
        m_InOptions = true;
    }
}
// If Down was pressed, move the enum value we store
else if (m_CurrentState.IsKeyUp(Keys.Down) && m_PreviousState.IsKeyDown(Keys.Down))
{
    // Check to see if we are in options submenu so we can move that value rather than 
    // the main menu's value
    if (m_InOptions)
    {
        m_CurrentOptionsOption++;
        // Checks to see if you went further than the last option and sets it to the
        // last option if you did
        if ((int)m_CurrentOptionsOption >= (int)OptionsOptions.MAX)
            m_CurrentOptionsOption = OptionsOptions.RAISE_LOWER_VOLUME;
    }
    else // You could add some else ifs before for other sub menus
    {
        // Since we are not in a submenu, update the current menu option
        m_CurrentMenuOptions++;
        // Checks to see if you went further than the last option and sets it to the
        // last option if you did
        if ((int)m_CurrentMenuOptions >= (int)MenuOptions.MAX)
            m_CurrentMenuOption = MenuOptions.QUIT;
    }
}
// If Up was pressed, move the enum value we store
else if (m_CurrentState.IsKeyUp(Keys.Up) && m_PreviousState.IsKeyDown(Keys.Up))
{
    // Check to see if we are in options submenu so we can move that value rather than
    // the main menu's value
    if (m_InOptions)
    {
        m_CurrentOptionsOption--;
        // Checks to see if you went further than the first option and sets it to the
        // first option if you did
        if ((int)m_CurrentOptionsOption <= (int)OptionsOptions.MIN)
            m_CurrentOptionsOption = OptionsOptions.MUTE_SOUND;
    }
    else // You could add some else ifs before for other sub menus
    {
        // Since we are not in a submenu, update the current menu option
        m_CurrentMenuOptions--;
        // Checks to see if you went further than the first option and sets it to the
        // first option if you did
        if ((int)m_CurrentMenuOptions <= (int)MenuOptions.MIN)
            m_CurrentMenuOption = MenuOptions.PLAY;
    }
}
// If Backspace was pressed, move back a menu if possible
else if (m_CurrentState.IsKeyUp(Keys.Back) && m_PreviousState.IsKeyDown(Keys.Back))
{
    if (m_InOptions) // you would tack on some || or else ifs for any other submenus
    {
        m_InOptions = false;
    }
}

对于这段代码,基本上是这样做的:

  1. 检查是否按下了回车键。如果是,则移动到子菜单(如果存在的话)。如果需要,您可以在那里进一步添加代码来更改菜单。
  2. 检查是否按下。
  3. 查看up是否被按下。
  4. 检查是否按下退格键。如果是,你移回一个菜单(如果可能)。

我希望这能澄清你如何去做你的菜单的东西。我唯一遗漏的代码是draw函数。只要弄清楚如何绘制当前菜单,你就会没事的。祝你好运!

你不能检查这个:

if(Keyboard.GetState().IsKeyDown(Keys.Enter) && state.IsKeyUp(Keys.Enter))

它将永远为假,因为当您声明

时,键不能同时为down和up。
KeyboardState state=Keyboard.GetState(); 

为什么使用这个:

Keyboard.GetState().IsKeyDown(Keys.Enter)

而不是

state.IsKeyDown(Keys.Enter)