Canvas-игра не работает, как исключено на низких FPS - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь создать холст для развлечения и обучения, но мой код работает не так, как я хочу.

У меня есть персонаж в игре, который ходит вправо / влево / вверх / вниз, и каждое движение добавляет пиксель к изображению и создает анимацию. Это означает, что если персонаж находится на 20px, 40px экрана и вы двигаетесь вправо, это будет 40px, 40px.

Мой код выглядит так:

start() {
    this.deltaTime();
    this.ctx.clearRect(0, 0, this.gameWindow.width, this.canvas.height);
    this.map.drawMap();
    this.player.drawPlayer();
    this.text.drawText('Coordinates X:'+this.player.position.x+', Y:'+this.player.position.y, 5, 5);
    this.text.drawText('FPS: '+this.graphic.lastfps, 5, 17);
    this.text.drawText('ms: '+this.graphic.lastDelta, 5, 29);
    this.text.drawText('delta: '+this.graphic.delta, 5, 41);
    this.text.drawText('Running time: '+this.runningTime, 5, 53);
    this.text.drawTextList();
}
deltaTime() {
    // Calc FPS
    let fps, delta;
    let performanceUse = performance.now();
    fps = delta = Math.floor(performanceUse / 1000);
    if(this.graphic.lastTimeFPSDate !== fps) {
        this.graphic.lastTimeFPSDate = fps;
        this.graphic.lastfps = this.graphic.fps;
        this.graphic.fps = 1;
        this.runningTime++;
    }
    else
        this.graphic.fps++;
    // Calc Delta
    this.graphic.delta = performanceUse - this.graphic.lastTimeDeltaCall;
    this.graphic.lastTimeDeltaCall = performanceUse;
    if(this.graphic.lastTimeDeltaDate !== delta) {
        this.graphic.lastTimeDeltaDate = delta;
        this.graphic.lastDelta = Math.floor(this.graphic.delta);
    }
}
animationMove(to) {
    let target;                                                                                             
    let animationSpeed = (this.running) ? this.engine.gameSpeed.runSpeed : this.engine.gameSpeed.walkSpeed; 
    let distanceBettwenSquares = this.engine.mapSettings.pxPerSquare;                                       
    let seconds = 1000;                                                                                   
    let everyStepAnimation = Math.ceil((60 / this.engine.graphic.lastfps));                               
    let runLoopForAnimationEveryXMS = Math.floor(seconds / distanceBettwenSquares);                     
    let stopLoop = false;
    let sign = null;
    //console.clear();
    console.log('runLoopForAnimationEveryXMS: '+runLoopForAnimationEveryXMS+', everyStepAnimation: '+everyStepAnimation);
    console.log('FPS: '+this.engine.graphic.lastfps+', deltaTime: '+this.engine.graphic.lastDelta);
    console.log('REAL FPS: '+this.engine.graphic.fps+', REAL deltaTime: '+this.engine.graphic.delta);
    // - - - - - - - - - -
    this.engine.animationLoop(true, 0, runLoopForAnimationEveryXMS, (id) => {
        // Stop the animation if it is 0 or bigger than the distance that require or stopLoop is true (which mean the numbers get over fed)
        if (this.playerAnimation[target] === 0 || Math.abs(this.playerAnimation[target]) > distanceBettwenSquares || stopLoop) {
            this.engine.animationLoop.kill(id);
            this.playerAnimation.walk = false;
            this.playerAnimation.needAnimation = true;
            this.playerAnimation[target] = 0;
            return;
        }
        // Do each step of the animation
        sign = Math.sign(this.playerAnimation[target]);                                                        
        this.playerAnimation[target] = sign * (Math.abs(this.playerAnimation[target]) - everyStepAnimation);  
        if (Math.sign(this.playerAnimation[target]) !== sign)                                                  
            stopLoop = true;                                                                                
    });
}
function game() {
    start();
    window.requestAnimationFrame(game);
}
window.requestAnimationFrame(game);

При нажатии на клавишу сначала выполняется анимация (перемещение изображения на несколько пикселей каждый шаг), а затем обновляются переменные для текущей позиции.

Вот проблема: Иногда анимация идет медленно, даже «прыгает». Без реальных изменений FPS (1-2 + -).

Итак, мои вопросы:

  1. Во-первых, я правильно сделал расчет FPS и дельта? (Я не ошибся?)
  2. Как видите, я использовал в main для рисования деталей, а в setInterval для изменения деталей (чтобы изменения никогда не замедляли код), вот как это должно быть сделано?
  3. В моем коде я полагаю, что 60FPS является лучшим и основан на этом для каждого шага, Я не хочу предполагать, что, возможно, в будущем FPS будет еще выше, Так как же мне сделать, чтобы расчет за один ход (квадрат 20 пикселей) занял одну секунду?
  4. Иногда код работает медленно, а иногда быстрее, почему?
  5. Как мне использовать здесь в дельта-время?
  6. В первую секунду игры все идет на максимальной скорости, потому что FPS по-прежнему равен нулю. Как я могу это исправить?

Спасибо и извините за мой английский, даже ответ на один ответ поможет!

...