Перемещение прямоугольника к месту с использованием deltatime - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь, чтобы простой прямоугольник переместился из текущего местоположения в местоположение щелчка на холсте. Когда я предоставляю постоянную скорость, прямоугольник появляется и движется нормально. Но когда я умножаю его на deltatime, прямоугольник больше не появляется. Я использую requestAnimationFrame для рисования l oop.

canvas.js

window.addEventListener('DOMContentLoaded', (event) => {
    let canvas = document.getElementById("gamecanvas");
    let ctx = canvas.getContext('2d');
    var oldframetime = 0;
    var x = 0;
    var y = 0;
    var dstx = 0;
    var dsty = 0;
    var deltatime = 0;
    var speed = 5;
    function getmousepos(evt){
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
    }
    canvas.addEventListener("mousedown",e=>{
        let coord = getmousepos(e);
        dstx = coord.x;
        dsty = coord.y;
    });
    function movetowards(current,target,maxdistancedelta){
        if(Math.abs(target - current)<=maxdistancedelta){
            return target;
        }
        return current+Math.sign(target - current) * maxdistancedelta;
    }
    function tick(timestamp){
        deltatime = (timestamp - oldframetime)/1000;   

        var step = deltatime*speed;
        var newlocx = movetowards(x,dstx-50,5);
        var newlocy = movetowards(y,dsty-50,5);

        ctx.clearRect(0,0,canvas.clientWidth,canvas.clientHeight);
        ctx.fillStyle = 'green';
        ctx.fillRect(newlocx,newlocy,100,100);

        x = newlocx;
        y = newlocy;
        console.log(newlocx+":"+newlocy);
        oldframetime = timestamp;
        requestAnimationFrame(tick);
    }
    requestAnimationFrame(function(){
        tick();
    });
});

В этом примере newlocx и newlocy выводят NaN: NaN. Но если я решу не использовать шаг и дать ему постоянную скорость, равную 5, то отлично работает.

    function tick(timestamp){
        deltatime = (timestamp - oldframetime)/1000;   

        var step = deltatime*speed;
        var newlocx = movetowards(x,dstx-50,5);
        var newlocy = movetowards(y,dsty-50,5);

        ctx.clearRect(0,0,canvas.clientWidth,canvas.clientHeight);
        ctx.fillStyle = 'green';
        ctx.fillRect(newlocx,newlocy,100,100);

        x = newlocx;
        y = newlocy;
        console.log(newlocx+":"+newlocy);
        oldframetime = timestamp;
        requestAnimationFrame(tick);
    }

Печать теперь тоже точная. Почему умножение step на deltatime предотвращает перемещение прямоугольника? Или даже появляется?

Вот HTML, если кому-то интересно.

index.html

<html>
    <head>
        <script src="canvas.js"></script>
    </head>
    <body>
        <canvas id="gamecanvas" width="2000" height="1000"></canvas>
    </body>
</html>

Ответы [ 2 ]

2 голосов
/ 17 февраля 2020

Я проверил и обнаружил, что проблема в первом утверждении функции тика. При запуске программы значение параметра не определено. И именно поэтому первое утверждение функции тика приводит к NaN.

Просто используйте некоторое значение по умолчанию для параметра "timestamp". Сейчас он работает, но скорость низкая, и я надеюсь, что вы знаете об этом.

Строка для проверки: отметка функции (timestamp = 10)

function tick(timestamp=10) {
  deltatime = (timestamp - oldframetime) / 1000;

  var step = deltatime * speed;
  var newlocx = movetowards(x, dstx - 50, 5);
  var newlocy = movetowards(y, dsty - 50, 5);

  ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
  ctx.fillStyle = 'green';
  ctx.fillRect(newlocx, newlocy, 100, 100);

  x = newlocx;
  y = newlocy;
  console.log(newlocx + ":" + newlocy);
  oldframetime = timestamp;
  requestAnimationFrame(tick);
}
1 голос
/ 17 февраля 2020

Вы должны начать анимацию с requestAnimationFrame, а не косвенно, как вы это сделали.

Заменить

requestAnimationFrame (function () {tick ();});

с

requestAnimationFrame(tick)

Затем в тике функции вы проверяете, установлено ли oldframetime, если не установлено deltaTime в 0, так как время не прошло, и таким образом запускает анимацию в начале. Если вы установите значение deltaTime на любое другое значение, то в конечном итоге анимация не будет отображаться с самого начала.

function tick(timestamp){
    if (!oldframetime) { 
       deltaTime = 0;
    } else { 
       deltatime = (timestamp - oldframetime)/1000;  
    }

    // .. animation code

    oldframetime = timestamp;
    requestAnimationFrame(tick);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...