Javascript 使用canvas和requestAnimationFrame设置图像数组动画时的位置问题

Javascript 使用canvas和requestAnimationFrame设置图像数组动画时的位置问题,javascript,html5-canvas,requestanimationframe,Javascript,Html5 Canvas,Requestanimationframe,我正在做一个射击游戏和动画七个敌人的形象。 你可以看到彼此之间的距离非常好,只有10px。但是动画完成后,最左侧的敌人图像变得更远,比10px高 <canvas id="canvas" width="700" height="600" style="border: 1px solid #333" ></canvas> <script> let canvas = docume

我正在做一个射击游戏和动画七个敌人的形象。

你可以看到彼此之间的距离非常好,只有10px。但是动画完成后,最左侧的敌人图像变得更远,比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>
我尝试了很多方法,发现问题出在更新方法上 对于(设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>

让canvas=document.querySelector(“canvas”);
设c=canvas.getContext(“2d”);
c、 fillRect(30470640100);
让敌人=[];
设limitObj={
enemyLimitDown:470,
enemyLimitLeft:30,
enemyLimitRight:670,
enemyLimitTop:30
};
阶级敌人{
构造器(x){
(这个.x=x),
(此.y=30),
(此宽度=50),
(该高度=50),
(this.xstep=2),
(this.ystep=50),
(this.direction=“right”),
敌人推(这个);
}
抽签(敌人){
for(设i=0;i=0;i--){
如果(敌人[i]。方向==“右”){
enemys[i].x+=enemys[i].xstep;
设max=0;
max=findMax();
if(max==limitObj.enemyLimitRight-enemys[i].width){
对于(设i=num-1;i>=0;i--){
敌人[i].y+=this.ystep;
敌人[i].direction=“left”;
}
}
}否则{
敌人[i].x-=敌人[i].xstep;
设min=findMin();
if(min==limitObj.enemyLimitLeft){
对于(设i=num-1;i>=0;i--){
敌人[i].y+=this.ystep;
敌人[i].direction=“right”;
}
}
}
}
}
制作动画(敌人){
更新(敌人);
这个.clear();
这个。画(敌人);
让canRequest=requestAnimationFrame(()=>{
使(敌人)活跃起来;
});
for(设i=0;i=limitObj.enemyLimitDown){
取消动画帧(canRequest);
}
}
}
}
函数findMax(){
设max=0;
for(设i=0;i{
c、 drawImage(图像敌人,x,30,50,50);
});
}
让敌人开始=10;
灌肠宽度=50;
设num=7;
for(设i=0;i
错误的结果,最后一个图像离得很远。 欢迎来到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
敌人[i].x+=敌人[i].xstep行进入限额检查的else条件

我相信你的问题是你一直在增加敌人[I].x
,即使是在你达到x限制并打算只增加y的回合中,每次迭代都会导致x的略微增加,但只针对最后一个敌人<代码>敌人[6]


希望能有所帮助。

非常感谢您的回答,它很有效。之后,我得出结论,当我们需要检查和移动时,我们应该首先进行检查,这是我在这个错误中坚持了整整3天之后的编码经验总结。@Abdullaabababakre现在不要停止,你仍然需要构建游戏的其余部分:-Dhello Graham P health,我很麻烦。对不起。你能回答我关于这个项目的新问题吗。