Android游戏开发之游戏帧动画的播放与处理(七)

235
回复
1306515
查看
  [复制链接]

249

主题

278

帖子

17

安币

初级码农

Rank: 1

发表于 2011-9-2 22:47:10 | 显示全部楼层 |阅读模式

带你走进游戏开发的世界之游戏帧动画的处理

1.帧动画的原理

       帧动画帧动画顾名思义,一帧一帧播放的动画就是帧动画。 帧动画和我们小时候看的动画片的原理是一样的,在相同区域快速切换图片给人们呈现一种视觉的假象感觉像是在播放动画,其实不过是N张图片在一帧一帧的切换罢了。
     
       如图所示:人物行走动画的实现方式, 4帧行走动画在播放区域 一帧一帧向左切换播放 给人们一种播放动画的假象 ,图片就动了起来, 很简单吧,其它三方向播放动画的方法类似我就不再一一举例。

2.动画资源的原始文件

动画资源的原始文件PNG 一般有三种形式的呈现方式 请听我细细道来。



1.每一帧是一张png图片中

       如图所示上下左右方向每一组动画中的每一帧都是一张png图片,播放动画须要切换整张图片 ,实现动画效果。代码中只需要将下一帧图片完整的覆盖住上一帧的图片就OK了,这种资源的排列方式在程序算法上是最简单的。

2.所有动画帧都存在一张png图片中

       如图所示一张png中存放了人物所有的帧动画,播放动画的时候程序需要计算出将要播放的图片在原始图片中的起始坐标和结束坐标,也就是说要从原始图片中把将要播放的图片扣出来,从而显示在手机屏幕上。这种资源的排列方式程序需要编写计算图片坐标位置的算法。

3.动画编辑器处理动画

游戏公司都会有自己的动画编辑器 ,动画编辑器的好处是
1.减少图片大小节省内存空间
2. 缩短美工对坐标时间 ,因为如果没有编辑器美工很痛苦的需要一张图片一张图片的对坐标,全是体力活。
3.完全数据驱动动画 ,动画出问题程序不用改代码。BUG都是美术的 ,呵呵。

       动画编辑器生成出来的其实就是坐标 告诉图片的每一个点 每个动画的点 拼接起来的每一个坐标 程序须要编辑对动画编辑器生成的xml文件 根据生成出来的坐标 进行解析然后绘制出游戏动画。AuroraGT动画编辑器是笔者使用最多的一款动画编辑器它的功能非常强大可以编出任意动画。由于考虑到商业用途 对于这个编辑器的解析与使用我不做任何解释 。如果只是单纯的想学习我把编辑器的下载地址贴出来,大家可以互相研究互相讨论互相学习。

下载地址:

给大家看看生成出来的动画效果很绚丽吧,是不是很给力呢 呵呵呵呵。



