В этом уроке я покажу вам, как создать игру, избегающую препятствий, используя Corona SDK. Вы узнаете больше о сенсорном управлении, обнаружении столкновений и физике. Цель игры состоит в том, чтобы избежать как можно большего количества препятствий для получения наибольшего количества очков. Давайте начнем.
1. Обзор приложения
Используя готовую графику, мы создадим развлекательную игру с использованием языка программирования Lua и API Corona SDK. Игрок сможет перемещать вертолет по экрану и должен избегать любых препятствий, с которыми он сталкивается. Вы можете изменить параметры в коде, чтобы настроить игру.
2. Целевое устройство
Первое, что нам нужно сделать, это выбрать платформу, на которой мы хотим запустить наше приложение, чтобы мы могли выбрать размер для изображений, которые мы будем использовать.
Платформа iOS предъявляет следующие требования:
- iPad 1/2 / Mini: 1024px x 768px, 132 ppi
- Сетчатка iPad: 2048px x 1536px, 264 ppi
- iPhone / iPod Touch: 320px x 480px, 163 ppi
- Сетчатка iPhone / iPod: 960 x 640 пикселей, 326 ppi
- iPhone 5 / iPod Touch: 1136 пикселей x 640 пикселей, 326 пикселей на дюйм
Поскольку Android является открытой платформой, существует множество различных устройств и разрешений. Вот некоторые из наиболее распространенных характеристик экрана:
- Asus Nexus 7 Tablet: 800px x 1280px, 216 ppi
- Motorola Droid X: 854 x 480 пикселей, 228 ppi
- Samsung Galaxy SIII: 720px x 1280px, 306 ppi
В этом уроке мы сосредоточимся на платформе iOS с точки зрения графики. В частности, мы будем разрабатывать для iPhone и iPod Touch. Тем не менее, код этого руководства также может быть использован в вашей целевой платформе Android.
3. Интерфейс
Мы будем использовать простой пользовательский интерфейс, включающий несколько фигур, кнопок, растровых изображений и многое другое. Графики, которые мы будем использовать для этого урока, можно найти в проекте, включенном в этот урок.
4. Экспорт графики
В зависимости от выбранного устройства вам может потребоваться преобразовать графику в рекомендованное разрешение (ppi), что вы можете сделать в своем любимом графическом редакторе. Я использовал параметр « Изменить размер…» в меню « Инструменты» приложения «Просмотр» в OS X. Не забудьте дать изображениям описательное имя и сохранить их в папке проекта.
5. Конфигурация приложения
Мы будем использовать файл конфигурации config.lua
, чтобы приложение работало на всех устройствах в полноэкранном режиме. Файл конфигурации показывает исходный размер экрана и метод, используемый для масштабирования содержимого в случае, если приложение запускается с другим разрешением.
1
2
3
4
5
6
7
8
9
|
application =
{
content =
{
width = 320,
height = 480,
scale = «letterbox»
},
}
|
6. main.lua
Давайте напишем фактическое приложение. Откройте предпочитаемый вами редактор Lua. Подойдет любой текстовый редактор, но рекомендуется использовать текстовый редактор с подсветкой синтаксиса. Создайте новый файл и сохраните его как main.lua
в папке вашего проекта.
7. Структура кода
Мы будем структурировать наш код, как если бы он был классом. Если вы знакомы с ActionScript или Java, вы должны найти структуру проекта знакомой.
01
02
03
04
05
06
07
08
09
10
11
|
Necessary Classes
Variables and Constants
Declare Functions
constructor (Main function)
class methods (other functions)
call Main function
|
8. Скрыть строку состояния
1
|
display.setStatusBar(display.HiddenStatusBar)
|
Этот фрагмент кода скрывает строку состояния. Строка состояния — это строка в верхней части экрана устройства, на которой отображаются время, сигнал и другие индикаторы.
9. Импортировать физику
Мы будем использовать библиотеку физики для обработки столкновений. Импортируйте библиотеку, используя фрагмент кода, показанный ниже.
1
2
3
4
|
— Physics
local physics = require(‘physics’)
physics.start()
|
10. Фон
Простой фон для пользовательского интерфейса приложения. Фрагмент кода ниже рисует фон на экране.
1
2
3
4
5
|
— Graphics
— [Background]
local gameBg = display.newImage(‘gameBg.png’)
|
11. Заголовок
Это заголовок. Это первый интерактивный экран, который появится в нашей игре. Эти переменные хранят его компоненты.
1
2
3
4
5
6
|
— [Title View]
local title
local playBtn
local creditsBtn
local titleView
|
12. Кредиты Просмотр
Представление «Кредиты» отображает кредиты и авторские права на приложение. Эта переменная используется для ее хранения.
1
2
3
|
— [CreditsView]
local creditsView
|
13. Инструкция Сообщение
В начале игры появится сообщение с инструкциями, которое исчезнет после первого нажатия.
1
2
3
|
— Instructions
local ins
|
14. Вертолет
Это рисунок вертолета. Игрок будет управлять вертолетом с помощью сенсорного управления.
1
2
3
|
— Helicopter
local helicopter
|
15. Блоки
Блоки — это препятствия, которых игрок должен избегать.
1
2
3
|
— Blocks
local blocks = {}
|
16. Оповещение
Предупреждение отображается, когда игрок пропускает мяч и игра окончена. Он отображает сообщение и заканчивает игру.
1
2
3
|
— Alert
local alertView
|
17. Звуки
Чтобы оживить игру, мы будем использовать звуковые эффекты. Звуки, используемые в игре, были получены от as3soundfxr . Я нашел фоновую музыку на playonloop .
1
2
3
4
|
— Sounds
local bgMusic = audio.loadStream(‘POL-rocket-station-short.wav’)
local explo = audio.loadSound(‘explo.wav’)
|
18. Переменные
Следующий фрагмент кода показывает переменные, которые мы будем использовать. Прочитайте комментарии, чтобы понять, для чего используется каждая переменная.
1
2
3
4
5
6
7
8
|
— Variables
local timerSrc —Blocks timer
local yPos = {90, 140, 180} —Possible positions for the blocks
local speed = 5 —Block speed
local speedTimer —Increases blocks speed
local up = false —Used to determine if helicopter is going up
local impulse = -60 —physics value to make helicopter go up
|
19. Объявить функции
Объявите все функции как local
в начале.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
— Functions
local Main = {}
local startButtonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local createBlock = {}
local movePlayer = {}
local increaseSpeed = {}
local update = {}
local alert = {}
|
20. Конструктор
Далее мы создаем функцию, которая будет инициализировать игровую логику.
1
2
3
|
function Main()
— code…
end
|
21. Добавить заголовок просмотра
Мы начнем с размещения представления заголовка на сцене и вызовем функцию, которая добавит прослушиватели касаний к кнопкам.
1
2
3
4
5
6
7
8
|
function Main()
titleBg = display.newImage(‘titleBg.png’)
playBtn = display.newImage(‘playBtn.png’, 220, 178)
creditsBtn = display.newImage(‘creditsBtn.png’, 204, 240)
titleView = display.newGroup(titleBg, playBtn, creditsBtn)
startButtonListeners(‘add’)
end
|
22. Пуск кнопки прослушивания
Следующая функция добавляет необходимых слушателей к TitleView
.
1
2
3
4
5
6
7
8
9
|
function startButtonListeners(action)
if(action == ‘add’) then
playBtn:addEventListener(‘tap’, showGameView)
creditsBtn:addEventListener(‘tap’, showCredits)
else
playBtn:removeEventListener(‘tap’, showGameView)
creditsBtn:removeEventListener(‘tap’, showCredits)
end
end
|
23. Показать кредиты
Экран кредитов отображается, когда пользователь нажимает кнопку о. Прослушиватель касаний добавляется в представление кредитов, чтобы отклонить его, когда пользователь нажимает на него.
1
2
3
4
5
6
|
function showCredits:tap(e)
playBtn.isVisible = false
creditsBtn.isVisible = false
creditsView = display.newImage(‘credits.png’, -110, display.contentHeight-80)
transition.to(creditsView, {time = 300, x = 55, onComplete = function() creditsView:addEventListener(‘tap’, hideCredits) end})
end
|
24. Скрыть кредиты
Когда пользователь нажимает на представление кредитов, оно анимируется со сцены и удаляется.
1
2
3
4
5
|
function hideCredits:tap(e)
playBtn.isVisible = true
creditsBtn.isVisible = true
transition.to(creditsView, {time = 300, y = display.contentHeight+creditsView.height, onComplete = function() creditsView:removeEventListener(‘tap’, hideCredits) display.remove(creditsView) creditsView = nil end})
end
|
25. Показать игровой вид
При нажатии кнопки воспроизведения вид заголовка анимируется за пределами экрана, и игра открывается. Есть несколько движущихся частей, поэтому мы подробнее рассмотрим каждую из них.
1
2
|
function showGameView:tap(e)
transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners(‘rmv’) display.remove(titleView) titleView = nil end})
|
26. Инструкция Сообщение
Следующий фрагмент кода добавляет сообщение с инструкциями.
1
2
|
ins = display.newImage(‘ins.png’, 180, 270)
transition.from(ins, {time = 200, alpha = 0.1, onComplete = function() timer.performWithDelay(2000, function() transition.to(ins, {time = 200, alpha = 0.1, onComplete = function() display.remove(ins) ins = nil end}) end) end})
|
27. Оценка TextField
Следующий фрагмент кода создает текстовое поле, которое показывает текущий счет игрока в правом верхнем углу сцены.
1
2
3
4
|
— TextFields
scoreTF = display.newText(‘0’, 450, 5, ‘Marker Felt’, 14)
scoreTF:setTextColor(255, 255, 255)
|
28. Вертолет
Затем пришло время добавить изображение вертолета на сцену, как показано ниже.
1
2
3
|
— Helicopter
helicopter = display.newImage(‘helicopter.png’, 23, 152)
|
29. Стены
В следующем фрагменте кода мы используем графический API-интерфейс Corona для создания нескольких строк, которые мы добавим к моделированию физики чуть позже в этом руководстве. Они будут использоваться для обнаружения столкновений с вертолетом.
1
2
3
4
5
6
7
|
— Walls
local top = display.newRect(0, 60, 480, 1)
top:setFillColor(34, 34, 34)
local bottom = display.newRect(0, 260, 480, 1)
bottom:setFillColor(34, 34, 34)
end
|
30. Физика
Далее нам нужно добавить необходимую физику к каждому объекту.
1
2
3
4
5
|
— Add physics
physics.addBody(helicopter)
physics.addBody(top, ‘static’)
physics.addBody(bottom, ‘static’)
|
31. Начать игру
Мы создаем группу для блоков, gameListeners
функцию gameListeners
и запускаем фоновую музыку.
1
2
3
4
|
blocks = display.newGroup()
gameListeners(‘add’)
audio.play(bgMusic, {loops = -1, channel = 1})
end
|
32. Слушатели игр
Следующий фрагмент кода может показаться сложным, но он просто добавляет несколько слушателей для запуска логики игры.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
function gameListeners(action)
if(action == ‘add’) then
gameBg:addEventListener(‘touch’, movePlayer)
Runtime:addEventListener(‘enterFrame’, update)
timerSrc = timer.performWithDelay(1300, createBlock, 0)
speedTimer = timer.performWithDelay(5000, increaseSpeed, 5)
helicopter:addEventListener(‘collision’, onCollision)
else
gameBg:addEventListener(‘touch’, movePlayer)
Runtime:removeEventListener(‘enterFrame’, update)
timer.cancel(timerSrc)
timerSrc = nil
timer.cancel(speedTimer)
speedTimer = nil
helicopter:removeEventListener(‘collision’, onCollision)
end
end
|
33. Создать блок
Как видно из createBlock
функция createBlock
создает блок и выводит его на экран. Полученный объект добавляется в физический движок для проверки столкновений.
01
02
03
04
05
06
07
08
09
10
|
function createBlock()
local b
local rnd = math.floor(math.random() * 4) + 1
b = display.newImage(‘block.png’, display.contentWidth, yPos[math.floor(math.random() * 3)+1])
b.name = ‘block’
— Block physics
physics.addBody(b, ‘kinematic’)
b.isSensor = true
blocks:insert(b)
end
|
34. Функция перемещения
В функции movePlayer
мы обновляем переменную up
. Пока его значение равно true
, функция update
перемещает вертолет вверх.
1
2
3
4
5
6
7
8
9
|
function movePlayer(e)
if(e.phase == ‘began’) then
up = true
end
if(e.phase == ‘ended’) then
up = false
impulse = -60
end
end
|
35. Увеличить скорость
Чтобы сделать игру более интересной, таймер увеличивает скорость каждые пять секунд. Значок отображается для предупреждения игрока об изменении скорости.
1
2
3
4
5
6
|
function increaseSpeed()
speed = speed + 2
— Icon
local icon = display.newImage(‘speed.png’, 204, 124)
transition.from(icon, {time = 200, alpha = 0.1, onComplete = function() timer.performWithDelay(500, function() transition.to(icon, {time = 200, alpha = 0.1, onComplete = function() display.remove(icon) icon = nil end}) end) end})
end
|
36. Переместить вертолет
Функция update
проверяет значение up
и перемещает вертолет вверх, если оно равно true
.
1
2
3
4
5
6
|
function update(e)
— Move helicopter up
if(up) then
impulse = impulse — 3
helicopter:setLinearVelocity(0, impulse)
end
|
37. Переместить блоки
Далее пришло время переместить блоки. Мы используем переменную speed
чтобы определить, сколько пикселей должны перемещаться блоки в каждом кадре.
1
2
3
4
5
6
|
— Move Blocks
if(blocks ~= nil)then
for i = 1, blocks.numChildren do
blocks[i].x = blocks[i].x — speed
end
end
|
38. Обновление счета
Алгоритм обновления счета прост. Счет увеличивается на один каждый кадр до тех пор, пока вертолет не разбился. Просто. Правильно?
1
2
3
|
— Score
scoreTF.text = tostring(tonumber(scoreTF.text) + 1)
end
|
39. Столкновения
Функция onCollision
проверяет, столкнулся ли вертолет с блоком. Если было обнаружено столкновение, мы воспроизводим звуковой эффект, взрыв, удаляем графику и показываем предупреждение игроку.
1
2
3
4
5
|
function onCollision(e)
audio.play(explo)
display.remove(helicopter)
alert()
end
|
40. Оповещение
Функция alert
создает представление оповещения и показывает его пользователю. Затем игра заканчивается.
1
2
3
4
5
|
function alert()
gameListeners(‘rmv’)
alert = display.newImage(‘alert.png’, (display.contentWidth * 0.5) — 105, (display.contentHeight * 0.5) — 55)
transition.from(alert, {time = 300, xScale = 0.5, yScale = 0.5})
end
|
41. Вызов Main
функции
Чтобы начать игру, необходимо вызвать функцию Main
. С остальной частью кода мы делаем это здесь.
1
|
Main()
|
42. Экран загрузки
На платформе iOS файл с именем Default.png
отображается во время запуска приложения. Добавьте это изображение в исходную папку вашего проекта, оно будет автоматически добавлено компилятором Corona.
43. Иконка
Используя графику, которую вы создали ранее, теперь вы можете создать красивый значок. Размеры значков для iPhone без сетчатки составляют 57px x 57px, в то время как версия Retina должна быть 114px x 114px. Иллюстрации для iTunes должны быть размером 1024px x 1024px. Я предлагаю сначала создать обложку iTunes, а затем создать изображения меньшего размера, уменьшив обложку iTunes до нужных размеров. Нет необходимости делать значок приложения глянцевым или добавлять закругленные углы, поскольку об этом позаботится операционная система.
44. Тестирование в симуляторе
Пришло время протестировать наше приложение в симуляторе. Откройте Corona Simulator, перейдите в папку вашего проекта и нажмите «Открыть». Если все работает, как ожидалось, вы готовы к последнему шагу.
45. Строительный проект
В Corona Simulator перейдите в File> Build и выберите целевое устройство. Заполните обязательные поля и нажмите « Построить» . Подождите несколько секунд, и ваше приложение готово к тестированию на устройстве и / или будет отправлено для распространения.
Вывод
В этом уроке мы узнали о сенсорных слушателях, обнаружении столкновений, физике, а также о некоторых других навыках, которые могут быть полезны во многих играх. Поэкспериментируйте с конечным результатом и попробуйте изменить игру, чтобы создать собственную версию игры. Я надеюсь, что вам понравился этот урок, и вы нашли его полезным. Спасибо за чтение.