Chapter 2 — Upward & Onward / Глава 2 – Вверх и Вперед

Chapter 2 — Upward & Onward / Глава 2 - Вверх и Вперед

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

Дизайн документов

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

 
Название игры Звезда Проводник - космический шутер
Описание Маневр ваш космический корабль через поле астероидов, уничтожая астероиды, как вы прогресса.
управления Нажмите на корабле к огню; перетащить корабль, чтобы двигаться влево и вправо.
Звуки Стрельба звук и звук взрыва, когда корабль сталкивается с астероидом.

Теперь у нас есть очень простой план для нашей игры. Это всегда хорошая идея, чтобы получить что-то записанную для ваших целей игры и идей. После того, как документ создан, вы будете удивлены тем, как быстро он растет!

Настройка проекта

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

  1. Из Corona Simulator , выберите команду Создать проект ... от в File меню.
  1. Для проекта / имя приложения, тип StarExplorerи убедитесь , что Бланк выбран вариант шаблона.
  2. На этот раз, в разделе , где вы можете выбрать размер экрана, выбрать Tablet предустановки . Обратите внимание на то, что ширина и высота значения изменяются до 768и1024соответственно.
  3. Оставьте остальные настройки по умолчанию и нажмите кнопку OK (Windows) или Next (Mac).
  4. Найдите и откройте папку проекта.

 

Настройки и конфигурация

Помимо main.luaпроекты Corona включают две важные файлы , которые вам необходимо настроить приложение , чтобы правильно работать на нескольких типах устройств: build.settingsи config.lua.

build.settings

build.settingsФайл содержит фактическое устройство (ы) с информацией о приложении , таких как имена ваших иконок приложений, плагинов включить специальную информацию , которая может потребоваться быть переданы устройств, поддерживаемых ориентации приложения и многое другое.

Используя текстовый редактор, найдите и откройте build.settingsфайл в папке проекта. Он будет содержать много информации, но давайте сосредоточимся на этом блоке кода:

    orientation =
    {
        default = "portrait",
        supported = { "portrait", }
    },

Наше StarExplorerприложение будет доступно только играть в портретном режиме, поэтому мы устанавливаем это значение по следующим двум направлениям:

  • default = "portrait" - Эта линия говорит Corona, что игра должна начаться в портретной ориентации.
  • supported = { "portrait", }- Эта линия говорит Corona , что поддерживается только ориентация также портрет. Как вы узнали в предыдущей главе, фигурные скобки указывают на таблицу на языке программирования Lua, и таблицы могут содержать несколько элементов. Мы могли бы включать в себя до четырех поддерживаемых ориентаций внутри этой таблицы, но так как это приложение будет поддерживать только одну ориентацию,"portrait"это все , что нам нужно включить в эту таблицу.

Есть много дополнительных вещей , которые могут быть включены внутри build.settingsфайла, но в интересах сохранения этого руководства так прост , как это возможно, давайте двигаться дальше.

config.lua

config.luaФайл содержит все параметры конфигурации приложения. Здесь мы говорим Corona , какое содержание резолюции приложение будет работать на, сколько кадров в секунду, как она должна работать с большими устройствами разрешение и т.д.

Используя текстовый редактор, найдите и откройте config.luaфайл в папку проекта и проверьте следующие строки:

