Подтвердить что ты не робот

С++ Начальное программирование игры: отслеживание объектов, списков инвентаря, массивов различных объектов объекта/персонажей и т.д.

Я просто играл в старую SNES RPG (Secret of Mana, если кто-то заботился), и задавался вопросом о некоторых общих вещах в игровом программировании.

Извините за некоторые из голодных вопросов, я действительно новичок.:)

Эти вопросы довольно общие, но используют RPG в стиле SNES как "шаблон", чтобы понять, что я имею в виду:

  • Как игры отслеживают все объекты, вызванные события и т.д. в своем "мире"? Например, как он отслеживает, какие сундуки с сокровищами уже открыты, какие двери заблокированы, какие сюжетные события уже вызваны?

    Создает ли он в основном массив элементов, каждый из которых соответствует сундуку/двери/событию/etc и "отметит" каждый (измените его значение от 0 до 1), когда он был открыт/вызван? Если есть несколько подходов, каковы они?

  • Как обрабатываются "списки переменных"? То есть, если у вас есть игра, когда вы можете иметь огромный инвентарь объектов (например, доспехи, мечи) и иметь X каждого объекта, как это сделать?

    Мое предположение: иметь структуру, которая имеет большой массив с пятном для каждого возможного объекта (массив из X ints, где X - количество возможных объектов для собственного), где каждое значение элемента представляет, сколько из этого объекта вы имеете, а затем иметь гигантское перечисление для каждого объекта, чтобы объект соответствовал соответствующему индексу и обращался к нему, например: numberOfSwords = inventory [SWORDS], где SWORDS является частью перечисления и имеет некоторое целочисленное число, связанное с ним. Как близко я?

  • Как насчет случая, когда количество объектов может меняться? То есть, если у меня есть игра, на которой у меня есть некоторое количество врагов на экране, и они могут быть убиты/родить новых врагов в любой момент, мне кажется, что мне понадобится массив "вражеских" объектов для цикла через процесс и процесс, но количество элементов будет меняться в любой момент времени. Каков обычный подход к этому? Связанные списки?

Любая помощь/подсказка/указатели действительно оценены.

4b9b3361

Ответ 1

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

Для инвентарей вместо того, чтобы отслеживать, сколько из каждого элемента имеет игрок, может быть лучше иметь базовый элемент для всего, что может забрать игрок; оружие, доспехи и даже деньги. Затем вы можете создать связанный список только тех предметов, которые есть у игрока. Используйте Enum для предмета, как вы упомянули, а затем количество этого предмета. Это позволило бы сортировать вещи, а также сохранить в памяти только те предметы, которые у игрока есть/есть. Вы можете расширить эту структуру данных, чтобы также отслеживать, если элемент оборудован. Вероятно, вы можете сохранить более общий тип элемента, который будет отображаться в таблице элементов.

Скорее всего, враги будут немного сложнее, поскольку вам нужно сделать еще несколько вещей с ними. Связанный список здесь, хотя, вероятно, ваш лучший выбор. Таким образом, удаление объекта из списка будет проще, чем бит, который может быть удален (можно просто удалить ссылку и т.п., Когда игрок убивает их или добавляет нового врага, где это необходимо в списке.)

Честно говоря, ответа нет, и это может зависеть от нескольких вещей. Лучший способ - это просто попробовать его. Для простого "что, если я сделаю это для этого", это действительно не заканчивается тем, что нужно так долго, чтобы дать ему вихрь и посмотреть, как далеко вы доберетесь. Если вы начинаете сталкиваться с проблемами, вы можете начать рассматривать другие варианты:)

Надеюсь, что это поможет.

Изменить: просто хотел добавить ссылку на www.codesampler.com. Как правило, больше ориентированных на DirectX учебников, но, как новичок, он может начать думать или дать вам множество мест для начала. В качестве дополнительного бонуса к примерам/образцам DirectX SDK начали форматироваться очень похоже на то, как это делается на этом сайте. Может помочь вам ослабить все это.

Ответ 2

В дополнение к превосходной почте Джеймса, некоторые ключевые слова для вас для google для

  • Структуры данных
    • Связанный список
    • дважды связанный список
    • очереди

