用Starling渲染Sprite

本文中要研究的是如何通过Starling框架使用2D游戏中Stage3D(比如用户GPU),来给资源做动画。视频和文章在内容上几乎完全相同(虽然主游戏类的路径稍微有所不同)。

[flash]http://player.youku.com/player.php/sid/XMzIxMTEzMzAw/v.swf[/flash]

在我的Vimeo中可以查看更多视频

我想我有必要说明一下怎么开始架构Starling,一个很明显的切入点就是如何用Starling以及GPU(通过Stage3D)绘制动画。幸好,Starling 把这些必要的繁琐环节都封装起来在幕后为你完成,你可以通过它直接和Stage3D交互。使用Starling的另一个好处就是它接入了一个你所熟悉的API,由于它紧紧遵循着相同的API,而此API用于指向传统Flash Display列表的时候。MovieClip,Image,Sprite,Button等等。

现在开始

下面看看要怎么开始用Starling添加内容和制作动画。首先,你创建好一个支持Starling的ActionScript项目后(如果你不知道要怎么做请查看这篇文章),第一件要做的就是创建一个Starling核心引擎的实例。
  • var _st:Starling = new Starling(AnimationExample, stage);
  • _st.start();
复制代码
可见创建Starling()实例时,你要给它提供两个参数(它确实需要额外的参数但是目前我们会先跳过)。第一个参数是当Starling运行的时候你要实例化的根类,在这里是AnimationExample。第二个参数是你要附加到根类实例的存储单元,在这里我们只要指定stage实例就可以了。

以上都完成后,现在剩下的就是让Starling实际运行了,你可以已经知道要怎么做了。你只需要调用Starling实例的start()方法。由上面两行代码,你的游戏文档类已经完成了(至少有个示例了),它应该跟下面代码看起来很像:
  • package
  • {
  •         import flash.display.Sprite;

  •         import starling.core.Starling;
  •         import com.flashgen.examples.AnimationExample;

  •         public class Starling101 extends Sprite
  •         {
  •                 public function Starling101()
  •                 {
  •                         var _st:Starling = new Starling(AnimationExample, stage);
  •                         _st.start();
  •                 }
  •         }
  • }
复制代码
创建游戏文档类

你可能会发现我漏掉了根类AnimationExample的创建,这个我们传入到Starling()构造函数的类。由于我想覆盖Starling一个特殊条件,就是说这个类必须要继承Starling的实现接口DisplayObject类。现在就很明了了,这个不是Flash的DisplayObject类,它是一个同名的Starling实现接口。最常用的实现接口就是从Starling的Sprite类中扩展这个类——你可能会将Starling的DisplayObject类一并扩展。这样你的基类AnimationExample如下:
  • package com.flashgen.examples
  • {
  •         import starling.display.Sprite;

  •         public class AnimationExample extends Sprite
  •         {
  •                 public function AnimationExample()
  •                 {
  •                         super();
  •                 }
  •         }
  • }
复制代码
现在你要创建一个叫init()的方法。对于这个例子,你可以将绝大部分代码放在这里。没有将代码放到实际的类构造函数中,是因为我们想确保在其他东西进入进程之前这个类已经放到舞台上了。而这样做,只需要在AnimationExample类构造函数中加入一个事件侦听,等到这个类完整的添加到舞台上才执行。
  • public function AnimationExample()
  • {
  •         super();

  •         addEventListener(Event.ADDED_TO_STAGE, init);
  • }
复制代码
需要反复重申的是这个我们侦听的事件不是flash.events.Event实现接口,而是Starling的实现接口,比如starling.events.Event。我知道对于确定类使用Starling的实现接口我有点啰嗦,但如果你碰巧用了Flash的实现接口可是会报错的。

添加资源

与Flash相比,Starling跟平常使用的制作动画方式有点不一样,但是最主要的是它用了Texture Atlas和Sprite Sheet *来渲染可视内容和制作动画。

Texture哈?Sprite什么!?
Texture Atlas和Sprite Sheet非常相似,它们都以一个包含许多小图像的大图像为中心。但它们在主要包含的内容范围上是不一样的。

Sprite Sheet一般只包括一个单独Sprite类型的位图信息——比方说一个士兵——包括它所需要的所有动画帧。

Texture Atlas包含了一整个游戏中所有需要的位图信息,(或者如果这个游戏每个单独的关卡都特别庞大),包括Sprite、静态资源等等。它还倾向于利用一个文本文档(一般是XML),或“Atlas”,来标出每个条目在大图像中的哪里。通过在文本文档中使用数据可以很容易的摘录你需要的条目;并且如果完成得比较迅速,你可以根据序列交换当前帧和下一帧,以此来制作动画。


我已经创建了一个Sprite Sheet,并且用app调用了TexturePacker关联了XML文件。我不是想在这篇文章中追踪怎么使用app的细节——我会把这留到一篇专门的博文中。现在主要做的就是怎么让这两部分(PNG图表和XML文档)相互关联。因为我早先提到了XML文档包含了一个对于图表中每个条目的引用,并给每个sprite提供了x,y,width,height属性:

  •    
  •    
  •    
  •    
