一、图集
1.调用
Laya.loader.load([{ url: "res/atlas/comp.json", type: Loader.ATLAS }],
Handler.create(this, this.onLoaded));
从chrome中的network可以看到,加载完这个json后,会去加载相应的png
2.json的结构
随便拆开一个图片,看看属性:
"Chips_10.png"
{
"frame":{"h":114,"idx":0,"w":111,"x":0,"y":0},
"rotated":false,"sourceSize":{"h":114,"w":111},
"spriteSourceSize":{"h":114,"w":111,"x":0,"y":0},
"trimmed":false
}
如果图集超过了一张png,meta中会用逗号分隔来存储:
"meta":{"image":"card.png,card1.png,card2.png","prefix":"card/"}
3.Laya.net.Loader.as中的onLoader方法
} else if (type === ATLAS) {
//处理图集
if (!data.src && !data._setContext) {
if (!_data) {
this._data = data;
//构造加载图片信息
if (data.meta && data.meta.image) {
//带图片信息的类型
var toloadPics:Array = data.meta.image.split(",");
var split:String = _url.indexOf("/") >= 0 ? "/" : "\\";
var idx:int = _url.lastIndexOf(split);
var folderPath:String = idx >= 0 ? _url.substr(0, idx + 1) : "";
//idx = _url.indexOf("?");
//var ver:String;
//ver = idx >= 0 ? _url.substr(idx) : "";
for (var i:int = 0, len:int = toloadPics.length; i < len; i++) {
toloadPics[i] = folderPath + toloadPics[i];
}
} else {
//不带图片信息
toloadPics = [_url.replace(".json", ".png")];
}
//保证图集的正序加载
toloadPics.reverse();
data.toLoads = toloadPics;
data.pics = [];
}
event(Event.PROGRESS, 0.3 + 1 / toloadPics.length * 0.6);
return _loadImage(toloadPics.pop());
} else {
_data.pics.push(data);
if (_data.toLoads.length > 0) {
event(Event.PROGRESS, 0.3 + 1 / _data.toLoads.length * 0.6);
//有图片未加载
return _loadImage(_data.toLoads.pop());
}
var frames:Object = this._data.frames;
var cleanUrl:String = this._url.split("?")[0];
var directory:String = (this._data.meta && this._data.meta.prefix) ?
this._data.meta.prefix : cleanUrl.substring(0, cleanUrl.lastIndexOf(".")) + "/";
var pics:Array = _data.pics;
var atlasURL:String = URL.formatURL(this._url);
var map:Array = atlasMap[atlasURL] || (atlasMap[atlasURL] = []);
map.dir = directory;
for (var name:String in frames) {
var obj:Object = frames[name];//取对应的图
var tPic:Object = pics[obj.frame.idx ? obj.frame.idx : 0];//是否释放
var url:String = URL.formatURL(directory + name);
cacheRes(url, Texture.create(tPic, obj.frame.x, obj.frame.y, obj.frame.w, obj.frame.h,
obj.spriteSourceSize.x, obj.spriteSourceSize.y, obj.sourceSize.w, obj.sourceSize.h));
loadedMap[url].url = url;
map.push(url);
}
delete _data.pics;
/*[IF-FLASH]*/
map.sort();
complete(this._data);
}
}
可以看到,第一步是去加载data.meta.image中相应的png。在第二步的时候,判断_data.toLoads.length > 0
,如果还有没加载完的,接着去加载。
var atlasURL:String = URL.formatURL(this._url);
var map:Array = atlasMap[atlasURL] || (atlasMap[atlasURL] = []);
这是准备放到atlasMap里,然后去遍历_data.frames,使用Texture.create方法把小图片全部放入loadedMap里。注意看区别:
/** @private 已加载的资源池。*/
public static const loadedMap:Object = {};
/**@private 已加载的图集资源池。*/
protected static const atlasMap:Object = {};
二、图片
1.调用
assets.push({ url: this.getExtraUrl("BetTable_light", "bg"),
type: Laya.Loader.IMAGE });
protected function onLoaded(data:* = null):void {
var type:String = this._type;
if (type === IMAGE) {
var tex:Texture = new Texture(data);
tex.url = _url;
complete(tex);
}
/**
* 加载完成。
* @param data 加载的数据。
*/
protected function complete(data:*):void {
this._data = data;
if (_customParse) {
event(Event.LOADED, data is Array ? [data] : data);
} else {
_loaders.push(this);
if (!_isWorking) checkNext();
}
}
三、Laya.net.URL类
1.formatURL
/**
* 格式化指定的地址并 返回。
* @param url 地址。
* @param base 路径。
* @return 格式化处理后的地址。
*/
public static function formatURL(url:String, base:String = null):String {
if (!url) return "null path";
//如果是全路径,直接返回,提高性能
if (url.indexOf(":") > 0) return url;
//自定义路径格式化
if (customFormat != null) url = customFormat(url, base);
var char1:String = url.charAt(0);
if (char1 === ".") {
return formatRelativePath((base || basePath) + url);
} else if (char1 === '~') {
return rootPath + url.substring(1);
} else if (char1 === "d") {
if (url.indexOf("data:image") === 0) return url;
} else if (char1 === "/") {
return url;
}
return (base || basePath) + url;
}
这里可以回答一个疑问:
Q:我的UI上,有两个image,img1.skin=comp/image.png,img2.skin=uiExRes/gameTitle.png.根据资源设置,img1.skin是图集comp中的一张小图,而img2.skin是外部加载的一张单图。在set skin时,是怎么区分从图集中获取texture,还是从外部加载获取texture呢
A:参考Image.as set skin方法,Loader.getRes方法。可以看到,最终都会去Loaer.loadedMap中取。观察前述loadedMap,已经全部转化为D:/LayaWorkSpace/TestEmbedFont/bin/
+url的key了。只有在atlasMap中才能看到原始的图集路径。
public function set skin(value:String):void {
if (_skin != value) {
_skin = value;
if (value) {
var source:Texture = Loader.getRes(value);
if (source) {
this.source = source;
onCompResize();
} else Laya.loader.load(_skin,
Handler.create(this, setSource, [_skin]), null, Loader.IMAGE,1,true,_group);
} else {
this.source = null;
}
}
}
/**
* 获取指定资源地址的资源。
* @param url 资源地址。
* @return 返回资源。
*/
public static function getRes(url:String):* {
return loadedMap[URL.formatURL(url)];
}
2.basePath
var location:* = Browser.window.location;
var pathName:String = location.pathname;
// 索引为2的字符如果是':'就是windows file协议
pathName = pathName.charAt(2) == ':' ? pathName.substring(1) : pathName;
URL.rootPath = URL.basePath = URL.getPath(location.protocol == "file:"
? pathName : location.protocol + "//" + location.host + location.pathname);
如果部署在本地服务器上,使用192.168.198.102:8080来访问,那么
根据代码basePath=http://192.168.198.102:8080/,如果是本地文件访问:
end