拿到一张图片(PNG),想要显示出来,可以让GUI Node显示,或者让Sprite显示。
(相关资料图)
GUI Node显示:将图片文件加载为纹理。先用sys.load_resource()将图片文件转换成String,然后用image.load将图片String转换为图片Lua表,最后用gui.new_texture()将图片Lua表转换为GUI纹理。把纹理绑定在GUI Node上,完成显示。
需要注意,GUI Node恒定遮挡游戏世界的元素。因此如果你的游戏不是100%用GUI Node实现的话,按这个方法就不能实现“封面铺底”一类的效果。
Sprite显示 法一
首先,想个办法让你的图片资源能出现在磁盘上。对于玩家导入曲目的音游,好说;对于制作方收录曲子的音游,设为Bundle Resource(可以自己实现一个压缩再解压/加密再解密什么的,也可以源文件存储)。
然后,用Lua io库打开文件,再用Defold-PNG原生扩展将打开的PNG文件转换成材质Buffer,另外手搓一个材质的header。
最后直接用resource.set_texture()把目标Sprite的材质改掉。
Sprite显示 法二
转变思路:Sprite原生只支持Atlas,那就尝试把图片转换成Atlas资源。转换比较简单,用Defold的编辑器创建一个Atlas,再加入我们的PNG图片即可。
第一反应是把Atlas文件存到Custom Resource中,然后尝试用sys.load_resource()的加载结果作为Sprite的image属性;或者直接上go.property("my_image",resource.atlas(path))再借助self userdata取得"my_image"属性的值,认为这个值是指向成品图集的hash,设置为Sprite的image属性。
这一堆都是不可行的。因为Custom Resource最终是原样打包不带任何检测,而编辑器产生的xxx.atlas文件并不是成品图集,仅仅是一个配置文件。。。。。。。
因此必须让最终可能加载的Atlas都进入静态资源树内,使其在打包时被转换为成品图集。这里有一计:
A. 准备index_01.go,index_02.go之类的Game Object文件,这些Game Object下的组件是各个Sprite,将它们的image属性设置成最终需要加载的Atlas;
B. 准备一个index.collection,集合内对每一个index_**.go添加一个Factory,这些Factory全部设为Load Dynamically(其实我们根本不打算让index.collection下面的Factory创建index_**.go的实例)
C. 将这个index.collection扔到启动集合内。
再之后,用resource.atlas()加载的Atlas就是成品图集了。用go.property()载入Atlas,然后把Atlas的Hash转移到目标Sprite的image属性,最后用sprite.play_flipbook()使设定的图片可以显示出来。
go.property(id,value)的value可以是一个提前建好的全局变量,这样Atlas的载入就动态起来了。
下次讲讲Defold的脚本文件加载。