application =
{
    content =
    {
        width = 768,
        height = 1024, 
        scale = "letterbox",
        fps = 60,

Во- первых, вы заметите , что этот файл Lua состоит из applicationтаблицы, и эта таблица содержит таблицу с именем ребенка content. Внутри contentтаблицы представляет собой ряд параметров конфигурации, в том числе:

  • widthи height- Эти значения указывают на область содержимого размер для приложения. В Corona, ваша базовая область содержимого может быть все , что вы хотите, но часто он базируется вокруг общего экрана ширина / высота пропорции как 3: 4, установить здесь 768и 1024. Важно понимать , что эти значения не указывают точное количество пикселей, а скорее относительное количество контента "единиц" для приложения.Область содержимого будет масштабироваться , чтобы соответствовать экрану, с тонкие различия продиктованы scaleопределения (смотрите следующий пункт) .
  • scale- Этот важный параметр говорит Corona , как обрабатывать область контента для экранов , которые не соответствуют пропорции , определяемую widthи heightнастройками, например , 2: 3 в данном случае. Два наиболее распространенных варианта "letterbox"и "zoomEven".

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

"zoomEven"масштабирует область содержимого для заполнения экрана, сохраняя при этом тот же формат. Некоторые материалы могут "просачиваться" от краев экрана на устройствах с соотношением сторон, которые отличаются от вашего контента соотношением сторон.

Почтовый ящик zoomEven
  • fps- Определяет количество кадров в секунду , при которой приложение будет работать. Корона поддерживает либо 30или 60для этого параметра (другие значения будут проигнорированы).

Для этой игры, давайте использовать "zoomEven"масштабный режим. Изменение scale = "letterbox",к следующему и не забудьте сохранить config.luaфайл после этого!

scale = "zoomEven",

 

Игра Фонд

Теперь, когда вы понимаете, основные параметры и настройки, давайте продолжим с создания игры.

Настройка физики

Как и в BalloonTapпроекте, эта игра будет использовать физический движок, так что давайте настроить его с самого начала. Если вы используете физику, часто лучше , чтобы включить свой основной код установки физики в начале программы.

С помощью выбранного текстового редактора, откройте main.luaфайл в папку проекта и эти команды типа:

local physics = require( "physics" )
physics.start()
physics.setGravity( 0, 0 )

Как вы можете видеть, после загрузки и запуска физический движок, мы устанавливаем гравитационные значения. По умолчанию, физический движок имитирует стандартную гравитацию Земли , которая заставляет объекты падать к нижней части экрана. Чтобы изменить это, мы используем physics.setGravity()команду , которая может имитировать гравитацию как в горизонтальном ( х ) или вертикальной ( у ) направлениях. Так как эта игра происходит в космическом пространстве, мы будем считать , что сила тяжести не применяется. Таким образом, мы устанавливаем оба значения 0.

Случайное зерно

Наша игра будет случайным образом появляться астероиды за пределами краев экрана, так что мы будем реализовывать функции генерации случайных чисел дальше в этом проекте. Во- первых, хотя, нам нужно установить «семя» для псевдослучайного генератора чисел. В некоторых операционных системах, этот генератор начинается с того же начального значения , которое вызывает случайные числа , чтобы повторить в предсказуемом образце. Следующая команда в нашем коде гарантирует , что генератор всегда начинается с другого семени.

-- Seed the random number generator
math.randomseed( os.time() )

На первом из этих двух линий, соблюдать знаки двойных минус ( --). Они используются , чтобы сказать Lua , что он должен игнорировать все остальное на линии. Это связано с тем , что вы можете оставить себе заметки или комментарии в коде. Хотя это может показаться не важно , когда вы изначально писать программу, тем сложнее приложение получает, или чем больше времени проходит , прежде чем вернуться к работе на приложение снова, тем более важно , чтобы включить комментарии.

Когда вы собираетесь генерировать случайные числа в приложении, засеять псевдослучайного числа генератора только один раз, обычно в пределах main.lua. Это несколько раз является излишним и ненужным.

в том числе изображения

Сначала нам нужно только два визуальных средств для этого проекта, которые можно скачать здесь . Как и прежде, они должны быть размещены в пределах вашей StarExplorerпапке проекта.

файл Размер (Ш × В) Применение
background.png 800 × 1400 Фоновое изображение (звездочки).
gameObjects.png 112 × 334 Изображение лист, содержащий наши игровые объекты.

Листы Загрузка изображений

Если вы использовали другую платформу разработки игр, вы можете быть знакомы с термином "спрайт листом" или "Texture атласе." В терминологии Corona, это известно как лист изображения и позволяет загружать несколько изображений / кадров из одного большого файла изображения. Image листов являются гораздо более эффективными , чем загрузка всех игровых изображений по отдельности , и они уменьшают потенциальный беспорядок десятков графических файлов в папке проекта.

Заметка

Image листы наиболее легко создаются с помощью такого инструмента, как TexturePacker , который собирает, организует и пакеты несколько изображений в Corona-совместимого листа изображения. В то время как это программное обеспечение не является обязательным требованием, это действительно сэкономит вам много времени и энергии.

При настройке изображения листа, то вам нужно сказать Corona , где изображения расположены внутри листа. Если все изображения в спрайт листа имеют одинаковый размер, вы можете просто обеспечить размер каждого изображения и сказать Corona , сколько "кадров" можно ожидать загрузки из листа. Для этой игры, однако, каждое изображение отличается по размеру, так что мы должны предоставить конкретные детали , которые определяют положение и размеры каждого из них. Мы делаем это путем подачи верхний левый угол каждого изображения в х и у координат , а также его ширины и высоты, все упаковано в настройке таблицы Lua:

-- Configure image sheet
local sheetOptions =
{
    frames =
    {
        {   -- 1) asteroid 1
            x = 0,
            y = 0,
            width = 102,
            height = 85
        },
        {   -- 2) asteroid 2
            x = 0,
            y = 85,
            width = 90,
            height = 83
        },
        {   -- 3) asteroid 3
            x = 0,
            y = 168,
            width = 100,
            height = 97
        },
        {   -- 4) ship
            x = 0,
            y = 265,
            width = 98,
            height = 79
        },
        {   -- 5) laser
            x = 98,
            y = 265,
            width = 14,
            height = 40
        },
    }
}

