为啥精灵角色更新位置会导致轨迹?

Posted

技术标签:

【中文标题】为啥精灵角色更新位置会导致轨迹?【英文标题】:Why is sprite character update position causing a trail?为什么精灵角色更新位置会导致轨迹? 【发布时间】:2019-08-15 16:29:18 【问题描述】:

当点击输入以重新渲染和移动精灵时,这会导致精灵在屏幕上出现某种拖尾/拖尾。

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

我正在使用与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;
)();

我希望精灵更新位置并重绘到画布,没有工件或以前的精灵。

【问题讨论】:

Canvas 是一个像素缓冲区,您需要清除它并在每帧重绘动画内容。在主渲染循环开始时使用ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height) 请将其作为答案,这样我就可以为您应得的解决方案归功于您:) 【参考方案1】:

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

正如blindman67 的评论所指出的

【讨论】:

以上是关于为啥精灵角色更新位置会导致轨迹?的主要内容,如果未能解决你的问题,请参考以下文章

从 GPS 读数更新折线轨迹的更好方法

cocos2dx:CCOrbitCamera 实现精灵的球面翻转或类似翻书操作,以及翻转轨迹优化问题

为啥我的python用pygame做图片移动会留下轨迹?

ORBSLAM回环检测之几何验证

轨迹数据之数据清洗以及异常检测

在物流行业地图开发中,如何实现车辆轨迹回放?