Jump to content
  • Advertisement
Sign in to follow this  
dawberj3

Keyboard input as soon as its pressed?!?!

This topic is 4846 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
If you are programming in Win32 you can find this code of mine usefull
(sorry for mixed comments )

This is the declaration file (.h)


/// @brief Gestisce input tastiera
class 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));

// ctor
KeyBoardState::KeyBoardState(void){
GetKeyboardState(ks1);
memcpy(ks2,ks1,sizeof(WINKEYBSTATE));
pck = ks1;
pok = ks2;
}

// read
void 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);
}

// reset
void 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.

Share this post


Link to post
Share on other sites
im using linux to create it, but Ill have a look if I can change yours.

Anyone have a linux method that works?

Thx

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
Well i have:

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!