[英]JavaScript canvas: “Random” errors with collision detection
在一个简单的画布应用程序上工作,用户可以用枪射击子弹。 (单击=新项目符号,箭头键=新方向)
几乎可以完美地工作,除了看似“随机”出现的地方,如果改变方向,碰撞将失败。
这是我的jsFiddle 。 相关摘要:
Bullet.prototype-animate():
animate: function () {
if (gun.velocity.direction === keys.left) {
this.coordinates.x -= this.velocity.speed.x;
} else if (gun.velocity.direction === keys.up) {
this.coordinates.y += this.velocity.speed.y;
} else if (gun.velocity.direction === keys.right) {
this.coordinates.x += this.velocity.speed.x;
} else if (gun.velocity.direction === keys.down) {
this.coordinates.y -= this.velocity.speed.y;
}
return this;
},
Bullet.prototype-碰撞():
collision: function (str) {
if (str === 'boundary') {
if (this.coordinates.x + this.velocity.speed.x > canvas.width || this.coordinates.x + this.velocity.speed.x < 0) {
this.velocity.speed.x = -this.velocity.speed.x;
} else if (this.coordinates.y + this.velocity.speed.y > canvas.height || this.coordinates.y + this.velocity.speed.y < 0) {
this.velocity.speed.y = -this.velocity.speed.y;
}
}
}
密钥处理:
document.onkeydown = function (e) {
e = e.keyCode;
if (e === keys.left) {
gun.velocity.direction = keys.left;
} else if (e === keys.up) {
gun.velocity.direction = keys.up;
} else if (e === keys.right) {
gun.velocity.direction = keys.right;
} else if (e === keys.down) {
gun.velocity.direction = keys.down;
}
};
我如何弄清楚为什么会发生这种情况以及如何制止这种情况?
好的,我看了一眼,发现了您的错误。
您有给定的速度为两个值x和y的项目符号,还有一个方向。 为子弹设置动画时,可以检查方向,并根据方向仅将x或y添加到正确的方向上。 但是,当您测试子弹是否撞到墙壁时,您会忽略方向,并测试子弹的速度。 整个时间中,子弹的x和y速度都不等于零。 您的碰撞测试是测试子弹对角移动。
如果您添加这段代码
ctx.strokeStyle = this.color;
ctx.beginPath();
// draw a line in the direction you are testing the wall to be
ctx.moveTo(this.coordinates.x, this.coordinates.y);
ctx.lineTo(this.coordinates.x + this.velocity.speed.x*10, this.coordinates.y + this.velocity.speed.y*10);
ctx.stroke();
在渲染项目符号的地方,您会看到项目符号并没有沿着this.velocity.speed
指示的方向this.velocity.speed
,但是您使用这些值来测试墙壁。
一个简单的修复程序有很多更改。
该怎么办。
对于每个子弹,请将速度保持为单个数字。 创建delta.x
和delta.y
作为项目符号向量。 将方向保持为单个值。 如您所愿。
拍摄时,请使用方向设定项目符号向量(delta); 上设置增量{x:0,y:-1},下设置增量{x:0,y:1},左设置增量{x:-1,y:0},右设置增量{x:1,y :0},
要移动子弹,只需将增量乘以速度即可;
bullet.pos.x += bullet.delta.x * bullet.speed;
bullet.pos.y += bullet.delta.y * bullet.speed;
速度与方向无关。 它是描述随时间变化的距离的正值。
Delta x和y确实是子弹方向所需要的全部,但只要将方向保持为单个值以及两个值都匹配,就不会有任何伤害。
测试墙
// check if the bullet is moving in the x direction
// then check if it's about to hit the wall
if(bullet.delta.x !== 0 && (bullet.pos.x + bullet.delta.x * bullet.speed > wallLoc ||
bullet.pos.x + bullet.delta.x * bullet.speed < 0)){
bullet.delta.x = -bullet.delta.x; // reverse bullet
}
对y方向做同样的事情。
我不知道您是否打算在按某个键时更改所有项目符号方向。 如果只是通过所有项目符号,并在按下某个键时更改那里的增量。
希望这很清楚。 请问您是否需要更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.