使用动画编辑器编辑、绘制复杂的精灵动画

咱们平时所玩的不少游戏都有着很是绚丽的动画效果,尤为是像ACT、RPG等类型的游戏,必须拥有华丽的魔法和攻击效果才能吸引玩家的眼球。本文将主要介绍如何使用OPhone API以及动画编辑器类的工具来编辑、绘制和处理精灵的动画,整个程序的运行效果以下图所示:

 


图1 游戏最终效果程序员

动画原理

咱们都看过动画片,看过电影,玩过游戏,里面都有各类绚丽的动画,实际上动画的绘制机制归纳说来就是以必定的速度连续播放静态的图片,这样人眼就能识别出动画。通常咱们人眼可以分辨的动画速度为10——20帧/秒,咱们称之为FPS(Frame Per Second),低于10帧就会变得很卡,高于20就会变成快动做,所以,控制好这个数值对游戏总体的流畅度相当重要。算法

那么总结起来,要想在游戏中绘制动画须要具有如下几个必要元素:api

1. 动画的原始图片数组

2.动画序列数据编辑器

3.动画刷新机制(下一帧)ide

常规的动画播放方法

1.实现第一步(动画的原始图片)工具

常规的播放2D动画方法的方法实际就是对上述过程的一个分解:在游戏中,精灵的图片常常是被放置到一张图片上,下图就是一个典型的2D游戏精灵图片:布局


图2 角色原始图片post

2.实现第二步(设定动画序列)动画

有了原始图片以后,咱们就能够把这些图片按照必定的尺寸进行分割,切割成的每一个块咱们称之为“帧”,同时为每一帧进行编号,为每帧分配惟一的索引号,索引号能够从任意数字开始,可连续也能够随机,但要注意不能有重复的索引号,分配好的索引号可参照下图所示:

表1 游戏帧序列

0 1 2 3 4 5 6 7 8 9 10 11

 

有了这个索引,咱们就能够为每一个动画设定动画序列了,好比,咱们能够分别定义精灵的上、下、左、右行走的动画序列,每一个动画的序列以下面代码所示:

final static int ACTION_UP[]={0,1,2};

    final static int ACTION_DOWN[]={6,7,8};

    final static int ACTION_LEFT[]={9,10,11};

    final static int ACTION_RIGHT[]={3,4,5}; 

    final static int ACTION_STAND[]={7};  

数组中的每一个元素值就是上面表格中的数值。

3.实现第三步(切换并播放动画)
 因为全部的图片块都被放置到了一个数组中保存起来,所以有个动画数据以后,咱们就能够把数据所对应的图片绘制到屏幕上了,而后,经过线程来控制一帧一帧的切换,这就是游戏中动画处理的通常过程。

 

上面这种播放动画的方式的优势是开发简单,便于切换和控制,可是也有以下的一些缺点:

  1.存在重复的图片资源

咱们能够从原始图片上看到,若是要实现精灵向下走的动画,须要使用4帧图片,可是这4帧图片中只有精灵脚步的图片存在差别,剩下的都大体相同,这就是一种图片上的浪费。而咱们的手机内存目前还比较小,所以这种浪费应该是要尽可能避免的。

  2.动画数据直接存在于代码中

上面的例子中,咱们直接把动画的序列以数组的形式保存到了代码中,也就是说,把对动画数据的处理交给了程序员来完成,而程序员的主要工做应该是处理游戏中的算法逻辑,所以,比较好的解决方法是把动画的处理交给美工和策划来完成。所以,上面这种方法也存在缺点。

  3.帧图片要求规整

若是采用上面的方法绘制动画,要求每一帧必须按照指定的长度和宽度进行分割,不然就是出现绘制错误,这在必定程度上也限制了程序的灵活性。

  4. 难易实现复杂的动画效果

因为帧的尺寸人为的被限定,同时每个动做就必需要一帧进行显示,若是要想实现复杂的动画序列就意味着要存在大量的帧序列,而原始图片势必要随之变得很大,进而增长了对内存的占用,而在这种状况下,帧数越多,重复的内容也会随之不断增多,显然这也不适合手机这种资源有限的设备的特色。

上面说了这些缺点,那么该如何解决呢?下面就为你介绍一下目前比较流行的一种动画处理方式,也是本文的重点——使用动画编辑工具。

做者介绍

李建,乐成数字通讯学院 高级讲师。层就任于国内数家SP,CP公司,具备丰富的软件、游戏开发经验。并从事多年教学工做,具备丰富的教学经验。目前主要从事OPhone、J2ME开发和教学方面的工做。

动画编辑器的原理

动画编辑器就是一种软件工具,它的做用就是经过软件对原始图片进行切割,而后在软件中把切割好的图片块拼成一帧一帧的图片,再选择相应的图片来组成动画序列,最后将数据导出以文件。

动画编辑器的使用

目前,不少的手机游戏公司都在使用动画编辑器来制做动画,而不一样的公司使用的工具也不尽相同,下图为一个功能比较强大且使用很普遍的动画编辑工具,界面以下图所示:

图3 动画编辑器界面

接下来我将一步一步的演示如何使用这个工具来制做动画:

1.         首先要创建一个工程,这个同时点击“”按钮引入一张图片,以下图:

图4 角色原始图片

从图中咱们看到,原始图片再也不是规则的帧序列,精灵图片被一块块的分解了。

