javascript - 当我使用 canvas 和 requestAnimationFrame 对图像数组进行动画处理时出现位置问题

标签 javascript html5-canvas requestanimationframe

我正在制作一款射击游戏并为七个敌人图像制作动画。 the image of the begining position

而且你可以看到彼此之间的距离还不错,只有10px。但是动画结束后,最左边的敌人图像变得更远了,已经超过了10px。

我尝试了很多方法,发现问题出在update方法上。当我改变循环的顺序时 for(let i=0;i=0;i--) ,最左边的敌人图像变得更远,距离大于10px。

    <canvas
      id="canvas"
      width="700"
      height="600"
      style="border: 1px solid #333"
    ></canvas>

    <script>
      let canvas = document.querySelector("canvas");
      let c = canvas.getContext("2d");
      c.fillRect(30, 470, 640, 100);

      let enemys = [];
      let limitObj = {
        enemyLimitDown: 470,
        enemyLimitLeft: 30,
        enemyLimitRight: 670,
        enemyLimitTop: 30
      };

      class Enemy {
        constructor(x) {
          (this.x = x),
            (this.y = 30),
            (this.width = 50),
            (this.height = 50),
            (this.xstep = 2),
            (this.ystep = 50),
            (this.direction = "right"),
            enemys.push(this);
        }

        draw(enemys) {
          for (let i = 0; i < num; i++) {
            c.drawImage(
              imageEnemy,
              enemys[i].x,
              enemys[i].y,
              enemys[i].width,
              enemys[i].height
            );
          }
        }

        clear() {
          c.clearRect(0, 0, canvas.width, canvas.height - 130);
        }

        update(enemys) {
          for (let i = num-1; i >=0; i--) {
            if (enemys[i].direction == "right") {
              enemys[i].x += enemys[i].xstep;
              let max = 0;
              max = findMax();
              if (max == limitObj.enemyLimitRight - enemys[i].width) {
                for (let i = num - 1; i >= 0; i--) {
                  enemys[i].y += this.ystep;
                  enemys[i].direction = "left";
                }
              }
            } else {
              enemys[i].x -= enemys[i].xstep;
              let min = findMin();
              if (min == limitObj.enemyLimitLeft) {
                for (let i = num - 1; i >= 0; i--) {
                  enemys[i].y += this.ystep;
                  enemys[i].direction = "right";
                }
              }
            }
          }
        }

        animate(enemys) {
          this.update(enemys);
          this.clear();
          this.draw(enemys);

          let canRequest = requestAnimationFrame(() => {
            this.animate(enemys);
          });

          for (let i = 0; i < num; i++) {
            if (enemys[i].y + this.height >= limitObj.enemyLimitDown) {
              cancelAnimationFrame(canRequest);
            }
          }
        }
      }

      function findMax() {
        let max = 0;
        for (let i = 0; i < num; i++) {
          if (max <= enemys[i].x) {
            max = enemys[i].x;
          }
        }
        return max;
      }

      function findMin() {
        let min = canvas.width + 1;
        for (let i = 0; i < num; i++) {
          if (min >= enemys[i].x) {
            min = enemys[i].x;
          }
        }
        return min;
      }

      //  initialize enemy picture
      let imageEnemy = new Image();
      imageEnemy.src = "https://raw.githubusercontent.com/AbdullA-Ababakre/BlogImage/master/enemy.png";

      function initEnemy(x) {
        imageEnemy.addEventListener("load", () => {
          c.drawImage(imageEnemy, x, 30, 50, 50);
        });
      }

      let enemyStart = 10;
      let enemyWidth = 50;
      let num = 7;
      for (let i = 0; i < num; i++) {
        enemys[i] = new Enemy(enemyStart + i * enemyWidth + i * 10);
        initEnemy(enemyStart + i * enemyWidth + i * 10);
      }

       enemys[0].animate(enemys);
    </script>

结果错误,最后一张图像距离较远。 the final effect of the code above

最佳答案

欢迎使用 Slack。

我查看了您的代码,我想让您知道问题所在并不是很明显。

最终我相信我已经为您找到了问题的根源,并且只需稍加调整即可解决它;

        [...]
          let max = 0;
          max = findMax();
          if (max == limitObj.enemyLimitRight - enemys[i].width) {
            for (let j = num - 1; j >= 0; j--) {
              enemys[j].y += this.ystep;
              enemys[j].direction = "left";
            }
          } else {
            enemys[i].x += enemys[i].xstep;
          }
        } else {
          let min = findMin();
          if (min == limitObj.enemyLimitLeft) {
            for (let j = num - 1; j >= 0; j--) {
              enemys[j].y += this.ystep;
              enemys[j].direction = "right";
            }
          } else {
            enemys[i].x -= enemys[i].xstep;
          }
        [...]

请注意我如何移动您的 enemys[i].x -=enemys[i].xstep;enemys[i].x +=enemys[i].xstep ; 行插入限制检查的 else 条件。

我相信您的问题是,即使在您达到 x 限制并打算仅增加 y 的回合中,您也会增加 enemy[i].x ,从而导致略有增加每次迭代 X,但仅限于最后一个敌人; 敌人[6]

希望有帮助。

关于javascript - 当我使用 canvas 和 requestAnimationFrame 对图像数组进行动画处理时出现位置问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57549790/

相关文章:

javascript - 滚动事件 : requestAnimationFrame VS requestIdleCallback VS passive event listeners

javascript - 如何用requestAnimationFrame控制fps?

javascript - 无法在 'requestAnimationFrame' : The callback provided as parameter 1 is not a function. 上执行 'Window'

javascript - TextureLoader 中的 onLoad 不起作用?

javascript - jQuery 函数显示带有显示 : none 的 div

javascript - HTML5/Canvas onDrop 事件没有触发?

javascript - 相机旋转后的 WebGL 平移(作为 FPS)

javascript - phonegap ios 和 android 中的多线程问题

javascript - 访问 socket.io 回调函数外部的变量

javascript - 如何停止 easljs 中的事件气泡?