我正在编程一个游戏,在我的inputhandler类中,我已经编写了一个getKeyState方法,该方法返回是否按下特定的键(bool)。
在某些情况下的问题是,无论我多么努力,按一个键总是花费"太长时间",我的getKeyState方法返回true多次,因为它被调用每一帧。
当我需要特定的操作只执行一次时,我必须这样写:
int n = 0; // global variable
(…)
// --- inside a class method which is called every frame as well: ---
if (Input.getKeyState(key))
{
n++;
if (n == 1)
{
// specific behaviour
}
}
else
{
n = 0;
}
我现在的问题是:我如何在我的InputHandler类中的方法中实现这一点。我不想每次都声明一个计数器变量,我需要一个"键只按一次"的方法。我想调用:
if (Input.isKeyPressedAndTriggerOnlyOncePls())
编辑:您需要检查是否按下键,然后再检查是否按下键。
bool keyPressed = false;
bool InputHandler(){
if(keyPresed == false){
if( key is being pressed ){
keyPressed = true;
return true;
}
}
else{
if( key is not being pressed ){
keyPressed = false;
}
return false;
}
}
Edit2:如果你真的想要InputHandler()做检查,你可以为每个调用者有一个标志数组并给每个调用者一个ID,然后如果InputHandler()被调用,key被按下并且ID的标志为假你返回真,否则你返回假,但是你必须在每次key未按下时重置所有标志。
所以前面的代码看起来像这样:bool arrayReset = true;
bool pressUsed[Number of callers] = {0};
bool InputHandler(int id){
if(key is being pressed){
if( pressUsed[id] == false){
pressUsed[id] = true;
arrayReset = false;
return true;
}
}
else if( key is not being pressed && arrayReset == false){
arrayReset = true;
set pressUsed[] all elements to false;
}
return false;
}
Edit3:如果在同一个循环中多次调用该方法,则可以执行以下操作:
bool keyPressed = false;
bool InputHandler(){
if(key is being pressed && keyPresed == false)
return true;
}
bool InputHandlerWithChange(){
if(keyPresed == false){
if( key is being pressed ){
keyPressed = true;
return true;
}
}
else{
if( key is not being pressed ){
keyPressed = false;
}
return false;
}
}
每次需要检查键是否按下时调用InputHandler()。调用InputHandlerWithChange()在你的循环结束或在你需要检查按键的最后一个地方,这样你所有的调用者将接收true当键被按下,并将停止接收true,直到键被取消。
这样做的一种方法是用静态数据成员创建父类。然后,您可以创建从该类继承的输入处理程序。
// Main parent class
class InputHandlerParent {
public:
InputHandlerParent() {} ;
virtual bool isKeyPressedAndTriggerOnlyOncePls()
{
return keypressed;
}
virtual void setKeyPressed()
{
keypressed = true ;
std::cout << "YOU PRESSED THE KEY!" << std::endl;
}
virtual void unsetKeyPressed()
{
keypressed = false ;
std::cout << "YOU RELEASED THE KEY!" << std::endl;
}
protected:
static bool keypressed ;
private:
};
// Now an example child class
class InputHandlerChild : public InputHandlerParent {
public:
InputHandlerChild() :
InputHandlerParent()
{};
protected:
private:
};
// Define keypressed
bool InputHandlerParent::keypressed = false ;
所有继承的子类都共享keypressed
变量,所以如果您这样做:
#include <iostream>
int main()
{
InputHandlerChild child1 ;
InputHandlerChild child2 ;
std::cout << "Child1 pressed: " << child1.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
std::cout << "Child2 pressed: " << child2.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
// Now set the key as pressed
child1.setKeyPressed() ;
std::cout << "Child1 pressed: " << child1.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
std::cout << "Child2 pressed: " << child2.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
// Unset the key ONLY if it was set for child2
if (child2.isKeyPressedAndTriggerOnlyOncePls()) {
child2.unsetKeyPressed() ;
}
std::cout << "Child1 pressed: " << child1.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
std::cout << "Child2 pressed: " << child2.isKeyPressedAndTriggerOnlyOncePls() << std::endl;
return 0 ;
}
这给出了输出
Child1 pressed: 0
Child2 pressed: 0
YOU PRESSED THE KEY!
Child1 pressed: 1
Child2 pressed: 1
YOU RELEASED THE KEY!
Child1 pressed: 0
Child2 pressed: 0
所以即使我只按了一个孩子,每个人都知道它被按了。基本上,只要按下键,就可以调用setKeyPressed()
将keypressed
设置为true。然后,当动作发生时,取消设置的键,你可以调用unsetKeyPressed()
,让每个人都知道该键不再按下。