简体   繁体   中英

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

I try to make an animation using the following code:

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

but obst var doesn't appear (but player1 appears)

class for obst:

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()
    }
}

When I run the code without clearrect() syntax it shows as it should be.

Full code:

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();


The async task of loading the image should be removed from the update loop. Have the objects follow a pattern where building and updating / drawing are independent, and where building is async and happens once...

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM