Javascript HTML 5画布元素在.setInterval方法中未正确设置动画

Javascript HTML 5画布元素在.setInterval方法中未正确设置动画,javascript,css,html,html5-canvas,Javascript,Css,Html,Html5 Canvas,代码将使用其中一个“框”渲染动画,但在setInterval方法中绘制两个“框”时,其行为非常奇怪。我怀疑这可能与ctx.clearRect有关 我已尝试将第二个框放置在它自己的.setInterval.中。由于未正确调整其宽度,动画渲染不正确 非常感谢您的帮助。我修复了您的问题,并重构了一些代码: 主要问题是使用clearRect方法清除画布。您没有指定正确的参数值 有些代码非常重复。现在这不是一个真正的问题,因为你只使用了两个外星人,但是一旦你有两个以上的外星人,这可能会成为一个问题。想

代码将使用其中一个“框”渲染动画,但在
setInterval
方法中绘制两个“框”时,其行为非常奇怪。我怀疑这可能与
ctx.clearRect
有关

我已尝试将第二个框放置在它自己的
.setInterval.
中。由于未正确调整其宽度,动画渲染不正确


非常感谢您的帮助。

我修复了您的问题,并重构了一些代码:

  • 主要问题是使用
    clearRect
    方法清除画布。您没有指定正确的参数值
  • 有些代码非常重复。现在这不是一个真正的问题,因为你只使用了两个外星人,但是一旦你有两个以上的外星人,这可能会成为一个问题。想象一下为40个外星人编写几乎相同的代码。这可以通过数组和
    for
    -循环来解决。此外,还可以使用布尔变量来确定何时从alienX中添加/减去。这也可能成为一个相当麻烦的问题。现在,我们检查宇宙飞船何时超过/低于允许的x值,并相应地改变你的速度符号
  • 正如上面评论中提到的,您可以将其用于动画,这比
    setInterval
    更适合此项目。为了保持起伏的动画效果,我使用了一个非常基本的计数器,使用
    %
    操作符在一秒钟内仅每4x执行一次代码(通常,reqAnimFrame每秒回调60x,因此60/15=4,在您的示例中等于250ms)(见下文)
代码:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var aliens = [];
var counter = 0;

function alien() {

  if (canvas.getContext) {

    function Spaceships(x) {
      this.baseX = x; // added a baseX to remember where the spaceship started off
      this.x = x;
      this.y = 100;
      this.velocityX = 10;
      this.color = "rgb(192, 192, 192)";

      this.draw = function() {
        ctx.beginPath();
        ctx.rect(this.x, this.y, 100, 100);
        ctx.closePath();
        ctx.fillStyle = this.color;
        ctx.fill();
      }
    }

    aliens.push(new Spaceships(100), new Spaceships(500));
    drawAllAliens();

    function redraw() {

      requestAnimationFrame(redraw);

      var maxXDiff = 100; //choose how far or near your aliens/squares can go
      counter ++;

      // remainder/modulo operator: 
      // reduce animation to every 4x per sec for that "choppy" animation
      if(counter%15 === 0){
        for (var i = 0; i < aliens.length; i ++) {
          if ( ( (aliens[i].baseX + maxXDiff) < aliens[i].x ) || (aliens[i].baseX > aliens[i].x) ) {
            aliens[i].velocityX = -aliens[i].velocityX; // switches the sign
          }
          aliens[i].x += aliens[i].velocityX;
        }
      }

      drawAllAliens();
    }

    redraw();

    function drawAllAliens() {
      ctx.clearRect(0,0,canvas.width,canvas.height);

      for (var i = 0; i < aliens.length; i++) {
        aliens[i].draw();
      }
    }

  } else {
    alert("you need a better browser to play this game");
  }
}

