我有一个javascript游戏,在某些计算机上运行速度非常快,而在其他计算机上运行速度非常慢。我一直在做一些研究,我发现我需要根据时间更新我的循环,但我似乎无法找到任何关于javascript的好例子。有人能指出我如何在任何硬件上以30fps的速度运行游戏吗?
由于
答案 0 :(得分:7)
正常情况下,游戏的工作时间是增量时间,即自上一帧渲染以来的时间量。
Psuedocode(大致是C#):
DateTime lastFrameTimeStamp = DateTime.Now;
void Draw()
{
TimeSpan timeSinceLastFrame = DateTime.Now.Subtract(lastFrameTimeStamp);
float deltaTime = timeSinceLastFrame.TotalSeconds;
// Do all of your movement and other time-based math based on the deltaTime, Like:
float x = x + (MovementPerSecond * deltaTime);
lastFrameTimeStamp = DateTime.Now;
}
使用增量时间可以防止对CPU功率的依赖性或帧的绘制频率。
答案 1 :(得分:6)
如果硬件无法实现,则不能强制游戏以30fps运行。如果它正在做的事情超过1/30秒,那你就不走运了。
您可以使用requestAnimationFrame让它尽可能快地运行。见这里:http://paulirish.com/2011/requestanimationframe-for-smart-animating/
答案 2 :(得分:1)
你可以有一个计时器功能,你可以测量你执行的时间,然后在你的((所需的间隔) - (执行时间)),伪代码回电给你自己
function timer(){
var timeStart = new Date();
// Your stuff
setTimeout (timer, (1000/30) - (new Date() - timeStart));
}
答案 3 :(得分:1)
您正在寻找的是JavaScript中delta timing的简单实现。在JavaScript中实现它是一项相对简单的任务。实际上它非常简单,可以在不到25行code中实现(删除空行和注释):
function DeltaTimer(render, interval) {
var timeout;
var lastTime;
this.start = start;
this.stop = stop;
function start() {
timeout = setTimeout(loop, 0);
lastTime = Date.now();
return lastTime;
}
function stop() {
clearTimeout(timeout);
return lastTime;
}
function loop() {
var thisTime = Date.now();
var deltaTime = thisTime - lastTime;
var delay = Math.max(interval - deltaTime, 0);
timeout = setTimeout(loop, delay);
lastTime = thisTime + delay;
render(thisTime);
}
}
使用它更简单。让我们通过例子学习:
var timer = new DeltaTimer(render, 1000 / 30);
var start = timer.start();
var body = document.body;
var frame = 0;
function render(time) {
time -= start;
body.innerHTML += (frame++) + ". " + time + " ms<br/>";
if (time >= 1000) {
var stop = timer.stop() - start;
body.innerHTML += "<br/>" + stop + " ms (stopped)";
}
}
我认为代码非常自我解释。对于现场演示,请单击此link。
答案 4 :(得分:0)
答案 5 :(得分:0)
JavaScript中唯一可用的计时机制是setTimeout和setInterval。但是,不能保证定时器的精度。事实上,由于浏览器中的JavaScript是单线程的,因此如果有JS已在其他地方运行,则无法保证计时器会在您需要时触发。
一般来说,如果您希望以指定的间隔定期发生某些事情,请使用setInterval。您必须确保回调的运行时间不会超过间隔的持续时间,否则您的下一个时间间隔将会延迟。如果事情发生得很晚,那么接下来的意愿也是可能的,而且你的处决也会越来越远。
许多现代浏览器都支持Web Workers,它本质上是一个后台JS执行(除了我们都熟悉的主UI阻塞线程)。我还没有使用Web Workers,所以我不能以任何权威或专业知识与他们交谈。
如果这是我,我会采取以下初步方法(http://jsfiddle.net/Ce3wq/):
var GameTimer = (function () {
var gameTimer = function (opts) {
var self = this;
opts = opts || {};
opts.stepInterval = opts.stepInterval || 30;
var callbacks = {};
var stepInterval= opts.stepInterval; // ms
this.domReady = function () {
setInterval(step, stepInterval);
};
this.registerService = function(callback){
callbacks[callback] = callback;
};
this.removeService = function(){
delete callbacks[callback];
};
var step = function () {
for(var id in callbacks){
callbacks[id]();
}
};
};
return new gameTimer;
})();
var eachTick = function(){
console.log(new Date().getTime());
};
GameTimer.registerService (eachTick);
jQuery(document).ready(GameTimer.domReady);
答案 6 :(得分:0)
您使用JavaScript的唯一选择是使用setTimeout
和setInterval
来模拟其他语言中的游戏循环。
你不能强迫你的游戏在每个硬件中以所需的速度运行(即使你的游戏在必备条件上非常低,因为网页浏览器JavaScript引擎会一直存在口吃),但你仍然可以使用Delta Timing每帧之间浪费时间。
Here是我用于JavaScript游戏的简单代码。这是一个在一秒钟内被称为FPS时间的函数。在这个例子中,每秒30次。