2.         下面咱们要对图片进行分割了,选中左边栏的“”,而后在图片上进行切割,把乌龟的各个零部件都用方块圈出来,最后的效果以下图:

图5 分割原始图片

3.         接下来就能够用这些“零件”拼图了。首先咱们在右上方的窗口中点击“”按钮,接下来就能够看到右侧窗口变成以下图所示的界面:

图6 frame窗口

4.         接下来双击上图中的“1-Frame”,就会出现以下图所示界面:

图7 拼图界面

5.         接下来你就能够在左边的窗口中按住鼠标左键选择你要的乌龟的零部件图片并将其拖入右边窗口的坐标系中,通常将其放置到第一象限,一个拼好的帧图片以下图所示:

图8 帧的拼图

在拼图中,你可使用左边的一些按钮来实现各个图块的位置和对齐,如图:

图9 布局排列按钮

能够点击“”来回到帧列表界面,同时可使用“”按键增长新的帧。按照上述方法能够拼出乌龟的上、下、左、右行走等各个帧序列,拼好的效果以下图:

图10 拼好的各个帧

6.         有了帧图片就能够利用它们来组成动画了,方法以下:

菜单中选择“Action——Edit”,效果以下图:

图11 增长动画

图12 动画编辑界面

7.         接下来在“Action Edit”窗口中经过“”按钮增长一个动画,而后就能够从Frame列表中选择相应的帧来组成相应动画了,以下图所示:

图13 设置动画

这样咱们就制做好了一个乌龟向下行走的动画,同时你能够点击“”按钮来观察这个动画,并根据效果对动画进行调整,很是方便。

如今咱们已经完成了整个动画的制做过程,下面就要将数据进行导出,过程以下图所示:

图14 导出数据

上面介绍了如何使用动画编辑器来设定动画,相信你已经掌握了这个工具的使用了。可是,用这个工具制做的动画并不能直接显示到手机屏幕上,还须要咱们经过代码的方式来对其进行处理。下面来介绍一下如何经过代码来绘制响应的动画。

动画播放类——Animation的实现:

要想实现对动画的播放必需要有一个动画的解析类,也就是须要对“.sprite”数据文件进行解析,这里咱们将这个类命名为SpriteX,这个类的做用是解析数据文件并提供动画的绘制方法,因该类内容较多,此处没有贴出源代码,请参考附件。

精灵类——Role的实现

每一个精灵类都须要有个SpriteX类的对象用来处理该精灵的动画,所以须要在这个类中定义以下属性:

SpriteX spx;     

精灵类的构造方法以下:

 public Role(GameView view)         {            spx=new SpriteX("s.sprite",R.drawable.a2,view);         }  
 

这里面的“view”为视图类的对象,稍后会有介绍。

注意:精灵图片须要放置到“res/drawable”文件夹,动画数据要放到“assets”文件夹下面。

精灵类的绘制方法以下:

 public void paint(Canvas g)         {             spx.paint(g,100,100);             spx.nextFrame();         }  
 

设计屏幕类

定义好精灵类只是实现了这个项目的第一步,咱们还不能在屏幕上看到精灵的动画,咱们须要一个视图来把精灵显示出来,接下来咱们定义视图类,在这里咱们自定义一个类GameView来实现这个功能。做为一个自定义的视图类,这个类须要继承View,关于这个类请参考api文档。这个类用来处理精灵的绘制,按键处理等功能。其构造方法以下:

 public GameView(Context view)         {            super(view);                       gamePaint = new Paint();            player=new Role(this);                  // 创建线程            Thread t = new Thread(this);            t.start();     }  
 

精灵对象建立完毕后,咱们就能够将其绘制到屏幕上了,这里须要重写View类中的onDraw()方法,此方法会在该类对象被Activity调用时自动调用,其方法以下:

 @Override       protected void onDraw(Canvas g)       {          role.draw(gamePaint);       }  
 

 

动画的刷新

在GameView类中须要处理动画的刷新,也就是每隔一段时间来播放动画的下一帧,所以咱们用线程来实现这个功能,线程的run方法以下所示:

 public void run()         {            while (true)            {                // 放慢速度                long bm = System.currentTimeMillis();                // 更新屏幕                postInvalidate();                long cm = System.currentTimeMillis();                if (cm - bm < SPLASH_RATE)                   try                   {                       Thread.sleep(SPLASH_RATE - (cm - bm));                   } catch (InterruptedException e)                   {                       e.printStackTrace();                   }            }         }  
 

在这里要注意给线程适当的休眠时间,用来控制FPS,这样有利于获得更好的游戏体验。

注意:SPLASH_RATE就是每一个线程的间隔时间

定义Activity

最后咱们定义一个Activity的子类用来运行该游戏,在Activitiy中咱们须要创一个GameView对象,而后经过setContentView()方法进行设定,代码以下:

 @Override         public void onCreate(Bundle savedInstanceState)         {             super.onCreate(savedInstanceState);             instance=this;                         view=new GameView(this);             setContentView(view);     }  
 

到此,咱们已经完成了全部的功能,你能够运行模拟器并观察其效果了。

总结

使用动画编辑工具的方法能够很是方便的开发复杂的动画效果,尽量的节约有限的内存资源而且使程序员和策划、美工的工做相分离,是如今手机端2D游戏开发广泛采用的一种高效、方便的方法。