alien();
var canvas=document.getElementById(“myCanvas”);
var ctx=canvas.getContext(“2d”);
var=[];
var计数器=0;
函数异形(){
if(canvas.getContext){
功能宇宙飞船(x){
this.baseX=x;//添加了一个baseX以记住宇宙飞船从哪里出发
这个.x=x;
这个y=100;
这是1.velocityX=10;
this.color=“rgb(192192192)”;
this.draw=函数(){
ctx.beginPath();
ctx.rect(this.x,this.y,100100);
ctx.closePath();
ctx.fillStyle=this.color;
ctx.fill();
}
}
外星人。推(新宇宙飞船(100),新宇宙飞船(500));
drawAllAliens();
函数重画(){
请求动画帧(重画);
var maxXDiff=100;//选择外星人/方格可以走多远或多远
计数器++;
//余数/模运算符:
//对于“起伏”动画,将动画减少到每秒4倍
如果(计数器%15==0){
for(变量i=0;i<0.length;i++){
if(((异形[i].baseX+maxdiff)<异形[i].x)| |(异形[i].baseX>异形[i].x)){
外星人[i].velocityX=-异形[i].velocityX;//切换符号
}
外星人[i].x+=外星人[i].velocityX;
}
}
drawAllAliens();
}
重画();
函数drawAllAliens(){
clearRect(0,0,canvas.width,canvas.height);
for(变量i=0;i<0.length;i++){
外星人[i].draw();
}
}
}否则{
提醒(“你需要一个更好的浏览器来玩这个游戏”);
}
}
外国人();

首先,所有对
ctx.clearRect(0,0,0,0)的调用将不产生任何结果(您正在请求清除画布的0宽×0高矩形)。最后,
setInterval
不是一个稳定的定时函数。它只是告诉浏览器在执行回调之前至少要等待250毫秒。对于动画,最好使用与屏幕刷新率同步的
requestAnimationFrame
。嘿,谢谢你的快速回复。你是对的。clearRect()中没有正确的参数。然而,我试图保持“起伏”的动画,试图模仿太空入侵者中的外星人。如果你注意到的话,左边的正方形不会相应地调整宽度。我不记得入侵者的船只是这样成长的。你不想每帧清除一次整个画面吗?噢,哇。我知道你在那里做了什么。我不会想到的。非常感谢。请注意,requestAnimationFrame(rAF)在第一个参数时间调用回调。时间是高精度时间(1/1000000),单位为毫秒(1/1000)(与performance.now()返回值相同)页面加载后的时间是毫秒。由于rAF将等待完整的1/60帧,如果它错过了一帧,那么您最好使用时间来设置帧速率(也有传闻称,rFA在某些机器上可以以120fps或更高的速度运行)
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var aliens = [];
var counter = 0;

function alien() {

  if (canvas.getContext) {

    function Spaceships(x) {
      this.baseX = x; // added a baseX to remember where the spaceship started off
      this.x = x;
      this.y = 100;
      this.velocityX = 10;
      this.color = "rgb(192, 192, 192)";

      this.draw = function() {
        ctx.beginPath();
        ctx.rect(this.x, this.y, 100, 100);
        ctx.closePath();
        ctx.fillStyle = this.color;
        ctx.fill();
      }
    }

    aliens.push(new Spaceships(100), new Spaceships(500));
    drawAllAliens();

    function redraw() {

      requestAnimationFrame(redraw);

      var maxXDiff = 100; //choose how far or near your aliens/squares can go
      counter ++;

      // remainder/modulo operator: 
      // reduce animation to every 4x per sec for that "choppy" animation
      if(counter%15 === 0){
        for (var i = 0; i < aliens.length; i ++) {
          if ( ( (aliens[i].baseX + maxXDiff) < aliens[i].x ) || (aliens[i].baseX > aliens[i].x) ) {
            aliens[i].velocityX = -aliens[i].velocityX; // switches the sign
          }
          aliens[i].x += aliens[i].velocityX;
        }
      }

      drawAllAliens();
    }

    redraw();

    function drawAllAliens() {
      ctx.clearRect(0,0,canvas.width,canvas.height);

      for (var i = 0; i < aliens.length; i++) {
        aliens[i].draw();
      }
    }

  } else {
    alert("you need a better browser to play this game");
  }
}

alien();