gpt4 book ai didi

javascript - HTML5 Canvas 游戏循环增量时间计算

转载 作者:搜寻专家 更新时间:2023-10-31 21:57:45 24 4
gpt4 key购买 nike

我是游戏开发新手。目前我正在为 js13kgames 做游戏比赛,所以游戏应该很小,这就是为什么我不使用任何现代流行框架的原因。

在开发我的无限游戏循环时,我找到了几篇文章和建议来实现它。现在它看起来像这样:

self.gameLoop = function () {
self.dt = 0;

var now;
var lastTime = timestamp();
var fpsmeter = new FPSMeter({decimals: 0, graph: true, theme: 'dark', left: '5px'});

function frame () {
fpsmeter.tickStart();
now = window.performance.now();

// first variant - delta is increasing..
self.dt = self.dt + Math.min(1, (now-lastTime)/1000);

// second variant - delta is stable..
self.dt = (now - lastTime)/16;
self.dt = (self.dt > 10) ? 10 : self.dt;

self.clearRect();

self.createWeapons();
self.createTargets();

self.update('weapons');
self.render('weapons');

self.update('targets');
self.render('targets');

self.ticks++;

lastTime = now;
fpsmeter.tick();
requestAnimationFrame(frame);
}

requestAnimationFrame(frame);
};

所以问题出在 self.dt 我最终发现第一个变体不适合我的游戏,因为它会永远增加并且武器的速度也会随之增加(例如this.position.x += (Math.cos(this.angle) * this.speed) * self.dt;..

第二种变体看起来更合适,但它是否对应于这种循环(http://codeincomplete.com/posts/2013/12/4/javascript_game_foundations_the_game_loop/)?

最佳答案

这是一个使用固定时间步长和可变渲染时间的 HTML5 渲染系统的实现:

http://jsbin.com/ditad/10/edit?js,output

它基于这篇文章:

http://gameprogrammingpatterns.com/game-loop.html

这是游戏循环:

    //Set the frame rate
var fps = 60,
//Get the start time
start = Date.now(),
//Set the frame duration in milliseconds
frameDuration = 1000 / fps,
//Initialize the lag offset
lag = 0;

//Start the game loop
gameLoop();

function gameLoop() {
requestAnimationFrame(gameLoop, canvas);

//Calcuate the time that has elapsed since the last frame
var current = Date.now(),
elapsed = current - start;
start = current;
//Add the elapsed time to the lag counter
lag += elapsed;

//Update the frame if the lag counter is greater than or
//equal to the frame duration
while (lag >= frameDuration){
//Update the logic
update();
//Reduce the lag counter by the frame duration
lag -= frameDuration;
}
//Calculate the lag offset and use it to render the sprites
var lagOffset = lag / frameDuration;
render(lagOffset);
}

render 函数在每个 sprite 上调用一个 render 方法,并引用 lagOffset

function render(lagOffset) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
sprites.forEach(function(sprite){
ctx.save();
//Call the sprite's `render` method and feed it the
//canvas context and lagOffset
sprite.render(ctx, lagOffset);
ctx.restore();
});
}

这是 Sprite 的渲染方法,它使用滞后偏移来插入 Sprite 在 Canvas 上的渲染位置。

o.render = function(ctx, lagOffset) {
//Use the `lagOffset` and previous x/y positions to
//calculate the render positions
o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;

//Render the sprite
ctx.strokeStyle = o.strokeStyle;
ctx.lineWidth = o.lineWidth;
ctx.fillStyle = o.fillStyle;
ctx.translate(
o.renderX + (o.width / 2),
o.renderY + (o.height / 2)
);
ctx.beginPath();
ctx.rect(-o.width / 2, -o.height / 2, o.width, o.height);
ctx.stroke();
ctx.fill();

//Capture the sprite's current positions to use as
//the previous position on the next frame
o.oldX = o.x;
o.oldY = o.y;
};

重要的部分是这段代码,它使用 lagOffset 和帧之间 Sprite 渲染位置的差异来确定其新的当前 Canvas 位置:

o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;

请注意,oldXoldY 值在该方法的末尾每帧重新计算,以便它们可以在下一帧中使用以帮助找出区别。

o.oldX = o.x;
o.oldY = o.y;

我实际上不确定这种插值是否完全正确,或者这是否是最好的方法。如果有人读到这篇文章知道这是错误的,请告诉我们:)

关于javascript - HTML5 Canvas 游戏循环增量时间计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25612452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com