Game Maker: делаем игры своими руками Глава 1-2
Пролог.
— Как странно! — подумала Алиса. — Впрочем, сегодня все странно. Войду-ка я в эту дверцу. Так она и сделала.
Л.Кэролл "Алиса в стране Чудес"
Вот уж не ожидал, что игровое сообщество проявит такой интерес к небольшой строчке в Путеводителе On-line, в которой я скромно предлагал осветить внутренности процесса создания игр. Признаться честно, я, конечно, ожидал, что геймеры проявят заинтересованность, но чтоб так... И это радует. Значит, рубрика не будет бесполезной. Я сам пока еще не знаю, сколько будет статей на эту тему, ведь решать, какой рубрике жить в газете, прежде всего, вам. Понравится - что ж, я ваш покорный слуга, со всеми вытекающими. Не понравится - рубрика скромно канет в Лету. А в целом, могу сказать, что если кто действительно очень заинтересуется, то и программировать научу, чтобы объявлений типа "Есть масса идей по созданию игр, требуется программист, который все это сделает" в газете вообще не было. Короче говоря, если вам интересно, то следуйте примеру Алисы - войдите в дверцу и посмотрите, что там с той стороны? Для этого нам будет необходимо: во-первых, игровой движок Game Maker версии 5.0. Взять его можно со следующего адреса:
http://www.gamemaker.nl/download/gmaker.exe (3,9 Mb).
Во-вторых, желательно, чтобы вы скачали следующие архивы с ресурсами:
http://www.gamemaker.nl/resources/res01.zip (1,3 Mb)
http://www.gamemaker.nl/resources/res02.zip (1,9 Mb)
http://www.gamemaker.nl/resources/res03.zip (1,9 Mb)
http://www.gamemaker.nl/resources/res04.zip (1,5 Mb).
Скачивать ресурсы необязательно, просто примеры, которые я буду рассматривать в дальнейших статьях, будут основаны на содержащихся в приведенных архивах ресурсах. Кроме того, если вы захотите создать свою игру, то сможете использовать все те же готовые ресурсы.
В-третьих, перед началом чтения статьи обязательно ознакомьтесь с help'ом, ибо самые основные моменты в нем описаны довольно неплохо. Если вы не знаете английский язык достаточно хорошо, то не смущайтесь. Есть переведенный help, который можно скачать отсюда:
http://gmaker4.narod.ru/download/doc/gmaker43help_ru.zip (470Kb)
Пусть вас также не смущает то, что данный help написан для версии 4.3. Особо глобальных изменений не произошло — лишь мелкие доработки + несколько фич, которые будут рассмотрены позже. Самое главное, чтобы вы научились определять события и поняли структуру движка. Можете даже не создавать примеры, описанные там, — все это мы сделаем вместе, только процесс будет немного интереснее. Итак, если вы прочитали help (т.е. научились добавлять спрайты, звуки и создавать объекты и комнаты), скачали и установили движок и вообще морально настроены созидать, тогда мы можем начать.
Глава 1: создаем первую игру
— Мне кажется, я бы лучше поняла, — учтиво проговорила Алиса, — если б я могла это записать. А так я не очень разобралась.
— Это все чепуха по сравнению с тем, что я могла бы сказать, если бы захотела, — ответила польщенная Герцогиня.
Л.Кэролл "Алиса в стране Чудес"
Итак, первой игрой у нас будет простой двумерный шутер. Значит, по экрану должен двигаться объект, при попадании по которому увеличиваются очки, объект уничтожается и появляется в другом месте. Поехали... Запускаем Game Maker (далее GM). Добавляем два спрайта — один для стены нашей комнаты, второй — для объекта, который будем уничтожать. Можно взять фото любимого препода, хе-хе-хе. Называем спрайты s_wall и s_object соответственно. Что означает s в начале названия? То, что это спрайт. Аналогично мы будем использовать b для заднего фона, snd — для звука, o — для объектов, и r — для комнат. Конечно, GM поддерживает перегрузку названий ресурсов (например, когда спрайт, комната и объект называются одинаково), но нам такое обозначение весьма пригодится, когда мы с вами начнем делать более сложные игры и перейдем от определения событий для объектов к написанию кода для каждого отдельного события объекта. Далее создаем аналогичные объекты: o_wall и o_object и назначаем для них соответствующие спрайты. Для этого в свойствах объекта выберите определенный спрайт в выпадающем меню Sprite. Для объекта o_wall обязательно поставьте галочку Solid. Это сделает объект "твердым", т.е. через него не будут проходить другие объекты. Теперь создадим комнату r_room. Пока просто создайте комнату и на вкладке Settings измените имя комнаты с room0 на r_room. Теперь расставим в комнате объекты. Для этого перейдите на вкладку Objects и в выпадающем списке выберите требуемый объект, после чего кликните на любой из клеток комнаты. В этой точке создастся выбранный вами объект. Если вы хотите удалить лишние объекты — выберите в списке пункт <delete>. Объектом o_wall надо обрисовать периметр комнаты. Далее поместите два объекта o_object внутрь комнаты. Результат можно видеть на рисунке 1. Все, уже можно запускать игру (чтобы сделать это быстро, просто нажмите F5). Красиво, правда? Только пока, к сожалению, ничего не двигается. Закрываем игру и возвращаемся в GM.
Теперь мы с вами определим события и действия для объектов таким образом, чтобы они ожили, а мы получили свою первую игру. Объект o_wall трогать не будем вообще. Посудите сами, он должен исполнять только одну функцию — не давать объекту o_object улететь за пределы экрана. Открываем свойства объекта o_object. Задаем событие Создания (Add Event >> Create). Для него назначаем действие с вкладки move (она вертикальная, находится справа), которое называется Set direction and speed of motion. В свойствах действия выбираем self, затем в графе direction пишем random(360), в графе speed пишем 5. Закрываем свойства. Далее назначаем событие столкновения с объектом o_wall (Add Event >> Collision >> o_wall). Для него определяем действие Bounce against solid objects. Это означает, что при столкновении со стеной объект o_object будет отлетать от него под углом в 90 градусов. Далее определяем событие щелчка по объекту левой кнопкой мыши (Add Event >> Mouse >> Left Button). Для него назначаем следующие действия (в порядке очередности): Destroy the instance (вкладка main1 справа), Create instance of object (там же) и, наконец, Set the score to (score). Для Destroy the instance выбираем self, для Create instance of object выбираем self, в графе object — o_object, в графе x — random(570)+32, в графе y — random(410)+32. Эти параметры определят создание объекта в случайном месте комнаты. В Set the score to пишем 10 и ставим галочку Relative. Эта галочка обозначает, что при уничтожении o_object к счету будет добавляться 10 очков.
Ну вот! Первая игра готова. Запускайте и наслаждайтесь. Если вдруг у вас что-то не получилось — напишите мне и я пришлю вам исходник. Если вы чего-то недопоняли, не расстраивайтесь, поймете чуть позже. Просто сейчас я хочу дать возможность начать изучать движок всем — от мала до велика, даже тем, кто совсем не знает программирования. Со временем, конечно, мы перейдем от определения действий к написанию кода на GML, что значительно упростит изучение (и преподавание, хе-хе) GM в будущем.
Глава 2: лабиринт
— Только я кончил первый куплет, как кто-то сказал: "Конечно, лучше б он помолчал, но надо же как-то убить время!" Королева как закричит: "Убить Время! Он хочет убить Время! Рубите ему голову!"
Л.Кэролл "Алиса в стране Чудес"
Первая игра создана. Вау! Теперь сделаем кое-что поинтереснее, а именно игру типа Лабиринт. Идея: персонаж может перемещаться по четырем стандартным направлениям (вверх,вниз, влево, вправо), собирать бонусы (за которые будут даваться очки) и ключи (которые будут открывать двери). В игре присутствуют монстры. Выход в следующий уровень закрыть дверью, которая откроется, когда все ключи будут собраны. Что ж, поехали. Для изображения героя, монстров, стены и бонусов я взял спрайты из набора pacman (Game_ Maker5/Sprites/pacman), все остальное — из various (Game_Maker5/Sprites/various).
Забиваем спрайты s_hero_left(pacman_left. gif), s_hero_right(pacman_right.gif), s_hero_up (pacman_up.gif), s_hero_down(pacman_down. gif), s_hero_stand(pacman_stand.gif), s_monster (monster5.gif), s_bonus(bonus.gif), s_wall(wall. gif), s_key(startup.ico), s_door(stop.ico) и s_finish(time.ico), а затем определяем соответствующие им объекты (в скобках указаны особенности объектов и названия соответствующих им спрайтов) o_hero(s_hero_stand), o_monster_ver(s_monster), o_monster_hor(s_monster), o_bonus(s_bonus), o_wall(s_wall, галочка Solid) o_key(s_key), o_door(s_door, галочка Solid), o_finish(s_finish). В результате должно получиться нечто похожее на рисунок 2.
Теперь делаем комнату r_room. В свойствах комнаты (Settings) в полях Snap_x и Snap_y пропишите значение 32. Это значит, что вся комната условно разбита на квадратики со стороной 32 пикселя. Теперь помещаем в нашу комнату объекты так, как показано на рисунке 3. После всего проделанного осталась самая малость — определить действия для каждого объекта. Для простоты я опишу действия для каждого объекта по следующему шаблону Тип_события->Событие<Действие(Параметры), Действие(Параметры), и т.д.>, и т.д.
Объект для o_hero:
Keyboard -> no key <Set the value of the variable(variable sprite_index:, value: s_hero_stand), If instance is aligned with grid(32,32), Start moving in a direction (квадратик, скорость = 8)>,
Keyboard -> Left < Set the value of the variable(variable sprite_index:, value: s_hero_left), If instance is aligned with grid(32,32), Start moving in a direction (влево, скорость = 8)>,
Keyboard -> Up < Set the value of the variable(variable sprite_index:, value: s_hero_up), If instance is aligned with grid(32,32), Start moving in a direction (вверх, скорость = 8)>,
Keyboard -> Right < Set the value of the variable(variable sprite_index:, value: s_hero_right), If instance is aligned with grid(32,32), Start moving in a direction (вправо, скорость = 8)>,
Keyboard -> Down < Set the value of the variable(variable sprite_index:, value: s_hero_down), If instance is aligned with grid(32,32), Start moving in a direction (вниз, скорость = 8)>,
Collision -> o_monster_hor <Restart Game>,
Collision -> o_monster_ver <Restart Game>,
Collision -> o_wall <If instance is aligned with grid(32,32), Start moving in a direction (квадратик, скорость = 8)>,
Collision -> o_bonus <Destroy the instance (other), Set the score(10, галочка Relative)>,
Collision -> o_key <Destroy the instance(other)>,
Collision -> o_door <If instance is aligned with grid(32,32), Start moving in a direction (квадратик, скорость = 8)>,
Collision -> o_finish <Display a message(Вы прошли игру!), Restart room>,
Step -> Step <If the number of instances is value(Object: o_key, number: 0, Operation: Equal to), Destroy the instance(Object: o_door)>.
Объект для o_monster_ver
Create <Start moving in direction (вниз, скорость = 5)>,
Collision -> o_wall <Reverse vertical direction>.
Объект для o_monster_hor
Create <Start moving in direction (влево, скорость = 5)>,
Collision -> o_wall <Reverse vertical direction>.
Постараюсь объяснить, как же оно все работает. При нажатии клавиш влево, вправо, вверх, вниз игра заменят спрайт объекта o_hero на соответствующий спрайт pacman'а, т.е. когда тот движется влево, вправо и т.д. Если не нажата ни одна клавиша, то игра заменят спрайт "идущего" pacman'а на спрайт "отдыхающего" pacman'а и останавливает его движение в ячейке "сетки". Кроме того, игра следит за тем, чтобы объект был в одной из ячеек "сетки", которую мы с вами определяли, когда делали комнату. Это сделано, чтобы было удобнее управлять объектом o_hero. Если объект o_hero выравнен относительно "сетки", то он будет перемещаться в соответствующем направлении, пока не будет отпущена клавиша или объект не столкнется со стеной(o_wall) или дверью(o_door). Для этих событий происходят такие же действия, как и для события, когда не нажата ни одна клавиша. Далее, если герой сталкивается с одним из монстров, то он умирает. Если он сталкивается с объектом o_finish, то появляется сообщение, что игра пройдена. В принципе, если у вас несколько комнат-лабиринтов, то такой объект ставится в последнюю комнату, а в промежуточные, вместо действия Restart Game, вставляется Go to next room. Если герой находит бонус, то объект бонуса уничтожается (пропадает) и увеличиваются очки; если герой находит ключ, то соответствующий ключ уничтожается (ведь герой его забрал). В событии шага (Step) игра отслеживает количество ключей в комнате: если оно равно 0, то уничтожается (открывается) объект o_door, обеспечивая доступ к выходу из уровня. Для монстров события определены таким образом, чтобы при создании они двигались в соответствующем направлении, а при столкновении со стеной меняли направление на противоположное.
Я понимаю, что объясняю немного занудно и понять меня местами сложновато. Все это от того, что я привык писать код на GML, вместо определения действий, а поэтому со следующего номера мы начнем учиться программировать на GML. Поверьте, от этого будет проще и мне, и вам.
Воронецкий "AlienRaven" Михаил
Продолжение следует...