我用代码详细的说明一下第一种和第二种游戏动画的代码实现方法。

       我自己写了一个动画类来处理播放动画,需要调用动画只需要new一个Animation对象传入动画所需要的参数通过调用 DrawAnimation 方法就可以按帧播放绘制动画。如果是单纯的学习的话我觉得这个类已经够学习使用了。
  1. package cn.m15.xys;

  2. import java.io.InputStream;

  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Paint;

  8. public class Animation {

  9.     /** 上一帧播放时间 **/
  10.     private long mLastPlayTime = 0;
  11.     /** 播放当前帧的ID **/
  12.     private int mPlayID = 0;
  13.     /** 动画frame数量 **/
  14.     private int mFrameCount = 0;
  15.     /** 用于储存动画资源图片 **/
  16.     private Bitmap[] mframeBitmap = null;
  17.     /** 是否循环播放 **/
  18.     private boolean mIsLoop = false;
  19.     /** 播放结束 **/
  20.     private boolean mIsend = false;
  21.     /** 动画播放间隙时间 **/
  22.     private static final int ANIM_TIME = 100;
  23.    
  24.    
  25.     /**
  26.      * 构造函数
  27.      * @param context
  28.      * @param frameBitmapID
  29.      * @param isloop
  30.      */
  31.     public Animation(Context context, int [] frameBitmapID, boolean isloop) {
  32.         mFrameCount = frameBitmapID.length;
  33.         mframeBitmap = new Bitmap[mFrameCount];
  34.         for(int i =0; i < mFrameCount; i++) {
  35.             mframeBitmap[i] = ReadBitMap(context,frameBitmapID[i]);
  36.         }
  37.         mIsLoop = isloop;
  38.     }
  39.    
  40.     /**
  41.      * 构造函数
  42.      * @param context
  43.      * @param frameBitmap
  44.      * @param isloop
  45.      */
  46.     public Animation(Context context, Bitmap [] frameBitmap, boolean isloop) {
  47.         mFrameCount = frameBitmap.length;
  48.         mframeBitmap = frameBitmap;
  49.         mIsLoop = isloop;
  50.     }
  51.    
  52.    
  53.    
  54.    /**
  55.     * 绘制动画中的其中一帧
  56.     * @param Canvas
  57.     * @param paint
  58.     * @param x
  59.     * @param y
  60.     * @param frameID
  61.     */
  62.     public void DrawFrame(Canvas Canvas, Paint paint, int x, int y,int frameID) {
  63.         Canvas.drawBitmap(mframeBitmap[frameID], x, y, paint);
  64.     }
  65.    
  66.    
  67.     /**
  68.      * 绘制动画
  69.      * @param Canvas
  70.      * @param paint
  71.      * @param x
  72.      * @param y
  73.      */
  74.     public void DrawAnimation(Canvas Canvas, Paint paint, int x, int y) {
  75.         //如果没有播放结束则继续播放
  76.         if (!mIsend) {
  77.             Canvas.drawBitmap(mframeBitmap[mPlayID], x, y, paint);
  78.             long time = System.currentTimeMillis();
  79.             if (time - mLastPlayTime > ANIM_TIME) {
  80.                 mPlayID++;
  81.                 mLastPlayTime = time;
  82.                 if (mPlayID >= mFrameCount) {
  83.                     //标志动画播放结束
  84.                     mIsend = true;
  85.                     if (mIsLoop) {
  86.                         //设置循环播放
  87.                         mIsend = false;
  88.                         mPlayID = 0;
  89.                     }
  90.                 }
  91.             }
  92.         }
  93.     }
  94.    
  95.     /**
  96.      * 读取图片资源
  97.      * @param context
  98.      * @param resId
  99.      * @return
  100.      */
  101.     public Bitmap ReadBitMap(Context context, int resId) {
  102.         BitmapFactory.Options opt = new BitmapFactory.Options();
  103.         opt.inPreferredConfig = Bitmap.Config.RGB_565;
  104.         opt.inPurgeable = true;
  105.         opt.inInputShareable = true;
  106.         // 获取资源图片
  107.         InputStream is = context.getResources().openRawResource(resId);
  108.         return BitmapFactory.decodeStream(is, null, opt);
  109.     }
  110. }
复制代码
大家看看我做的游戏demo  利用上下左右按键 播放向上 向下 向左 向右人物行走动画。



最后由于代码较多我就不贴在博客中了 , 下面给出Demo源码的下载地址欢迎大家下载阅读互相学习,互相研究


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

点评

太好好好好好好了 学习了了了 你太伟大了了了了  发表于 2014-2-23 20:15
bucuo  发表于 2013-2-28 15:46

14

主题

361

帖子

199

安币

程序猿

Rank: 2

发表于 2011-9-7 12:15:25 | 显示全部楼层
xiexie了谢谢了谢谢

0

主题

80

帖子

56

安币

程序猿

Rank: 2

QQ
发表于 2011-9-5 14:15:19 | 显示全部楼层
值得下载学习!

0

主题

380

帖子

715

安币

代码手工艺人

Rank: 4

发表于 2011-9-3 20:18:52 | 显示全部楼层
学习了~!

0

主题

160

帖子

114

安币

程序猿

Rank: 2

发表于 2011-9-9 14:43:50 | 显示全部楼层
好东西,值得学习

2

主题

40

帖子

326

安币

攻城狮

Rank: 3Rank: 3

QQ达人

QQ
发表于 2011-9-9 16:06:51 | 显示全部楼层
好,学习了。谢谢
QQ:1280514588
Email:lifangshun@126.com
android: game coding

2

主题

40

帖子

326

安币

攻城狮

Rank: 3Rank: 3

QQ达人

QQ
发表于 2011-9-9 16:07:13 | 显示全部楼层
比较详细。
QQ:1280514588
Email:lifangshun@126.com
android: game coding

1

主题

25

帖子

12

安币

初级码农

Rank: 1

发表于 2011-9-13 13:19:25 | 显示全部楼层
比较good。。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )