在JavaScript画布中连续绘制矩形会在几秒钟后降低程序速度

时间:2018-11-09 01:47:18

标签: javascript performance graphics html5-canvas

现在,我正在尝试在JavaScript画布中制作一个简单的2D平台游戏。这是我到目前为止的内容:

<!DOCTYPE html>
<html>
<body>

<style>

canvas{
  background: #eee;
}

</style>

<canvas id="ctx" tabindex=0 width=900 height=500 style="border:1px solid #000000;" onkeypress="movePlayer(event)" onkeyup="keyUp(event)"></canvas>

<script>
var canvas = document.getElementById("ctx");
var ctx = canvas.getContext("2d");
canvas.setAttribute('tabindex', 0);
canvas.focus();
canvas.addEventListener("keydown", movePlayer);

//Maybe I can get a class working?

function Platform(x,y,xSize,ySize){
  this.xPos = x;
  this.yPos = y;
  ctx.fillStyle = "red";
  ctx.fillRect(x,y,xSize,ySize);

  this.getX = function(){
    return this.xPos;
  };
  this.getY = function(){
    return this.yPos;
  };
  this.getxSize = function(){
    return this.xSize;
  };
  this.getySize = function(){
    return this.ySize;
  };
}

//Function arrays?
platformArray = [];

//Too many vars smh:

var x_previous = 50;
var y_previous = 50;

var x_new = 50;
var y_new = 50;

var isJumping = false;
var isColliding = false;

var right = false;
var left = false;
var up = false;
var down = false;

var speed = 5;

function movePlayer(event) {
    switch(event.keyCode){
      //Right
      case 39:
        right = true;
        break;
      //Left
      case 37:
        left = true;
        break;
      //Up
      case 38:
        isJumping = true;
        up = true;
        break;
    }
}

function keyUp(event){
  switch(event.keyCode){
    //Up key up:
    case 38:
      isJumping = false;
      up = false;
      break;
    //Right key up:
    case 39:
      right = false;
      break;
    //Left key up:
    case 37:
      left = false;
      break;
    //Down key up:
    case 40:
      down = false;
      break;
  }
}

setInterval(update,1);
setTimeout(update,1)

function boundsIntersect(x1,y1,x2,y2){
  if(x1 > x2-20 && x1 < x2+200 && y1 < y2 && y1 > y2-55){
    return true;
  }
  return false;
}

function update(){
  ctx.clearRect(0,0,900,500)
  ctx.fillStyle = "black";
  ctx.beginPath();
  ctx.fillRect(x_new,y_new,50,50);
  //Draw ground:
  ctx.beginPath();
  ctx.rect(0,490,900,10);
  ctx.fillStyle = "green";
  ctx.fill();

  if(right == true){
    x_new+=speed;
    x_previous=x_new-speed;
  } else if(left == true){
    x_new-=speed;
    x_previous=x_new-speed;
  } else if(down == true){
    y_new+=speed;
    y_previous=y_new-speed;
  } else if(up == true){
    y_new-=speed;
    y_previous=y_new-speed;
  }

  if(y_new < 440 && isJumping == false && isColliding == false){
    y_new+=5;
    y_previous=y_new-5;
  }

  //Platforms:
  platform1 = new Platform(50,300,200,10);
  platformArray.push(platform1);

  platform2 = new Platform(300,200,200,10);
  platformArray.push(platform2);

  platform3 = new Platform(400,300,200,10);
  platformArray.push(platform3);

  //Platform intersections:

  platformArray.forEach(function(platform){
    if(boundsIntersect(x_new,y_new,platform.getX(), platform.getY()) && isJumping == false){
      isColliding = true;
      y_new -= 0.5;
    } else if(boundsIntersect(x_new,y_new,platform.getX(), platform.getY()) && isJumping == true){
      isJumping = false;
      y_new += 10;
      isColliding = true;
    } else {
      isColliding = false;
    }
  });

  ctx.save();
  ctx.restore();
}

update();

</script>

</body>
</html>

程序运行良好,直到大约20秒标记,然后开始运行得越来越慢,直到几乎不再移动播放器为止。

我已经尝试了在网上找到的所有可能的解决方案,但似乎没有任何效果。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

使用window.requestAnimationFrame代替使用window.interval重画框架。有一个使用方法的示例。

您正在做的是尝试每1/1000秒重新绘制一帧,反正这太快了。

window.requestAnimationFrame的作用是根据需要巧妙地请求重新绘制新帧,以保持流畅的动画效果。