Пишем Space Invaders при помощи Corona. Настройка проекта
5К открытий5К показов
В этой серии уроков мы будем писать игру по мотивам старой доброй Space Invaders. В рамках этих статей мы познакомимся с Corona, а именно:
- с управлением сцен;
- с таймерами;
- с перемещением героев;
- со встроенным физическим движком.
Также мы узнаем, как использовать модули для эмуляции классов на языке программирования Lua. Прилагаем полный список всех статей в этой серии:
- Настройка проекта.
- Реализация геймплея. Часть 1
- Реализация геймплея. Часть 2
- Заключение
Создание проекта
Откройте Corona Simulator, нажмите New Project и сконфигурируйте проект так, как показано на изображении ниже. Не забудьте выбрать папку для сохранения проекта и нажмите OK. После этого создастся указанная вами папка, которая будет содержать ряд иконок и три особенно важных файла: main.lua, config.lua и build.settings. Мы поговорим о каждом из них чуть позже.
Настройка сборки
Файл build.settings, как несложно догадаться, отвечает за настройки сборки проекта. Откройте этот файл и удалите его содержимое, вместо которого напишите следующее:
Здесь мы указываем, что ориентация экрана должны быть по умолчанию портретной. Более того, игра будет поддерживать только портретный режим. Более подробно о параметрах вы можете прочитать в официальной документации.
Настройка приложения
Файл config.lua отвечает за настройки самого приложения. Откройте этот файл, также удалите его содержимое, вместо которого напишите следующее:
Здесь все просто: мы устанавливаем размер рабочего пространства и задаем частоту кадров. Все подробности в официальной документации.
Примечание переводчика Стоит отдельно рассказать про третью строчку, в которой устанавливается масштаб. Параметр scale может принимать различные значения ("letterbox", "zoomEven", "adaptive" и т.д.). Автор статьи использует "letterbox", и это означает, что если размер экрана отличается от установленного нами, то изображение наше будет масштабироваться до тех пор, пока оно целиком входит в экран. Иными словами, если окно будет размером 800×1024, то слева и справа от изображения будут черные полосы. Проще увидеть, чем прочитать:
Точка входа
Файл main.lua является точкой входа в приложение. Мы будем использовать этот файл для того, чтобы установить несколько параметров по умолчанию и загрузить первый экран при помощи библиотеки Composer.
Если вы не знакомы с Composer, то мы вам настоятельно рекомендуем прочитать официальную документацию по библиотеке по этой ссылке. Если говорить о ней вкратце, то Composer — встроенный в Corona инструмент для управления сценами.
Вышеупомянутая библиотека достаточно новая, она заменяет уже устаревшую StoryBoard.
Статус бар
В игре статус бар не особо-то и нужен, а потому мы уберем его. Для этого следует в файле main.lua прописать следующий код:
Точка привязки
Когда мы указываем координаты для некоторого объекта, мы должны учитывать точку привязки, в качестве которой удобнее всего использовать центральную точку. Для этого добавьте в main.lua:
Значения параметров anchorX и anchorY лежит в диапазоне от 0 до 1. Отсчет начинается слева и сверху. Например, если вы хотите указать в качестве точки привязки левый верхний угол, то выставьте оба значения в нули.
Зерно генерации
Наша игра будет использовать функцию math.random, и для того, чтобы числа получались по-настоящему случайными, нам надо задать зерно генерации псевдослучайных чисел. Если этого не сделать, то при каждом запуске мы будем получать одни и те же значения.
Хорошим параметром для зерна генерации может послужить функция os.time, которая будет различной при каждом запуске приложения. Для определения этого параметра напишите следующий код:
«Нет» глобальным переменным
При использовании Corona и, в частности, языка программирования Lua (да и не только Lua) используют глобальные переменные для того, чтобы расширить область их видимости. Чтобы объявить глобальную переменную в Lua, достаточно убрать ключевое слово local перед ее именем.
Например, в следующем блоке кода объявляются две переменные, первая из которых локальная (она видна только в той функции, в которой объявлена), а вторая — глобальная (она видна в любом месте файла после объявления).
Но использование глобальных переменных, как правило, считается плохой практикой: могут возникнуть конфликты между двумя переменными с одним и тем же названием. Мы можем решить эту проблему с помощью модулей. Создайте новый Lua файл, назовите его gamedata.lua и добавьте в него следующий код:
Мы попросту создали таблицу и вернули ее. Для того, чтобы использовать этот код, мы воспользуемся методом require. Добавьте этот код в main.lua:
Мы можем добавить в gameData ключи, которые будут искусственно глобальными. Взгляните на пример ниже:
Всякий раз, когда мы хотим получить эти переменные, мы должны вызвать функцию require, чтобы загрузить gamedata.lua. Каждый раз, когда мы загружаем модуль при помощи вышеупомянутой функции, сам модуль помещается в таблицу package.loaded. При следующем запросе игровые данные не будут заново прогружаться, а попросту извлекутся из кэша.
Загружаем Composer
Прежде чем воспользоваться модулем Composer, его нужно «затребовать». Добавьте в main.lua следующий код:
Первая сцена
Чтобы перейти к какой-либо сцене, следует воспользоваться функцией gotoScene. Причем каждая сцена будет описана в своем файле. Добавьте следующий код, чтобы перейти к сцене start, определенной в файле start.lua (да, ее пока нет, но мы вскоре ее создадим):
Обратите внимание, что при использовании функции gotoScene расширение файла писать не нужно.
Запуск сцены
Итак, давайте создадим файл start.lua, в которой и опишем нашу первую сцену. Как уже говорилось выше, для того, чтобы управлять сценами, нам потребуется модуль Composer — самое время его подключить. Добавьте следующий код в start.lua:
Вызов метода newScene сделает start.lua частью иерархии сцен модуля Composer. Именно поэтому все то, что мы хотим увидеть в первой сцене, должно быть написано между этой строчкой и ключевым словом return.
Локальные переменные
Вот те переменные, которые нам потребуются в файле start.lua:
Важно помнить, что эти строчки будут вызваны лишь единожды. А дальше при вызове метода gotoScene эти переменные уже будут проинициализированы.
Есть несколько способов, как сделать так, чтобы переменные каждый раз переинициализировались. Мы будем использовать самый простой способ: удалим сцену из иерархии модуля Composer с помощью метода removeScene. В этом уроке мы будем использовать именно такой подход.
Мы также будем использовать два кастомных модуля: pulsatingText и starFieldGenerator. Создадим два новых файла в папке проекта с названиями pulsatingtext.lua и starfieldgenerator.lua.
События сцены
Если вы нашли время и прочитали документацию, ссылку на которую мы прилагали в начале статьи, то вы наверняка заметили шаблон, содержащий все возможные события модуля Composer. К каждому событию прилагается комментарий, в котором указывается, для чего оно используется. Нас интересуют следующие функции: scene:create, scene:show и scene:hide.
Шаг 1: scene:create
Добавьте этот отрывок кода в файл start.lua:
Этот метод вызывается, когда сцена еще не существует. Здесь вы должны проинициализировать все переменные и объекты и добавить их на сцену. Переменная group, являясь экземпляром класса GroupObject, указывает на саму сцену, и именно «на нее» добавляются все изображения и другие визуальные элементы.
Мы создаем кнопку startButton при помощи метода newImage объекта класса Display. Сама функция принимает в качестве аргументов путь к изображению и координаты будущей кнопки.
Шаг 2: scene:show
Этот метод имеет 2 фазы. Фаза will вызывается, когда сцена по-прежнему еще не на экране, но вот-вот будет. Фаза did вызывается, когда сцена уже появилась и видна пользователю. Именно во второй фазе мы и будем «оживлять» нашу игру: запустим таймеры, добавим слушателей, начнем проигрывать музыку и т.д.
В этом уроке фаза will нам не понадобится.
Мы объявляем локальную переменную phase, в которую и записываем текущую фазу выполнения метода. Так как позднее мы будем к этой сцене возвращаться, то проверим, есть ли предыдущая сцена, и если она есть — удаляем ее. Также мы добавляем слушателя для кнопки startButton (при ее нажатии вызовется метод startGame).
Шаг 3: scene:hide
Метод hide тоже имеет две фазы: will и did. По смыслу они такие же, как и в scene:show. Во время выполнения фазы will мы будем останавливать таймеры, удалять слушателей различных событий, останавливать музыку и т.д. Фаза did вызывается ровно один раз, когда сцена исчезает с экрана. В наших статьях она нам не понадобится.
Начало игры
Функция startGame вызывается тогда, когда игрок нажимает на кнопку startButton. В этом методе мы будем вызывать gotoScene и переходить к сцене gamelevel.
Игровая сцена
Создайте новый файл с именем gamelevel.lua и добавьте в него следующий код:
Все знакомо, не правда ли? Да, мы здесь попросту создаем новую сцену.
Слушатель сцен
Теперь нам следует добавить слушателя сцен для методов create, show, hide. Для этого напишем в start.lua:
Запуск
Если вы в данный момент запустите игру, то увидите черный экран с одной кнопкой — это сцена start. При нажатии на кнопку вы попадете на другой экран, который пока полностью пустой — это сцена gamelevel.
Вывод
Итак, мы подошли к концу статьи. Мы создали хорошую базу для игры, научились переключаться между сценами и познакомились с основами Corona. В следующей части статьи мы займемся реализацией самого геймплея. Оставайтесь с нами!
Перевод статьи «Create a Space Invaders Game in Corona: Project Setup»
5К открытий5К показов