【问题标题】:Button press calls method multiple times按钮按下多次调用方法
【发布时间】:2012-11-07 20:39:39
【问题描述】:

我正在开发一款 XNA 游戏,但遇到了问题。每当我在游戏中按下一个键时,按键触发的方法就会被多次调用。例如,当用户按下攻击按钮(空格)时,角色会在一次按键内攻击 10 次。我希望按键仅触发一次该方法。即使用户按住一个键,我也希望某些方法只调用一次。现在我已经通过在每次按下按钮后编写一个 thread.sleep 来解决它,但这似乎非常低效。我希望我的问题可以理解。提前致谢!

【问题讨论】:

  • 你需要一个标志。释放键时重置标志。

标签: c# xna


【解决方案1】:

您需要在 keydown 上将按钮标记为按下,然后在 keyup 上将其标记为未按下。在keydown方法期间..检查按钮是否已经按下..如果是..在keyup设置它之前什么都不做。

原因是,在按键期间,您的应用程序/游戏/任何东西通过其消息队列每秒接收数千条消息。即使您非常快速地敲击空格键,也有可能通过消息队列处理了大约 50 条 WM_KEYDOWN 消息。

例子:

bool SpacebarPressed = false;

private void KeyDown() {
    if (!SpacebarPressed) {
        SpacebarPressed = true;
        DoSomethingWithSpacebarBeingPressed();
    }
}

private void KeyUp() {
    if (SpacebarPressed) SpacebarPressed = false;
}

【讨论】:

    【解决方案2】:

    我知道这已经回答了,但是你可以使用这样的方法。 让 oldKeyBoardState 落后于当前一帧,并且在做IsKeyToggled(Keys.Space)

    bool IsKeyToggled(Keys key)
    {
        if (!oldKeyBoardState.IsKeyDown(key) && keyboardState.IsKeyDown(key))
           return true;
        else
           return false;
    }
    

    使用后面设置一个,需要2个全局变量。

     public static KeyboardState keyboardState;
     public static KeyboardState oldKeyBoardState;
    

    您的Update() 方法应如下所示:

     protected override void Update(GameTime gameTime)
     {
       keyboardState = Keyboard.GetState();
       //TODO: Add update logic here
       //This comes last
       oldKeyBoardState = keyboardState;
     }
    

    【讨论】:

    • 我使用相同的解决方案,但我认为如果您添加 Update() 方法代码以突出显示您更新键盘状态的位置,您可以稍微改进您的答案。 (即澄清“落后一帧”)
    【解决方案3】:

    您需要在第一次按下键时设置一个标志,然后在释放键时重置。一个粗略的例子:

    if(keyIsPressed() && !myFlag)
    {
       //do stuff
       myFlag = true;
    }
    else if(!keyIsPressed())
       myFlag = false;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-01
      • 2012-12-26
      • 2019-02-20
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      相关资源
      最近更新 更多