我的编程逻辑是否正确?
const char IsPressed = 1; // 1
const char WasHeldDown = 2; // 10
const char IsFirstPress = 4; // 100
char* keystates[256];
Class::CalculateKeyStates()
{
for(int i = 0; i < 256; ++i)
{
if(this->IsDown(i))
{
keystates[i] |= IsPressed; // turn on
if(keystates[i] & WasHeldDown)
{
//keystates[i] |= IsFirstPress;
keystates[i] &= ~IsFirstPress; // turn off
}
else
{
keystates[i] |= WasHeldDown + IsFirstPress; // Turn on
}
}
else
{
keystates[i] = 0; // Turn ALL off
}
}
}
该函数将是类Class的成员函数。另一个成员函数IsDown将返回true,如果有问题的关键字是关闭的,否则返回false。我的编程逻辑是否正确?
你能看到进一步改进这个功能的方法吗?
感谢
编辑:
我将扩大一点,什么是做为什么。这是对通过数组keyStates(这是三个bools的结构)设置的所有密钥的IsPressed设置为false的代码的修改。然后再次将Ispressed设置为this-> IsDown的值,然后第三次循环检查密钥是否已被保留,如果已经不再按第一次,则将其设置为false。如果它没有被按下,那么先设置为true并且保持为真,那么下次它被标记为已被保持。
EDIT2:
添加到代码的一些意见和纠正一行
就个人而言,我会定义密钥状态为不相交的状态,写一个简单的状态机,即:
enum keystate
{
inactive,
firstPress,
active
};
keystate keystates[256];
Class::CalculateKeyStates()
{
for (int i = 0; i < 256; ++i)
{
keystate &k = keystates[i];
switch (k)
{
inactive:
k = (isDown(i)) ? firstPress : inactive;
break;
firstPress:
k = (isDown(i)) ? active : inactive;
break;
active:
k = (isDown(i)) ? active : inactive;
break;
}
}
}
这是容易扩展和易于阅读,如果它得到任何更加复杂。
我真的应该停止忘记关于C++中的枚举,而不仅仅是c#。我喜欢这个解决方案,如果你认为第一次按压是一个单独的状态重复保持,那么确实会提供帮助。 IsDown是一个不是数组顺序的函数,但这不应该在这里有所作为。 – thecoshman 2010-10-21 15:04:56
+1状态机建议。 – mouviciel 2010-10-21 15:05:24
你总是设置IsFirstPress
如果该键一次,这可能不是你想要的。
我不确定你想用IsFirstPress
达到什么目的,因为关键状态无法记住任何以前的印刷。如果你想用这个标记来标记,那是你第一次识别出键被关闭,那么你的逻辑在对应的if
语句中是错误的。
keystates[i] & WasHeldDown
如果您已经为此密钥状态更早地设置了位WasHeldDown
,则其结果为真。 在这种情况下,您可能想要执行的操作实际上是通过移除IsFirstPress
位:keystates[i] ^= IsFirstPress
你的权利,我错了,我试图转向IsFirstPress。我确实有代码只是打开它,但我想让它只是转过来,而不是切换。更正了我的问题。 – thecoshman 2010-10-21 15:11:56
添加注释?关于你想要做什么以及为什么你这样做,以及你的函数的输入和输出是什么。 – mouviciel 2010-10-21 14:41:35
有点偏离主题,但许多键盘API都是基于事件的,在这种情况下,您只需监听关键事件并在这些事件中更新模型即可。 – 2010-10-21 14:42:55
@mouviciel,虽然我不会说根本不需要评论。这个代码相当自我解释是不是?显然,没有I/O。我会接受,按比例可以做评论,除非程序员可能应该能够知道按位操作正在做什么。 – thecoshman 2010-10-21 15:07:30