Клавиатура OpenGL / GLUT управляется с помощью bool *: все значения, по-видимому, устанавливаются в ints при второй инициализации.Есть идеи? - PullRequest
2 голосов
/ 02 июля 2011

Создание игры с OpenGL / GLUT и C ++.

Я слышал, что самый простой способ управления клавиатурой в GLUT - это использовать массив bool.

Итак, вотчто у меня есть:

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;
}

Тогда, если я хочу узнать состояние ключа, я просто возвращаю ключи [ключ].

У меня есть аналогичная настройка для специальных клавиш.Теперь, в моей игре, когда ты умрешь, он сбрасывает все значения, которые нужно сбросить, и снова запускает игру.До сих пор это включало

keys = new bool[256];

и аналогичное объявление для массива специальных ключей.Что не имеет смысла для меня, так это то, что иногда предполагаемый сброс массивов приводит к тому, что некоторые или все значения в ключах становятся двузначными или трехзначными целыми числами (следовательно, всегда оценивая значение true и заставляя персонажа игрока двигаться неуправляемо, пока один илибольше клавиш, которые были явно внизу, были нажаты).У меня есть подозрение, что это произошло, потому что во время эндшпиля одна из клавиш была нажата, что приводило в замешательство C ++, когда он пытался сделать весь массив ложным и обнаружил, что одна вещь застряла.

Человек, этосбивает с толку.Проблема была решена путем устранения всех дополнительных инициализаций ключей, насколько я могу видеть.Но я не понимаю.Кто-нибудь получил какие-либо идеи о том, как мне удалось превратить некоторые bools в целые?

Ответы [ 3 ]

6 голосов
/ 02 июля 2011

Это утверждение

keys = new bool[256];

Выделяет память.Он не инициализирует эту память любым конкретным значением.Чтобы сделать это, вы можете сделать memset(keys, 0, sizeof(bool) * 256) в ноль.

Однако вам не следует выделять память (что и делает new) для повторной инициализации массива.Вы должны на самом деле реинициализировать его, используя memset или любую другую функцию, которую вы использовали для инициализации его "ложными" значениями.

Наконец, почему вы выделяете этот массив с new, чтобы начатьс?Просто сделайте его глобальным массивом: bool keys[256].Инициализируйте его (memset) перед его использованием, и все будет хорошо.

Я бы предложил std::vector<bool>, но, к сожалению, их нельзя использовать.Вы можете использовать std::vector<char>, хотя 0 означает false.Или std::bitset с 256 битами.Все они содержат свои распределения внутри (таким образом, будучи безопасными) и имеют способы очистить их память до некоторого значения.

, создавая игру с OpenGL / GLUT и C ++.

Кстати, я бы этого не советовал.GLUT не является инструментом, разработанным для тех времен, которые нужны большинству игр.GLFW позволяет вам контролировать основной цикл, а не использовать обратные вызовы, поэтому он является более подходящим инструментом для игры.

3 голосов
/ 02 июля 2011

Из-за гранулярности ЦП вы можете получить доступ к вещам только в виде байта, поэтому bools всегда разрешает какой-либо тип беззнакового символа, размер которого составляет 1 байт.Таким образом, вы можете получить значения в диапазоне 0-255.Что происходит, так это то, что любое ненулевое значение истинно, а 0 ложно.Мы не можем реализовать bool как один бит (за исключением вектора C ++ STL и т. Д., Где они преобразуются в битовые поля) из-за этой детализации, если вы не решите создать массив и индексировать биты в конкретных записях.

0 голосов
/ 02 июля 2011

Поскольку размер маленький, тип данных (bool) маленький, а размер массива детерминированный; Я бы выделил его в стеке (на уровне класса или на глобальном уровне - везде, где объявлено keys).

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

И имея функцию, это будет ResetKeys:

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