简体   繁体   English

如何在sdl中同时使用键盘的两个键

[英]How to use two keys of keyboard simultaneously in sdl

I'm writing a simple game in C with SDL and I have defined that player one controls it's_for example_tank with arrow key of the keyboard and player two controls it's tank with the keys "W","A","S","D" of the key board.我正在用 SDL 用 C 语言编写一个简单的游戏,我已经定义了玩家一控制它_例如_tank 用键盘的箭头键和玩家二控制它的坦克用键“W”、“A”、“S”,键盘的“D”。

My problem is they can't press the keys simultaneously.我的问题是他们不能同时按下这些键。

I have a function called "handle_events" that controls the events in the infinite while of the game and it's code is like below:我有一个名为“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);
            }

        }

I'm looking for a way that two players can play simultaneously because right now if for example both players press the up key and the w key, none of them can move their tank.我正在寻找一种让两个玩家可以同时玩的方式,因为现在如果两个玩家同时按下向上键和 w 键,他们都不能移动他们的坦克。

On Windows you can use the GetAsyncKeyState() function.在 Windows 上,您可以使用GetAsyncKeyState()函数。

For an equivalent on Linux see this question .对于 Linux 上的等效项,请参阅此问题

It appears you rely on key repeat - feature of operating/windowing system to repeat last pressed key with fixed interval after some initial pause, eg when you keep key pressed in text editor it starts filling that symbol after some delay.看来您依赖于按键重复 - 操作系统/窗口系统的功能在一些初始暂停后以固定间隔重复上次按下的按键,例如,当您在文本编辑器中按住按键时,它会在一些延迟后开始填充该符号。 Only last key is repeated though.但是只重复最后一个键。

With SDL, you should know when key is repeated from repeat field of keyboard event .使用 SDL,您应该知道何时从键盘事件的repeat字段中repeat However, you almost never want to make prolonged movement based on keypress event.但是,您几乎从不想根据按键事件进行长时间的移动。 With your current scheme, I can press a key very quickly and tank will move faster, or I can modify my OS repeat interval.使用你当前的方案,我可以非常快速地按下一个键,坦克会移动得更快,或者我可以修改我的操作系统重复间隔。 Movement, if supposed to be at constant speed, should rely on time, not how fast user can press a button.运动,如果应该是匀速的,应该取决于时间,而不是用户按下按钮的速度。 That is why you only need to take nothion of "ok, button A pressed, - as long as it pressed, I will attempt to rotate left at each fixed update interval", and when you get key-released event - you drop that intention.这就是为什么你只需要考虑“确定,按钮 A 按下, - 只要它按下,我就会尝试在每个固定的更新间隔向左旋转”,当你得到按键释放事件时 - 你放弃了这个意图.

As Danny_ds said, it is often much easier and robust to use key state array instead of events (mostly because of repeat) - with SDL, you can get that via SDL_GetKeyboardState .正如 Danny_ds 所说,使用键状态数组而不是事件(主要是因为重复)通常更容易和健壮 - 使用 SDL,您可以通过SDL_GetKeyboardState获得它。 Make your update_movements or whatever function, and call it every N miliseconds.制作您的update_movements或任何函数,并每 N 毫秒调用一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM