0

我正在尝试使用 Vanilla JS 中的 Web 组件编写一个简单的游戏。但是,在重绘画布元素时我遇到了一些麻烦。第一次调用总是很好,它像我想要的那样画了一个圆圈,但是当调用 requestAnimationFrame(draw) 时,所有属性都变得未定义。为什么会这样,我该如何解决这个问题?这是我的代码

class GamePanel extends HTMLElement{
    constructor() {
        super();
        this.shadow = this.attachShadow({ mode: "open" });
        this.rightPressed = false;
        this.leftPressed = false;
        this.upPressed = false;
        this.downPressed = false;
        this.canvas = document.createElement("canvas");
        this.canvas.width = 1000;
        this.canvas.height = 500;
        this.canvas.style.backgroundColor = "black";
        this.shadow.appendChild(this.canvas);
        this.ctx = this.canvas.getContext("2d");
        this.x = this.canvas.width/2;
        this.y = this.canvas.height-30;
        this.dx = 2;
        this.dy = 2;
        this.ballRadius = 10;
        this.addEventListener("keydown", this.keyDownHandler, false);
      }
      draw(){
        console.log(this.ctx);
        console.log(this.x);
        console.log(this.y);
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.drawBall();
        if(this.rightPressed){
            this.x += this.dx;
        }
        else if(this.leftPressed){
            this.x -=this.dx;
        }
        if(this.downPressed){
            this.y+= this.dy;
        }
        else if(this.upPressed){
            this.y-=this.dy
        }
        if(this.x+this.dx > this.canvas.width + this.ballRadius) this.x = 0;
        else if(this.x - this.dx < 0 - this.ballRadius) this.x = this.canvas.width
        if(this.y+this.dy > this.canvas.height + this.ballRadius) this.y = 0;
        else if(this.y - this.dy < 0 - this.ballRadius) this.y = this.canvas.height;
        requestAnimationFrame(this.draw);
    }
    drawBall(){
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, this.ballRadius, 0, Math.PI*2);
        this.ctx.fillStyle = "#0095DD";
        this.ctx.fill();
        this.ctx.closePath();
    }
    keyDownHandler(e){
        if(e.key == "Right" || e.key == "ArrowRight") {
            this.rightPressed = true;
            this.leftPressed = false;
        }
        else if(e.key == "Left" || e.key == "ArrowLeft") {
            this.leftPressed = true;
            this.rightPressed = false;
        }
        if(e.key == "Up" || e.key == "ArrowUp"){
            this.upPressed = true;
            this.downPressed = false;
        }
        else if(e.key =="Down" || e.key == "ArrowDown"){
            this.downPressed = true;
            this.upPressed = false;
        }
    }
}

customElements.define("game-panel", GamePanel);
document.getElementsByTagName("game-panel")[0].draw();

我得到的错误是: Uncaught TypeError: Cannot read property 'ctx' of undefined at draw (script.js:24)

4

1 回答 1

0

您需要绑定thisdraw

requestAnimationFrame(this.draw.bind(this));

或者,您可以定义draw为箭头函数,这意味着this永远是GamePanel

draw = () => {
  ...
  requestAnimationFrame(this.draw);
};
于 2020-08-30T21:18:54.367 回答