С помощью этой таблицы информации, теперь мы можем загрузить спрайт лист с graphics.newImageSheet()командой. Это принимает имя файла изображения для листа изображения ( gameObjects.png) и ссылки наsheetOptionsтаблицу , которую мы только что создали:

local objectSheet = graphics.newImageSheet( "gameObjects.png", sheetOptions )

Инициализация переменных

В более крупных программ, это хорошая идея, чтобы объявить все переменные, которые используются по всему файлу около начала. Это помогает нам оставаться организованным и обеспечивает быструю ссылку, если мы забываем, что имя переменной было и / или если переменная имела начальное значение.

После параметров изображения листа / настройки, добавьте следующие строки:

-- Initialize variables
local lives = 3
local score = 0
local died = false

local asteroidsTable = {}

local ship
local gameLoopTimer
local livesText
local scoreText

Сначала мы объявляем переменные , чтобы следить за количеством жизней остальных (начальное значение 3) , текущий счет (начальное значение 0) , и действительно ли умер игрок (изначально false) .

Далее мы объявляем переменную , asteroidsTableкоторая будет использоваться для очень конкретной цели на протяжении всей игры. Как вы помните из предыдущей главы, фигурные скобки ( {}) указывают на Lua таблицу(массив). Помимо всего прочего, таблицы используются для отслеживания аналогичных типов информации. Так как будет много астероиды на экране в этой игре, это нецелесообразно объявлять каждый в качестве уникальной переменной , такой как asteroid1, asteroid2, asteroid3и т.д. Более эффективный метод необходим и что, где столы могут помочь - по существу, таблицы могут содержать большое количество ссылок объектов и других данных, рост и сжатие по мере необходимости на протяжении всей жизни игры.

На следующих нескольких строках, мы объявляем переменную - заполнитель для объекта (корабля ship), заполнитель для таймера мы реализуем позже, и две переменные для текстовых объектов , которые будут отображаться оставшиеся жизнь игрока и счет.

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

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

Использование группы отображения

В предыдущей главе, мы просто размещены объекты на сцене  - это, по существу , основной слой / группа , в которой существуют все объекты дисплея. В этой игре мы будем вставлять объекты в отдельные группы отображения для более контролируемой и наслаивать организации. В основном, дисплей группа представляет собой особый вид экранного объекта , который может содержать другие экранные объекты и даже другие группы отображения. Представьте себе , это как чистый лист бумаги , на котором вы "нарисовать" изображения, текст, фигуры и анимированные спрайты.

В предыдущей главе вы узнали , что изображения , загруженные последовательно будут складываться от задней стенки к передней с точки зрения визуальной отводками. Этот же принцип применим и для отображения групп - не только отображать объекты , вставленные в группы отображения стека / слоя в этой задней к передней манере, но вы также можете слой группы отображения один на другой, создавая их в аналогичной последовательности.

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

-- Set up display groups
local backGroup = display.newGroup()  -- Display group for the background image
local mainGroup = display.newGroup()  -- Display group for the ship, asteroids, lasers, etc.
local uiGroup = display.newGroup()    -- Display group for UI objects like the score

Наиболее важным аспектом здесь является порядок, в котором будут созданы группы. Обратите внимание на то, что первая группа, мы создаем на самом деле группа, которая должна появиться дальнее спину. После этого, мы создаем основную группу для игровых объектов, то мы создаем третью группу для объектов, которые всегда должны появляться выше всего остального.

Загрузка фона

Как и в предыдущем проекте, мы будем загружать фоновое изображение в первую очередь. После строки выше, добавьте следующие команды:

-- Load the background
local background = display.newImageRect( backGroup, "background.png", 800, 1400 )
background.x = display.contentCenterX
background.y = display.contentCenterY

Эти команды должны появиться прямо в этот момент, но есть одно очень важное различие! Проверьте первый параметр display.newImageRect ()  - перед именем файла изображения (теперь второй параметр), мы указываемгруппу отображения , чтобы поместить объект. Это говорит о том , что Corona фоновое изображение после загрузки должен быть вставлен в backGroupгруппу отображения.

Большинство API для отображения объектов Corona принимают действительную переменную отображения группы в качестве первого параметра. Это удобный встроенный ярлык для вставки объекта в эту группу.

Загрузка корабль

Как уже упоминалось ранее, графические листы могут быть использованы в качестве источника для анимированной последовательности изображений (спрайтов), или же они могут быть использованы для организации коллекции статических изображений, которые будут использоваться в вашем приложении. Для этого проекта мы будем использовать второй метод.

