如何在sdl中同时使用键盘的两个键
How to use two keys of keyboard simultaneously in sdl
我正在用 C 语言和 SDL 编写一个简单的游戏,我已经定义玩家一控制它's_for example_tank 用键盘的箭头键和玩家二控制它的坦克键盘的键 "W","A","S","D".
我的问题是他们不能同时按键。
我有一个名为 "handle_events" 的函数,它可以在游戏的无限时间内控制事件,它的代码如下所示:
int handle_events(Tank* tank,Tank* tanker, Wall walls[]){
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
return EXIT;
if (event.type == SDL_KEYDOWN){
if(event.key.keysym.sym==SDLK_UP){
move_tank_forward(tank,colliding(tank,walls));
}else if(event.key.keysym.sym==SDLK_DOWN){
move_tank_back(tank,colliding(tank,walls));
} else if(event.key.keysym.sym==SDLK_RIGHT || event.key.keysym.sym==SDLK_LEFT) {
turn_tank(event.key.keysym.sym, tank);
} else if(event.key.keysym.sym==SDLK_w){
move_tank_forward(tanker,colliding(tanker,walls));
} else if (event.key.keysym.sym==SDLK_s){
move_tank_back(tanker,colliding(tanker,walls));
} else if(event.key.keysym.sym==SDLK_d || event.key.keysym.sym==SDLK_a){
turn_tank(event.key.keysym.sym, tanker);
}
}
我正在寻找一种可以让两个玩家同时玩的方法,因为现在如果两个玩家同时按下向上键和 w 键,其中 none 个玩家可以移动他们的坦克。
在 Windows 上您可以使用 GetAsyncKeyState() 功能。
有关 Linux 的等效内容,请参阅 this question。
您似乎依赖按键重复 - operating/windowing 系统的功能在初始暂停后以固定间隔重复最后按下的按键,例如当您在文本编辑器中按住键时,它会在一段时间后开始填充该符号。不过只有最后一个键被重复了。
使用 SDL,您应该知道何时从 keyboard event 的 repeat
字段重复键。但是,您几乎不想根据按键事件进行长时间的移动。使用您当前的方案,我可以非常快速地按下一个键,坦克将移动得更快,或者我可以修改我的 OS 重复间隔。如果运动应该以恒定速度进行,则应该取决于时间,而不是用户按下按钮的速度。这就是为什么您只需要不理会 "ok, button A pressed, - as long as it pressed, I will attempt to rotate left at each fixed update interval",当您收到按键释放事件时 - 您就放弃了那个意图。
正如 Danny_ds 所说,使用键状态数组而不是事件(主要是因为重复)通常更容易和更可靠 - 使用 SDL,您可以通过 SDL_GetKeyboardState 获得它。创建您的 update_movements
或任何函数,并每 N 毫秒调用一次。
我正在用 C 语言和 SDL 编写一个简单的游戏,我已经定义玩家一控制它's_for example_tank 用键盘的箭头键和玩家二控制它的坦克键盘的键 "W","A","S","D".
我的问题是他们不能同时按键。
我有一个名为 "handle_events" 的函数,它可以在游戏的无限时间内控制事件,它的代码如下所示:
int handle_events(Tank* tank,Tank* tanker, Wall walls[]){
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
return EXIT;
if (event.type == SDL_KEYDOWN){
if(event.key.keysym.sym==SDLK_UP){
move_tank_forward(tank,colliding(tank,walls));
}else if(event.key.keysym.sym==SDLK_DOWN){
move_tank_back(tank,colliding(tank,walls));
} else if(event.key.keysym.sym==SDLK_RIGHT || event.key.keysym.sym==SDLK_LEFT) {
turn_tank(event.key.keysym.sym, tank);
} else if(event.key.keysym.sym==SDLK_w){
move_tank_forward(tanker,colliding(tanker,walls));
} else if (event.key.keysym.sym==SDLK_s){
move_tank_back(tanker,colliding(tanker,walls));
} else if(event.key.keysym.sym==SDLK_d || event.key.keysym.sym==SDLK_a){
turn_tank(event.key.keysym.sym, tanker);
}
}
我正在寻找一种可以让两个玩家同时玩的方法,因为现在如果两个玩家同时按下向上键和 w 键,其中 none 个玩家可以移动他们的坦克。
在 Windows 上您可以使用 GetAsyncKeyState() 功能。
有关 Linux 的等效内容,请参阅 this question。
您似乎依赖按键重复 - operating/windowing 系统的功能在初始暂停后以固定间隔重复最后按下的按键,例如当您在文本编辑器中按住键时,它会在一段时间后开始填充该符号。不过只有最后一个键被重复了。
使用 SDL,您应该知道何时从 keyboard event 的 repeat
字段重复键。但是,您几乎不想根据按键事件进行长时间的移动。使用您当前的方案,我可以非常快速地按下一个键,坦克将移动得更快,或者我可以修改我的 OS 重复间隔。如果运动应该以恒定速度进行,则应该取决于时间,而不是用户按下按钮的速度。这就是为什么您只需要不理会 "ok, button A pressed, - as long as it pressed, I will attempt to rotate left at each fixed update interval",当您收到按键释放事件时 - 您就放弃了那个意图。
正如 Danny_ds 所说,使用键状态数组而不是事件(主要是因为重复)通常更容易和更可靠 - 使用 SDL,您可以通过 SDL_GetKeyboardState 获得它。创建您的 update_movements
或任何函数,并每 N 毫秒调用一次。