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

Started by
1 comment, last by josiahpeters 12 years, 9 months ago
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!
Advertisement
Check out this article if you haven't already run across it.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


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!

This topic is closed to new replies.

Advertisement