Inferno #02
01 мая 2001

Gameland - Как написать игру. Том 3. Часть первая.

        Как написать игру. Том 3
             Часть первая

(c) Дронов Константин

        "Способ стойки на ушах"

                Если вы говорите с богом
                   это молитва , если же
                 бог говорит с вами , то
                        это шизофрения .


              Предисловие

 То  что  вы видите является статьей на-
писаной  по  просьбе "стаи товарищей", с
мольбой в глазах, со скрючеными пальцами
судорожно  сжимающих мышку и криком : "А
ну поделись опытом #ля-я-я , а то заксо-
рю !!!". Ну хошь-не хошь, а делиться на-
до.  Эта статья основана на личном опыте
и  представляет  интерес  в основном для
дизайнеров и програмеров. В основном она
будет полезна для разработчиков игр типа
ACTION  или, на крайняк, RTS, но ограни-
чено  и для других. Здесь не будет гото-
вых  процедур,  а только намеки как сде-
лать  то или иное, а как это сделать ре-
шайте сами, основываясь на личном опыте.
Выбор системы програмирования не являет-
ся  самым  важным,  так  выбор  актуален
только  на  SPECCY, так как кроме как на
ASSEMBLER'е сделать что-либо стоящее не-
возможно.  Для современных платформ этот
выбор не актуален так как здесь все мож-
но свалить на мощность процессора.


     "С чего начать писать игру ?"

 Самый часто  задаваемый  вопрос выведен
во  главу  этой  статьи.  Ответ столь же
прост  сколь и странен : "Я НЕЗНАЮ !". У
каждого  должен появиться свой собствен-
ный  подход.  Лично  я сначала обдумываю
идею,  которая безусловно должна вас за-
разить,  заставить  вас думать, хорошо и
во   всех  деталях  представить  будущий
проект. Взять для примера можно что-либо
из существующего, к примеру для моей иг-
ры  "PROJECT  X"  таким прототипом стала
серия  "ALIEN  BREED",  а для "CYBEREAL"
серия  "STAR DUST". Нет нужды изобретать
каждый  раз  велосипед,  так как это до-
вольно  сложно,  а  на  мой взгляд с су-
ществующим    уровнем   техники   просто
невозможно.  Все  так называемые новинки
есть  ремиксы  старых игр и кроме совер-
шенствования  графики и звука ничего но-
вого  не  несут.  Лично для меня кажется
интересным  поразить каждого конкретного
игрока  чем-нибудь  в  вашей игре: так в
"PROJECT  X"  это  были  50FPS  и мощное
оформление (позже я понял ошибку, 50 FPS
далеко  не  самое главное), в "CYBEREAL"
это сама игра с красивой графикой и зву-
ком  плюс сама глобальность происходяще-
го. Итак, у вас есть идея, но приступать
так  же  еще рано, Важно оценить возмож-
ность  создания  на  вашей  компьютерной
платформе  этого  будущего шедевра ;-) .
Здесь вам необходим весь опыт, который у
вас  разумеется  должен  быть, поскольку
если  у  вас нет опыта программирования,
то из написния игры не выйдет ничего хо-
рошего.  Идеален  опыт demomaker'а, этот
опыт  позволит  вам  подойти к написанию
игры с огромной библеотекой знаний и го-
товых  процедур.  Вам  необходимо осмыс-
лить, представить всю вашу программу так
хорошо, чтобы к моменту, когда вы сядете
за   компьютер  у  вас  было  бы  полное
представление  о  том, что вы будете де-
лать.


            " Ты начал ... "

 Разработай  все    необъходимые    тебе
