XNA按键

时间:2014-05-31 12:04:15

标签: c# xna xna-4.0

我需要在游戏中制作一个菜单。我做到了,但如果我想进入内部"选项"部分我无法返回主菜单。首先,我在屏幕上绘制了基本图像(播放,选项和退出),如果计数器是例如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();
        }
        }

2 个答案:

答案 0 :(得分:1)

你无法检查:

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

它总是假的,因为当你声明了

时,钥匙不能同时向下和向上
KeyboardState state=Keyboard.GetState(); 

为什么要用这个:

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

而不是

state.IsKeyDown(Keys.Enter)

答案 1 :(得分:0)

我有一些改进您输入内容的建议,您可能会发现它们很有用。我假设这是一个更新功能,因为你似乎首先抓住状态并在整个过程中使用它(如果我错了,请告诉我。)

要检查并查看按键是否被按下一次(未按住),您可以通过存储两个KeyboardStates来实现,如下所示。

// 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. 检查是否按下了向上。如果是,则向上移动当前菜单。
  4. 检查是否按下了退格键。如果是,则返回菜单(如果可能)。
  5. 我希望这可以澄清你如何去做你的菜单。我遗漏的唯一代码是你的绘图功能。只是弄清楚如何绘制当前菜单是什么,你会没事的。祝你好运!