2015-10-20 3 views
-4

Похоже, что есть другие вопросы, подобные этому, и я бы хотел избежать буфера и/или requestAnimationFrame().Javascript canvas мерцающий

В недавнем проекте игрок мерцает, но я не могу узнать причину. Вы можете найти проект на 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); 
} 
+0

В JavaScript нет 'const'. – klenium

+0

Взгляните на Mozilla-разработчик https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/const? – user2531284

+0

@ пользователь2531284 То есть es6. Не реализовано в каждом браузере, а также большое предупреждение сверху ... – Michelangelo

ответ

0

Каждый раз, когда вы пишете в видимой части холста браузера хотят, чтобы обновить экран. Процедуры рисования могут быть не синхронизированы с обновлением отображения браузеров. Функция requestAnimationFrame позволяет запускать все ваши процедуры рисования до того, как дисплей обновится. Ваш другой друг использует невидимый буферный холст. Нарисуйте все на холст буфера, а затем нарисуйте буфер на видимый холст. Функция gameEngine должна выполняться только один раз за кадр, и если она выполняется несколько раз, вы можете видеть мерцание. Попробуйте выполнить следующие действия для очистки нескольких прогонов в одном и том же фрейме.

(изменить): Вы также можете очистить холст вместо установки ширины.

(edit2): Вы можете комбинировать clearRect, rect и fill с одной командой 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); 
}