Статьи

Создайте игру для разрушения кирпичей с помощью Corona SDK: обнаружение столкновений

Добро пожаловать в финальное руководство в нашей серии игр Brick Breaker! В этом уроке мы рассмотрим логику оставшихся коллизий, проверим состояния выигрышей и проигрышей, уровни изменений и многое другое.


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

Когда мяч сталкивается с кирпичом, мы будем использовать ту же технику, которая применяется к веслу, чтобы определить сторону, по которой будет следовать мяч:

1
2
3
4
5
6
7
8
function removeBrick(e)
    — Check the which side of the brick the ball hits, left, right
    if(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) < (e.other.x + e.other.width * 0.5)) then
        xSpeed = -5
    elseif(e.other.name == ‘brick’ and (ball.x + ball.width * 0.5) >= (e.other.x + e.other.width * 0.5)) then
        xSpeed = 5
    end
end

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

1
2
3
4
5
6
— Bounce, Remove
if(e.other.name == ‘brick’) then
    ySpeed = ySpeed * -1
    e.other:removeSelf()
    e.other = nil
    bricks.numChildren = bricks.numChildren — 1

Каждый удар по кирпичу добавит 100 очков к счету. Оценка будет взята из постоянной оценки и добавлена ​​к текущей оценке в виде текста.

1
score = score + 1<br /> scoreNum.text = score * SCORE_CONST<br /> scoreNum:setReferencePoint(display.CenterLeftReferencePoint)<br /> scoreNum.x = 54 <br /> end

Этот код проверяет, остались ли еще кирпичи на сцене, и отображает сообщение «Вы выиграли», если нет:

1
2
3
4
5
    if(bricks.numChildren < 0) then
        alert(‘ You Win!’, ‘ Next Level ›’)
        gameEvent = ‘win’
    end
end

Скорость мяча определяется переменными xSpeed и ySpeed . Когда функция обновления выполняется, шар начинает двигаться, используя эти значения для размещения на каждом кадре.

1
2
3
4
5
function update(e)
    — Ball Movement
 
    ball.x = ball.x + xSpeed
    ball.y = ball.y + ySpeed

Этот код проверяет столкновения стен с мячом и отвечает, отправляя мяч в противоположном направлении, когда это необходимо:

1
2
3
if(ball.x < 0) then ball.x = ball.x + 3 xSpeed = -xSpeed end—Left
if((ball.x + ball.width) > display.contentWidth) then ball.x = ball.x — 3 xSpeed = -xSpeed end—Right
if(ball.y < 0) then ySpeed = -ySpeed end—Up

Оператор if используется для проверки пропуска мяча веслом. Если это правда, отображается предупреждение, спрашивающее пользователя, если они хотели бы попробовать еще раз.

1
if(ball.y + ball.height > paddle.y + paddle.height) then alert(‘ You Lose’, ‘ Play Again ›’) gameEvent = ‘lose’ end—down/lose

Экран оповещения показывает игроку информацию о состоянии игры. Отображается при достижении события выигрыша / проигрыша.

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

  • t: заголовок предупреждения
  • м: короткое сообщение
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function alert(t, m)
    gameListeners(‘remove’)
    alertBg = display.newImage(‘alertBg.png’)
    box = display.newImage(‘alertBox.png’, 90, 202)
    transition.from(box, {time = 300, xScale = 0.5, yScale = 0.5, transition = easing.outExpo})
    titleTF = display.newText(t, 0, 0, ‘akashi’, 19)
    titleTF:setTextColor(254,203,50)
    titleTF:setReferencePoint(display.CenterReferencePoint)
    titleTF.x = display.contentCenterX
    titleTF.y = display.contentCenterY — 15
    msgTF = display.newText(m, 0, 0, ‘akashi’, 12)
    msgTF:setTextColor(254,203,50)
    msgTF:setReferencePoint(display.CenterReferencePoint)
    msgTF.x = display.contentCenterX
    msgTF.y = display.contentCenterY + 15
    box:addEventListener(‘tap’, restart)
    alertScreen = display.newGroup()
    alertScreen:insert(alertBg)
    alertScreen:insert(box)
    alertScreen:insert(titleTF)
    alertScreen:insert(msgTF)
end

Следующая функция проверяет статус игры (выиграть, проиграть, закончен) и выполняет соответствующее действие:

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
function restart(e)
    if(gameEvent == ‘win’ and table.maxn(levels) > currentLevel) then
        currentLevel = currentLevel + 1
        changeLevel(levels[currentLevel])—next level
        levelNum.text = tostring(currentLevel)
    elseif(gameEvent == ‘win’ and table.maxn(levels) &lt;= currentLevel) then
        box:removeEventListener(‘tap’, restart)
        alertScreen:removeSelf()
        alertScreen = nil
        alert(‘ Game Over’, ‘ Congratulations!’)
        gameEvent = ‘finished’
    elseif(gameEvent == ‘lose’) then
        changeLevel(levels[currentLevel])—same level
    elseif(gameEvent == ‘finished’) then
        addMenuScreen()
        transition.from(menuScreen, {time = 300, y = -menuScreen.height, transition = easing.outExpo})
        box:removeEventListener(‘tap’, restart)
        alertScreen:removeSelf()
        alertScreen = nil
        currentLevel =
        scoreText:removeSelf()
        scoreText = nil
        scoreNum:removeSelf()
        scoreNum = nil
        levelText:removeSelf()
        levelText = nil
        levelNum:removeSelf()
        levelNum = nil
        ball:removeSelf()
        ball = nil
        paddle:removeSelf()
        paddle = nil
        score = 0
    end
end

Эта функция изменяет уровень обновлений при необходимости:

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
function changeLevel(level)
         
    — Clear Level Bricks
             
    bricks:removeSelf()
             
    bricks.numChildren = 0
    bricks = display.newGroup()
 
    — Remove Alert
             
    box:removeEventListener(‘tap’, restart)
    alertScreen:removeSelf()
    alertScreen = nil
             
    — Reset Ball and Paddle position
             
    ball.x = (display.contentWidth * 0.5) — (ball.width * 0.5)
    ball.y = (paddle.y — paddle.height) — (ball.height * 0.5) -2
             
    paddle.x = display.contentWidth * 0.5
             
    — Redraw Bricks
             
    buildLevel(level)
             
    — Start
             
    background:addEventListener(‘tap’, startGame)
end

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

1
Main()

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


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

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


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


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


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

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