Статьи

Corona SDK: создание игры, похожей на качели — создание интерфейса

Из этого урока вы узнаете, как создать игру, вдохновленную Teeter. Цель игры — сбалансировать мяч и избежать препятствий для достижения цели. Читай дальше!


Используя готовую графику, мы создадим развлекательную игру с использованием Lua и API Corona SDK.

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


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

Платформа iOS имеет следующие характеристики:

  • iPad: 1024×768 пикселей, 132 т / д
  • iPhone / iPod Touch: 320×480 пикселей, 163 т / д
  • iPhone 4: 960×640 пикселей, 326 точек на дюйм

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

  • Google Nexus One: 480×800 пикселей, 254 точек на дюйм
  • Motorola Droid X: 854×480 пикселей, 228 пикселей на дюйм
  • HTC Evo: 480×800 пикселей, 217 пикселей на дюйм

В этом руководстве мы сосредоточимся на платформе iOS с графическим дизайном, специально разработанной для распространения на iPhone / iPod touch, но представленный здесь код должен также применяться к разработке Android с Corona SDK.


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

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


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

Я использовал функцию « Настроить размер …» в приложении «Просмотр» в Mac OS X.

Не забудьте дать изображениям описательное имя и сохранить их в папке вашего проекта.


Мы будем использовать звуковые эффекты для улучшения игрового ощущения. Вы можете найти звуки, используемые в этом примере на Soungle.com, используя ключевые слова bell и buzz .


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

1
2
3
4
5
6
7
8
9
application =
{
    content =
    {
        width = 320,
        height = 480,
        scale = «letterbox»
    },
}

Давайте напишем заявку!

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


Мы будем структурировать наш код, как если бы это был класс. Если вы знаете ActionScript или Java, вы должны найти структуру знакомой.

1
Necessary Classes Variables and Constants Declare Functions contructor (Main function) class methods (other functions) call Main function

1
display.setStatusBar(display.HiddenStatusBar)

Этот код скрывает строку состояния. Строка состояния — это строка в верхней части экрана устройства, которая показывает время, сигнал и другие индикаторы.


Мы будем использовать библиотеку физики для обработки столкновений. Используйте этот код для его импорта:


Простая графика используется в качестве фона для интерфейса приложения, следующая строка кода сохраняет его.

1
2
3
4
5
— Graphics
 
— [Background]
 
local bg = display.newImage(‘bg.png’)

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

1
2
3
4
5
6
— [Title View]
 
local titleBg
local playBtn
local creditsBtn
local titleView

Это представление покажет кредиты и авторские права на игру, эта переменная будет использоваться для ее хранения.

1
2
3
— [CreditsView]
 
local creditsView

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
— [Game View]
 
— [Player]
 
local player
 
— [Bars Table]
 
local bars = {}
 
— [Holes Table]
 
local holes = {}
 
— [Goal]
 
local goal

Эти строки хранят ссылку на звуковые файлы.

1
2
local bell = audio.loadSound(‘bell.caf’)
local buzz = audio.loadSound(‘buzz.caf’)

Вот полный код, написанный в этом руководстве, вместе с комментариями, которые помогут вам идентифицировать каждую часть:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
— Teeter like Game
— Developed by Carlos Yanez
 
— Hide Status Bar
 
display.setStatusBar(display.HiddenStatusBar)
 
— Physics
 
local physics = require(‘physics’)
physics.start()
physics.setGravity(0, 0)
 
— Graphics
 
— [Background]
 
local bg = display.newImage(‘bg.png’)
 
— [Title View]
 
local titleBg
local playBtn
local creditsBtn
local titleView
 
— [Credits]
 
local creditsView
 
— [Player]
 
local player
 
— [Bars Table]
 
local bars = {}
 
— [Holes Table]
 
local holes = {}
 
— [Goal]
 
local goal
 
— Sounds
 