программы,  например: редактор уровней и
т.п.  Какие  возможности  у  него должны
быть решать тебе я могу сказать, что мой
редактор  для  игры  "Incubation Period"
имеет функции загрузки спрайтов, нарезка
спрайтов  из большой карты, загрузка па-
литры, редактор атрибутов блоков, редак-
тор крупных изображений, редактор анима-
ции для блоков, редактор карты, редактор
накладки изображений второго уровня, ре-
дактор описателя, работа с пре-файлами и
наконец  компилятор файла уровня. Но на-
писание такого редактора тема отдельного
разговора  или можете воспользоватся лю-
быми  другими,  уже  готовыми, например,
моими для SPECCY и AMIGA, они будут ско-
ро  выложены  на страницу LASER DREAMS в
сети  INTERNET. Но это не выход, так как
они расчитаны на отдельный случай.

 Заведите себе  основную тетрадь, разде-
лите тетрадь на две части, где вы будете
хранить  данные  о  переменных, их месте
расположения и о процедурах с данными на
вход  и выход. Внесите все возможные пе-
ременные,  которые  придут  вам на ум. К
примеру:  жизни,  энергию, заряды к ору-
жию,  тип оружия, время, режим отладки и
т.д.  Отдельно  выделите место для внут-
ренних переменных игры как то: какой эк-
ран активен, адрес расположения открытой
библиотеки и т.д. И оставляйте как можно
больше места для будущих внесенных изме-
нений. Определите как вы хотите работать
с экраном, оцените быстродействие, опре-
делите как вы будете выводить графику на
экран.  Мой  совет: забудьте возможность
рисования прямо в экран, используйте бу-
фер или работайте в режиме двух экранов,
иначе  возникнут  проблемы с синхрониза-
цией  вывода на экран. Так, например, на
AMIGA  есть возможность организовать эк-
ран,  где  угодно в памяти, что позволит
вам применить схему :

              ┌───────────┐
              │ проверить │
              │ счетчик   │ <────────┐
              └───────────┘          │
          равен 0 / \ равен 1        │
                 /   \               │
      ┌──────────┐   ┌──────────┐    │
      │показываем│   │показываем│    │
      │в экран 0 │   │в экран 1 │    │
      └───┬──────┘   └────┬─────┘    │
          │               │          │
      ┌───┴─────┐     ┌───┴─────┐    │
      │ рисуем  │     │ рисуем  │    │
      │в экран 1│     │в экран 0│    │
      └─────────┘     └─────────┘    │
                 \   /               │
                  \ /                │
                   │                 │
       ┌───────────────────────┐     │
       │ увеличим счетчик на 1 │     │
       └───────────┬───────────┘     │
                   └─────────────────┘


 Разумеется счетчик   можно  оптимизиро-
вать.  Так  на SPECCY можно организовать
работу  с  двумя  экранами  и  применить
блок:

BWRITE    LD   A,23
          XOR  10
          LD   (BWRITE+1),A
          LD   BC,32765
          OUT   (C),A

 Разумеется это  несет известные ограни-
чения  и сложности при работе со страни-
цами,  но также даст возможность не тра-
тить время на переброску экрана. Поэтому
оцените  возможности  и посмотрите, если
объемы данных превышают размеры 32kb, то
возможно есть смысл тратить процессорное
время  на  организацию програмной переб-
роски.  Хотя я, например, в игре PROJECT
X делал так: переключал страницу памяти,
перекидывал  нужные  данные  в буффер, и
работал далее с двумя экранами.

 На  AMIGе  при работе напрямую с чипсе-
том  можно  просто изменить указатель на
BITPLAN'ы  в COOPER LIST. А при работе с
видеокартами можно пользоватся функциями
системы, то есть библиотеками, а можно и
ознакомиться с возможностями видеокарто-
чек  и работать на прямую, но это потре-
бует больше времени и нервов. К примеру,
воспользоватся функцией переброски блока
памяти, но это на мой взгляд очень грубо
и  есть более элегантные способы, напри-
мер, открыть два экрана и воспользоватся
функцией переключения экранов :
 -252 ScreenToFront из intuition.library
 Но это несколько нестандартный способ и
не  стоит им пользоваться, это лишь при-
мер  своеобразного  подхода. Вообще есть
куча способов для работы с двумя экрана-
ми,  просто  загляните  в список функций
библиотек.

