Javascript画布闪烁

时间:2015-10-20 14:52:10

标签: javascript html5 canvas

似乎还有其他问题,我希望避免使用缓冲区和/或requestAnimationFrame()。

在最近的一个项目中,玩家正在闪烁,但我找不到原因。您可以在JSFiddle上找到该项目:https://jsfiddle.net/90wjetLa/

function gameEngine() {
    timer += 1;
    timer = Math.round(timer);
    // NEWSHOOT?
    player.canShoot -= 1;
    // MOVE:
    movePlayer();
    shootEngine(); // Schussbewegung & Treffer-Abfrage

    // DRAW:
    ctx.beginPath();

    canvas.width = canvas.width;
    ctx.beginPath();

    ctx.fillStyle = 'black';
    ctx.rect(0, 0, canvas.width, canvas.height);
    ctx.fill();
    drawField();
    drawPlayer();

    drawShoots();

    setTimeout(gameEngine, 1000 / 30);
}

1 个答案:

答案 0 :(得分:2)

每次您写入可见画布时,浏览器都需要更新显示。您的绘图例程可能与浏览器显示更新不同步。 requestAnimationFrame功能允许您在显示刷新之前运行所有绘图例程。你的另一个朋友正在使用一个不可见的缓冲画布。将所有内容绘制到缓冲区画布,然后将缓冲区绘制到可见画布上。 gameEngine函数每帧只运行一次,如果它运行多次,你会看到闪烁。请尝试以下操作以清除同一帧中的多个运行。

(编辑):您可能还想清除画布而不是设置宽度。

(edit2):您可以将clearRectrectfill合并为一个命令ctx.fillRect(0, 0, canvas.width, canvas.height);

var gameEngineTimeout = null;
function gameEngine() {
    // clear pending gameEngine timeout if it exists.
    clearTimeout(gameEngineTimeout);
    timer += 1;
    timer = Math.round(timer);
    // NEWSHOOT?
    player.canShoot -= 1;
    // MOVE:
    movePlayer();
    shootEngine(); // Schussbewegung & Treffer-Abfrage

    // DRAW:
    ctx.beginPath();

    //canvas.width = canvas.width;
    //ctx.clearRect(0, 0, canvas.width, canvas.height);
    //ctx.beginPath();

    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    //ctx.fill();
    drawField();
    drawPlayer();

    drawShoots();

    gameEngineTimeout = setTimeout(gameEngine, 1000 / 30);
}