我试图将一个简单的矩形从当前位置移动到画布上的单击位置。当我提供恒定的速度时,矩形会出现并可以正常移动。但是,当我将其乘以deltatime时,矩形不再显示。我使用requestAnimationFrame作为绘制循环。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
但是,如果我选择不使用step并将其恒定速度设为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);
}
打印现在也准确了。为什么逐步乘以deltatime会阻止矩形移动?甚至出现?
如果有人感兴趣,这里是HTML。
index.html
<html>
<head>
<script src="canvas.js"></script>
</head>
<body>
<canvas id="gamecanvas" width="2000" height="1000"></canvas>
</body>
</html>
最佳答案
您应该从requestAnimationFrame
开始动画,而不是像间接那样从头开始。
更换
requestAnimationFrame(function(){
蜱();
});
与
requestAnimationFrame(tick)
然后在功能刻度中,检查是否已设置
oldframetime
,如果未设置deltaTime
则将其设置为0,因为没有时间过去,因此从头开始动画。如果将deltaTime
的值设置为任何其他值,最终将不会从头开始渲染动画。function tick(timestamp){
if (!oldframetime) {
deltaTime = 0;
} else {
deltatime = (timestamp - oldframetime)/1000;
}
// .. animation code
oldframetime = timestamp;
requestAnimationFrame(tick);
}