ЕСЛИ  ХОТИТЕ  ИМЕТЬ  КАК МОЖНО
МЕНЬШЕ  ПРОБЛЕМ С ОТЛАДКОЙ И С
ЖЕЛЕЗОМ,   ЧТО  БЫ  ВАША  ИГРА
ИСПРАВНО  ПОДДЕРЖИВАЛА ВСЕ НО-
ВОЕ ЖЕЛЕЗО, РАБОТАЙТЕ ПОД СИС-
ТЕМУ,  ПИШИТЕ OS-FRENDLY ПРОГ-
РАММЫ

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

 Первоначально создайте  основной  цикл,
который  будет отображать блок схему, но
вместо "вывод на экран" можно внести вы-
зов  подпрограммы  с процедурой вывод на
экран.  И  вообще, старайтесь везде (где
это  не  скажется  на  скорости) вводить
подпрограммы  и  не используйте ни каких
"извращенных"  приемов  в основном цикле
программы,  легче  будет  разобраться. В
каждом  цикле  указаной выше схемы жела-
тельно  обратиться к процедуре синхрони-
зации. Для SPECCY есть команда процессо-
ра HALT, которая синхронизуется по нача-
лу прорисовки экрана, а для AMMY это мо-
жет быть функция:
 -270 WaitTOF из graphics.library

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


        "Восток дело тонкое ..."

 К началу  желательно  иметь уже хотя бы
часть  графики к игре. Нужна также карта
игры.

 Перейдем к  частностям.  Ну, к примеру,
как сделать процедуру прорисовки графики
в буффер здесь нужно смотреть какая игра
2D  или  3D  графика в ней используется.
Разберем  сначала  2D.  Ваша задача сво-
диться ...

  1.  изменить карту соответстенно вашим
описателям анимации
  2. напечатать карту в буффер
  3. нанести сверху объекты
  4. спецэффекты
  5. конец

 Пункт 1:   не   является  обязательным,
но... Вообщем решайте сами. Как же проще
всего  организовать  анимацию  блока  на
карте  ? А очень просто !!! Можно к при-
меру задать в памяти такую структуру :

┌───────────────────┬──────────────────┐
│первый блок памяти │второй блок памяти│
├───────────────────┼──────────────────┤
│  данные первого   │ номер следующего │
│     спрайта       │     спрайта      │
├───────────────────┼──────────────────┤
│  данные второго   │ номер следующего │
│     спрайта       │     спрайта      │
├───────────────────┼──────────────────┤
:                   :                  :
.                   .                  .

.                   .                  .
:                   :                  :
├───────────────────┼──────────────────┤
│  данные  NNNNNNN  │ номер следующего │
│      спрайта      │      спрайта     │
├───────────────────┼──────────────────┤
│  данные  NNNNN+1  │ номер следующего │
│      спрайта      │      спрайта     │
├───────────────────┼──────────────────┤
:                   :                  :
.                   .                  .

.                   .                  .
:                   :                  :
├───────────────────┼──────────────────┤
│  данные  KKKKKKK  │ номер следующего │
│      спрайта      │      спрайта     │
├───────────────────┼──────────────────┤
│  данные  KKKKK+1  │ номер следующего │
│      спрайта      │      спрайта     │
├───────────────────┼──────────────────┤
:                   :                  :
.                   .                  .

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

        ┌─────────────────────┐
        │ N = данные счетчика │
        └──────────┬──────────┘
                   │
  ┌────────────────┴────────────────┐
  │ A = номер блока из карты уровня │
  └────────────────┬────────────────┘
                   │
     ┌─────────────┴─────────────┐
     │A=номер блока следующего за│
     │    блоком A из таблицы    │<─┐
     └─┬─────────────────────────┘  │
       │                            │
       │     ┌─────────────────┐    │
       └─────┤ повторить N раз ├────┘
             └───────┬─────────┘
                     │
                     :
                     .

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

 Пункт  2:  Здесь  даже объяснять ничего
не  надо,  достаточно  просто произвести
печать  в буффер последовательно каждого
блока.   Единственный  совет  старайтесь
сделать  так, чтобы в размеры блока были
пропорциональными 8, 16, 32 и т.д. Самим
будет  легче.  Но это я так, ведь енто и
ежику ясно ;-) ...

 Пункт 3  :  Здесь  тоже все как в парке
