Статьи

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

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


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


Эта функция добавляет необходимых слушателей к кнопкам 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
7
8
9
function showCredits:tap(e)
    playBtn.isVisible = false
    creditsBtn.isVisible = false
    creditsView = display.newImage(‘credits.png’, 0, display.contentHeight)
     
    lastY = titleBg.y
    transition.to(titleBg, {time = 300, y = (display.contentHeight * 0.5) — (titleBg.height + 40)})
    transition.to(creditsView, {time = 300, y = (display.contentHeight * 0.5) + 35, onComplete = function() creditsView:addEventListener(‘tap’, hideCredits) end})
end

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

1
2
3
4
function hideCredits:tap(e)
    transition.to(creditsView, {time = 300, y = display.contentHeight + 25, onComplete = function() creditsBtn.isVisible = true playBtn.isVisible = true creditsView:removeEventListener(‘tap’, hideCredits) display.remove(creditsView) creditsView = nil end})
    transition.to(titleBg, {time = 300, y = lastY});
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
— Game BG
     
gameBg = display.newImage(‘gameBg.png’, 10, 10)

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

1
2
3
4
— Movements Textfield
     
movements = display.newText(‘0’, 211, 66, display.systemFont, 16)
movements:setTextColor(224, 180, 120)

Эта часть создает блоки, определенные в переменной Level, используя оператор double для оператора.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    — Create Level
     
    hblocks = display.newGroup()
    vblocks = display.newGroup()
     
    for i = 1, #l1 do
        for j = 1, #l1[1] do
            if(l1[i][j] == 1) then
                local v = display.newImage(‘vrect.png’, 10 + (j * 50)-50, 120 + (i * 50)-50)
                v:addEventListener(‘touch’, dragV)
                vblocks:insert(v)
            elseif(l1[i][j] == 2) then
                local h = display.newImage(‘hrect.png’, 10 + (j * 50)-50, 120 + (i * 50)-50)
                h:addEventListener(‘touch’, dragH)
                hblocks:insert(h)
            elseif(l1[i][j] == 3) then
                s = display.newImage(‘square.png’, 10 + (j * 50)-50, 120 + (i * 50)-49)
                s:addEventListener(‘touch’, dragH)
            end
        end
    end
     
     gameListeners(‘add’)
end

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

1
2
3
4
5
6
7
function gameListeners(action)
    if(action == ‘add’) then
        Runtime:addEventListener(‘enterFrame’, update)
    else
        Runtime:removeEventListener(‘enterFrame’, update)
    end
end

Следующая функция обрабатывает горизонтальное перетаскивание блоков.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function dragH(e)
    e.target.lastX = 0
    local currentX = 0
    local initX = 0
    if(e.phase == ‘began’) then
        e.target.lastX = ex — e.target.x
        initX = e.target.x
        movements.text = tostring(tonumber(movements.text) + 1)
    elseif(e.phase == ‘moved’) then
        e.target.x = ex — e.target.lastX
        currentX = e.target.x
        — Calculate direction
        if(initX < currentX) then
            dir = ‘hl’ —horizontal-left
        elseif(initX > currentX) then
            dir = ‘hr’ —horizontal-right
        end
    end
end

Теперь мы создаем функцию вертикального перетаскивания.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function dragV(e)
    e.target.lastY = 0
    local currentY = 0
    local initY = 0
    if(e.phase == ‘began’) then
        e.target.lastY = ey — e.target.y
        initY = e.target.y
        movements.text = tostring(tonumber(movements.text) + 1)
    elseif(e.phase == ‘moved’) then
        e.target.y = ey — e.target.lastY
        currentY = e.target.y
        — Calculate direction
        if(initY < currentY) then
            dir = ‘vu’ —Vertical-upwards
        elseif(initY > currentY) then
            dir = ‘vd’ —Vertical-downwards
        end
    end
end

Мы будем использовать отличную и полезную функцию для обнаружения столкновений без физики. Вы можете найти оригинальный пример и исходный код на веб-сайте CoronaLabs Code Exchange .

1
2
3
4
5
6
7
function hitTestObjects(obj1, obj2)
        local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin
        local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax
        local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin
        local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax
        return (left or right) and (up or down)
end

Этот код ограничивает движение, создавая виртуальные границы.

1
2
3
4
5
6
7
8
9
function update(e)
    — Vertical Borders
     
    for i = 1, vblocks.numChildren do
        if(vblocks[i].y >= 370) then
            vblocks[i].y = 370
        elseif(vblocks[i].y <= 170) then
            vblocks[i].y = 170
        end

Здесь мы обрабатываем столкновения между вертикальными и горизонтальными блоками.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
    — Hit Test
     
    if(hitTestObjects(vblocks[i], hblocks[i]) and dir == ‘vu’) then
        vblocks[i].y = hblocks[i].y + 75
    elseif(hitTestObjects(vblocks[i], hblocks[i]) and dir == ‘vd’) then
        vblocks[i].y = hblocks[i].y — 75
    end
     
    if(hitTestObjects(vblocks[i], hblocks[i]) and dir == ‘hr’) then
        hblocks[i].x = vblocks[i].x + 75
    elseif(hitTestObjects(vblocks[i], hblocks[i]) and dir == ‘hl’) then
        hblocks[i].x = vblocks[i].x — 75
    end
     
    if(hitTestObjects(s, vblocks[i])) then
        sx = vblocks[i].x — 50
    end
end

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
    — Horizontal Borders
     
    for j = 1, hblocks.numChildren do
        if(hblocks[j].x >= 260) then
            hblocks[j].x = 260
        elseif(hblocks[j].x <= 60) then
            hblocks[j].x = 60
        end
    end
     
    — Square
     
    if(sx >= 320) then
        display.remove(s)
        display.remove(vblocks)
        display.remove(hblocks)
        alert()
    elseif(sx <= 35) then
        sx = 35
    end
end

Функция оповещения останавливает игру, отображает сообщение и удаляет активных слушателей.

1
2
3
4
5
6
7
function alert()
    gameListeners(‘rmv’)
     
    local alertView = display.newImage(‘alert.png’, 80, display.contentHeight * 0.5 — 41)
    transition.from(alertView, {time = 300, y = -82})
endend
end

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

1
Main()

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


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

Это не должно иметь закругленные углы или прозрачные блики; iTunes и iPhone сделают это за вас.


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


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


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