Непрерывное рисование прямоугольников на холсте JavaScript замедляет работу программы через несколько секунд - PullRequest
0 голосов
/ 09 ноября 2018

Прямо сейчас я пытаюсь сделать простой 2D-платформер на холсте JavaScript. Это то, что я до сих пор:

<!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 голосов
/ 09 ноября 2018

Вместо использования window.interval для перерисовки кадров, используйте window.requestAnimationFrame. Там есть пример, как его использовать.

То, что вы делаете, пытается перерисовывать кадры каждые 1/1000 секунды, что в любом случае слишком быстро.

Что делает window.requestAnimationFrame, так это то, что он умно запрашивает новые кадры для перерисовки по мере необходимости, чтобы поддерживать плавную анимацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...