Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to process several key events at the same time?
Forum Updated to NodeBB v4.3 + New Features

How to process several key events at the same time?

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 3 Posters 6.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Suares
    wrote on last edited by Suares
    #1

    Have you ever heard about Battle City game? In this game you can move (left, up, right and down) your tank and make a shot (fire). I'm working on User Input module and one problem happens when I hold one key, and press another at the same time. If I move my tank and press shot key (space), it stops moving.
    I created own KeyEventFilter class where override eventFilter method:

    bool KeyEventFilter::eventFilter(QObject *, QEvent *event)
    {
    	bool result = false;
    
    	if (event->type() == QEvent::KeyPress) {
    		QKeyEvent *ke = static_cast<QKeyEvent *>(event);
    		const auto key = ke->key();
    
    		qDebug() << "QEvent::KeyPress";
    
    		switch (key) {
    		case Qt::Key_Left:
    		case Qt::Key_Up:
    		case Qt::Key_Right:
    		case Qt::Key_Down:
    		case Qt::Key_Space:
    			if (!ke->isAutoRepeat()) {
    				_keys.insert(key); // _keys is std::set<int>
    			}
    			result = true;
    			break;
    		}
    	} else if (event->type() == QEvent::KeyRelease) {
    		QKeyEvent *ke = static_cast<QKeyEvent *>(event);
    		const auto key = ke->key();
    
                    qDebug() << "QEvent::KeyRelease";
    
    		switch (key) {
    		case Qt::Key_Left:
    		case Qt::Key_Up:
    		case Qt::Key_Right:
    		case Qt::Key_Down:
    		case Qt::Key_Space:
    			_keys.erase(key);
    			result = true;
    			break;
    		}
    	}
    
    	if (result) {
    		for (const auto& key : _keys) {
    			emit Send(MakeCommand(key)); // Send() is a signal. MakeCommand() creates command object according to pressed key.
    		}
    	}
    
    	return result;
    }
    

    Here are messages from debug (<-- - my comments):

    <-- Press Down key.
    QEvent::KeyPress
    "MoveDownCommand::Execute"
    ... <- Still holding.
    QEvent::KeyPress
    "MoveDownCommand::Execute"
    <-- Press 2nd key - Space to fire.
    QEvent::KeyPress
    "ShotCommand::Execute"
    "MoveDownCommand::Execute"
    QEvent::KeyRelease
    "MoveDownCommand::Execute"
    <-- Here I still holding Down key but there are no events except one above.

    Could you please help me how to move tank and fire at the same time?
    Or is there maybe another good way to create key event handler?

    raven-worxR 1 Reply Last reply
    0
    • QT-static-prgmQ Offline
      QT-static-prgmQ Offline
      QT-static-prgm
      wrote on last edited by
      #2

      I'd always run with x and y by a speedvariable. Pressing left/right key will set the speed variable to -1/1, releasing the key, set it to 0. You can do that through signal/slot
      (speedXplus1 - press right and release left, speedXminus1 - press left and release right)
      Pressing space send an other signal to fire

      S 1 Reply Last reply
      2
      • QT-static-prgmQ QT-static-prgm

        I'd always run with x and y by a speedvariable. Pressing left/right key will set the speed variable to -1/1, releasing the key, set it to 0. You can do that through signal/slot
        (speedXplus1 - press right and release left, speedXminus1 - press left and release right)
        Pressing space send an other signal to fire

        S Offline
        S Offline
        Suares
        wrote on last edited by
        #3

        @QT-static-prgm, thank you for answer.
        I'll play around with your proposition as soon as possible.

        1 Reply Last reply
        0
        • S Suares

          Have you ever heard about Battle City game? In this game you can move (left, up, right and down) your tank and make a shot (fire). I'm working on User Input module and one problem happens when I hold one key, and press another at the same time. If I move my tank and press shot key (space), it stops moving.
          I created own KeyEventFilter class where override eventFilter method:

          bool KeyEventFilter::eventFilter(QObject *, QEvent *event)
          {
          	bool result = false;
          
          	if (event->type() == QEvent::KeyPress) {
          		QKeyEvent *ke = static_cast<QKeyEvent *>(event);
          		const auto key = ke->key();
          
          		qDebug() << "QEvent::KeyPress";
          
          		switch (key) {
          		case Qt::Key_Left:
          		case Qt::Key_Up:
          		case Qt::Key_Right:
          		case Qt::Key_Down:
          		case Qt::Key_Space:
          			if (!ke->isAutoRepeat()) {
          				_keys.insert(key); // _keys is std::set<int>
          			}
          			result = true;
          			break;
          		}
          	} else if (event->type() == QEvent::KeyRelease) {
          		QKeyEvent *ke = static_cast<QKeyEvent *>(event);
          		const auto key = ke->key();
          
                          qDebug() << "QEvent::KeyRelease";
          
          		switch (key) {
          		case Qt::Key_Left:
          		case Qt::Key_Up:
          		case Qt::Key_Right:
          		case Qt::Key_Down:
          		case Qt::Key_Space:
          			_keys.erase(key);
          			result = true;
          			break;
          		}
          	}
          
          	if (result) {
          		for (const auto& key : _keys) {
          			emit Send(MakeCommand(key)); // Send() is a signal. MakeCommand() creates command object according to pressed key.
          		}
          	}
          
          	return result;
          }
          

          Here are messages from debug (<-- - my comments):

          <-- Press Down key.
          QEvent::KeyPress
          "MoveDownCommand::Execute"
          ... <- Still holding.
          QEvent::KeyPress
          "MoveDownCommand::Execute"
          <-- Press 2nd key - Space to fire.
          QEvent::KeyPress
          "ShotCommand::Execute"
          "MoveDownCommand::Execute"
          QEvent::KeyRelease
          "MoveDownCommand::Execute"
          <-- Here I still holding Down key but there are no events except one above.

          Could you please help me how to move tank and fire at the same time?
          Or is there maybe another good way to create key event handler?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @Suares
          are you sure this isn't a bug in your game logic?
          I mean since the key handling looks correct that you simply stop moving your tank as soon as another command comes in?

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          S 1 Reply Last reply
          1
          • raven-worxR raven-worx

            @Suares
            are you sure this isn't a bug in your game logic?
            I mean since the key handling looks correct that you simply stop moving your tank as soon as another command comes in?

            S Offline
            S Offline
            Suares
            wrote on last edited by Suares
            #5

            @raven-worx

            As for the first question I'm not sure. I start from User Input module. Now game doesn't have any GUI and update logic. My main loop is very simple:

            while (true)
            {
              auto cmd = processInput(); // I'm working here.
              update(cmd); // Has only one call cmd->Execute();
              render(); // Empty.
              delay();
            }
            

            As for second one, I don't want to stop moving my tank as soon as another command comes in.

            1. Press only one of the move keys (left, up, right, down) - everything is okay.
            2. Press only fire (space) - everything is okay too.
            3. Hold move key and press (not hold) fire key - failure. I can see fire and move commands in debug messages, but after it my tank can't continue moving while I still hold move button. And I noticed there are no more key events in debug messages after pressing and releasing space key for fire. Hmmm...
            raven-worxR 1 Reply Last reply
            0
            • S Suares

              @raven-worx

              As for the first question I'm not sure. I start from User Input module. Now game doesn't have any GUI and update logic. My main loop is very simple:

              while (true)
              {
                auto cmd = processInput(); // I'm working here.
                update(cmd); // Has only one call cmd->Execute();
                render(); // Empty.
                delay();
              }
              

              As for second one, I don't want to stop moving my tank as soon as another command comes in.

              1. Press only one of the move keys (left, up, right, down) - everything is okay.
              2. Press only fire (space) - everything is okay too.
              3. Hold move key and press (not hold) fire key - failure. I can see fire and move commands in debug messages, but after it my tank can't continue moving while I still hold move button. And I noticed there are no more key events in debug messages after pressing and releasing space key for fire. Hmmm...
              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @Suares said in How to process several key events at the same time?:

              As for second one, I don't want to stop moving my tank as soon as another command comes in.

              yes i know.
              As i said, i simply suspect a bug in your game logic in the key event processing -> processInput()

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              S 1 Reply Last reply
              2
              • raven-worxR raven-worx

                @Suares said in How to process several key events at the same time?:

                As for second one, I don't want to stop moving my tank as soon as another command comes in.

                yes i know.
                As i said, i simply suspect a bug in your game logic in the key event processing -> processInput()

                S Offline
                S Offline
                Suares
                wrote on last edited by
                #7

                @raven-worx

                Okay, I'll check it once again.

                1 Reply Last reply
                0
                • QT-static-prgmQ Offline
                  QT-static-prgmQ Offline
                  QT-static-prgm
                  wrote on last edited by
                  #8

                  best way for help is to upload your code somewhere (github) and give us a link to the source. Additionally you can point to the (in your opinion) important part of the code. That way we can easier look for other function, you may thought are not important

                  S 2 Replies Last reply
                  1
                  • QT-static-prgmQ QT-static-prgm

                    best way for help is to upload your code somewhere (github) and give us a link to the source. Additionally you can point to the (in your opinion) important part of the code. That way we can easier look for other function, you may thought are not important

                    S Offline
                    S Offline
                    Suares
                    wrote on last edited by
                    #9

                    @QT-static-prgm

                    It'll be very nice. When I come home I'll push project to github and notify you.

                    1 Reply Last reply
                    0
                    • QT-static-prgmQ QT-static-prgm

                      best way for help is to upload your code somewhere (github) and give us a link to the source. Additionally you can point to the (in your opinion) important part of the code. That way we can easier look for other function, you may thought are not important

                      S Offline
                      S Offline
                      Suares
                      wrote on last edited by
                      #10

                      @QT-static-prgm

                      Hello! I've uploaded project to github.

                      Game.cpp line 8 - create and install my custom event filter.
                      Game.cpp line 22 - main game loop.
                      KeyEventFilter.cpp line 14 - overridden eventFilter method.
                      And UserInput class contains queue with user commands.

                      Thank you for help!

                      raven-worxR 1 Reply Last reply
                      0
                      • S Suares

                        @QT-static-prgm

                        Hello! I've uploaded project to github.

                        Game.cpp line 8 - create and install my custom event filter.
                        Game.cpp line 22 - main game loop.
                        KeyEventFilter.cpp line 14 - overridden eventFilter method.
                        And UserInput class contains queue with user commands.

                        Thank you for help!

                        raven-worxR Offline
                        raven-worxR Offline
                        raven-worx
                        Moderators
                        wrote on last edited by raven-worx
                        #11

                        @Suares
                        your Command::Execute() methods are empty?
                        I guess your Commands (shared pointers) run out of scope as soon as you execute the next command.

                        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                        If you have a question please use the forum so others can benefit from the solution in the future

                        S 1 Reply Last reply
                        1
                        • raven-worxR raven-worx

                          @Suares
                          your Command::Execute() methods are empty?
                          I guess your Commands (shared pointers) run out of scope as soon as you execute the next command.

                          S Offline
                          S Offline
                          Suares
                          wrote on last edited by
                          #12

                          @raven-worx

                          Not exactly. They have one line:

                          qDebug() << ...
                          

                          As for second your sentence. I'm sorry I didn't quite get that. Could you please explain?

                          raven-worxR 1 Reply Last reply
                          0
                          • QT-static-prgmQ Offline
                            QT-static-prgmQ Offline
                            QT-static-prgm
                            wrote on last edited by
                            #13

                            I wonder about the executes, too. You just print things on qdebug, so how you know you are no longer moving when firing?? You're actually never start moving

                            1 Reply Last reply
                            0
                            • S Suares

                              @raven-worx

                              Not exactly. They have one line:

                              qDebug() << ...
                              

                              As for second your sentence. I'm sorry I didn't quite get that. Could you please explain?

                              raven-worxR Offline
                              raven-worxR Offline
                              raven-worx
                              Moderators
                              wrote on last edited by
                              #14

                              @Suares said in How to process several key events at the same time?:

                              As for second your sentence. I'm sorry I didn't quite get that. Could you please explain?

                              But it would be interesting how you exactly implemented the moving. Because thats essential to know when it stops doing what it's supposed to be doing ;)

                              I mean that the commands maybe get deleted because no object holds a reference to it anymore. But again this needs insight how the commands actually work.

                              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                              If you have a question please use the forum so others can benefit from the solution in the future

                              S 1 Reply Last reply
                              0
                              • raven-worxR raven-worx

                                @Suares said in How to process several key events at the same time?:

                                As for second your sentence. I'm sorry I didn't quite get that. Could you please explain?

                                But it would be interesting how you exactly implemented the moving. Because thats essential to know when it stops doing what it's supposed to be doing ;)

                                I mean that the commands maybe get deleted because no object holds a reference to it anymore. But again this needs insight how the commands actually work.

                                S Offline
                                S Offline
                                Suares
                                wrote on last edited by
                                #15

                                @raven-worx

                                If user stop pressing keys - NoCommand will be executed.

                                Please look at UserInput.cpp line 27:

                                return (cmd) ? cmd : std::make_shared<NoCommand>();
                                

                                If there is no command from user - queue is empty that is why I return NoCommand.

                                Definition of this command is:

                                void NoCommand::Execute() noexcept
                                {
                                }
                                
                                raven-worxR 1 Reply Last reply
                                0
                                • S Suares

                                  @raven-worx

                                  If user stop pressing keys - NoCommand will be executed.

                                  Please look at UserInput.cpp line 27:

                                  return (cmd) ? cmd : std::make_shared<NoCommand>();
                                  

                                  If there is no command from user - queue is empty that is why I return NoCommand.

                                  Definition of this command is:

                                  void NoCommand::Execute() noexcept
                                  {
                                  }
                                  
                                  raven-worxR Offline
                                  raven-worxR Offline
                                  raven-worx
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  @Suares
                                  yes, but still it's not clear how the actual moving is implemented...

                                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                  If you have a question please use the forum so others can benefit from the solution in the future

                                  1 Reply Last reply
                                  1
                                  • QT-static-prgmQ Offline
                                    QT-static-prgmQ Offline
                                    QT-static-prgm
                                    wrote on last edited by
                                    #17

                                    you need to have something like this:

                                    void updateScene()
                                    {
                                        littleMan.positionX += moveX;  // you remember what i told you about the moveX variable and the signal?
                                        littleMan.positionY += moveY;
                                    
                                        for(auto& it : boldList)
                                            it.update();  // while this update function will move your bold one step forward in the fire direction.
                                    }
                                    

                                    and your slot for firing will add an bold to the boldList. An bold can be a struct like this:

                                    struct Bold {
                                        QPoint position;
                                        QVector2D direction;
                                        int speed;
                                    }
                                    
                                    1 Reply Last reply
                                    0
                                    • S Offline
                                      S Offline
                                      Suares
                                      wrote on last edited by
                                      #18

                                      Please wait. I need more time to implement real moving for my tank.
                                      I'll show you my way as soon as possible.

                                      1 Reply Last reply
                                      0
                                      • QT-static-prgmQ Offline
                                        QT-static-prgmQ Offline
                                        QT-static-prgm
                                        wrote on last edited by
                                        #19

                                        Man, how you know you stop moving, when you never implemented moving???

                                        S 1 Reply Last reply
                                        0
                                        • QT-static-prgmQ QT-static-prgm

                                          Man, how you know you stop moving, when you never implemented moving???

                                          S Offline
                                          S Offline
                                          Suares
                                          wrote on last edited by
                                          #20

                                          @QT-static-prgm

                                          I implemented movement. If don't belieave you can build project :)
                                          Tank moves, but I can't move and fire at the same time. I want to fix it.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved