Статьи

Создать игру в пинбол: добавление взаимодействия

Это вторая часть нашего учебного пособия по Corball SDK для игры в пинбол. В сегодняшнем уроке мы добавим наш интерфейс, а затем закодируем взаимодействие с игрой. Читай дальше!


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


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

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
— Left Wall Parts
     
    l1 = display.newImage(‘l1.png’)
    l2 = display.newImage(‘l2.png’, 0, 214)
    l3 = display.newImage(‘l3.png’, 0, 273)
    l4 = display.newImage(‘l4.png’, 0, 387)

Этот код размещает правую стену тем же способом.

1
2
3
4
5
6
— Right Wall Parts
 
r1 = display.newImage(‘r1.png’, 238, 0)
r2 = display.newImage(‘r2.png’, 274, 214)
r3 = display.newImage(‘r3.png’, 291, 273)
r4 = display.newImage(‘r4.png’, 195, 387)

Добавьте мяч и HitLines с помощью следующего кода:

1
2
3
ball = display.newImage(‘ball.png’, display.contentWidth * 0.5, 0)
hitLine1 = display.newImage(‘hitLine.png’, 70, 28)
hitLine2 = display.newImage(‘hitLine.png’, 110, 28)

Цели добавляются с использованием следующих нескольких строк:

1
2
3
4
5
6
7
8
— Hit balls
 
hitBall1 = display.newImage(‘hitBall.png’, 160, 186)
hitBall2 = display.newImage(‘hitBall.png’, 130, 236)
hitBall3 = display.newImage(‘hitBall.png’, 187, 236)
hitBall1.name = ‘hBall’
hitBall2.name = ‘hBall’
hitBall3.name = ‘hBall’

Затем мы добавляем весла и даем им имя, чтобы использовать его позже.

1
2
3
4
pLeft = display.newImage(‘paddleL.png’, 74, 425)
pRight = display.newImage(‘paddleR.png’, 183, 425)
pLeft.name = ‘leftPaddle’
pRight.name = ‘rightPaddle’

Эти кнопки будут управлять веслами, добавьте их с помощью этого кода:

1
2
3
4
lBtn = display.newImage(‘lBtn.png’, 20, 425)
rBtn = display.newImage(‘rBtn.png’, 260, 425)
lBtn.name = ‘left’
rBtn.name = ‘right’

Наконец, мы добавляем текстовое поле счета.

1
2
3
4
— Score TextField
 
score = display.newText(‘0’, 2, 0, ‘Marker Felt’, 14)
score:setTextColor(255, 206, 0)

Вы, наверное, удивляетесь, почему мы добавили стены по частям. Поскольку мы выполняем на них пиксельные столкновения, мы не можем просто использовать метод addBody (поскольку это также добавит прямоугольник, покрывающий альфа-канал), вместо этого мы используем параметр shape, чтобы определить многоугольник для изображения.

Почему не один полигон?

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

01
02
03
04
05
06
07
08
09
10
11
12
13
— Left Wall Parts
 
physics.addBody(l1, ‘static’, {shape = {-40, -107, -11, -107, 40, 70, 3, 106, -41, 106}})
physics.addBody(l2, ‘static’, {shape = {-23, -30, 22, -30, 22, 8, 6, 29, -23, 29}})
physics.addBody(l3, ‘static’, {shape = {-14, -56, 14, -56, 14, 56, -14, 56}})
physics.addBody(l4, ‘static’, {shape = {-62, -46, -33, -46, 61, 45, -62, 45}})
 
— Right Wall Parts
 
physics.addBody(r1, ‘static’, {shape = {10, -107, 39, -107, 40, 106, -5, 106, -41, 70}})
physics.addBody(r2, ‘static’, {shape = {-22, -30, 22, -30, 22, 29, -6, 29, -23, 9}})
physics.addBody(r3, ‘static’, {shape = {-14, -56, 14, -56, 14, 56, -14, 56}})
physics.addBody(r4, ‘static’, {shape = {32, -46, 61, -46, 61, 45, -62, 45}})

Аналогичные методы используются с другими фигурами, за исключением кругов, которые используют параметр radius .

