You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas点击发射新弹丸时旧弹丸集体转向,Array.forEach更新异常问题求助

问题根源

你所有的Projectile实例都共享了cannon配置对象里的同一个velocity引用。
在创建弹丸时,你直接将cannon传入Projectile构造函数,构造函数执行this.velocity = config.velocity时,只是把cannon.velocity这个对象的内存地址赋值给了实例的velocity属性,没有生成新的对象。后续每次修改新弹丸的weapon.velocity.x/weapon.velocity.y,本质都是修改同一个全局的cannon.velocity对象的属性,自然所有关联这个引用的旧弹丸都会同步转向。

修复方案

两种常用修复方式,任选其一即可:

方式1:修改Projectile构造函数,对velocity做浅拷贝

修改indexh.js里的构造函数逻辑,赋值velocity时生成新对象,切断引用关联:

class Projectile {
    constructor(config) {
        this.color = config.color || "rgb(60, 179, 113)";
        this.radius = config.radius || 1;
        this.speed = config.speed || 5;
        this.rounds = config.rounds || 2;
        this.x = config.x || canvas.width / 2;
        this.y = config.y || canvas.height /2;
        // 这里改为浅拷贝velocity对象,每个实例独占一个velocity
        this.velocity = {...config.velocity};
    }
    // 其余代码保持不变
}

方式2:创建弹丸时直接传入独立的velocity对象

修改runh.js里的点击事件逻辑,不需要修改构造函数:

canvas.addEventListener('mousedown', (event) => {
    if (fire % fireRate == 0) {
      if (mouse.click == true) {
        mouse.x = event.x;
        mouse.y = event.y;

        const angle = Math.atan2(mouse.y - (canvas.height / 2), mouse.x - (canvas.width / 2));
        const fireY = Math.sin(angle) * 9;
        const fireX = Math.cos(angle) * 9;
        // 传入新的velocity对象,不共享cannon的velocity引用
        var weapon = new Projectile({
            ...cannon,
            velocity: {x: fireX, y: fireY}
        });
        projectilesArray.push(weapon);
      }
    }
  });

内容的提问来源于stack exchange,提问作者Travis Heidelberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:06:00