Archived

This topic is now archived and is closed to further replies.

Gar2

Keyboard problem with glut.

Recommended Posts

Gar2    122
I’m taking a short introductory course on opengl graphics through games, and I’ve come up against a problem. The focus of the course is on graphics, and I know absolutely nothing about windows programming (and very little about programming in general). I also don’t really want to read 50 pages of tutorials to get the point where I can do this myself. My problem is that whenever I press a key, if a key was already being pressed, the program “ignores” the previous key. As far as I understand, this is because the glut functions which we use don’t support multiple keys being pressed simultaneously. They also don’t support shift and control keys, which would be helpful to have in a game. As you can probably guess, this can be quite a problem when making a 2 player game! (It would also be a problem with even one player, as you can’t rotate and accelerate at the same time.) So what I’m asking for is some code that will do this for me. Eventually I intend to learn how to do this on my own, but with my limited experience that’s a long way away. Everything else in the game is functional (collision detection, firing, acceleration, rotation, etc.), but without the keyboard working I can’t really play it.

Share this post


Link to post
Share on other sites
KiwiMelon    122
Glut is good if you want to learn OpenGL programming without worrying about the platform specific stuff.

I am not aware of the multiple key press problem, I don’t see any reason why the callback you register with glutKeyboardFunc wouldn’t be called with every key press. I would have to look at some code to see if there was a problem or not but passing NULL to glutKeyboardFunc will disable any keyboard handling as well.
You can use glutGetModifiers to find out if the Shift, Alt or Control keys are being pressed and glutSpecialFunc for other non-ascii keys.

If your going to use glut you might want to go to opengl.org and download the glut-3 spec pdf file (sorry I don’t have a link handy).

If you really do hit a wall using glut then you could also take a look at using SDL.

Share this post


Link to post
Share on other sites
Gar2    122
You could probably see the problem better if I attached it, but there doesn’t seem to be an attachment option? I had to use another forum to upload it to but here it is -
www.civfanatics.net/uploads5/BaseAttack.zip.

Player one is controlled by arrow keys, and player 2 is controlled by r, d, f, and g. To shoot player one uses "/", and player 2 uses "z". This is an early version so don’t expect an actual game, but you can see the problem pretty clearly. Try rotating one “ship” and while its still rotating, press g to rotate the other ship. The first ship stops rotating even though the key is still being pressed. This is the same for every keyboard function, making the game unplayable.


//Here is how I call the keyboard functions in main –

glutSpecialFunc(keypressSpecial);
glutKeyboardFunc(keypressNormal);
//And here is the actual code for them.


void keypressSpecial (int key, int x, int y)
{ glutSetKeyRepeat(0);

if (key== GLUT_KEY_UP){
ship1->accelerate();
cout<<"up"<<endl;
}

if (key== GLUT_KEY_DOWN){
ship1->deaccelerate();
cout<<"down"<<endl;
}

if (key== GLUT_KEY_RIGHT){
ship1->rotateRight();
cout<<"right"<<endl;
}

if (key== GLUT_KEY_LEFT){
ship1->rotateLeft();
cout<<"left"<<endl;
}
if (key== GLUT_KEY_INSERT){
ship1->test();
cout<<"test"<<endl;
}
}

void keypressNormal (unsigned char key, int x, int y)
{
if (key==47){ // /

shot1 = new CircularShot (ship1->getAngle(),ship1->getRadius(),10,ship1->getxPosition(),ship1->getyPosition(),0);
}
if (key==122){ // z

shot2 = new CircularShot (ship2->getAngle(),ship2->getRadius(),10,ship2->getxPosition(),ship2->getyPosition(),0);
}
if (key==114){ // r

ship2->accelerate();
}
if (key==102){ // f

ship2->deaccelerate();
}
if (key==103){ // g

ship2->rotateRight();
}
if (key==100){ // d

ship2->rotateLeft();
}
}



