我希望得到一个数组,表示用户只按下所有按键(不按下,只是按下,就像你正在输入一样)。我认为最好的方法是使用3个数组 - currentKeyboard(cK),previousKeyboard(pK),并在函数中获取当前按下的键,返回键盘(rK)。
假设cK和pK看起来像这样:
pK = [1 1 0 1 0 1]
cK = [0 1 1 0 1 0]
两者上的按位OR应该返回
rK = cK | rK //[1 1 1 1 1 1]
通过在rK和pK上使用按位XOR,它应该给我当前被按下的按键,这些按键之前没有被按下。
[1 1 0 1 0 1]
XOR [1 1 1 1 1 1]
------------------
[0 0 1 0 1 0]
然而,当我运行我的代码时,似乎我总是回到0数组。 (我假设我的按位运算没有出错;如果我这样做,请告诉我!)
以下是获取按键的代码:
Uint8* KeyboardController::getPressedKeys()
{
Uint8* r_Keyboard= new Uint8[283];
//Loop through every SDL_SCANCODE(starting at 4) and set them to 0 in r_Keyboard
for (int i = 0; i < 283; i++) {
r_Keyboard[i] = 0;
}
//If there is a previous keyboard to compare to
if (m_preKeyboard) {
//Now, compare m_curKeyboard to m_preKeyboard and set 1 in r_Keyboard to any differences (OR pK and cK, then XOR pK with the resultant of OR)
for (int i = 4; i < 283; i++) {
r_Keyboard[i] = m_preKeyboard[i] | m_curKeyboard[i];
r_Keyboard[i] = m_preKeyboard[i] ^ r_Keyboard[i];
}
}
//Testing - am I just getting back a 0 array?
for (int i = 0; i < 283; i++) {
if (r_Keyboard[i]) {
printf("%d\n", i);
}
}
return r_Keyboard;
}
我设置m_curKeyboard和m_preKeyboard的函数:
void KeyboardController::Update()
{
if (m_curKeyboard) {
m_preKeyboard = m_curKeyboard;
}
m_curKeyboard = SDL_GetKeyboardState(NULL);
}
这是主循环代码:
bool isOn = true;
while (isOn)
{
//Pump events(Needed for SDL_GetKeyboardState to work)
SDL_PumpEvents();
keyboard->Update();
//Get window surface
screenSurface = SDL_GetWindowSurface(window);
//Fill the surface white
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
//Update the surface
SDL_UpdateWindowSurface(window);
Uint8 *keysPressed = keyboard->getPressedKeys();
if (keysPressed[SDL_SCANCODE_A]==1) {
printf("A key pressed!\n");
}
if (keysPressed[SDL_SCANCODE_S]==1) {
printf("S key was pressed!\n");
}
if (keysPressed[SDL_SCANCODE_ESCAPE]==1){
isOn = false;
//delete keysPressed;
}
}
现在,如果我在getPressedKeys()函数中注释掉OR或XOR行,我将从程序中获得输出。然而,它是徒劳的,因为它会垃圾输出看到一个键被按下而不是被按下。
答案 0 :(得分:2)
您可以使用标准模板库轻松完成此操作。这是一个小例子。另请注意,您需要修复返回临时引用(请参阅我对该问题的评论)。移至std::vector
(如本例所示)将使您的生活更轻松:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
// previous keyboard presses
std::vector<int> prev_kb{0, 0, 0, 1, 1, 0, 0, 0, 1, 1};
// current keyboard presses
std::vector<int> next_kb{0, 1, 1, 1, 1, 1, 0, 0, 1, 0};
// combined keyboard - sized to the size of next
std::vector<int> combined(next_kb.size());
// apply the logical_or<int> algorithm to each keyboard press
std::transform(
prev_kb.begin(),
prev_kb.end(),
next_kb.begin(),
combined.begin(),
logical_or<int>());
// print to verify it worked
std::for_each(
combined.begin(),
combined.end(),
[] (int c)
{
cout << c << ' ';
});
return 0;
}
答案 1 :(得分:1)
我猜SDL_GetKeyboardState
总是返回相同的指针。所以这个:
if (m_curKeyboard) {
m_preKeyboard = m_curKeyboard;
}
真的是无操作。您需要分配和复制数组:
void KeyboardController::Update()
{
if (m_curKeyboard) {
if (!m_preKeyboard)
m_preKeyboard = new Uint8[283];
for (int i = 0; i < 283; i++) {
m_preKeyboard[i] = m_curKeyboard[i];
}
}
if (!m_curKeyboard)
m_curKeyboard = new Uint8[283];
auto curKeyboard = SDL_GetKeyboardState(NULL);
for (int i = 0; i < 283; i++) {
m_curKeyboard[i] = curKeyboard[i];
}
}