带有冲突检测的HTML画布和JavaScript旋转对象
我正在用JavaScript和HTML画布创建一个游戏。这是一款多人2D游戏,坦克试图互相攻击。坦克可以移动也可以旋转。如何使用旋转的矩形对象进行碰撞检测?我知道,我可以把它们做成正方形,然后使用圆形探测,但当坦克撞到墙上时,它看起来非常混乱。感谢所有试图提供帮助的人:)将生命点移动到本地空间 首先是另一种选择 有很多方法可以做到这一点。最简单的方法。当计算点与线之间的叉积时,如果点位于线的右侧,则叉积为负值,如果点位于线的左侧,则叉积为正值。如果你依次做四个边,它们都是相同的符号,那么点必须在里面 求直线与点的叉积带有冲突检测的HTML画布和JavaScript旋转对象,javascript,html,canvas,collision,detection,Javascript,Html,Canvas,Collision,Detection,我正在用JavaScript和HTML画布创建一个游戏。这是一款多人2D游戏,坦克试图互相攻击。坦克可以移动也可以旋转。如何使用旋转的矩形对象进行碰撞检测?我知道,我可以把它们做成正方形,然后使用圆形探测,但当坦克撞到墙上时,它看起来非常混乱。感谢所有试图提供帮助的人:)将生命点移动到本地空间 首先是另一种选择 有很多方法可以做到这一点。最简单的方法。当计算点与线之间的叉积时,如果点位于线的右侧,则叉积为负值,如果点位于线的左侧,则叉积为正值。如果你依次做四个边,它们都是相同的符号,那么点必须在
//x1,y1,x2,y2 is a line
// px,py is a point
// first move line and point relative to the origin
// so that the line and point is a vector
px -= x1;
py -= y1;
x2 -= x1;
y2 -= y1;
var cross = x2 * py - y2 * px;
if(cross < 0){
// point left of line
}else if(cross > 0) {
// point right of line
}else {
// point on the line
}
这个变换包含了所有我们需要做的计算,我们需要做的就是将它倒置,然后将子弹与倒置的矩阵相乘
var tankInvMatrix = ctx.getTransform().invertSelf(); // get the inverted matrix
子弹在bx处,因此创建一个
然后对每个坦克使用
现在只需在坦克局部坐标空间进行测试
if(relBullet.x > -20 && relBullet.x < 20 && relBullet.x > -10 && relBullet.x < 10){
/// bullet has hit the tank
}
将生命点移动到局部空间
首先是另一种选择
有很多方法可以做到这一点。最简单的方法。当计算点与线之间的叉积时,如果点位于线的右侧,则叉积为负值,如果点位于线的左侧,则叉积为正值。如果你依次做四个边,它们都是相同的符号,那么点必须在里面
求直线与点的叉积
//x1,y1,x2,y2 is a line
// px,py is a point
// first move line and point relative to the origin
// so that the line and point is a vector
px -= x1;
py -= y1;
x2 -= x1;
y2 -= y1;
var cross = x2 * py - y2 * px;
if(cross < 0){
// point left of line
}else if(cross > 0) {
// point right of line
}else {
// point on the line
}
这个变换包含了所有我们需要做的计算,我们需要做的就是将它倒置,然后将子弹与倒置的矩阵相乘
var tankInvMatrix = ctx.getTransform().invertSelf(); // get the inverted matrix
子弹在bx处,因此创建一个
然后对每个坦克使用
现在只需在坦克局部坐标空间进行测试
if(relBullet.x > -20 && relBullet.x < 20 && relBullet.x > -10 && relBullet.x < 10){
/// bullet has hit the tank
}
哇!我完全没想到会有人走这么远来回答我的问题!先生,你的回答太过分了!谢谢你解释这一切。现在它更有意义了。我将尝试实现您的编码,并让您知道它是如何进行的。非常感谢你,我希望你有一个美好的一天!有史以来最好的答案!:)你真是太棒了。你走了这么远才得出这个答案,它绝对完美。哇!!!我完全没想到会有人走这么远来回答我的问题!先生,你的回答太过分了!谢谢你解释这一切。现在它更有意义了。我将尝试实现您的编码,并让您知道它是如何进行的。非常感谢你,我希望你有一个美好的一天!有史以来最好的答案!:)你真是太棒了。你走了这么远才得出这个答案,它绝对完美。
// create a vector aligned to the tanks direction
var xdx = Math.cos(r);
var xdy = Math.sin(r);
// set the 2D API to the tank location and rotation
ctx.setTransform(xdx,xdy,-xdy,xdx,x,y); // create the transform for the tank
// draw the tank
ctx.fillRect(-20,-10,40,20); // rotated about center
// create inverted matrix for the tank
// Only invert the tank matrix once per frame
var d = xdx * xdx - xdy * -xdy;
var xIx = xdx / d;
var xIy = -xdy / d;
// I am skipping c,d of the matrix as it is perpendicular to a,b
// thus c = -b and d = a
var ix = (-xdy * y - xdx * x) / d;
var iy = -(xdx * y - xdy * x) / d;
// For each bullet per tank
// multiply the bullet with the inverted tank matrix
// bullet local x & y
var blx = bx * xIx - by * xIy + ix;
var bly = bx * xIy + by * xIx + iy;
// and you are done.
if(blx > -20 && blx < 20 && bly > -10 && bly < 10){
// tank and bullet are one Kaaboommmm
}