Чэд Фримен (Chad Freeman) Dreamforge Intertainment



Чэд Фримен (Chad Freeman), Dreamforge Intertainment

Чэд Фримен - ведущий программист студии Dreamforge Intertainment, выпустившей в 1998 году великолепный квест Sanitarium. До этого проекта Чэд работал над играми Anvil of Dawn и Warwind.

В данном разделе Чэд предлагает игровым программистам несколько бесплатных советов и даже образец программы.

Вам, возможно, приходилось слышать, что при написании игровых программ одним из основных критериев является эффективность кода. Не верьте этому ни на минуту! Лишь для 10-20% вашей программы эффективность может оказаться критичной. Остальной код должен быть гибким, поскольку вам придется много раз его изменять. В противном случае, если код окажется слишком хрупок, чтобы допускать изменения, игра получится «второсортной».

Не стесняйтесь использовать что-либо по той только причине, что это придумано не вами. Многие замечательные решения, примененные в 3D-играх, основаны на технологиях, созданных для программ трехмерной визуализации несколькими годами ранее. Потратьте немного времени на исследование технических приемов, которые вы хотели бы использовать в своей игре. Впоследствии это освободит вас для размышлений над по-настоящему уникальными аспектами игры.

Самое важное на первых порах - довести хоть что-нибудь до конца. Способность завершить игру - вот то, что будет отличать вас от тех героев, что начали, но не смогли... Один из моих приятелей, программист, любит повторять: «Завершить игру невозможно, можно лишь прекратить над ней работать». Всегда найдется что-то, что улучшит код, но однажды надо набраться смелости и сказать: «Хватит, он уже достаточно хорош», - и оставить игру в покое.

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

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



Пример массива:

При использовании указателей и динамического выделения памяти связанный список может выглядеть примерно так:

Содержимое адресов памяти
001 [Указатель на первый элемент (010)]
002 [Указатель на последний элемент (062)]

...

010 [Указатель на графическое представление объекта]
011 [Здоровье]
012 [Указатель на следующий элемент (053)]

...

053 [Указатель на графическое представление объекта]
054 [Здоровье]
055 [Указатель на следующий элемент (098)]

...

062 [Указатель на графическое представление объекта]
063 [Здоровье]
064 [Указатель на NULL (конец списка)]

...

098 [Указатель на графическое представление объекта]
099 [Здоровье]
100 [Указатель на следующий элемент (062)]

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

При использовании массива реализация может выглядеть следующим образом:

Заголовок списка:

Первый [индекс первого объекта - 001]
Последний [индекс последнего объекта - 003]

Список:

Индекс массива - данные - индекс следующего элемента

001 Данные объекта 1 002
002 Данные объекта 4 004
003 Данные объекта 2 -1
004 Данные объекта 3 003

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

При использовании этого метода в игре Warwind было задействовано множество списков, и все они имели дело с одним массивом. Общий модуль выполнял просмотр массива сверху донизу. Когда нам было необходимо выполнить обработку для конкретного игрока, мы просматривали список объектов данного игрока. Когда должна была выполняться обработка для некоторых типов элементов, мы просматривали соответствующий список и так далее.

И еще несколько слов о гибкости:

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

Чтобы знать все о компании Dreamforge Intertainment, ее служащих и играх, обратитесь на веб-сайт www.dreamforge.com.



Содержание Назад Вперед