keypress delay

Started by
8 comments, last by losethos 15 years, 8 months ago
I'm trying to make a pong game and i'm having a problem with reading key input. I use 'w' and 's' to move the paddle up and down, but when i hold either of the keys down, the paddle moves once, then there's about a 1 second delay before the paddle starts moving continuously. This is what it looks like now:

void KeyboardHandler(unsigned char key, int x, int y)
{
    if (key == 'w') 
    {
            ypos1 += 10; //move paddle 10 pixels
            glutPostRedisplay();     
    }

    else if (key == 's')
    {
            ypos1 -= 10; //move paddle 10 pixels
            glutPostRedisplay(); 
    }

  glutPostRedisplay();
} // end KeyboardHandler()
I appreciate any help.
Advertisement
This is normal behavior. What you want to do is, when you receive the first "key down" message, you note the key as being down, and as soon as you receive a "key up" message, you note the key as being up.

Then, your code will look whether the key is currently up or down do decide what to do.
It's been years since I used GLUT so I don't remember exactly how it works, but it seems like it's just detecting the auto-repeat that happens in Windows when you hold down a key. I remember way back in the olden days when I made a game with GLUT we used an array of bool's to store the state of any key on the keyboard. Kinda like this:

bool keys[256];void Keyboard(unsigned char key, int x, int y){    keys[key] = true;}void KeyboardUp(unsigned char key, int x, int y){    keys[key] = false;}


I've done some more research based on what you've both said and came up with a more basic example just to get things working. Unfortunately, it still doesn't work. You should be able to rotate the square using 'wasd', but nothing happens using this method. Here's the entire source:

#include <GL/gl.h>
#include <GL/glut.h>
#include <cstdlib>
#include <iostream>
using namespace std;

int _angley = 0;
int _anglex = 0;
bool key_state[256]= {false};

/****************************************************************************
Reshape()

Reset the viewport for window changes
*****************************************************************************/
void Reshape(int width, int height)
{
if (height == 0)
return;

glViewport(0, 0, (GLsizei) width, (GLsizei) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, width/height, 1, 100.0);
glMatrixMode(GL_MODELVIEW);
} // end Reshape

void update_func()
{

if(key_state['a'] == true) {
// move left
_anglex+=5;
}

if(key_state['d'] == true) {
// move right
_anglex-=5;
}

if(key_state['w'] == true) {
// move up
_angley+=5;
}

if(key_state['s'] == true) {
// move down
_angley-=5;
}

glutPostRedisplay();
}

void key_down_func(unsigned char key, int x, int y)
{
key_state[key] == true;
}

void key_up_func(unsigned char key, int x, int y)
{
key_state[key] == false;
}

/****************************************************************************
Display()

Clear and redraw the scene.
*****************************************************************************/
void Display()
{
update_func();

glEnable(GL_DEPTH_TEST);
// set up the camera

glLoadIdentity();
gluLookAt(0.0, 0.0, 10.0, //position
0.0, 0.0, 0.0, //look at
0.0, 1.0, 0.0); //y-axis is the upward direction

// clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glRotatef(_angley,0,1,0);
glRotatef(_anglex,1,0,0);

glBegin(GL_QUADS);
//front
glColor3f(0,1,0);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glEnd();
glPopMatrix();

// draw everything and swap the display buffer
glutSwapBuffers();
} // end Display()


/****************************************************************************
main()

Setup GLUT and OpenGL, drop into the event loop
*****************************************************************************/
int main(int argc, char **argv)
{
// Setup the basic GLUT stuff
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

// Create the window
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 150);
glutCreateWindow("Rotating Box");

// Register the event callback functions
glutDisplayFunc(Display);
glutIdleFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(key_down_func);
glutKeyboardUpFunc(key_up_func);

glutIgnoreKeyRepeat(true);

glutMainLoop();
return 0;
} // end main()
Quote:glutIdleFunc(Display);

You cannot call OpenGL functions from something other than a registered displayfunc and expect it to work. Have the idle func call glutPostRedisplay if you want to have continuous redrawing.

That's probably not the problem, though. What does the debugger tell you is happening?
I wasn't sure about how to implement the update function. I tried having glutIdleFunc call update_func, but that still doesn't do anything. There aren't any errors, the program runs fine and displays the rectangle, i just don't have any control over rotating it.
As I said, have the idle function call glutPostRedisplay. Read the documentation for that function if you're not sure what it does differently than simply calling Display. As for my other question, I was asking about what the debugger shows you, not the compiler. Are the key states correctly changed? Do the keydown and keyup functions get called with the correct parameters? If you don't yet know how to use your debugger, now's the time to learn.
It works! thank you very much for the help. I debugged and found out the key_state array wasn't getting the true and false values from key_down_func and key_up_func because i used '==' instead of '='.
Im not sure if its what your looking for or not, but heres a little idea i had that suits my work just fine.

All you need, is the ability to register is a key is down, or if it is up, and a currectkeystates variable, and a oldkeystates variable.

Before you check for input, set the old to the current, and then update the current with whatever the actual state is.

If old is up, and current is down, the key is pressed.
If old is down, and current is up, the key is released.
If old is down, and current is down, the key is held.

Work that into some sort of handler function and all should work good.
MJP, thanks for the bool array idea. I just built it into my operating system, LoseThos.

This topic is closed to new replies.

Advertisement