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'е, то попытка оптимизировать та- кое количество сравнений похожа на само- убийство, вы конечно сможете, но нервов и мата будет много. Продолжение читайте в следующем разде- ле.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября