我正在使用JavaScript和canvas
开发游戏。当游戏加载时,将使用所有将要使用的图像。
观察资源时间线,我看到以下代码触发异步请求:
var sprite = new Image();
sprite.src = "sprites/sheet1.png";
引擎将继续执行,最终开始绘制并播放关卡。绘制第一帧后加载的图像可能永远不会因剪裁而出现(即没有“脏”)。
所以我测试了以下内容:
console.log("begin");
var sprite = new Image();
sprite.onload = function() { console.log('loaded!'); };
sprite.src = "sprites/sheet1.png";
console.log("end");
生成的控制台输出顺序为:
begin
end
loaded!
我正在寻找与$.ajax
async: false
类似的方式来执行加载。无法弄清楚如何...提前感谢您的帮助!
学家
答案 0 :(得分:60)
您不应该进行任何同步(甚至不是AJAX)调用,而只需将代码放入适当的回调中:
function loadSprite(src, callback) {
var sprite = new Image();
sprite.onload = callback;
sprite.src = src;
}
然后像这样使用它:
loadSprite('sprites/sheet1.png', function() {
// code to be executed later
});
如果要传递其他参数,可以这样做:
sprite.onload = function() {
callback(whatever, args, you, have);
};
如果要加载多个元素并需要等待所有元素完成,请考虑使用jQuery deferred对象:
function loadSprite(src) {
var deferred = $.Deferred();
var sprite = new Image();
sprite.onload = function() {
deferred.resolve();
};
sprite.src = src;
return deferred.promise();
}
在加载精灵的函数中,你可以这样做:
var loaders = [];
loaders.push(loadSprite('1.png'));
loaders.push(loadSprite('2.png'));
loaders.push(loadSprite('3.png'));
$.when.apply(null, loaders).done(function() {
// callback when everything was loaded
});
答案 1 :(得分:2)
这个问题很老,但有一种方法可以做到这一点而不需要jquery,或冻结浏览器。
在image1.onLoad中,使其加载image2。
在image2.onLoad中,使其加载image3。
在image3.onLoad中,使其加载image4。
....
在图像 n .onLoad中,使其加载主函数。
我不确定这是否是完全最好的方法,但它至少比冻结浏览器更好。
您还可以加载所有音频文件或您需要的任何其他资源,或者您需要运行的任何其他JavaScript。
不需要冻结浏览器
答案 2 :(得分:0)
我在画布上遇到了这个问题 我尝试了你的解决方案,但最好和最简单的方法是:
function COLPOinitCanvas(imagesfile) {
COLPOcanvas = document.getElementById("COLPOcanvas");
COLPOctx = COLPOcanvas.getContext("2d");
var imageObj = new Image();
imageObj.src = imagesfile;
imageObj.onload = function () {
COLPOctx.drawImage(imageObj, 0, 0, COLPOcanvas.width, COLPOcanvas.height);
};
}