2015-11-05 79 views
1

在用户可以用枪射击子弹的简单画布应用上工作。 (点击=新的项目符号,箭头键=新的方向)JavaScript画布:带有碰撞检测的“随机”错误

工作几乎完美,除了看似“随机”出现的地方,如果方向改变,碰撞将失败。我的jsFiddle。有关片段:

Bullet.prototype - 动画():

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; 
    } 
}; 

我如何弄清楚为什么会发生这种情况,我该如何阻止它?

回答

1

好吧,我看了看,发现你的错误。

你有子弹,你已经给出属性速度是两个值x,你也有一个方向。当为子弹设置动画时,您需要检查方向,并根据方向仅向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.xdelta.y作为项目符号向量。 保持方向为单个值。正如你已经拥有。

当你拍摄时使用方向来设置子弹矢量(增量); 上集delta {x:0,y:-1}, 下集delta {x:0,y:1}, 左集delta {x:-1,y:0}, 右集delta {x :1,y:0},

要移动子弹只需添加deltas乘以速度;

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方向上的相同。

我不知道您是否打算在按下某个键时更改所有子弹的方向。如果只是通过所有项目符号并在按下某个键时更改那里的增量。

希望这是明确的。请问是否需要更多信息。