为什么精灵角色更新位置会导致拖尾?

Why is sprite character update position causing a trail?

当点击输入以重新渲染和移动精灵时,这会导致精灵在屏幕上排序 trail/smear。

我试过 clearRect() 但这似乎没有任何区别。我也以此为灵感 https://github.com/jlongster/canvas-game-bootstrap 但我不太明白 canvas 是如何被覆盖的

我正在使用与 https://github.com/jlongster/canvas-game-bootstrap 非常相似的渲染实体方法,但这仍然不是玩球。

ctx.save();
ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
entity.settings.sprite.render( ctx );
ctx.restore();

这是我的index.js

(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;

    var playerSpeed = 200;

    resources.load([
        "images/rsprites_iddle/trump_iddle.png",
        "images/rsprites_run/trump_run.png"
    ]);

    function init() {
        loop();
    }

    resources.onReady( init );

    var previousCoords = {
        x: 0,
        y: 0,
    };

    window.previousCoords = previousCoords;

    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d'),
        width = window.innerWidth,
        height = window.innerHeight,
        keys = [],
        friction = 0.8,
        gravity = 0.4,
        boxes = [],
        powerup = [];

        var playerCharacter = new Player({
            direction: 'forward',
            pos: [0, 0],
            sprite: new Sprite( "images/rsprites_iddle/trump_iddle.png", [0, 0], [ 256, 256 ], 14, [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], 'horizontal' ),
            x: width / 2,
            y: height - 256,
            width: 256,
            height: 256,
            speed: 3,
            velX: 0,
            velY: 0,
            jumping: false,
            grounded: true,
        });

        window.playerCharacter = playerCharacter;

        canvas.width = width;
        canvas.height = height;


    function update( dt ) {

        handleInput(dt);
        updateEntities( dt )

        draw();
    }

    function draw(){
        renderEntity( playerCharacter );
    }

    // draw();
    var lastTime = 0;
    function loop(timestamp) {
        var now = Date.now();
        var dt = (now - lastTime) / 1000.0;
        var progress = timestamp - lastRender;

        update(dt);
        lastRender = timestamp;
        lastTime = now;
        window.requestAnimationFrame(loop);
    }

    document.body.addEventListener("keydown", function(e) {
        keys[e.keyCode] = true;
    }); 

    document.body.addEventListener("keyup", function(e) {
        keys[e.keyCode] = false;
    });


    function renderEntity( entity ) {
        ctx.save();
        ctx.clearRect( previousCoords.x, previousCoords.y, playerCharacter.settings.width, playerCharacter.settings.height );
        ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
        entity.settings.sprite.render( ctx );
        ctx.restore();
    }

    function updateEntities( dt ) {
        playerCharacter.settings.sprite.update( dt );
    }

    function handleInput( dt ) {
        if( input.isDown( 'LEFT' ) || input.isDown( 'a' ) ) {
            playerCharacter.settings.pos[0] += playerSpeed * dt;
            playerCharacter.settings.direction = "LEFT";
        }

        if( input.isDown( 'RIGHT' ) || input.isDown( 'd' ) ) {
            playerCharacter.settings.pos[0] -= playerSpeed * dt;
            playerCharacter.settings.direction = "RIGHT";
        }

        previousCoords.x = playerCharacter.settings.pos[0];
        previousCoords.y = playerCharacter.settings.pos[1];
    }

    var lastRender = 0;

})();

sprite.js

(function() {
    function Sprite( url, pos, size, speed, frames, dir, once ) {
        this.pos = pos;
        this.size = size;
        this.speed = typeof speed === 'number' ? speed : 0;
        this.frames = frames;
        this._index = 0;
        this.url =  url;
        this.dir = dir || 'horizontal';
        this.once = once;
    } 

    Sprite.prototype = {
        update: function( dt ) {
            this._index += this.speed * dt;
        },
        render: function( ctx ) {
            var frame;

            if( this.speed > 0 ) {
                var max = this.frames.length;
                var idx = Math.floor( this._index );
                frame = this.frames[ idx % max ];

                if( this.once && idx >= max ) {
                    this.done = true;
                    return;
                }
            } 
            else {
                frame = 0;
            }

            var x = this.pos[0];
            var y = this.pos[1];


            if( this.dir == 'vertical' ) {
                y += frame * this.size[1];
            }
            else {
                x += frame * this.size[0];
            }

            if( playerCharacter.settings.direction !== "forward" ) {
                if( playerCharacter.settings.direction == "LEFT" ) {
                    x = this.size[0];
                }
                else if( playerCharacter.settings.direction == "RIGHT" ) {
                    x = this.size[0] * 2;
                }
                else {
                    x = 0;
                }

            }

            ctx.drawImage( resources.get( this.url ), 256, y, this.size[0], this.size[1], window.innerWidth / 2 - ( this.size[ 0 ] / 2 ), window.innerHeight - this.size[0], this.size[0], this.size[1] );
        }
    };

    window.Sprite = Sprite;
})();

我希望 sprite 更新位置并重新绘制到 canvas,那里没有工件或以前的 sprite。

Canvas 是一个像素缓冲区,您需要清除它并在每一帧重新绘制动画内容。在主渲染循环开始时使用 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)

正如blindman67的评论所指出的