local bell = audio.loadSound(‘bell.caf’)
local buzz = audio.loadSound(‘buzz.caf’)

Объявите все функции как локальные в начале.

01
02
03
04
05
06
07
08
09
10
local Main = {}
local startButtonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local movePlayer = {}
local onCollision = {}
local alert = {}
local dragPaddle = {}

Далее мы создадим функцию, которая инициализирует всю игровую логику:

1
2
3
function Main()
    — code…
end

Теперь мы помещаем TitleView в сцену и вызываем функцию, которая добавит прослушиватели касаний к кнопкам.

1
2
3
4
5
6
7
8
function Main()
    titleBg = display.newImage(‘titleBg.png’)
    playBtn = display.newImage(‘playBtn.png’, display.contentCenterX — 35.5, display.contentCenterY + 10)
    creditsBtn = display.newImage(‘creditsBtn.png’, display.contentCenterX — 50.5, display.contentCenterY + 65)
    titleView = display.newGroup(titleBg, playBtn, creditsBtn)
     
    startButtonListeners(‘add’)
end

Эта функция добавляет необходимых слушателей к кнопкам 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

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

1
2
3
4
5
6
function showCredits:tap(e)
    playBtn.isVisible = false
    creditsBtn.isVisible = false
    creditsView = display.newImage(‘credits.png’, 0, display.contentHeight+40)
    transition.to(creditsView, {time = 300, y = display.contentHeight-20, onComplete = function() creditsView:addEventListener(‘tap’, hideCredits) end})
end

При нажатии на экран кредитов, он будет отключен со сцены и удален.

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

Когда нажата кнопка « Воспроизведение» , вид заголовка изменяется и удаляется, открывая вид игры.

1
2
function showGameView:tap(e)
    transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners(‘rmv’) display.remove(titleView) titleView = nil end})

Здесь мы ставим цель в ее позиции. Мы также даем ему имя, чтобы идентифицировать его при столкновении.

1
2
3
4
5
6
— Goal
 
goal = display.newImage(‘goal.png’)
goal.x = 439
goal.y = 31
goal.name = ‘g’

Стены созданы вокруг сцены, чтобы не дать мячу уйти.

1
2
3
4
5
6
— Walls
     
    local left = display.newLine(-1, 0, -1, display.contentHeight)
    local right = display.newLine(display.contentWidth+1, 0, display.contentWidth+1, display.contentHeight)
    local top = display.newLine(0, -3, display.contentWidth, -3)
    local bottom = display.newLine(0, display.contentHeight, display.contentWidth, display.contentHeight)

Эти полосы являются препятствиями на сцене. Добавьте их следующими строками:

1
2
3
4
5
6
— Bars
 
local b1 = display.newImage(‘bar.png’, 92, 67)
local b2 = display.newImage(‘bar.png’, 192, -2)
local b3 = display.newImage(‘bar.png’, 287, 67)
local b4 = display.newImage(‘bar.png’, 387, -2)

Можно сказать, что лунки являются «врагами» этой игры, если мяч коснется одного, игра закончится.

01
02
03
04
05
06
07
08
09
10
11
12
13
— Holes
 
local h1 = display.newImage(‘hole.png’, 62, 76)
local h2 = display.newImage(‘hole.png’, 124, 284)
local h3 = display.newImage(‘hole.png’, 223, 224)
local h4 = display.newImage(‘hole.png’, 356, 114)
local h5 = display.newImage(‘hole.png’, 380, 256)
— Name holes for collision detection
h1.name = ‘h’
h2.name = ‘h’
h3.name = ‘h’
h4.name = ‘h’
h5.name = ‘h’

Далее мы добавляем мяч. Это будет перемещено игроком, использующим акселерометр.

1
2
3
4
5
6
— Player
 
player = display.newImage(‘player.png’)
player.x = 49
player.y = 288
player:setReferencePoint(display.CenterReferencePoint)

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