   Input management
  Hi,with the following code, my camera moves with some latency and its movements are not continuous/smooth such as in any game (eg quake).switch(uMsg){    case WM_KEYDOWN:    {   if((int)wParam == KEYBOARD_ARROW_UP || (int)wParam == KEYBOARD_W)   {    Camera.Move(0.0f, 0.0f, -10.0f);}if((int)wParam == KEYBOARD_ARROW_DOWN || (int)wParam == KEYBOARD_S){    Camera.Move(0.0f, 0.0f, 10.0f);}...   ...    }}What could that be due to?Is it a programming problem - should I do something like:switch(uMsg){    case WM_KEYDOWN:    {   if((int)wParam == KEYBOARD_ARROW_UP || (int)wParam == KEYBOARD_W)   {    Camera.StartMoving(0.0f, 0.0f, -10.0f);}if((int)wParam == KEYBOARD_ARROW_DOWN || (int)wParam == KEYBOARD_S){    Camera.StartMoving(0.0f, 0.0f, 10.0f);}...   ...    }    case WM_KEYUP:    {   if((int)wParam == KEYBOARD_ARROW_UP || (int)wParam == KEYBOARD_W)   {    Camera.StopMoving();}if((int)wParam == KEYBOARD_ARROW_DOWN || (int)wParam == KEYBOARD_S){    Camera.StopMoving();}...   ...    }}or is it because of the way windows manages messages and I should change the way I control the user input?Thanks!   
  There's a few problems with your approach. First of all, it doesn't take time into account: if your framerate drops, your movement speed drops as well, because you're moving the same distance each frame. Secondly, this code ties camera movement to input handling - but these are two unrelated things. When you have to add a menu to your game or simulation, you suddenly find yourself putting checks for that in your input code...Who or what owns the camera? Make that code responsible for checking the input state (either by polling it, or by receiving events from the input code) and make it control the camera. The input handling itself should not concern itself with how it's used.   ;  Hello,Captain P has a very good point , don't combine the game logic with the input management;A solution to that would be:case WM_KEYDOWN: KeysPressd[wParam] = true; break;case WM_KEYUP: KeysPressd[wParam] = false; break;where KeysPressed is a bool [256];In your main loop ,each frame you check if  KeysPressed[KEYBOARD_ARROW_UP]==true or whatever key you want to see if is pressed, if yes you COMPUTE THE DELTA TIME and adjust the movement according to the delta. This is a simplified system , you can build on top of this stuff to check when the key is released or other stuff, but the main purpose of WndProc is just to do assign true or false to that vector.Raxvan   ;Quote:Original post by Makaancase WM_KEYDOWN: KeysPressd[wParam] = true; break;case WM_KEYUP: KeysPressd[wParam] = false; break;where KeysPressed is a bool [256];Sure this will work, but it's not really an improvement. You are flattening out the buffered input into a flat array, and losing the advantage of having a queue in the first place. Doing this is no different than just polling the keyboard state every logic frame. The problem with doing that is you're going to miss some keypresses when the framerate gets low. Imagine you make a quick key tap during some slow frames, then the next time you run through your message loop you'll first handle a KEYDOWN, setting the flag, then a KEYUP, unsetting the flag. In your next logic loop you will have missed the key press.Also, it certainly does not decouple your game logic from your message loop. What you really want is a handler that can take raw keyboard input and translate that into a data-driven game event (e.g. "MOVE LEFT"). Then, in your game logic you will not be checking for a left arrow keypress to move the player via KeyPressed[VK_LEFT], you will instead handle the "MOVE LEFT" event. Then when a player says "I don't want the left arrow to move left, I want 'a' to move left" you just map the "MOVE LEFT" event to the other input key.   ;Quote:Original post by y2kiahQuote:Original post by Makaancase WM_KEYDOWN: KeysPressd[wParam] = true; break;case WM_KEYUP: KeysPressd[wParam] = false; break;where KeysPressed is a bool [256];Sure this will work, but it's not really an improvement. You are flattening out the buffered input into a flat array, and losing the advantage of having a queue in the first place. Doing this is no different than just polling the keyboard state every logic frame. The problem with doing that is you're going to miss some keypresses when the framerate gets low. Imagine you make a quick key tap during some slow frames, then the next time you run through your message loop you'll first handle a KEYDOWN, setting the flag, then a KEYUP, unsetting the flag. In your next logic loop you will have missed the key press.Also, it certainly does not decouple your game logic from your message loop. What you really want is a handler that can take raw keyboard input and translate that into a data-driven game event (e.g. "MOVE LEFT"). Then, in your game logic you will not be checking for a left arrow keypress to move the player via KeyPressed[VK_LEFT], you will instead handle the "MOVE LEFT" event. Then when a player says "I don't want the left arrow to move left, I want 'a' to move left" you just map the "MOVE LEFT" event to the other input key.Oh, you think to much :),For all the problems stated above i would just change the KeyPressed type form bool[256] to Input_Manager_That_Solves_All_The_Timing_Problems_And_Event_Handling and keys with events, but before i finish to explain inner workings of that, the Christmas will be here. That's why my example was very basic, and Luca D can stick first to that because is very easy to implement.Raxvan   ;  Thank you guys for all your answers.The question about separating the game logic with the input management is absolutely true, and I'm working on it.Anyway it seems that the reason why my movements are not smooth, is that I'm not considering the time.I already have a timer which computes the deltaTime between frames, but I'm not sure about writing good code to bind movements with the time.If I ask you how to create an input handler, as Makaan suggested, Christmas will be here.. :) Hence, could you point me to some good books or tutorials about this subject?Thank you!   ;  ok, i don't really know any websites that offer a good solution for this , but i can explain a bit how my imagination would solve this( i'm not sure if this might actually work but if you see bad stuff inside please shout).First: you need a queue class which can take 3 values inside 1:a time 2:a key and 2:a flag: true or false.Second: you need a `action` class with the following stuff:attributes: LastUpdateTime, Key , isActive(bool) and operators: void onBegin(),onUpdate(time delta), onEnd().in WndProc what you do is the following:1.on WM_KEYDOWN check to see if the key is already down; if not you insert into the queue the Key, current time and `true`(meaning that the key was just pressed) and mark the key as pressed(using a simple bool KeyDown[256] table, used to prevent repeatedly inserting into the queueu)2.on WM_KEYUP you insert into the queue the Key , current time and flag false , meaning that the Key was just released. also do KeyDown[wParam] = false;in Main loop of the game on each frame you do:- Tell WndProc to put the input in another empty queue and the one WndProc has(with the input inside) grub it. (here you have all key events that happened during now and the last frame)for each item in the quque:{1. if you have a key inside with the flag true take the action having that key assigned and mark isActive with `true`; call onBegin(); mark the LastUpdateTime with the time assigned to the key in the queue.2. if you have a key with flag false inside( key released )assign to the variable KeyTime the time assigned to the key in the queue,  take the action with the equivalent key and do a onUpdate(KeyTime - LastUpdateTime); onEnd(). mark the flag isActive with false;}After the iteration completed take all the actions with the idActive == true and do onUpdate(CurentFrameTime - LastUpdateTime); assign to LastUpdateTime the value of CurentFrameTime.with this you can bind a action to a key;onBegin will be triggered when the key is down , onEnd then is released.The onUpdate is called with a delta time , and the sum of all delta times should not be larger than the time the key was kept down. If a key is kept for multiple frame the delta time should be equivalent to the frame delta time.A simple Camera Movement action should look like:class MoveCamera : public Action{public:Camera *camera;public:virtual void onBegin() { /*nothig here , activate a sound or something*/ }virtual void onUpdate(DWORD delta){camera->move(delta);}virtual void onEnd(){/*empty*/}};Raxvan.   ;  It just comes down to scaling your displacements (movements) with the time delta.So, instead of camera.move(10), do camera.move(10 * timeDelta).@Makaan: interesting approach. However, making Camera inherit the Action interface is flawed. What happens if you want a camera to behave differently in another game-mode or menu? You'll end up changing the Camera class itself, because it's reactions to input are hard-coded in it's Action function implementations.Besides that, I think you'll find it pretty hard to make a camera move properly if it's only able to react to one key only (for multiple keys, you need multiple Actions, with different implementations).No, instead, the camera should not handle it's own usage. There's some game-code or menu code that owns and controls a camera (or a bunch of cameras), and that code should receive input/action events and control it's camera accordingly. It owns the camera, it knows how to react to input, so that's where the magic happens. A camera is just a camera that can be moved around and input code is just input code that sends input events (and/or allows key state polling).I wouldn't really call this class an Action, either. It's more common to call it an event, and to pass on some event information along with it. For example, what key was pressed, and if it was pressed or unpressed.   ;  @Captain P: The Camera doens't inherit the Action class. Specialized actions are inheriting from the abstract action class.@Makaan: I do like your solution, it's a sort of "Command" Design Pattern. Are you already using in somewhere? Have you already faced the problems Captain P pointed out?   ;  I don't think the whole Action interface is necessary. What you can do instead is hijack the Windows message queue and use it for your own diabolical needs, like gathering and translating input data. If you have a messaging system in your game/engine, you can funnel interesting messages into your message queue and have game objects register to listen for them just like any other message. Your input interpreter will register for raw input messages, like WM_KEYDOWN, and turn them into game commands, like FIRE. It will then send these game commands out through the message system to anyone who's interested.Your camera movement should be handled by some other entity in your game logic. It will receive a command like MOVE_CAMERA_LEFT (assuming your control scheme uses such commands) and in response it will, well, move the camera left. Notice that the game logic has no notion of system input, and the input interpreter has no notion of cameras or camera handlers. This is nice and decoupled, just the way we like it.[Edited by - Ariste on June 17, 2009 5:34:11 PM]