开发者

OpenGL/GLUT keyboard managed with bool*: all values appear to be set to ints at second initialisation. Any ideas?

Making a game with OpenGL/GLUT and C++.

I've heard the easiest way to manage keyboard stuff in GLUT is to use an array of bools.

So basically, here's what I have:

bool* keys = new bool[256];

...

void keyDown(unsigned char ch, int x, int y)
{
    keys[ch] = true;    
开发者_运维百科}

void keyUp(unsigned char ch, int x, int y)
{
    keys[ch] = false;
}

Then if I want to know the state of a key, I just return keys[key].

I have a similar setup for the special keys. Now, in my game when you die, it resets all the values that need to be reset and starts the game again. Until just now, that included

keys = new bool[256];

and a similar declaration for the special keys array. What makes no sense to me is that occasionally, this supposed resetting of the arrays would cause some or all of the values in keys to become two- or three-digit integers (therefore always evaluating true and making the player character move uncontrollably until one or more of the keys that were apparently down were depressed). I have a suspicion that this happened because at time of endgame one of the keys was pressed down, thereby confusing C++ when it tried to make the whole array false and found that one thing was stuck true.

Man, that's confusing. The problem has been solved by eliminating all the extra initialisations of keys, as far as I can see. But I don't get it. Anyone got any ideas on how I managed to turn some bools into ints?


This statement

keys = new bool[256];

Allocates memory. It does not initialize that memory to any particular value. To do that, you could do a memset(keys, 0, sizeof(bool) * 256) to zero.

However, you shouldn't allocate memory (which is what new does) to reinitialize an array. You should actually reinitialize it, using memset or whatever feature you used to initialize it with "false" values.

Lastly, why are you allocating this array with new to begin with? Just make it a global array: bool keys[256]. Initialize it (with memset) before you use it, and everything will be fine.

I would have suggested a std::vector<bool>, but sadly, those are not usable. You could use a std::vector<char> though, with 0 meaning false. Or a std::bitset with 256 bits. All of these contain their allocations internally (thus being safe), and have ways to clear their memory to some value.

making a game with OpenGL/GLUT and C++.

As an aside, I wouldn't advise that. GLUT isn't a tool designed for the kinds of timings that most games need. GLFW allows you to control the main loop, rather than using callbacks, so it is a more appropriate tool for a game.


Because of CPU granularity you can only access things as a byte therefore bools always resolve to some kind of unsigned char type which are 1 byte in size. This way you can get from 0-255 range in values. What happens is that any non zero value is true and 0 is false. We can't implement bool as a single bit (except in C++ STL vector etc... where they are converted to bitfields) because of that granularity unless you decide to make an array and index bits in particular entries.


Since the size is small, data type (bool) is small, and array size is deterministic; I would have allocated it in stack (at class level, or global level - wherever keys are declared).

class GlutWrapper
{
    bool Keys[256];
...
};

And having a function, that would ResetKeys:

void GlutWrapper::ResetKeys()
{ 
   memset(Keys, 0, sizeof(Keys));
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