днем. Так же все понятно. Проблема самая
большая  это  обрезание ( ;-) ) объектов
границами  экрана, по-научному клиппиро-
вание.  Решения  могут быть разными, ну,
например,  если  вы копируете буффер, то
вы  вполне  можете сделать буффер таким,
чтобы у него был своеобразный бордюр, то
есть  пространство  в  которое можно без
проблем записать весь объект. Типа:

┌──────────────────────────────────────┐
│               AAAA-объект            │
│ X1,Y1         AAAA                   │
│  ┌────────────────────────────────┐  │
│  │                                │  │
│  │                                │  │
│  │     область перекидываемая     │  │
│  │            в экран             │  │
│  │                                │  │
│  │                                │  │
│  └────────────────────────────────┘  │
│               бордюр           X2,Y2 │
│                                      │
└──────────────────────────────────────┘

 Это  имеет  смысл  только  если объекты
являются  независимыми  от карты уровня,
то  есть  не задаются блоками, иначе вся
проблема  сводиться  к проверке на выход
за границы области типа :


  ┌────────────────────────┐
  │ X,Y-верхний левый угол │
  │     объекта XD=X       │
  └──────────┬─────────────┘
             │
         ┌───┴────┐   нет
         │ X < X2 ├────────────────┐
         └───┬────┘                │
             │ да                  │
         ┌───┴────┐   нет          │
         │ Y < Y2 ├────────────────┤
         └───┬────┘                │
             │ да                  │
         ┌───┴────┐   нет          │
   ┌─────┤ X > X1 ├──────────────┐ │
   │     └───┬────┘              │ │
   │         │ да                │ │
   │     ┌───┴────┐   нет        │ │
   │     │ Y > Y1 ├────────────┐ │ │
   │     └───┬────┘            │ │ │
   │         │ да              │ │ │
   │ ┌───────┴──────────────┐  │ │ │
   │ │ блок входит в пределы│  │ │ │
   │ │        экрана        │  │ │ │
   │ └───────┬──────────────┘  │ │ │
   │         │                 │ │ │
   │      ┌──┴───┐             │ │ │
   │      │ X=X+1├─────────────┘ │ │
   │      └──┬───┘               │ │
   │         │                   │ │
   │нет┌─────┴─────────┐         │ │
   ├───┤ X=максимальный│         │ │
   │   │  размер по X  │         │ │
   │   └─────┬─────────┘         │ │
   │         │ да                │ │
   │     ┌───┴───┐               │ │
   │     │ Y=Y+1 ├───────────────┘ │
   │     │ X=XD  │                 │
   │     └───┬───┘                 │
   │         │                     │
   │нет┌─────┴─────────┐           │
   └───┤ Y=максимальный│           │
       │  размер по Y  │           │
       └─────┬─────────┘           │
             │ да                  │
        ┌────┴────────┐            │
        │ все , конец ├────────────┘
        └────┬────────┘
             │
             :
             .

 Этот прием    можно   применить   и для
независимых объектов, но нужно его моди-
фицировать,  так  как,  иначе вам потре-
буется проверять каждую точку объекта, а
это  тянет ненужные затраты времени CPU.
Да, бесплатный совет, нет нужды пытаться
оптимизировать эту схему, если вы пишете
на  ASM'е, то попытка оптимизировать та-
кое количество сравнений похожа на само-
убийство,  вы конечно сможете, но нервов
и мата будет много.

 Продолжение читайте  в следующем разде-
ле.




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Юмор - Как затащить хакера в спальню.
Реклама - Реклама и объявления.
Всякая всячина - обзор нового софта: PЕDRО in 3 parts, Video Studio, Return to Spectrum, AMP-PAСK 0.05, UNRAR 0.33, 8-СОLОR 0.04, AСЕ 0.666, Real Commander 2.3, Bestvide 2.14.

В этот день...   26 сентября