【问题标题】:Array.forEach Updating each Item in Array on clickArray.forEach 点击时更新数组中的每个项目
【发布时间】:2021-12-25 07:37:13
【问题描述】:

当程序运行时,单击鼠标会从屏幕中心创建一个弹丸,每帧都朝发射方向移动(鼠标位置在单击时)。

当 N+1 个射弹发射后,屏幕上的所有射弹移动到新的点击位置,而不是继续其路径。

当新射弹的速度对之前的射弹没有影响时,我无法弄清楚为什么当前射弹会改变方向。

index.html

<canvas></canvas>
<script src="./guns.js"></script>
<script src="./indexh.js"></script>
<script src="./runh.js"></script>

runh.html

const projectilesArray = [];
let frameCount = 0;

function animate() {
    animationID = requestAnimationFrame(animate);
    c.fillStyle = "rgba(0, 0, 0, 1)";
    c.fillRect(0, 0, canvas.width, canvas.height);

    projectilesArray.forEach((Projectile, pIndex) => {
        Projectile.update();
        console.log(Projectile)
  
        if (
          Projectile.x + Projectile.radius < 0 ||
          Projectile.x - Projectile.radius > canvas.width ||
          Projectile.y + Projectile.radius < 0 ||
          Projectile.y - Projectile.radius > canvas.height
        ) {
          setTimeout(() => {
            projectilesArray.splice(pIndex, 1);
          }, 0);
        }
      });
    
    frameCount++;
    if (frameCount > 150) {
        
    }
}
var fire = 1;
let fireRate = 1;
const mouse = {
    x: 0,
    y: 0,
    click: true,
  };

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);
        const fireX = Math.cos(angle);
        //score -= 0;
        //scoreL.innerHTML = score;
        var weapon = new Projectile(cannon);
        weapon.velocity.x = fireX * 9;
        weapon.velocity.y = fireY * 9;
       
        projectilesArray.push(weapon);
     

        //var gun = object.constructor()
      }
    }
  });

  animate();

indexh.js

const canvas = document.querySelector("canvas");
const c = canvas.getContext("2d");

canvas.width = innerWidth;
canvas.height = innerHeight;



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;
        this.velocity = config.velocity;
    }
    draw() {
        c.beginPath();
        c.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
        c.fillStyle = this.color;
        c.fill();
    }
    update() {
        this.draw();
        this.x = this.x + this.velocity.x * this.speed;
        this.y = this.y + this.velocity.y * this.speed;
    }
}

gums.js

let pistol = {
    color : "rgb(255, 0, 0)",
    radius : 10,
    speed : 1,
    rounds : 1,

    velocity : {
        x: 1,
        y: 1
    }
}

let cannon = {
    color : "rgb(0, 0, 255)",
    radius : 30,
    speed : .5,
    rounds : 1,

    velocity : {
        x: 1,
        y: 1
    }
}

谢谢

【问题讨论】:

  • 你能用你的代码创建一个JSFiddle并分享吗
  • N+1 是什么意思?另外,我在projectilesArray.splice(pIndex, 1); 行看到了一个错误,这些超时可以立即排队,然后它们将删除错误的索引。不过,我认为这不是您发布的问题。
  • 您现在可以尝试评论 projectilesArray.splice(pIndex, 1); 一行。这意味着你的弹丸将永远飞走,但这只是看看这是否是你的问题。
  • N+1 是屏幕上投射物的数量,所以不超过一个。 JSFiddle。我将来会这样做。感谢您在接头上发现错误。今天将对此进行调查。

标签: javascript html canvas javascript-objects


【解决方案1】:

问题是您将这个大炮对象用作配置对象:

let cannon = {
    color : "rgb(0, 0, 255)",
    radius : 30,
    speed : .5,
    rounds : 1,

    velocity : {
        x: 1,
        y: 1
    }
}

在您的Projectile 构造函数中,您分配this.velocity = config.velocity; 您将this.velocity 分配为所有Projectiles 的相同对象实例。要修复它,请尝试复制对象,例如:

this.velocity = {...config.velocity};

这将复制对象而不是共享同一个对象实例。

另请注意,您在此行中有一个您没有询问的错误:

projectilesArray.splice(pIndex, 1);

如果两个超时在同一个循环中排队,当第一个超时触发时数组将移位,第二个超时将在错误的索引上操作。

【讨论】:

  • 这行得通,我将不得不对projectilesArray.splice(pIndex, 1); 新的 Projectile 构造函数进行一些研究,如下所示。 ``` class Projectile { constructor(config) { ... //this.velocity = config.velocity; this.velocity = { x : config.velocity.x, y : config.velocity.y } }``` 投我一票……我在这里没有足够高的活动,但我点击了它,谢谢
  • 如果解决了您的问题,请采纳!解决splice 问题的一种方法是将数组中的条目设置为undefined(没有setTimeout),然后在循环之后执行projectilesArray = projectilesArray.filter(p =&gt; p) 之类的操作(使数组变为非const)。
  • 谢谢,我将其标记为已解决。并感谢拼接的输入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 2011-04-21
相关资源
最近更新 更多