1
2
3
4
5
6
7
8
physics.addBody(ball, ‘dynamic’, {radius = 8, bounce = 0.4})
physics.addBody(hitLine1, ‘static’, {shape = {-20, -42, -15, -49, -6, -46, 18, 39, 15, 44, 5, 44, }})
physics.addBody(hitLine2, ‘static’, {shape = {-20, -42, -15, -49, -6, -46, 18, 39, 15, 44, 5, 44, }})
physics.addBody(hitBall1, ‘static’, {radius = 15})
physics.addBody(hitBall2, ‘static’, {radius = 15})
physics.addBody(hitBall3, ‘static’, {radius = 15})
physics.addBody(pRight, ‘static’, {shape = {-33, 11, 27, -12, 32, 1}})
physics.addBody(pLeft, ‘static’, {shape = {-33, 1, -28, -12, 32, 11}})

Простая линия добавляется в верхней части экрана в виде стены, чтобы отскок мяча.

1
2
3
4
— Top Wall
 
local topWall = display.newLine(display.contentWidth * 0.5, -1, display.contentWidth * 2, -1)
physics.addBody(topWall, ‘static’)

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

01
02
03
04
05
06
07
08
09
10
11
12
13
function gameListeners(action)
    if(action == ‘add’) then
        lBtn:addEventListener(‘touch’, movePaddle)
        rBtn:addEventListener(‘touch’, movePaddle)
        ball:addEventListener(‘collision’, onCollision)
        Runtime:addEventListener(‘enterFrame’, update)
    else
        lBtn:removeEventListener(‘touch’, movePaddle)
        rBtn:removeEventListener(‘touch’, movePaddle)
        ball:removeEventListener(‘collision’, onCollision)
        Runtime:removeEventListener(‘enterFrame’, update)
    end
end

Кнопки на экране запускают вращение лопастей. Этот код обрабатывает это.

1
2
3
4
5
6
function movePaddle(e)
    if(e.phase == ‘began’ and e.target.name == ‘left’) then
        pLeft.rotation = -40
    elseif(e.phase == ‘began’ and e.target.name == ‘right’) then
        pRight.rotation = 40
    end

Вращение вернется в исходное состояние, когда кнопка больше не будет нажата.

1
2
3
4
5
    if(e.phase == ‘ended’) then
        pLeft.rotation = 0
        pRight.rotation = 0
    end
end

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

1
2
3
4
5
6
7
function onCollision(e)
    — Shoot
    if(e.phase == ‘began’ and e.other.name == ‘leftPaddle’ and e.other.rotation == -40) then
        ball:applyLinearImpulse(0.05, 0.05, ball.y, ball.y)
    elseif(e.phase == ‘began’ and e.other.name == ‘rightPaddle’ and e.other.rotation == 40) then
        ball:applyLinearImpulse(0.05, 0.05, ball.y, ball.y)
    end

Счет увеличится после столкновения с любым хитболом.

1
2
3
4
5
6
7
    if(e.phase == ‘ended’ and e.other.name == ‘hBall’) then
        score.text = tostring(tonumber(score.text) + 100)
        score:setReferencePoint(display.TopLeftReferencePoint)
        score.x = 2
        audio.play(bell)
    end
end

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

1
2
3
4
5
6
7
function update()
    — Check if ball hit bottom
    if(ball.y > display.contentHeight) then
        ball.y = 0
        audio.play(buzz)
    end
end

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

1
Main()

Файл Default.png — это изображение, которое будет отображаться сразу после запуска приложения, пока iOS загружает основные данные для отображения главного экрана. Добавьте это изображение в исходную папку вашего проекта, оно будет автоматически добавлено компилятором Corona.


Используя графику, которую вы создали ранее, теперь вы можете создать красивый и красивый значок. Размер значка для iPhone без изображения Retina составляет 57x57px, но версия Retina составляет 114x114px, а для магазина iTunes требуется версия 512x512px. Я предлагаю сначала создать версию 512×512, а затем уменьшить ее для других размеров. Значок не должен иметь закругленных углов или прозрачного блика, iTunes и iPhone сделают это за вас.


Пришло время провести финальный тест. Откройте Corona Simulator, перейдите в папку вашего проекта и нажмите «Открыть». Если все работает, как ожидалось, вы готовы к последнему шагу!


В Corona Simulator перейдите в File> Build и выберите ваше целевое устройство. Заполните необходимые данные и нажмите кнопку « Создать» . Подождите несколько секунд, и ваше приложение будет готово для тестирования устройства и / или отправки для распространения!


Поэкспериментируйте с конечным результатом и попробуйте сделать свою собственную версию игры!

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