Keyboard input as soon as its pressed?!?!
Im creating a 3D engine at the moment and I can walk around, but if i press forward, it doesnt move straight away, it delays for a split second then moves forward (Keyboard polling I think its called).
How can I fix this so as soon as i press the button it moves with no delay?
Thx
If you are programming in Win32 you can find this code of mine usefull
(sorry for mixed comments )
This is the declaration file (.h)
This is the rest of the implementation (.cpp file)
Usage:
Simply create an histance of the class in your main class or create it as static(or global).
Then each frame simply call the method Read()
Then you can use the functions Key[Up][Down][Pressed][Release] to retrieve current
state. The id of the key is the virtual code...you can find virtual codes in your help (ie: VK_ESCAPE, VK_DOWN, VK_UP,...) or find VK_ in your windows header files
(pseudo) simple example
I'va also implemented functions to manage key names and descriptions but for brevity I've removed them.
I hope this will be useful for you.
(sorry for mixed comments )
This is the declaration file (.h)
/// @brief Gestisce input tastieraclass KeyBoardState{public: typedef SHORT WINKEYBSTATE[256]; typedef SHORT* LPWINKEYBSTATE; /// @brief true if key down inline bool KeyDown(BYTE vkey)const{ return KeyDown(pck,vkey); } /// @brief true if key up inline bool KeyUp(BYTE vkey)const{ return KeyUp(pck,vkey); } /// @brief true if key pressed inline bool KeyPressed(BYTE vkey)const{ return KeyUp(pok,vkey) && KeyDown(pck,vkey); } /// @brief true if key released inline bool KeyReleased(BYTE vkey)const{ return KeyDown(pok,vkey) && KeyUp(pck,vkey); } /// @brief void ctor KeyBoardState(void); /// @brief Read new state (call this each 'frame') void Read(void); /// Reset void Reset(void); /// @brief Legge lo stato di tutti i tasti void GetKeyboardState(LPWINKEYBSTATE pks); /// @brief Funzione base static inline SHORT GetKeyState(BYTE vkey){ return(GetAsyncKeyState(vkey)); } /// @brief Converte in carattere (minuscolo) /// Se -1 -> nessuna traduzione possibile static inline UINT ToChar(BYTE vkey){ return((unsigned char)MapVirtualKey(vkey,2)); } /// @brief Converte vkey static inline SHORT ToVkey(unsigned char ch){ return((BYTE)VkKeyScan(ch)); } /// @brief Traduce il char nel vkey code static unsigned char CharToVK(char ch){ return (unsigned char)VkKeyScan((TCHAR)ch); }private: inline bool KeyDown(LPWINKEYBSTATE pk, BYTE vkey)const{ return (pk[vkey]&DOWNMASK)!=0; } inline bool KeyUp(LPWINKEYBSTATE pk, BYTE vkey)const{ return !KeyDown(pk,vkey); } LPWINKEYBSTATE pck; // current keyboard LPWINKEYBSTATE pok; // old (previous) keyboard WINKEYBSTATE ks1; // buffer1 for kstate WINKEYBSTATE ks2; // buffer2 for kstate static const SHORT DOWNMASK;};
This is the rest of the implementation (.cpp file)
// key down -> MSB short true const SHORT KeyBoardState::DOWNMASK = (SHORT)(1<<(8*sizeof(SHORT)-1));// ctorKeyBoardState::KeyBoardState(void){ GetKeyboardState(ks1); memcpy(ks2,ks1,sizeof(WINKEYBSTATE)); pck = ks1; pok = ks2;} // readvoid KeyBoardState::Read(void){ // AC::Swap(pck,pok); swap pointers pck <--> pok LPWINKEYBSTATE tmp = pck; pck = pok; pok = tmp; this->GetKeyboardState(pck);}// acquisisce stato su pks (static)void KeyBoardState::GetKeyboardState(LPWINKEYBSTATE pks){ for(int vk=0;vk<256; vk++) pks[vk]=this->GetKeyState(vk);}// resetvoid KeyBoardState::Reset(void){ memset(pck,0,256*sizeof(SHORT)); memset(pok,0,256*sizeof(SHORT));}
Usage:
Simply create an histance of the class in your main class or create it as static(or global).
Then each frame simply call the method Read()
Then you can use the functions Key[Up][Down][Pressed][Release] to retrieve current
state. The id of the key is the virtual code...you can find virtual codes in your help (ie: VK_ESCAPE, VK_DOWN, VK_UP,...) or find VK_ in your windows header files
(pseudo) simple example
...KeyBoardState _ks;...void main(void){ while(loop) { _ks.Read(); if(_ks.KeyDown(VK_UP)) goForward(); // while UP is down if(_ks.KeyPressed(VK_F9)) TakeSnapShot(); // once RenderSomething(); }}
I'va also implemented functions to manage key names and descriptions but for brevity I've removed them.
I hope this will be useful for you.
im using linux to create it, but Ill have a look if I can change yours.
Anyone have a linux method that works?
Thx
Anyone have a linux method that works?
Thx
Linux??? Ooops sorry :)
However I'm sure you should have similar low level functions to retrieve (asyncronous) keyboard state.
The trick as you can see is to store the previous and the current state and compare them (if you need only to track up/down states you could resolve with a single function)
However I'm sure you should have similar low level functions to retrieve (asyncronous) keyboard state.
The trick as you can see is to store the previous and the current state and compare them (if you need only to track up/down states you could resolve with a single function)
Well i have:
This recognises the key is pressed straight away and moves once, then a short delay (I have my finger pressed on "w") Then it moves forward, but I want it so when you press it, it moves forward steadily until I let go.
I read somewhere this problem is due to frame based rendering instead of time based rendering.
Any Ideas?
static void key(unsigned char k, int x, int y){ switch (k) { case 27: exit(0); break; case 'w': Camera.moveForward(); break; case 'd': ... ... ... } // Refresh the Window glutPostRedisplay();}
This recognises the key is pressed straight away and moves once, then a short delay (I have my finger pressed on "w") Then it moves forward, but I want it so when you press it, it moves forward steadily until I let go.
I read somewhere this problem is due to frame based rendering instead of time based rendering.
Any Ideas?
There are 2 different types of messages from the keyboard. First is "key is pressed", second is "key released". In different API's there are different ways of telling whether the key is pressed or released. In glut for example there are 2 callback functions glutKeyboardFunc and glutKeyboardUpFunc respectivly, in Windows API there are just 2 different types of message from WndProc. There should be a well known alternative in Linux. Thes easiest way to implement action without delay on pressing a key is to have boolean variables for keys that are used. When the program catches the event of pressing a key it should set the variable 'true'. And when it catches the event of releasing a key, variable should be 'false'. And each iteration of the main cycle the function responsible for the action should check the variable before implementation. It's that easy.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement