Continuously drawing rectangles in JavaScript canvas slows the program after a few seconds

2442 views javascript
-5

Right now I'm trying to make a simple 2D platformer in JavaScript canvas. This is what I have so far:

<!DOCTYPE html>
<html>
<body>

<style>

canvas{
  background: #eee;
}

</style>

<canvas id="ctx" tabindex=0 width=900 height=500  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>

The program runs just fine up until right around the 20sec mark, then it starts to run slower and slower until it just barely moves the player anymore.

I've tried every possible solution I've found online, but nothing seems to work. Any help is appreciated!

answered question

1 Answer

4

Instead of using window.interval to redraw the frames, use window.requestAnimationFrame. There is an example there how to use it.

What you're doing is trying to redraw the frames every 1/1000 of second, which is way too fast anyway.

What window.requestAnimationFrame does is it smartly requests new frames to redraw as needed, in order to maintain a smooth animation.

posted this

Have an answer?

JD

Please login first before posting an answer.