Starling 1.4版本中的UV Scrolling,AssetManager

我已经有很多次遇到需要接连不断地滚动背景图片的需求了,例如说跑酷类型游戏的背景,星空,远景的云海等等。
以从右向左滚动为例,之前的实现办法,是把一个长卷的背景图切成两片,先滚动其中一片(用Tweener或是用EnterFrame随便你),当该片滚到stageWidth-imageWidth的位置时,马上将第二片移动到屏幕右侧以同样的速度滚动,这样在视觉上就造成了一个接连不断的假象。
在参照了Devon O. Wolfgang的博客后(原文 他管这个叫UV Scrolling,好高端哦~),得知在Starling中提供了一种非常方便的办法,同时由于其使用了位图像素操作的办法,效率很不错,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Embed(source="sky.jpg")]  
var skyClass:Class;
var sky:Image;

var img:Bitmap = new skyClass();
var tex:Texture = Texture.fromBitmap(img, false, true);
//this is the point that make texture successive
tex.repeat = true;
sky = new Image(tex);
this.addChild(sky);

this.addEventListener(Event.ENTER_FRAME,function(e:Event):void{
var p:Point;
for (var i:int = 0; i < 4; i++)
{
//this is the point that make texture scroll
p = sky.getTexCoords(i);
p.x += 5 * .00002;
sky.setTexCoords(i, p);
}
});

这种办法滚起来很自然,效率也不错。其原理(我猜测)和我刚刚讲述得很相似,只是位图操作可以部分地截取和拼贴位图,所以效率会好一些。

另外,为了解决之前程序在打开时,初始化要等半天(15秒),卡成翔的问题,(我曾经一度将其归咎为Starling初始化的机制问题,但是当我把官方附送的例子发布出来后,发现人家不卡……),我暂时有两点可以谨记:

  1. 少用Embed标签绑定资源,除非特殊情况,例如初始化时的背景图,某些超过Starling位图渲染尺寸的图片资源。

  2. 使用Starling自带的AssetsManager,加载TextureAtlas格式的SpriteSheet资源,效率要高很多。

  3. 只初始化马上要用的可视元件。
    通过这几点,我的程序启动时间已经缩短到了5秒以内,可以接受了。

    在这里,我再做一下树形深入,关于如何制作一个TextureAtlas格式的SpriteSheet资源,官网教程里介绍了一款很不错的工具,叫做TexturePacker,

    TexturePacker

    操作非常简单,需要注意的是这里使用的几个参数,
    在当前的例子里,这种格式就是满足需求的,它还支持很多其他格式。因为Starling 目前支持的最大位图资源尺寸为2048*2048,所以,如果较大的资源,例如背景图,选择直接绑定,或者单独加载效果会更好,另外,相对于移动设备上的开发,切片,分层的管理资源,本身就等于是在做优化操作,毕竟移动设备的显示尺寸有限。

    当准备好了TextureAtlas资源后,就可以用AssetManager加载资源了,代码如下:

    1
    2
    3
    4
    5
    6
    7
    var scaleFactor:int = viewPort.height <= 640 ? 1 : 2;  
    var appDir:File = File.applicationDirectory;
    assets = new AssetManager(scaleFactor);
    assets.verbose = Capabilities.isDebugger;
    assets.enqueue(
    appDir.resolvePath("assets/")
    );

    AssetManager包办了资源识别,内容格式化等功能,只要路径正确,资源名称匹配正确,你就可以很方便的通过getTexture函数调用对应的资源了。
    同时它还很贴心地支持了preloader功能。代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    assets.loadQueue(function(ratio:Number):void  
    {
    //change your progress bar with ratio
    if (ratio == 1)
    Starling.juggler.delayCall(function():void
    {
    //assets load completed
    }, 0.15);
    });

资源列表:

UV Scrolling in Starling by Devon O. Wolfgang