正在开发一个简单的 Canvas 应用程序,用户可以用枪射击子弹。 (点击=新项目符号,箭头键=新方向)
工作几乎完美,除了看似“随机”发生的情况,如果方向改变,碰撞将会失败。
这是我的 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;
}
}
}
key 处理:
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 速度都不等于 0。您的碰撞测试正在测试沿对 Angular 线移动的子弹。
如果添加这段代码
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
指示的方向行进,但您可以使用这些值来测试墙壁。
对于一个简单的修复来说,需要改变的地方太多了。
做什么。
对于每个项目符号 将速度保持为一个数字。 创建 delta.x 和 delta.y 作为项目符号向量。 将方向保持为单一值。正如您已经拥有的那样。
当你射击时,你可以使用方向来设置子弹矢量(delta); 设置增量 {x:0,y:-1}, 向下设置 delta {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 方向执行相同的操作。
不知道你是否有意在按下某个键时改变所有的项目符号方向。如果只是遍历所有项目符号并在按下某个键时更改增量。
希望这是清楚的。请询问您是否需要更多信息。
关于JavaScript Canvas : "Random" errors with collision detection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33538166/