для теории управления динамической памятью.

Кроме того, позвольте мне поделиться стандартными рекомендуемыми ссылками для людей, обращающихся за помощью по базовому С++:

Полномасштабный учебник по С++

Справочник по языку С++ (включая STL)

Ссылка на язык ANSI C для всех этих досадных вещей C, которые С++ продолжает использовать

Ответ 3

Это довольно продвинутый вопрос для новичков.

Я хотел бы повторить ответ "Силико", чтобы вы изучили основы языка С++, прежде чем заниматься этим вопросом.

Чтобы дать вам место для начала, вы должны знать о классах контейнеров (Linked Lists, Vectors, HashTables/Dictionaries, Queues и т.д.) и о том, как они работают. Поскольку стандартная библиотека шаблонов (STL) довольно стандартизирована, было бы неплохо начать для начинающего.

Вы также должны знать о наследовании и о том, как создать иерархию классов.

Например, вы спросили об инвентаре в ролевой игре: Я бы начал с определения класса InventoryItem, который определяет или настраивает интерфейс для всего кода, необходимого для участия элемента в вашей системе инвентаризации. Что-то вроде:

class InventoryItem
{
private:
    std::string description; // A description of the item
    bool inInventory;  // True if in the players inventory, false if on the ground etc...
    int weight;        // How much the item weighs
    int size;          // How much space the item takes in inventory
    // etc...
};

В классе InventoryItem вы также определяете функции-члены и данные, необходимые для InventoryItem, которые нужно поместить в выбранный вами класс контейнера.

То же самое относится к срабатывающим элементам, вещам на земле и т.д. Они обычно хранятся в каком-то классе контейнеров.

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

вектор - хорошее место для начала общего списка элементов. HashTables/Dictionaries хороши для поиска вещей с помощью ключа.

Надеюсь, этого достаточно, чтобы вы начали. Удачи.

Ответ 4

Ваш вопрос не относится к "программированию игр". Вы спрашиваете, как произвольные данные организованы и хранятся в больших программах. На это нет определенного ответа, существует множество разных подходов. Общий общий подход заключается в создании модели данных всех вещей, которые вы хотите сохранить. В С++ (или любых других языках с объектно-ориентированными возможностями) для этой цели можно создать объектно-ориентированную модель класса. Это введение в С++ содержит полный учебник по объектно-ориентированному моделированию на С++.

В большинстве приложений используется многоуровневый подход - модель данных является одним слоем в вашем приложении, отделенным от других уровней, таких как уровень представления или приложение ( "игра" ).

Ваш подход к моделированию данных будет иметь дело с постоянством (это означает, что вы хотите сохранить все свои данные на диске и перезагрузить его позже). Этот вопрос был задан ранее здесь, на SO. Этот факт даст вам некоторые ограничения, например, на использование указателей.

EDIT: если ваша модель данных достигает определенной сложности, вы можете рассмотреть возможность использования (облегченной) базы данных, например SQLlite, которая имеет C/С++ api.

Наконец, вот ссылка, которая может дать вам хорошее начало, похоже, точно соответствует вашему вопросу:

http://www.dreamincode.net/forums/topic/26590-data-modeling-for-games-in-c-part-i/

Ответ 5

Что касается вопроса № 1, я согласен с Джеймсом и другими в использовании базы данных, в которой хранится постоянное состояние ваших игровых объектов.

В отношении вопросов № 2 и № 3 о переменных количествах объектов и объектов, которые требуют частого обновления: я бы предложил поддерживать реестр объектов, которые нуждаются в обновлении для каждого цикла игры (большинство игр работают на циклах - циклы, если вам нравится, хотя в современной игре используется множество циклов, созданных как отдельные потоки).

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

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

Учитывая это, я не могу особо подчеркнуть важность изучения передовых структур данных до того, как вы займетесь каким-либо серьезным проектом программирования. На эту тему есть множество замечательных книг, и вы бы хорошо их изучили. Здесь ссылка на переносимый обзор классических структур данных: http://randu.org/tutorials/c/ads.php