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

This is the 7th step out of 10 of the Gamedev Canvas tutorial. You can find the source code as it should look after completing this lesson at Gamedev-Canvas-workshop/lesson7.html.

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

Это наше решение, как реализовать это, конечно, но может быть сложно определить, касается ли шар касания к прямоугольнику или нет, потому что для этого нет вспомогательных функций в Canvas. Ради этого урока мы сделаем это самым простым способом. Мы проверим, сталкивается ли центр мяча с любым из данных кирпичей. Это не даст идеального результата каждый раз, и есть намного более сложные способы обнаружения столкновений, но это будет прекрасно работать, чтобы научить вас основным понятиям.

 

Функция обнаружения столкновения

Чтобы отбросить все это, мы хотим создать функцию обнаружения столкновений, которая будет проходить через все кирпичи и сравнивать каждую позицию одного кирпича с координатами шара при каждом рисовании кадра. Для лучшей читаемости кода мы будем определять переменную b для хранения объекта кирпича в каждом цикле обнаружения столкновения:

 

function collisionDetection() {
    for(var c=0; c<brickColumnCount; c++) {
        for(var r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            // calculations
        }
    }
}

 

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

  • Положение x шара больше, чем положение x кирпича.
  • Положение x шара меньше, чем x положение кирпича плюс его ширина.
  • Положение y шара больше y-положения кирпича.
  • Положение y шара меньше, чем y-позиция кирпича плюс его высота.

Давайте напишем это в коде:

 

function collisionDetection() {
    for(var c=0; c<brickColumnCount; c++) {
        for(var r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
                dy = -dy;
            }
        }
    }
}

Добавьте вышеприведенный блок к вашему коду под keyUpHandler() функцией .

Удаление кирпичей после их попадания

Вышеприведенный код будет работать по желанию, и мяч изменит свое направление. Проблема в том, что кирпичи остаются там, где они есть. Мы должны выяснить, как избавиться от тех, с которыми мы уже попали с мячом. Мы можем сделать это, добавив дополнительный параметр, чтобы указать, хотим ли мы рисовать каждый кирпич на экране или нет. В той части кода, где мы инициализируем кирпичи, добавим свойство status к каждому кирпичному объекту. Обновите следующую часть кода, как показано выделенной линией:

 

var bricks = [];
for(var c=0; c<brickColumnCount; c++) {
    bricks[c] = [];
    for(var r=0; r<brickRowCount; r++) {
        bricks[c][r] = { x: 0, y: 0, status: 1 };
    }
}

Затем мы проверим значение свойства свойства каждого кирпича в функцииdrawBricks() перед его рисованием - если status равен 1 , а затем нарисуйте его, но если он равен 0 , то он попал в мяч, и мы его не хотим на экране больше.Обновите drawBricks() следующим образом:

function drawBricks() {
    for(var c=0; c<brickColumnCount; c++) {
        for(var r=0; r<brickRowCount; r++) {
            if(bricks[c][r].status == 1) {
                var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
                var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
                bricks[c][r].x = brickX;
                bricks[c][r].y = brickY;
                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = "#0095DD";
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}

Отслеживание и обновление состояния в функции обнаружения столкновений

Теперь нам нужно задействовать свойство status кирпича в функции collisionDetection() : если кирпич активен (его статус равен 1 ), мы проверим, произойдет ли столкновение; если произойдет столкновение, мы установим статус данного кирпича равным 0 чтобы он не был нарисован на экране. Обновите функцию collisionDetection() как показано ниже:

 

function collisionDetection() {
    for(var c=0; c<brickColumnCount; c++) {
        for(var r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            if(b.status == 1) {
                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
                    dy = -dy;
                    b.status = 0;
                }
            }
        }
    }
}

Активация нашего обнаружения столкновений

Последнее, что нужно сделать, это добавить вызов функции collisionDetection() в нашу основную функцию draw() . Добавьте следующую строку в функцию draw() , чуть ниже drawPaddle() :

 

collisionDetection();

Сравните свой код

Обнаружение столкновения шара теперь проверяется на каждом кадре, с каждым кирпичом. Теперь мы можем уничтожить кирпичи! : -

 

Упражнение : измените цвет шара, когда он ударит по кирпичу.

Следующие шаги

Мы определенно добираемся туда сейчас; Давайте двигаться дальше! В восьмой главе мы будем смотреть, как отслеживать счет и выигрывать .

 

Метки документа и участники

Внесли вклад в эту страницу: DanInSpace104
Обновлялась последний раз: DanInSpace104,