Jump to content
  • Advertisement
Sign in to follow this  
josiahpeters

GLFW Keypress Question - should I fire events to manipulate an object or set the object's state?

This topic is 2656 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

Hey everyone, this is my first post after lurking and reading for a while. I am a web programmer and started learning graphics / game programming with C# and XNA a while ago. I have never released anything but have made a few useless "tech demos." I have been learning C++ recently and decided to tackle making a little game with Open GL. I am using GLFW as my window library and things have been going relatively smoothly thus far.

My question is about how I am handling input. Right now I fire an event to my character system telling it to move the character every time a keypress is detected. This works great for one key being held down. It also works for two keys being held down. However once I let go of the second key while the first key is still held down, GLFW stops calling back my keypress call back function each frame until I let go of the key that is held down.

Example:

0 seconds -
Hold W key to
start walking forward
keypress function is called back,
w has a value of 1

5 seconds -
W key is still held down
still walking forward
keypress function is called back,
w has a value of 1

10 seconds-
W key is still down, now hold Left Shift Key down
still walking forward, but now at 2x speed because of the shift key being down
keypress function is called back
w has value of 1, shift has value of 1

15 seconds -
W key is still down, let go of the shift key -
no longer moving forward
keypress function is called back
w has value of 1, shift has value of 0 - indicating key was let go

15.1 seconds
W key has been down the whole time
no movement since letting go of the shift key
no callbacks on my keypress function

20 seconds
W key has been down the whole time
no movement since letting go of the shift key
no callbacks on my keypress function

25 seconds
let go of W key
keypress function is called back
w key has a value of 0 - indicating key was let go

Below is some code from my callback function that GLFW calls on a keypress:



void GLFWCALL OnKeyPress(int key, int action)
{

if(glfwGetKey(GLFW_KEY_LSHIFT) )
{
eventData data(eventType::CHAR_SPRINT, moveableCharacter);
EventSystem->TriggerEvent(eventType::CHAR_SPRINT, &data);
}

if(glfwGetKey('W') )
{
eventData data(eventType::CHAR_FORWARD, moveableCharacter);
EventSystem->TriggerEvent(eventType::CHAR_FORWARD, &data);
}
// ... more of the same
}



First, is this how GLFW is supposed to work and am I going about this all wrong? Should I be manipulating the character through triggering events or should I have a character state that gets altered by the events such as WALKING, IDLE, RUNNING, etc... Or, is this a bug in GLFW?


TLDR: GLFW reports a keypress event for the W key each frame it is held down until I press a second key while still holding W down. A keypress event is reported when I let go of the key but nothing happens in between.

Thanks for looking at this!

Share this post


Link to post
Share on other sites
Advertisement

Check out this article if you haven't already run across it.


I had not seen this yet, thanks!

*EDIT*

So I decided to do a few things differently. First of all I was coding my input callback all wrong.

Before I was calling glfwGetKey(GLFW_KEY_LSHIFT) inside of each key callback, see below:



void GLFWCALL OnKeyPress(int key, int action)
{
if(glfwGetKey('W') )
{
eventData data(eventType::CHARACTER_MOVE, moveableCharacter);
EventSystem->TriggerEvent(eventType::CHARACTER_MOVE, &data);
}
}


Instead of looking up the key in the call back like I was doing, I am now using the key code provided by the callback, as below:


void GLFWCALL OnKeyPress(int key, int action)
{

switch(key)
{
case GLFW_KEY_SPACE:
state = JUMPING;
stateOn = action;
break;
case GLFW_KEY_LSHIFT:
state = SPRINTING;
stateOn = action;
break;
case 'W':
state = MOVE_FORWARD;
stateOn = action;
break;
case 'S':
state = MOVE_BACKWARD;
stateOn = action;
break;
case 'A':
state = MOVE_LEFT;
stateOn = action;
break;
case 'D':
state = MOVE_RIGHT;
stateOn = action;
break;
}
}


That article helped me wrap my head around not having the input system drive my character directly. There was a little too much typing to do to implement their system, so I went with a simpler approach. On each keypress I pass a character state and a bool value of whether the state is on or off. This gets fired as a MOVE_CHARACTER event. My character system then updates the state for the character, turning on or off different states.

Meanwhile my update statement reads the various states and whether they are on or off and does the moving of the character depending on the states. This means I can be jumping, sprinting, moving forward and strafing left all at the same time.

I still intend on following through with reading character mappings from a file and mapping them to various actions, I'm just not there yet. That article was very useful, thanks for that again!

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!