Пишем Space Invaders при помощи Corona. Реализация геймплея. Часть 1

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

Пара слов о метатаблицах

Язык программирования Lua по умолчанию не имеет классовой системы, а потому не умеет работать с классами. Тем не менее при помощи метатаблиц в Lua можно эмулировать систему классов. На сайте Corona есть отличный пример, демонстрирующий, как это можно сделать.

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

Пульсирующий текст

В прошлой части мы говорили, что будем использовать в игре пульсирующий текст. Для этого мы напишем свой модуль, который можно будет использовать в любом месте программы. Более того, этим модулем вы сможете воспользоваться в любой вашей программе, написанной на Lua.

Итак, давайте добавим следующий код в файл pulsatingtext.lua, который был создан нами еще в прошлом уроке (убедитесь, что приведенный код вы вставили перед return):

Здесь мы создали главную таблицу pulsatingText и метатаблицу pulsatingText_mt. В методе new мы создали новое текстовое поле, добавили его в newPulsatingText, который будет использован в качестве метатаблицы, и вставили сам текст в объект group. Важно понимать, что текст находится на сцене, при удалении которой исчезнет и сам текст.

У нас есть еще два метода, которые имеют доступ к текстовому полю и выполняют над ним определенные действия. Один из них меняет цвет самого текста при помощи метода setFillColor, который принимает в качестве аргументов цвет в формате RGB, определенный 3 числами в диапазоне от 0 до 1. Второй метод использует библиотеку Transition, чтобы создать пульсацию. Текст растет и уменьшается при помощи коэффициентов xScale и yScale. Параметр iterations, равный -1, позволяет повторять пульсацию бесконечно.

Использование пульсирующего текста

Откройте файл start.lua и измените метод scene:create следующим образом:

Здесь мы создали новое текстовое поле, в котором написали «INVADERZ», задали ему цвет и вызвали метод pulsate. Обратите внимание на последнюю переменную, переданную в метод new, — это group. Именно на group — объект класса Display — и будет добавляться наш пульсирующий текст.

Для более футуристичного вида пульсирующего текста воспользуемся шрифтом «Conquest». Добавьте его в папку проекта, если вы хотите использовать его. Будьте осторожны, не нарушайте права авторов при использовании сторонних шрифтов.

Для использования стороннего шрифта мы должны изменить файл build.settings:

Если вы запустите игру в том виде, в котором она есть сейчас, то увидите что-то похожее:

pulsating_text

Генератор звезд

Чтобы игра была чуточку разнообразнее, добавим движущиеся звезды на задний фон. Для этого, так же, как и в случае с пульсирующим текстом, создадим отдельный модуль. Откройте созданный еще в прошлой статье файл starfieldgenerator.lua и добавьте в него следующий код:

Сначала мы создаем главную таблицу starFieldGenerator и метатаблицу starFieldGenerator_mt. В методе new мы имеем таблицу allStars, в которой будут храниться все звезды, которые создаются в течение цикла. Количество итераций равно numberOfStars (т. е. количеству звезд), а для рисования самих звезд мы используем метод newCircle объекта Display.

Расположение кружков (звезд) случайное, в пределах границ экрана. Размер варьируется от 2 до 8. Каждая звезда после создания вставляется в таблицу allStars, а затем на ту сцену, которую передали в параметрах метода new.

Мы задаем allStars и starSpeed в качестве ключей временной таблицы, а затем связываем ее с метатаблицей. Для осуществления движения звезд мы должны иметь доступ как к allStars, так и к starSpeed.

Непосредственно за движение отвечают две функции: starFieldGenerator:moveStars (используется при самом движении) и starFieldGenerator:checkStarsOutOfBounds (используется при выходе звезды за границу экрана).

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

Все вышеописанные функции вызываются в методе starFieldGenerator:enterFrame. Добавьте следующий блок кода в метод scene:create в файле start.lua:

Обратите внимание на порядок выполнения функций. Кнопка добавляется уже после того, как сгенерировались все звезды. Если сделать наоборот, то звезды пролетали бы над кнопкой, а не под.

Порядок (order) можно изменить и вручную. Для этого у класса Display есть два метода: toFront и toBack.

Если вы сейчас запустите игру, то увидите кучу недвижимых звезд с одной кнопкой. Чтобы звезды пришли в движение. добавьте следующий код в метод scene:show в файле start.lua:

Здесь мы добавляем слушателя события enterFrame, который, как вы помните, как раз и заставляет звезды двигаться.

Как говорится, сколько раз new, столько же раз delete. Именно поэтому мы должны удалить слушателя, если он нам больше не нужен. А не нужен он нам будет при удалении сцены:

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

STARFIELD

Вывод

А на этом все! Мы написали два собственных модуля, один из которых создает пульсирующий текст, а другой — иллюзию потока звезд в космосе. В следующей части мы поговорим непосредственно об игровой сцене: добавим героя и поговорим о коллизии. Оставайтесь с нами!

Перевод статьи «Create a Space Invaders Game in Corona: Implementing Gameplay»