JavaScript中画布上的碰撞检测

Collision detection on a canvas in JavaScript

本文关键字:碰撞检测 JavaScript      更新时间:2023-09-26

我正在为大学的作业制作一款游戏。这个想法是,你通过绘制一条线(点击,拖动&)来保护中心圆圈免受来袭小行星(线)的伤害。释放来画一条线),这条线会阻止它们。如果一颗小行星撞上一条直线,那么这条直线和这颗小行星都会被摧毁。

我目前遇到的问题是没有检测到碰撞。

我有两行&小行星。这些行由简单的开始&结束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();      
            }
        }

问题是,小行星永远不会与&我无论如何也想不出原因,也想不出其他简单的方法。如有任何建议,我将不胜感激,谢谢。

我认为你的问题是,当你旋转上下文,以前绘制的项目(线)不得到旋转,只有旋转后绘制对象被旋转。更多信息请看此页

你可以在平移和旋转画布之前尝试执行你的小行星/直线相交测试,并使用余弦和正弦来找到你想要从中获得图像数据的像素的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之前,确保你的角度是以弧度为单位。

我又考虑了一下这个问题,&意识到这种做事的方法绝对不是最好的方法。它应该可以在没有视图的情况下实现——一个模型视图控制器设计模式。解决这个问题的最好方法就是用数学!

对于两条线的交点有简单的数学运算,但这需要在一个范围内的两条线的交点。我发现了一个算法,它进一步简化了这一点,使用八个坐标-开始x &y和;结束x &

我已经公布了结果。谢谢你的帮助。