I have code like this to move the player in my game left, right, up, and down:
keysSetRepeat(20, 5);
while (lives) {
scanKeys();
if (keysDownRepeat() & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN)) {
u8 new_x = x;
u8 new_y = y;
if (keysDownRepeat() & KEY_LEFT) {
new_x--;
} else if (keysDownRepeat() & KEY_RIGHT) {
new_x++;
} else if (keysDownRepeat() & KEY_DOWN) {
new_y++;
} else if (keysDownRepeat() & KEY_UP) {
new_y--;
}
// ...
}
// ...
swiWaitForVBlank();
}
Why are the keys not being detected? If I replace keysDownRepeat()
with keysDown()
it works (without the repeat rate, of course). The documentation is no help here.
I had to find the libnds source code to figure this out. Look at the implementation of keysDownRepeat():
uint32 keysDownRepeat(void) {
uint32 tmp = keysrepeat;
keysrepeat = 0;
return tmp;
}
It actually returns the keys then resets them back to 0. This wasn't documented. I solved this by storing the result of keysDownRepeat()
into a variable and using the variable to check the keys:
keysSetRepeat(20, 5);
while (lives) {
scanKeys();
u32 keys_down_repeat = keysDownRepeat();
if (keys_down_repeat & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN)) {
u8 new_x = x;
u8 new_y = y;
if (keys_down_repeat & KEY_LEFT) {
new_x--;
} else if (keys_down_repeat & KEY_RIGHT) {
new_x++;
} else if (keys_down_repeat & KEY_DOWN) {
new_y++;
} else if (keys_down_repeat & KEY_UP) {
new_y--;
}
// ...
}
// ...
swiWaitForVBlank();
}