Обнаружение столкновений на холсте в JavaScript
Я работаю над игрой для университетского задания. Идея состоит в том, что вы защищаете центральный круг от входящих астероидов (линий), рисуя линию (нажмите, перетащите и отпустите, чтобы нарисовать линию), которая блокирует их. Астероид, поражающий линию, должен уничтожить оба астероида.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что столкновение не обнаруживается.
У меня есть массивы объектов обеих линий и астероидов. Линии состоят из простого начала и конца x & y, астероиды состоят из случайной скорости и случайного угла (их входящий угол) - контекст вращается, астероид рисуется, а затем он сбрасывается для следующей строки.
Чтобы обнаружить столкновение, я использую getImageData и проверяю перед астероидами, сколько бы пикселей ни проходила линия в этой итерации (в основном, их скорость), и если цвет будет красным, это разрушит астероид - я не успел уничтожив линию, я преодолею это препятствие, когда я приду к ней (хотя предложения приветствуются).
function asteroids_draw() {
for (var i = 0; i < asteroids.length; i++) {
// Drawing setup
context.save();
context.translate(width / 2, height / 2);
context.rotate(asteroids[i].angle);
// Detecting close asteroids
if ((asteroids[i].distance - asteroids[i].speed) < planet.size) {
asteroids.splice(i, 1);
game_life_lost();
context.restore();
return;
} else if ((asteroids[i].distance - asteroids[i].speed) < 150){
asteroids[i].colour = '#FF0000';
}
// Scanning ahead for lines
for (var j = 0; j < asteroids[i].speed; j++) {
if (context.getImageData(asteroids[i].distance - j, 0, 1, 1).data[0] == 255) {
asteroids.splice(i, 1);
context.restore();
return;
}
}
// Drawing asteroid
context.beginPath();
context.moveTo(asteroids[i].distance -= asteroids[i].speed, 0);
context.lineTo(trig, 0);
context.strokeStyle = asteroids[i].colour;
context.stroke();
context.closePath();
context.restore();
}
}
Проблема в том, что астероиды никогда не сталкиваются с линиями, и я не могу на всю жизнь понять, почему, или не вижу другого простого способа сделать это. Любой совет будет высоко ценится, спасибо заранее.
2 ответа
Я еще немного подумал о проблеме и понял, что этот метод ведения дел определенно не лучший. Это должно быть выполнимо без представления - как шаблон проектирования контроллера представления модели. Лучший способ решить это - использовать математику!
Существует простая математика для пересечения двух линий, но для этого необходимо пересечение двух линий в диапазоне. Я нашел алгоритм, который упрощает это далее, используя восемь координат - начало x & y & конец x & y двух линий.
Я опубликовал результаты. Спасибо за помощь.
Я думаю, что ваша проблема в том, что когда вы вращаете контекст, ранее нарисованные элементы (линии) не поворачиваются, вращаются только объекты, нарисованные после вращения. Смотрите эту страницу для получения дополнительной информации.
Вы можете попробовать выполнить тест пересечения астероидов и линий перед тем, как перевести и повернуть холст, и использовать косинус и синус, чтобы найти координаты x и y пикселей, из которых вы хотите получить данные изображения.
var pixelLocation =
[Math.cos(asteroids[i].angle) * j, Math.sin(asteroids[i].angle) * j];
if (context.getImageData(pixelLocation[0], pixelLocation[1], 1, 1).data[0] == 255) {
Просто убедитесь, что ваш угол в радианах, прежде чем переходить к cos и sin.