JavaScript画布:";“随机”;碰撞检测错误

JavaScript画布:";“随机”;碰撞检测错误,javascript,html,canvas,Javascript,Html,Canvas,在一个简单的画布应用程序上工作,用户可以用枪射击子弹。(单击=新项目符号,箭头键=新方向) 工作几乎完美,除了有看似“随机”的地方,如果方向改变,碰撞将失败 这是我的。相关片段: Bullet.prototype-动画() Bullet.prototype-碰撞(): 我该如何找出发生这种情况的原因以及如何阻止它?好的,我查看了一下,发现了您的错误 你有子弹,你给属性速度是两个值x,y,你还有一个方向。为项目符号设置动画时,检查方向并根据方向仅添加到x或y,从而沿正确方向移动项目符号。但是当你测

在一个简单的画布应用程序上工作,用户可以用枪射击子弹。(单击=新项目符号,箭头键=新方向)

工作几乎完美,除了有看似“随机”的地方,如果方向改变,碰撞将失败

这是我的。相关片段:

Bullet.prototype-动画()

Bullet.prototype-碰撞():


我该如何找出发生这种情况的原因以及如何阻止它?

好的,我查看了一下,发现了您的错误

你有子弹,你给属性速度是两个值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
指示的方向移动,而是使用这些值来测试墙

对于一个简单的修复,有太多的改变

怎么办

每颗子弹 保持速度作为一个单一的数字。 创建
delta.x
delta.y
作为项目符号向量。 将方向保持为单个值。就像你已经做的那样

拍摄时,使用方向设置子弹矢量(增量); 设置增量{x:0,y:-1}, 下集增量{x:0,y:1}, 左集合delta{x:-1,y:0}, 右集合delta{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
}
//检查项目符号是否在x方向移动
//然后检查它是否会撞到墙上
如果(bullet.delta.x!==0&&(bullet.pos.x+bullet.delta.x*bullet.speed>wallLoc||
子弹头位置x+子弹头增量x*子弹头速度<0)){
bullet.delta.x=-bullet.delta.x;//反向bullet
}
对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();
bullet.pos.x += bullet.delta.x * bullet.speed;
bullet.pos.y += bullet.delta.y * bullet.speed;
// 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
}