JavaScript Canvas : "Random" errors with collision detection

标签 javascript html canvas

正在开发一个简单的 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/

相关文章:

javascript - 元素的 src 属性替换,以便在加载时首先呈现修改后的元素

Android - 具有硬件加速和抗锯齿的画线会导致伪影

javascript - 如何重新创建此 "wavy"图像效果?

javascript - 在附加元素内附加元素在 jQuery 中不起作用

javascript - 复选框显示隐藏字段 - 无法加载

javascript - 调用 Angularjs 模块一次

javascript - 更改另一个下拉选项时隐藏下拉选项

javascript - 如何更改单选按钮的默认外观,而不是功能?

javascript 返回上一个事件 div

javascript - 如何从 Canvas 上的多个旋转弧中删除直线?