gpt4 book ai didi

JavaScript 游戏循环在 chrome/浏览器中播放追赶/模糊/重影

转载 作者:行者123 更新时间:2023-11-30 13:12:59 28 4
gpt4 key购买 nike

我一直在尝试设置一个 javascript 游戏循环,但我遇到了两个问题。我发现在 chrome 中,当我失去浏览器窗口的焦点,然后单击返回我正在运行的动画时,会发生这种奇怪的“ catch ”事情,它会快速运行它应该在后台渲染的帧。我还注意到,以当前速度移动时动画会变得模糊,但其他人已经能够让他们的 Canvas 绘图快速移动并且看起来仍然清晰。我知道他们似乎对此不以为然,但我无法理解我的问题到底是什么。我认为这是创建游戏循环的推荐方法。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Frame Test</title>
<link href="/css/bootstrap.css" media="all" rel="stylesheet" type="text/css" />
<script language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"
type="text/javascript">
</script>
<script language="javascript" src="js/jquery.hotkeys.js" type="text/javascript"></script>
<script language="javascript" src="js/key_status.js" type="text/javascript"></script>
<script language="javascript" src="js/util.js" type="text/javascript"></script>
<script language="javascript" src="js/sprite.js" type="text/javascript"></script>
</head>
<body>
<button id="button1">
Toggle Loop</button>
<h1 id="frameCount">
Game Loop Test</h1>
<canvas id="gameCanvas" width="800" height="500">
<p>Your browser doesn't support canvas.</p>
</canvas>
<script type='text/javascript'>



// demo code used for playing around with javascript-canvas animations
var frameCount = 0;
var drawingCanvas = document.getElementById('gameCanvas');
// Check the element is in the DOM and the browser supports canvas
if (drawingCanvas.getContext) {
var context = drawingCanvas.getContext('2d');
var x = 100;
var y = 100;
var right = true;
context.strokeStyle = "#000000";
context.fillStyle = "Green";
context.beginPath();
context.arc(x, y, 50, 0, Math.PI * 2, true);
context.closePath();
context.stroke();
context.fill();

}



function Timer(settings) {
this.settings = settings;
this.timer = null;
this.on = false; //Bool that represents if the timer is running or stoped
this.fps = settings.fps || 30; //Target frames per second value
this.interval = Math.floor(1000 / 30);
this.timeInit = null; //Initial time taken when start is called

return this;
}

Timer.prototype =
{
run: function () {
var $this = this;

this.settings.run();
this.timeInit += this.interval;

this.timer = setTimeout(
function () { $this.run() },
this.timeInit - (new Date).getTime()
);
},

start: function () {
if (this.timer == null) {
this.timeInit = (new Date).getTime();
this.run();
this.on = true;
}
},

stop: function () {
clearTimeout(this.timer);
this.timer = null;
this.on = false;
},

toggle: function () {

if (this.on) { this.stop(); }
else { this.start(); }
}
}

var timer = new Timer({
fps: 30,
run: function () {
//---------------------------------------------run game code here------------------------------------------------------
//Currently Chorme is playing a catch up game with the frames to be drawn when the user leaves the browser window and then returns
//A simple canvas animation is drawn here to try and figure out how to solve this issue. (Most likely related to the timer implimentation)
//Once figured out probably the only code in this loop should be something like
//updateGameLogic();
//updateGameCanvas();


frameCount++;
if (drawingCanvas.getContext) {
// Initaliase a 2-dimensional drawing context

//Canvas commands go here
context.clearRect((x - 52), 48, (x + 52), 104);

// Create the yellow face
context.strokeStyle = "#000000";
context.fillStyle = "Green";
context.beginPath();
if (right) {
x = x + 6;
if (x > 500)
right = false;
} else {
x = x - 6;
if (x < 100)
right = true;
}
context.arc(x, 100, 50, 0, Math.PI * 2, true);
context.closePath();
context.stroke();
context.fill();
}
document.getElementById("frameCount").innerHTML = frameCount;
//---------------------------------------------end of game loop--------------------------------------------------------
}
});
document.getElementById("button1").onclick = function () { timer.toggle(); };
frameCount++;
document.getElementById("frameCount").innerHTML = frameCount;

</script>
</body>
</html>

------------更新--------------------

我使用了 requestanimation frame 并解决了帧速率问题,但在动画运行时我仍然会出现奇怪的重影/模糊。知道我应该怎么画这个东西吗?

最佳答案

好的,您的部分问题是当您切换标签页时,Chrome 会降低其性能。

基本上,当您离开时,Chrome 会将页面上的所有计算速度减慢到 1 或 2 fps(省电,并提高当前标签的性能)。
以您所拥有的方式使用 setTimeout 基本上是在安排所有这些调用,它们等待用户回来(或者最多仅以 1fps 的速度运行)。

当用户回来时,您有数百个这样的堆积调用等待处理,并且由于它们所有都已提前安排,它们'都已经过了它们的“等待”时间,所以它们都将尽可能快地执行(快进),直到堆栈清空到您必须开始等待 32 毫秒以等待下一次调用的位置。

解决这个问题的方法是在有人离开时停止计时器——暂停游戏。
在某些以有意义的方式支持 Canvas 游戏的浏览器上,还支持 PageVisibility API。你应该调查一下。对于其他浏览器,它会不那么简单,但是您可以绑定(bind)到 window 上的模糊事件。

请确保当您重新启动时,您还清除了更新间隔。

最终,我建议转移到“requestAnimationFrame”,因为它会智能地处理帧速率,并且还会处理您看到的由于堆栈调用而导致的节流,但您的计时器看起来像是浏览器的不错替代品还没有。

至于模糊,那需要更多的洞察力。
如果你在谈论图像,我脑海中浮现出的原因要么是你的 Canvas 的宽度/高度是在 CSS 中设置的,要么是你的 Sprite 没有以图像的 1:1 比例使用他们是从中拉出来的。

它也可以归结为图像的亚像素定位或旋转。

希望对您有所帮助。

...实际上,在再次查看您的代码后,尝试从 HTML 中的 Canvas 中删除“宽度”和“高度”,而是更改 canvas.width = 800; canvas.height = 500; 在 JS 中,看看是否有帮助。

关于JavaScript 游戏循环在 chrome/浏览器中播放追赶/模糊/重影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13204714/

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