[edited by - Gar2 on August 6, 2003 11:09:12 PM]

[edited by - Gar2 on August 6, 2003 11:09:56 PM]

Share this post


Link to post
Share on other sites
KiwiMelon    122
Mmmm tricky one, I would be interested to see what behavior you would get if you called glutKeyboardFunc(keypressNormal) before glutSpecialFunc(keypressSpecial).

It’s a real pain in the ass you just can’t have one callback for any key press (ascii and non-ascii), but that’s glut for you. Oh well the source for glut is also freely available from opengl.org if you feel so inclined.

In the meantime the only other thing I think of is setting the key repeat off before calling glutMainLoop using glutIgnoreKeyRepeat or glutSetKeyRepeat (check out glut.h) and using glutKeyboardUpFunc and glutSpecialUpFunc.

You just want to start moving the ship when the key is first pressed down (for example only call ship1->rotateLeft() once) and stop moving it when the key comes back up.

Hope that helps, good luck.

Share this post


Link to post
Share on other sites
AndreTheGiant    329
What i do is maintain an array of 256 boolean values. Using the glut functions:

glutKeyboardFunc();
glutKeyboardUpFunc();
glutSpecialFunc();
glutSpecialUpFunc();

(i think these names are correct - and you can just type any of those funcions in google, click on first link and it will provide lots more info)

Basically, to each of these functions, you pass it a function that does whatever you want to happen when they occur. for example,

void myKeypressed(int key, int x, int y) {
printf("the %c key was pressed\n", key);
// or in c++,
cout<<"the "<<(int)key<<" key was pressed"<}

you create the above function yourself, and then you tell glut thats what you want to happen every time a key is PRESSED DOWN. for eg:

glutKeyboardFunc(myKeypressed);

now if you run the prog and press a key, you will see something similar to :
the t key was pressed

If you want more than one key to be handled at one time, then your myKeypressed funcion should be more like this: (it uses the array of 256 bools i mentioned)

void myKeypressed(int key, int x, int y) {
keys[key] = true;
}

and then you have to ''unset'' the keys in the glutKeyboardUpFunc() funcion: example:

void myKeyUnpressed(int key, int x, int y) {
keys[key] = false;
}

then register this function as well:

glutKeyboardUpFunc(myKeyUnpressed);

now, at any point during your program, your keys[] array will hold all the keys that are being pressed at that instant. The idea is that you access this array in your update() function, if you have one, and take any appropriate actions with respect to each key that is down at that moment.

the other two functions, glutSpecialFunc() and glutSpecialUpFunc(), are for wierd characters on the keyboard. Im not sure exactly which buttons this includes, but i know it includes the 4 arrow keys. If your going to use these, then you need to make glutSpecial funcs similar to how you made the first two functions. One word of warning though: you''ll probably want to use a separate array for the special keys, say call it specKeys[256], because there is at least some overlap in the numbers that are used for each. For example, I think that the Left arrow key is 100, but so is the ''d'' button (or something like that), so if your going to use the arrow keys in your prog, you should make two separate keys arrays, otherwise your program will act like your pressing the ''d'' key and the arrow key at the same time, whenever your only pressing one of them.

One last note: pressing a key, for example t is a certain value, and will set a certain value in your keys array. Pressing Shift+t is a DIFFERENT value and sets a different value in the keys array. Heres the kicker: if you-
press and hold t,
press shift,
and then release t,

you get the strange behavior that the keys[t] element gets set, and then the keys[shift+t] element is unset, so it will seem like the t key is still held down even when its not. How did i get around this? i didnt. Im just making a simple demo that will probably only be operated by me, and ill just be careful not to press shift Anyway, im sure theres an easy way around this, but its not that big of a concern to me right now.

If you have any more questions or want clarification, let me know. I just implemented the keyboard part of my demo this morning, so its all relatively fresh

cheers.

Share this post


Link to post
Share on other sites