简体   繁体   中英

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.

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:

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.

On Windows you can use the GetAsyncKeyState() function.

For an equivalent on Linux see this question .

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 . 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.

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 . Make your update_movements or whatever function, and call it every N miliseconds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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