Nano Hash - криптовалюты, майнинг, программирование

Клавиатура OpenGL/GLUT, управляемая с помощью bool*: кажется, что все значения устанавливаются в целые числа при второй инициализации. Любые идеи?

Создание игры с помощью OpenGL/GLUT и C++.

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

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

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[key].

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

keys = new bool[256];

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

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

02.07.2011

  • Надеюсь, вы заранее решили delete старый массив. 02.07.2011
  • ...было бы так, да. Я новичок в С++, как я сказал ниже, но особенно в жестком управлении памятью. 02.07.2011
  • Может быть, вы еще не знаете о RAII? Если вы не хотите вручную управлять памятью (чего вам не нужно делать), вы можете использовать RAII и интеллектуальные указатели. В Boost есть библиотека интеллектуальных указателей. 02.07.2011

Ответы:


1

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

keys = new bool[256];

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

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

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

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

создание игры с помощью OpenGL/GLUT и C++.

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

02.07.2011
  • По порядку: - Я как-то не знал что про новый. - Я не знал, что memset существует, но я просто подумал, что такая штука будет удобна, прежде чем публиковать. >.< - Почему? Потому что я слишком привык к Java. И даже там, вероятно, это плохая практика. - Я думал о чем-то подобном, но решил придерживаться массива, потому что именно он использовался в примере. - Так я слышал. В данный момент я изучаю SDL, а в следующий раз планирую изучить GLFW. Сегодня прочитал много подобных мнений. 02.07.2011
  • @PROGRAM_IX: Java собирает мусор, а C++ — нет. Также в C++ есть шаблон проектирования под названием RAII: выделение ресурсов — это инициализация. Технически это означает, что вы не выделяете большинство экземпляров класса с помощью new, а просто определяете их переменную. Конечно, это означает много копировальной работы. Основная идея заключается в том, что вы управляете большими объемами данных в классах доступа, которые реализуют семантику интеллектуальных/слабых указателей. Вместо указателей вы передаете экземпляры классов (по скопированному значению!). Библиотеки Boost (boost.org) предоставляют интеллектуальные указатели именно для этого. 02.07.2011
  • Эта библиотека Boost звучит неплохо, да. Я не думаю, что знаю достаточно С++, чтобы использовать этот шаблон. 02.07.2011

  • 2

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

    02.07.2011
  • Это интересно, потому что я вычислял все значения, которые проверял («w», «s», «a», «d»), и они всегда были 0 или 1, за исключением тех случаев. 02.07.2011
  • хорошо, потому что память нового оператора не гарантируется обнулением, поэтому вы можете считывать данные из кучи из другого распределения. 02.07.2011
  • Ага. Я довольно новичок в C++. Наверное, это было так. Спасибо. :) 02.07.2011

  • 3

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

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

    И имея функцию, которая бы ResetKeys:

    void GlutWrapper::ResetKeys()
    { 
       memset(Keys, 0, sizeof(Keys));
    }
    
    02.07.2011
  • Знаешь, я как раз вчера вечером думал о том, чтобы включить эту часть программы в класс? Хе. Возможно, я буду, сейчас. 02.07.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..