繁体   English   中英

JavaScript canvas:冲突检测中的“随机”错误

[英]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.xdelta.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM