В этом уроке я покажу вам, как создать прыгающую игру с помощью Corona SDK. Вы узнаете больше об API рисования, сенсорном управлении и случайных числах. Цель этой игры — использовать весло, чтобы шарики не касались пола. Чтобы узнать больше, читайте дальше!
1. Обзор приложения
Мы будем использовать готовую графику для кодирования захватывающей игры с использованием API Lua и Corona SDK.
По завершении игрок будет использовать сенсорный экран на устройстве для управления веслом. Параметры в коде могут быть изменены для настройки игры.
2. Целевое устройство
Первое, что нам нужно сделать, это выбрать платформу, на которой мы хотим запустить наше приложение. Таким образом, мы сможем выбрать размер для изображений, которые мы будем использовать.
Платформа iOS имеет следующие характеристики:
- iPad 1/2 / Mini: 1024×768 пикселей, 132 т / д
- iPad Retina: 2048×1536, 264 ppi
- iPhone / iPod Touch: 320×480 пикселей, 163 т / д
- iPhone / iPod Retina: 960×640 пикселей, 326 точек на дюйм
- iPhone 5 / iPod Touch: 1136×640, 326 т / д
Поскольку Android является открытой платформой, существует множество различных устройств и разрешений. Некоторые из общих характеристик экрана:
- Asus Nexus 7 Tablet: 800×1280 пикселей, 216 пикселей на дюйм
- Motorola Droid X: 854×480 пикселей, 228 пикселей на дюйм
- Samsung Galaxy SIII: 720×1280 пикселей, 306 пикселей на дюйм
В этом уроке мы сконцентрируемся на платформе iOS с графическим дизайном, специально для разработки для распространения на iPhone / iPod touch, но представленный здесь код применим и к разработке Android с Corona SDK.
3. Интерфейс
Будет использован простой и дружественный интерфейс. Это включает в себя несколько фигур, кнопок, растровых изображений и многое другое.
Графические ресурсы интерфейса, необходимые для этого урока, можно найти в прилагаемой загрузке.
4. Экспорт графики
В зависимости от выбранного устройства вам может потребоваться экспортировать графику в рекомендуемом PPI. Вы можете сделать это в вашем любимом графическом редакторе.
Я использовал функцию « Настроить размер …» в приложении «Просмотр» в Mac OS X.
Не забудьте дать изображениям описательное имя и сохранить их в папке вашего проекта.
5. Конфигурация приложения
Мы будем использовать внешний файл, чтобы приложение стало полноэкранным на всех устройствах (файл config.lua ). Этот файл показывает исходный размер экрана и метод, используемый для масштабирования этого содержимого в случае, если приложение работает с другим разрешением экрана.
1
2
3
4
5
6
7
8
9
|
application=
{
content=
{
width=320,
height=480,
scale=»letterbox»
},
}
|
2. 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
contructor (Main function)
class methods (other functions)
call Main function
|
8. Скрыть строку состояния
1
|
display.setStatusBar(display.HiddenStatusBar)
|
Приведенный выше код скрывает строку состояния. Строка состояния — это строка в верхней части экрана устройства, которая показывает время, сигнал и другие индикаторы.
9. Справочная информация
Простой вектор используется в качестве фона для интерфейса приложения. Следующая строка кода создает его.
1
2
3
4
5
6
|
— Graphics
— [Background]
local bg = display.newRect(0, 0, display.contentWidth, display.contentHeight)
bg:setFillColor(52, 46, 45)
|
10. Заголовок
Это заголовок, это будет первый интерактивный экран, который появится в нашей игре. Эти переменные хранят его компоненты:
1
2
3
4
5
6
|
— [Title View]
local title
local playBtn
local creditsBtn
local titleView
|
11. Кредиты Просмотр
Этот вид покажет кредиты и авторские права на игру. Эта переменная будет использоваться для ее хранения:
1
2
3
|
— [CreditsView]
local creditsView
|
12. Инструкция Сообщение
Сообщение с инструкцией появится в начале игры и будет отключено через 2 секунды. Вы можете изменить время позже в коде.
1
2
3
|
— Instructions
local ins
|
13. Цветные круги
Вот круги или шары. Цель игры — не дать им дотронуться до нижней части экрана.
1
2
3
|
— Color Circles
local circles = display.newGroup()
|
14. Оповещение
Это предупреждение, которое будет отображаться, когда мяч касается пола. Он покажет счет и завершит игру.
1
2
3
|
— Alert
local alertView
|
15. Звуки
Мы будем использовать звуковые эффекты, чтобы улучшить ощущение игры. Звуки, используемые в этой игре, были созданы в as3sfxr .
1
2
3
4
|
— Sounds
local bounceSnd = audio.loadSound(‘bounce.wav’)
local loseSnd = audio.loadSound(‘lose.wav’)
|
16. Переменные
Эти переменные мы будем использовать. Вы можете прочитать комментарии в коде, чтобы узнать больше о них.
1
2
3
4
|
— Variables
local circleTimer — Adds a new circle every time is called
local colors = {{71, 241, 255},{255, 204, 0},{245, 94, 91},{0, 255, 204},{250, 140, 254},} — Possible colors for the circles (R, G, B)
|
17. Объявить функции
Затем объявите все функции как локальные в начале.
01
02
03
04
05
06
07
08
09
10
11
12
|
— Functions
local Main = {}
local startButtonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local moveBar = {}
local addCircle ={}
local onCollision = {}
local alert = {}
|
18. Конструктор
На этом шаге мы создадим функцию, которая инициализирует игровую логику:
1
2
3
|
function Main()
— code…
end
|
19. Добавить заголовок просмотра
Теперь мы поместим TitleView на сцену и вызовем функцию, которая добавляет прослушиватели касаний к кнопкам.
1
2
3
4
5
6
7
8
|
function Main()
title = display.newImage(‘title.png’)
playBtn = display.newImage(‘playBtn.png’, 130, 248)
creditsBtn = display.newImage(‘creditsBtn.png’, 125, 316)
titleView = display.newGroup(title, playBtn, creditsBtn)
startButtonListeners(‘add’)
end
|
20. Пуск кнопки прослушивания
Эта функция добавляет необходимых слушателей к кнопкам 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
|
21. Показать кредиты
Экран кредитов отображается, когда пользователь нажимает кнопку « о» , к представлению кредитов добавляется прослушиватель касаний, чтобы удалить его.
1
2
3
4
5
6
7
|
function showCredits:tap(e)
playBtn.isVisible = false
creditsBtn.isVisible = false
creditsView = display.newImage(‘credits.png’, 0, display.contentHeight)
transition.to(creditsView, {time = 300, y = display.contentHeight — (creditsView.height — 40), onComplete = function() creditsView:addEventListener(‘tap’, hideCredits) end})
end
|
22. Скрыть кредиты
При нажатии на экран кредитов, он будет отключен со сцены и удален.
1
|
function hideCredits:tap(e) transition.to(creditsView, {time = 300, y = display.contentHeight + 40, onComplete = function() creditsBtn.isVisible = true playBtn.isVisible = true creditsView:removeEventListener(‘tap’, hideCredits) display.remove(creditsView) creditsView = nil end}) end
|
23. Показать игровой вид
При нажатии кнопки « Воспроизведение» титульный вид изменяется и удаляется, открывая игровой вид . С этим представлением связано много частей, поэтому мы разделим их на следующие несколько шагов.
1
2
|
function showGameView:tap(e)
transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners(‘rmv’) display.remove(titleView) titleView = nil end})
|
24. Инструкция Сообщение
Следующие строки добавляют сообщение с инструкциями:
1
2
|
ocal ins = display.newImage(‘ins.png’, 160, 355)
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})
|
25. Добавить весло
Этот шаг создает весло и помещает его на сцену. Имя может быть добавлено позже для более легкого доступа.
1
2
3
4
|
— Add Bar
bar = display.newRoundedRect(70, 340, 160, 10, 3)
bar.name = ‘bar’
|
26. Стены
Теперь мы создадим стены вокруг экрана, чтобы шары не покидали сцену.
1
2
3
4
5
6
7
8
|
— Walls
left = display.newLine(0, 240, 0, 720)
left.isVisible = false
right = display.newLine(320, 240, 320, 720)
right.isVisible = false
bottom = display.newLine(160, 480, 480, 480)
bottom.isVisible = false
|
27. Оценка
Вот оценка TextField для создания в правом верхнем углу сцены:
1
2
3
|
— Score
score = display.newText(‘0’, 300, 0, ‘Futura’, 15)
|
28. Физика
Далее нам нужно добавить физику к нашим объектам. Здесь мы будем использовать свойство Filter, которое предотвращает столкновение определенных объектов друг с другом. Это предотвращает столкновение наших кругов, сохраняя при этом столкновения между стенами и веслом. Вы можете найти простое объяснение его поведения на сайте Corona .
1
2
3
4
5
6
7
8
9
|
— Physics
physics.addBody(bar, ‘static’, {filter = {categoryBits = 4, maskBits = 7}})
physics.addBody(left, ‘static’, {filter = {categoryBits = 4, maskBits = 7}})
physics.addBody(right, ‘static’, {filter = {categoryBits = 4, maskBits = 7}})
physics.addBody(bottom, ‘static’, {filter = {categoryBits = 4, maskBits = 7}})
gameListeners(‘add’)
end
|
29. Игровые слушатели
Следующая функция добавляет необходимых слушателей для запуска логики игры:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
function gameListeners(action)
if(action == ‘add’) then
bg:addEventListener(‘touch’, moveBar)
circleTimer = timer.performWithDelay(2000, addCircle, 5)
bar:addEventListener(‘collision’, onCollision)
bottom:addEventListener(‘collision’, alert)
else
bg:removeEventListener(‘touch’, moveBar)
timer.cancel(circleTimer)
circleTimer = nil
bar:removeEventListener(‘collision’, onCollision)
bottom:removeEventListener(‘collision’, alert)
end
end
|
30. Переместить весло
Прикосновение к фону вызывает следующую функцию, которая обрабатывает движение весла. Он следует за пальцем и остается на нем.
01
02
03
04
05
06
07
08
09
10
|
function moveBar(e)
if(e.phase == ‘moved’) then
bar.x = ex
bar.y = ey — 40
end
— Keep bar 1/3 from the top
if(bar.y < 160) then
bar.y = 160
end
end
|
31. Добавить круг
circleTimer
вызывает этот код. Он создает круг или шар в верхней части экрана (который затем перемещается вниз под действием силы тяжести) и дает ему случайный размер и цвет, выбранный из нашей таблицы colors
. Значения цвета затем сохраняются для изменения весла. Небольшой толчок добавляется в случайном направлении, рассчитанном переменными dir
и r
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
function addCircle()
local r = math.floor(math.random() * 12) + 13
local c = display.newCircle(0, 0, r)
cx = math.floor(math.random() * (display.contentWidth — (r * 2)))
cy = — (r * 2)
— Circle color
local color = math.floor(math.random() * 4) + 1
c.c1 = colors[color][1]
c.c2 = colors[color][2]
c.c3 = colors[color][3]
c:setFillColor(c.c1, c.c2, c.c3)
physics.addBody(c, ‘dynamic’, {radius = r, bounce = 0.95, filter = {categoryBits = 2, maskBits = 4}})
circles:insert(c)
—Move Horizontally
local dir
if(r < 18) then dir = -1 else dir = 1 end
c:setLinearVelocity((r*2) * dir, 0 )
end
|
32. Столкновения
Эта функция запускается, когда весло сталкивается с мячом. Он воспроизводит звук, увеличивает счет и меняет цвет весла.
1
2
3
4
5
6
7
|
function onCollision(e)
audio.play(bounceSnd)
bar:setFillColor(e.other.c1, e.other.c2, e.other.c3)
score.text = tostring(tonumber(score.text) + 50)
score:setTextColor(e.other.c1, e.other.c2, e.other.c3)
score.x = 300
end
|
33. Оповещение
Функция оповещения создает представление оповещения, оживляет его и завершает игру.
01
02
03
04
05
06
07
08
09
10
|
function alert()
audio.play(loseSnd)
gameListeners(‘rmv’)
alertView = display.newImage(‘alert.png’, 90, 200)
transition.from(alertView, {time = 200, alpha = 0.1})
local scoreTF = display.newText(score.text, 145, 253, ‘Futura’, 17)
scoreTF:setTextColor(255, 255, 255)
— Wait 100 ms to stop physics
timer.performWithDelay(100, function() physics.stop() end, 1)
end
|
34. Вызов основной функции
Чтобы начать игру, необходимо вызвать функцию Main . С помощью приведенного выше кода мы сделаем это здесь:
1
|
Main()
|
35. Экран загрузки
Файл Default.png — это изображение, которое отображается при запуске приложения, когда iOS загружает основные данные для отображения на главном экране. Добавьте это изображение в исходную папку вашего проекта, затем оно будет автоматически добавлено компилятором Corona.
36. Иконка
Используя графику, которую вы создали ранее, теперь вы можете создать красивый значок. Размер значка для iPhone, не относящегося к сетчатке, составляет 57x57px, а для версии Retina — 114x114px. Помните, что для магазина iTunes требуется версия 512x512px. Я предлагаю сначала создать версию 512×512, а затем уменьшить ее для других размеров.
Для этого не нужно иметь закругленные углы или прозрачные блики, iTunes и iPhone сделают это за вас.
37. Тестирование в симуляторе
Пришло время для финального теста. Откройте Corona Simulator, перейдите в папку вашего проекта и нажмите « Открыть» . Если все работает как положено, вы готовы к последнему шагу!
38. Построить
В симуляторе Corona зайдите в File> Build и выберите ваше целевое устройство. Заполните необходимые данные и нажмите Build . Подождите несколько секунд, и ваше приложение готово для тестирования устройства и / или отправки для распространения!
Вывод
В этом уроке мы узнали об API рисования, таймерах, случайных числах и других навыках, которые могут быть невероятно полезны в широком спектре игр.
Поэкспериментируйте с конечным результатом и попробуйте создать собственную версию игры!
Надеюсь, вам понравился этот урок, и вы нашли его полезным. Спасибо за чтение!