Загрузка отдельные изображения из листа изображения очень похож на загружая его из файла. Вместо того , чтобы указать название изображения, тем не менее, мы указываем ссылку на листе изображения ( objectSheet) ,вместе с номером кадра. Так как судно 4 - й кадр на основе нашей конфигурации изображения листа, мы укажем в 4качестве рамки (третий параметр). И, наконец, как обычно, мы задаем ширину и высоту изображения корабля , как 98и 79для соответствия этих значений в конфигурации изображения листа.

ship = display.newImageRect( mainGroup, objectSheet, 4, 98, 79 )
Заметки
  • Потому что мы объявили локальную вперед ссылку на объект корабля ранее в программе ( local ship) , нам не нужно предварить этот экземпляр с local. По сути, мы сейчас установив переменную , объявленную ранее фактического значения (объект изображения) .
  • Обратите внимание , что мы вставляем корабль в mainGroupгруппе индикации, не backGroupгде мы вставили фоновое изображение.

В следующей группе команд, мы устанавливаем корабль в нижнем центре экрана. Затем мы добавляем корабль в физический движок с radiusсвойством 30. Кроме того, мы указываем важное свойство: isSensor=true. Это говорит Corona , что объект должен быть датчик объекта. По существу, объекты датчик обнаружения столкновения с другими физическими объектами , но они не производят физической реакции. Например, если нормальный тело сталкивается с телом датчика, оба тела будут не отскакивают друг от друга , или привести к какой - либо другой физической реакции. Это идеально подходит для нашего объекта корабля, потому что мы только хотим, чтобы обнаружить столкновения с астероидами, не отскакивают от них.

И, наконец, мы даем объекту myNameсвойство "ship". Это свойство будет использоваться в дальнейшем , чтобы помочь определить , какие типы столкновений происходят в игре.

ship.x = display.contentCenterX
ship.y = display.contentHeight - 100
physics.addBody( ship, { radius=30, isSensor=true } )
ship.myName = "ship"

Живет и баллы

Теперь давайте размещать ярлыки UI для жизни игрока и счет на экране:

-- Display lives and score
livesText = display.newText( uiGroup, "Lives: " .. lives, 200, 80, native.systemFont, 36 )
scoreText = display.newText( uiGroup, "Score: " .. score, 400, 80, native.systemFont, 36 )

Для того, чтобы держать вещи простыми, мы используем специальный метод Lua с этикетками , чтобы показать нашу жизнь и счет. Размещение двух периодов вместе в Lua ( ..) называется конкатенация . Конкатенация соединяет две строки в одну. Таким образом, в приведенной livesText = display.newText()выше команде, мы вступаем в строку Lives:и переменную livesдля результата , Lives: 3что отображается на экране (помните ,что мы устанавливаем начальное значение livesдля 3ранее).

Действие!

Давайте проверим результат нашего кода до сих пор. Сохраните измененный main.luaфайл и повторно запустить Simulator. Если все прошло хорошо, фон, корабль, и текстовые метки должны теперь быть показаны на экране.

Заметка

Все выглядит хорошо до сих пор за несколько отвлекающих кроме строки состояния в верхней части экрана. На мобильных устройствах, эта система сгенерированных элемент обычно отображает различную информацию , такую как прочность сотовой связи / Wi - Fi, время, оставшееся время автономной работы и т.д. Хотя эта информация является ценным для общего использования устройства, оно может быть отвлекающим , когда пользователь играет в игру.

Давайте скрыть строку состояния с помощью следующей команды:

-- Hide the status bar
display.setStatusBar( display.HiddenStatusBar )

И, наконец, давайте напишем функцию , чтобы обновить textсвойство как livesTextи scoreText. Это будет похоже на функцию , которую мы написали в предыдущей главе. Как вы помните, в любое время создать новый ярлык или объект с display.newText () , метка / значение тексте хранится в textсвойстве объекта, поэтому мы обновляем это свойство с каскаднойстроковым значением метки и связанное с ним переменная.

local function updateText()
    livesText.text = "Lives: " .. lives
    scoreText.text = "Score: " .. score
end

Теперь, когда у нас есть основные визуальные объекты на месте, могут загружать изображения с листа изображения, а также обновлять метки пользовательского интерфейса для обеих жизней и забить, мы готовы приступить к работе по логике игры и событий!

 

Глава Концепции

Мы рассмотрели еще несколько концепций в этой главе. Вот краткий обзор:

Команда / Недвижимость Описание
physics.setGravity () Устанавливает х и Y компоненты глобального вектора силы тяжести в единицах м / с².
math.randomseed () Устанавливает «семя» для псевдослучайного генератора чисел.
graphics.newImageSheet () Создает ImageSheet объект для загрузки нескольких изображений / кадров из одного большого файла изображения.
display.newGroup () Создает группу отображения для организации / отводками экранных объектов.
display.contentHeight Ярлык для высоты области содержимого.
display.setStatusBar () Скрывает или изменяет внешний вид строки состояния на большинстве устройств.

Language