复制代码
然而,在继续之前,我们看看在游戏中你实际上是怎么引用这两个文件的。首先你要做的是用[Embed]元数据来嵌入这两个文件。不要忘记替XML文件设置正确的mimeType 属性(mimeType=”application/octet-stream”)。如果你忘记在你的XML的嵌入代码中写这个,程序就会报错且不能编译。而PNG的Sprite Sheet就不用设置mimeType属性了,你的代码现在看起来应该跟下面一样(显然你的资源路径会不一样):
  • public class AnimationExample extends Sprite
  • {
  •         [Embed(source="assets/spritesheets/Bilbo-walk.xml", mimeType="application/octet-stream")]
  •         private var AnimData:Class;

  •         [Embed(source="assets/spritesheets/Bilbo-walk.png")]
  •         private var AnimTexture:Class;

  •         public function AnimationExample()
  •         {
  •                 super();

  •                 addEventListener(Event.ADDED_TO_STAGE, init);
  •         }

  •         protected function init(e:Event):void
  •         {

  •         }                
  • }
复制代码
一旦你嵌入了你的Sprite资源,你需要为它们创建一个实际的引用。所以就要为这两个文件在init()方法中分别创建实例,这样你就要为Starling的Texture()类创建一个实例并给这个变量从Sprite Sheet传递数据:
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  • }
复制代码
注意这里使用了静态方法Texture.fromBitmap()来获取并指定PNG文件实例。Starling的Texture()类还有其他“from…”方法,这在以后的文章里会研究到。创建一个XML文件实例非常简单,你只需要确保将XML实例转换成了XML()函数——这是因为我们使用了普通的Class()类作为两个嵌入文件的数据类型,而且为了确保XML文件已经正确赋值也是需要强制转换的。
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  •         var _d:XML = XML(new AnimData());

  • }
复制代码
现在我们要合并这两个变量来创建让Starling可以在场景中执行的部分了,你要创建一个Starling的TextureAtlas()实例,这样就创建了Sprite Sheet和XML数据文件的关联,其中XML文件包含了图表中每个Sprite的位置信息。
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  •         var _d:XML = XML(new AnimData());

  •         var _ta:TextureAtlas = new TextureAtlas(_t, _d);
  • }
复制代码
让它动起来

我们刚刚研究了怎么设置好Starling来进行渲染。现在看看要如何渲染画面你才能实际看到你的Sprite。就如我一直在本文中提到的,Starling的实现接口是Flash一般的API类,其中一个就是MovieClip()类。然而,跟Flash同等对比,它的设置和用法稍微有点不同(这应该也是你所想要的)。创建一个Starling的MovieClip()类实例:
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  •         var _d:XML = XML(new AnimData());

  •         var _ta:TextureAtlas = new TextureAtlas(_t, _d);

  •         var _mc:MovieClip = new MovieClip(_ta.getTextures("Bilbo"), 30);
  • }
复制代码
注意这里使用了TextureAtlas()实例并且调用了getTextures()方法来检索要跟MovieClip()实例放在一起的Sprite。可以看到getTextures()方法里的字符串是XML文件name属性的前缀:
复制代码
这提供了一个机制来获取包含在一个PNG中的元素,也关联了游戏视图的各个部分。还有第一个你可以在实例化的时候定义的可选择参数,就是你希望MovieClip()渲染的帧频。在本例中设置为30fps,而这个帧频与主游戏的帧频是不同的。现在你要做的就是添加这个MovieClip()实例到Starling显示列表中了,展示完整的代码,并进行测试。
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  •         var _d:XML = XML(new AnimData());

  •         var _ta:TextureAtlas = new TextureAtlas(_t, _d);

  •         var _mc:MovieClip = new MovieClip(_ta.getTextures("Bilbo"), 30);

  •         addChild(_mc);
  • }
复制代码
呃,中断了?

如果你测试了而且Bilbo在画面中显示但却不动,而你不知道为什么,不要慌张,你没有错过任何东西——程序正如预期的运行。你看,MovieClip()实例应该已经有了所有动起来的条件了,你只需要在每个渲染周期使用一个方法来更新帧就可以了。这样你可以使用Juggler,Juggler(就如名称所指)窜改了动画帧,在每个周期都进行了更新。不用担心这个听起来有点陌生,一旦你使用这个方法几次后,你会发现这平常不过了。

最简单的方式就是用Starling()实例来接入Juggler 。你只需要引用Starling()实例并添加MovieClip()实例给Juggler关联就可以了。
  • protected function init(e:Event):void
  • {
  •         var _t:Texture = Texture.fromBitmap(new AnimTexture());
  •         var _d:XML = XML(new AnimData());

  •         var _ta:TextureAtlas = new TextureAtlas(_t, _d);

  •         var _mc:MovieClip = new MovieClip(_ta.getTextures("Bilbo"), 30);

  •         addChild(_mc);

  •         Starling.juggler.add(_mc);
  • }
复制代码
现在如果你保存文件并测试,Bilbo会如你所愿的动起来。

总结

在本文中你已经知道了要怎么开始使用Starling框架,也明白了用Flash的API制作动画的不同(只是稍微),你也看到了Starling是如何与Sprite和Texture交互的,还有使用这些资源类型时的常规实现接口的工作流程。

相关文档

STR001-AnimatingSprites.zip

你可能感兴趣的:(Starling框架,FlashPlayer11,AIR3,Stage3D,xml,function,flash,actionscript,游戏,文档)