Javascript canvas 使用 clarrect() 后 drawimage() 不起作用

Javascript canvas drawimage() doesn't work after using clearrect()

我尝试使用以下代码制作动画:

var obst = new Obstacle(x, y)
obst.build()
function animate() {
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    requestAnimationFrame(animate);
    obst.update(-1, 0)
    player1.build();
}

但是obst var没有出现(但是player1出现了)

class 对象:

class Obstacle {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    build() {
        var img = new Image();
        img.src = 'assests/obst.png';
        img.onload = () => {
            ctx.drawImage(img, this.x, this.y, 60, 60);
        }
    }

    update(x, y) {
        this.x += x;
        this.y += y;
        this.build()
    }
}

当我 运行 没有 clearrect() 语法的代码时,它会按应有的方式显示。

完整代码:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    obst.update(-1, 0)
    player1.build();
}

class Player {
    constructor(x, y, radius, color) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.color = color;
    }

    build() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color;
        ctx.fill();
    }

    update(x, y) {
        this.x += x
        this.y += y
        this.build()
    }
}

class Obstacle {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    build() {
        var img = new Image();
        img.src = 'assests/obst.png';
        img.onload = () => {
            ctx.drawImage(img, this.x, this.y, 60, 60);
        }
    }

    update(x, y) {
        this.x += x;
        this.y += y;
        this.build()
    }
}

var obst = new Obstacle(canvas.width, canvas.height / 2 - 30)
obst.build()

var player1 = new Player(canvas.width / 2, canvas.height / 2, 30, 'blue');
player1.build();

animate();


加载图像的异步任务应该从更新循环中移除。让对象遵循一种模式,其中构建和更新/绘图是独立的,并且构建是异步的并且只发生一次...

class Obstacle {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    // don't use the object until this promise resolves
    async build() {
        var img = new Image();
        img.src = 'assests/obst.png';
        return new Promise(resolve => img.onload = resolve)
    }

    // call the method that draws current state "draw"
    draw() {
      ctx.drawImage(img, this.x, this.y, 60, 60);
    }

    // call the method that updates current state and draws "update"
    update(x, y) {
        this.x += x;
        this.y += y;
        this.draw()
    }
}


class Player {
    constructor(x, y, radius, color) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.color = color;
    }

    // for symmetry, and maybe someday player will need to do async work here
    async build() {
      return Promise.resolve();
    }

    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
        ctx.fillStyle = this.color;
        ctx.fill();
    }

    update(x, y) {
        this.x += x
        this.y += y
        this.draw()
    }
}

function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    obst.update(-1, 0)
    player1.update(0, 1);
}

async function play() {
    const obst = new Obstacle(canvas.width, canvas.height / 2 - 30)
    await obst.build();

    const player1 = new Player(canvas.width / 2, canvas.height / 2, 30, 'blue');
    await player1.build();  

    animate();
}

play()