gpt4 book ai didi

javascript - 第一次在 Chrome 中绘制大图像的小延迟

转载 作者:搜寻专家 更新时间:2023-11-01 04:19:36 25 4
gpt4 key购买 nike

我正在使用 canvas 标签开发一个简单的基于 JavaScript 的游戏。作为游戏的一部分,我有几个大型 Sprite 表(例如 2816x768 和 4096x4864),每个都包含屏幕 Angular 色的相关动画。当游戏开始时,游戏只会播放 Angular 色的空闲动画。当用户按下空格键时,我开始播放来自完全不同的恶意表单的另一个动画。

这是绘制 Sprite 的代码:

Sprite.prototype.drawFrame = function(x, y)
{
ctx.drawImage(this.image,
x*this.width, y*this.height,
this.width, this.height,

this.position[0], this.position[1],
this.width, this.height);
};

这是加载图片的代码:

Stage.prototype.loadImage = function(src)
{
var image = new Image();
this.incAssets();
var stage = this;
image.onload = function()
{
stage.decAssets();
}
image.src = src;
return image;
}

问题在于,从用户按下空格键到实际绘制新 sprite 表中的帧之间存在 1.5 秒的延迟。这只是一次,不影响后续动画的流畅度。我已经使用 new Image 预加载了 sprite 表,并且在所有相应的 image.onload 事件都已触发之前游戏甚至不会开始,所以我知道浏览器不会等待它们加载。我已经使用 Chrome 17.0 中的调试器逐步执行 JavaScript,并将延迟缩小到对上下文的 drawImage 调用。最令人困惑的是 Firefox 10.0.2 中没有这种延迟,所以这是 Chrome 特有的问题。这对游戏玩法造成了极大的干扰。

我在这里做错了什么?无论如何,我可以减少 Chrome 中的这种延迟吗?

编辑:我尝试按照 Peter Wishart 的建议在加载后立即绘制整个下一帧,但效果很小。我还尝试按如下方式修改 loadImage:

Stage.prototype.loadImage = function(src)
{
var image = new Image();
this.incAssets();
var stage = this;
image.onload = function()
{
ctx.drawImage(image, 0, 0);
stage.decAssets();
}
image.src = src;
return image;
};

这也没有效果。

事实上,我确实找到了解决方案,但效率极低。我突然想到 Chrome 可能会在解码后尝试对图像内存做一些聪明的事情。如果图像长时间未使用(这只是猜测),Chrome 将从内存中删除解码数据,并在再次需要时将其拉回。通常情况下,解码过程花费的时间很少,但我使用的大图像会导致性能急剧下降。使用它我将绘制循环更改为:

function draw()
{
var currentTime = new Date().getTime();
var deltaTime = currentTime - lastTime;
lastTime = currentTime;

var dt = deltaTime / 1000.0;

// The hack that keeps all decoded image data in memory is as following.
if (this.stage.nextStage != undefined)
this.stage.nextStage.draw(0); // The 0 here means the animations advance by 0 milliseconds, thereby keeping the state static.

ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
if (stage != undefined && stage.loaded)
{
stage.draw(dt);
}
}

这个解决方案确实有效,但正如我所说,这似乎是一种可怕的浪费。我必须绘制下一组动画的整个帧,只是为了防止解码数据在 Chrome 中变得陈旧。

是否有比此策略更不浪费且更不麻烦的替代方案?

最佳答案

考虑到 Chrome 只是在一段时间后丢弃解码后的图像数据,我尝试将图像复制到屏幕外的 Canvas 中,假设 Chrome 不会费心从内存中取出该 Canvas 。执行此操作的代码非常适合 loadImage 函数。

Stage.prototype.loadImage = function(src)
{
var useCanvasCache = Prototype.Browser.WebKit; // If we are in a WebKit browser (e.g. Chrome)
var decodeCanvas;
var dectodeCtx;
if (useCanvasCache)
{
// Creates a canvas to store the decoded image.
decodeCanvas = document.createElement('canvas');
dectodeCtx = decodeCanvas.getContext('2d');
}
var image = new Image();
this.incAssets();
var stage = this;
image.onload = function()
{
stage.decAssets();
// Simply transfer the image to the canvas to keep the data unencoded in memory.
if (useCanvasCache)
{
decodeCanvas.width = image.width;
decodeCanvas.height = image.height;
dectodeCtx.drawImage(image, 0, 0);
}

}
image.src = src;
// Canvas works the same as an image in a drawImage call, so we can decide which to return.
if (useCanvasCache)
{
return decodeCanvas;
}
else
{
return image;
}
};

它也有效。加载页面时会有一个小的初始损失,并且它可能会使用更多内存,但这是一个可行的解决方案,因为在此应用程序中速度比内存更重要。

关于javascript - 第一次在 Chrome 中绘制大图像的小延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9540998/

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