[Из песочницы] Создаем платформер за четыре вечера
Сразу оговорюсь: речь пойдет о гейм-девелопменте для души. Чтобы не стыдно было показать игру миру — придется попотеть подольше.
Как и многие, я стал программистом из-за детской мечты написать собственную игру. Со временем я посвятил себя другой области, но однажды решил во что бы то ни стало воплотить мечту в жизнь. Здесь я хочу поделиться своим опытом, чтобы, возможно, вдохновить вас.
1. Цель Моей целью было создание классического платформера, но с такими сюжетом, персонажами и уровнями, которые интересны мне. Я хотел сделать игру своими силами и специально для себя; при этом сделать ее с минимальными затратами сил и своего свободного времени.2. Поиск инструментов Конечно, создавать геймплей с нуля неразумно. Я начал с поиска конструкторов и сред разработки игр и нашел достаточно большой список на сайте [http://gcup.ru/load/konstruktory_igr/12]. Отдельного внимания хочу удостоить конструкторы, позволяющие быстро создать тематические игры: например, Open Zelda [http://openzelda.net/] или Mario Worker [http://www.softendo.com/game/Mario%20Worker]. Настоящий клад для фанатов. Не редкость и конструкторы, которые позволяют создавать игры классических жанров (в том числе и платформеры), и при этом вообще не требуют навыков программирования. Например, 001 Game Creator [http://www.engine001.com/] или Rune Sword [http://www.runesword.com/]. При всей своей функциональности, подобные конструкторы в некоторой мере ограничивают творца в возможностях. Кроме того, большинство фич этих инструментов, таких как портирование игр на Андроид, платные.Среди прочих средств проектирования игр, мое внимание привлек Tululoo Game maker [http://tululoo.com/]. Преимущества налицо: полностью бесплатный инструмент, объединяющий в себе удобство готового движка с вариативностью программирования специфических аспектов игры. К тому же, готовая игра представляет собой веб-страницу на HTML5 с javascript, что позволяет выложить игру в интернет. Самым большим неудобством можно считать отсутствие отладчика. И все же, это вариант отлично решает мою задачу, поэтому на нем я и остановился.3. Быстрый старт в Tululoo Game maker Для работы со средой Tululoo Game maker необходимы какие-никакие знания ООП, javascript, а также наличие браузера с поддержкой HTML5. В среде существует 2 проекта-примера: адвенчура и платформер. Я взял за основу предложенный платформер, что значительно упростило старт написания своей игры. В примере уже существуют один уровень и персонаж, который умеет перемещаться, прыгать, собирать монетки и стрелять по ящикам, — великолепный шаблон для дальнейших экспериментов. Для тех, кто заинтересовался созданием игры с помощью Tululoo Game Maker, я рассмотрю несколько этапов работы для более быстрого и приятного старта.4. Редактирование персонажа В редакторе игры переходим на вкладку Objects → Двойной клик по объекту obj_player → в списке обработчиков событий объекта выберем Step. В поле Code preview подгрузится соответствующий событию javascript.
Следует отметить, что в коде объекта obj_player сосредоточена основная механика игры — через взаимодействие игрока с остальными объектами игрового мира. Событие Step выполняется по таймеру каждый кадр; количество кадров в секунду настраивается при редактировании уровней (я принял значение по умолчанию — 60 кадров в секунду). Сейчас в событии Step обрабатывается нажатие клавиш и столкновение игрока с объектами ландшафта. Первым делом заменим изображение игрока на нашего героя. Нового персонажа я нарисовал в пэинте в двух вариантах: смотрящим влево и вправо, и добавил получившиеся рисунки в спрайты на вкладке Sprites. После загрузки каждой картинки по кнопке Edit можно перейти к редактированию изображения, где есть полезная опция Erase color, — с помощью нее можно стереть фон, добившись тем самым правильного контура.
Теперь необходимо вернуться к редактированию объекта obj_player и указать для него один из новых спрайтов. Поработаем с кодом: научим объект игрока поворачиваться влево и вправо. Для этого будем менять картинку персонажа между левосторонней и правосторонней, используя свойство sprite_index (более полное описание API можно увидеть в хелпе).obj_player событие Step:
В самом начале кода редактируем строки:
if (x > room_width) { x = room_width; instance_destroy (); room_goto_next (); } if (keyboard_check (vk_right)) { x += 4; if (direction > 0) sprite_index = spr_player_right; //change sprite if direction changed direction = 0; if (place_meeting (x, y, obj_ground) != null || place_meeting (x, y, obj_box) != null) { x = xprevious; } }
if (keyboard_check (vk_left)) { x -= 4; if (direction == 0) sprite_index = spr_player_left; //change sprite if direction changed direction = 180; if (place_meeting (x, y, obj_ground) != null || place_meeting (x, y, obj_box) != null) { x = xprevious; }
} Запускаем и радуемся. Анимацию шагов делать сложнее, поэтому не буду рассматривать здесь эту процедуру.
5. Добавление объектов Добавим два объекта: противника и снаряд, которым он будет стрелять. При создании объекта противника унаследуем его от obj_box, чтобы он препятствовал прохождению сквозь себя игрока, а также уничтожался при попадании снаряда. В обработчики событий Creation и Step добавим код для стрельбы по игроку. Код игрока придется подредактировать: при контакте со снарядом противника obj_player будет уничтожаться. Также вынесем объект игрока в глобальную переменную. Код объектов: Global variables:
global.player = obj_player; obj_player событие Creation:
this.air = 0; this.jump = 0; global.player = id; obj_player событие Collision with obj_enemy_bullet:
instance_destroy (); obj_enemy_1 событие Creation:
this.timer_max = 60; this.timer = this.timer_max; this.distance_fire = 480; this.bullet_speed = 5; this.bullet_height = 25; obj_enemy_1 событие Step:
//aim player distance = global.player.x — x; direction = 0;
if (distance < 0) { distance = -distance; direction = 180; }
function fire () { // DECREASE THE TIMER timer--; if (timer <= 0 ) { bullet = instance_create(x,y - bullet_height, obj_enemy_bullet); bullet.direction = direction; bullet.speed = bullet_speed; timer = timer_max; } }
if (distance < distance_fire) { fire(); } 6. Редактирование уровней Последний шаг, важный для создания полноценного платформера — создание уровней. В Tululoo для этого весьма простой интуитивно понятный интерфейс: в конструкторе на вкладке Scenes набрасываем нужные объекты в игровую зону — и готово. Конечно, дизайн уровней — важный и самый трудоемкий процесс. Здесь настоящий простор для воображения. Отдельно опишу часть кода, отвечающую за переключение между уровнями. Для это используется функция room_goto_next (более полное описание API можно увидеть в хелпе).obj_player событие Step:
Заменим последнюю строку кода на:
if (x > room_width) { x = room_width; instance_destroy (); room_goto_next (); } Результирующий код этого события будет выглядеть так:
obj_player событие Step:
if (keyboard_check (vk_right)) { x += 4; if (direction > 0) sprite_index = spr_player_right; //changew sprite if direction changed direction = 0; if (place_meeting (x, y, obj_ground) != null || place_meeting (x, y, obj_box) != null) { x = xprevious; } }
if (keyboard_check (vk_left)) { x -= 4; if (direction == 0) sprite_index = spr_player_left; //changew sprite if direction changed direction = 180; if (place_meeting (x, y, obj_ground) != null || place_meeting (x, y, obj_box) != null) { x = xprevious; }
}
if (keyboard_check_pressed (vk_up) && jump == 0) { jump = 1; air = 12; //sound_play (snd_jump); }
if (air > -5) air -= 0.5;
y -= air;
if (place_meeting (x, y, obj_ground) != null || place_meeting (x, y, obj_box) != null) { y = yprevious; air = 0; jump = 0; }
if (keyboard_check_pressed (vk_space)) { bullet = instance_create (x, y — 25, obj_bullet); bullet.direction = direction; bullet.speed = 15; }
if (x < 0 ) x = 0; if ( x > room_width) { x = room_width; instance_destroy (); room_goto_next (); } 7. Резюме Существует множество способов простого создания игры своей мечты. Я разобрал лишь один из них; возможно, кто-то сможет найти более удобные инструменты, — прошу оставлять ваши отзывы о них в комментариях. Желаю Вам творческих успехов!