requestAnimationFrame работает только без использования классов, как я могу это исправить? - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь изучить javascript и canvas для анимации и простых игр, я написал 2 версии тестовой игры, сначала функциональное программирование, затем объекты (с babel), оба имеют одинаковый необработанный код для обновления анимации но в браузере работает только первая версия, oop, выдает ошибку:

ReferenceError: update is not defined

как мне управлять обновлением по запросу AnimationFrame?

Я пытался изменить переменную на this.update или this.update (), но результат тот же

функционал:


var c = document.getElementById("game");
var ctx = c.getContext("2d");
c.width = window.innerWidth/2;
c.height = window.innerHeight/2;
ctx.scale(20,20);
var player = {
  pos: { x:0, y:0 },
  vel: 2

};

var keys = {
  left:37, up:38, right: 39, down:40
};



function update() {
  ctx.clearRect(0, 0, c.width, c.height);
  draw();
  requestAnimationFrame(update);
}

function draw() {
  ctx.fillRect(player.pos.x, player.pos.y, 1, 1);
  //ctx.clearRect(0, 0, c.width, c.height);
}

function keyboardHandler(event) {
  switch(event.keyCode) {
      case keys.left:
        player.pos.x -= 1*player.vel;
        console.log(player.pos.x);
        break;
      case keys.up:
        player.pos.y -= 1*player.vel;
        console.log(player.pos.y);
        break;
      case keys.right:
        player.pos.x += 1*player.vel;
        console.log(player.pos.x);
        break;
      case keys.down:
        player.pos.y += 1*player.vel;
        console.log(player.pos.y);
        break;
  } // switch
} // keyboardhandler

document.addEventListener('keydown', keyboardHandler, false);
update();

объекты (Babel):


class Game {

  constructor() {
    this.c = document.getElementById("game");
    this.ctx = this.c.getContext("2d");
    this.c.width = window.innerWidth/2;
    this.c.height = window.innerHeight/2;
    this.ctx.scale(20,20);
    this.player = {
      vel: 2,
      pos: {x:0,y:0}      
    };
    this.keys = {
  left:37, up:38, right: 39, down:40
};
  } // constructor

  draw() {
    this.ctx.fillRect(this.player.pos.x, this.player.pos.y, 1, 1);
  }

  update() {
    this.ctx.clearRect(0, 0, this.c.width, this.c.height);
    this.draw();
    requestAnimationFrame(this.update);


  }
  /* keyboardHandler(event) {
    switch(event.keyCode){
      case self.keys.left:
        this.player.pos.x -= 1;
        console.log("Sinistra -> " + self.player.pos.x);
        break;
        case self.keys.up:
        self.player.pos.y -= 1;
        console.log("Su -> " + self.player.pos.y);
        break;
        case self.keys.right:
        this.player.pos.x += 1;
        console.log("Destra -> " + self.player.pos.x);
        break;
        case self.keys.down:
        this.player.pos.y += 1;
        console.log("Giù -> " + self.player.pos.y);
        break;
    } // switch
  } // keyboardHandler*/
}


// calls

let game = new Game();
game.update();
console.log(game);
document.addEventListener('keydown', (event) => {
  switch(event.keyCode){
      case game.keys.left:
        game.player.pos.x -= 1;
        console.log("Sinistra -> " + game.player.pos.x);
        break;
        case game.keys.up:
        game.player.pos.y -= 1;
        console.log("Su -> " + game.player.pos.y);
        break;
        case game.keys.right:
        game.player.pos.x += 1;
        console.log("Destra -> " + game.player.pos.x);
        break;
        case game.keys.down:
        game.player.pos.y += 1;
        console.log("Giù -> " + game.player.pos.y);
        break;
    } // switch
}, false);

1 Ответ

1 голос
/ 26 марта 2019

Вы должны либо: 1) bind свой метод this, либо 2) использовать функцию стрелки .

1-й вариант:

...
update() {
    this.ctx.clearRect(0, 0, this.c.width, this.c.height);
    this.draw();
    requestAnimationFrame(this.update.bind(this));
}

2-й вариант:

...
update = () => {
    this.ctx.clearRect(0, 0, this.c.width, this.c.height);
    this.draw();
    requestAnimationFrame(this.update);
}
...