帶你走進游戲開發的世界之游戲幀動畫的處理<ignore_js_op> 1.幀動畫的原理 幀動畫幀動畫顧名思義,一幀一幀播放的動畫就是幀動畫。 幀動畫和我們小時候看的動畫片的原理是一樣的,在相同區域快速切換圖片給人們呈現一種視覺的假象感覺像是在播放動畫,其實不過是N張圖片在一幀一幀的切換罷了。 如圖所
帶你走進游戲開發的世界之游戲幀動畫的處理
<ignore_js_op>
1.幀動畫的原理
幀動畫幀動畫顧名思義,一幀一幀播放的動畫就是幀動畫。 幀動畫和我們小時候看的動畫片的原理是一樣的,在相同區域快速切換圖片給人們呈現一種視覺的假象感覺像是在播放動畫,其實不過是N張圖片在一幀一幀的切換罷了。
如圖所示:人物行走動畫的實現方式, 4幀行走動畫在播放區域 一幀一幀向左切換播放 給人們一種播放動畫的假象 ,圖片就動了起來, 很簡單吧,其它三方向播放動畫的方法類似我就不再一一舉例。
<ignore_js_op>
2.動畫資源的原始文件
動畫資源的原始文件PNG 一般有三種形式的呈現方式 請聽我細細道來。
1.每一幀是一張png圖片中
如圖所示上下左右方向每一組動畫中的每一幀都是一張png圖片,播放動畫須要切換整張圖片 ,實現動畫效果。代碼中只需要將下一幀圖片完整的覆蓋住上一幀的圖片就OK了,這種資源的排列方式在程式演算法上是最簡單的。
<ignore_js_op>
2.所有動畫幀都存在一張png圖片中
如圖所示一張png中存放了人物所有的幀動畫,播放動畫的時候程式需要計算出將要播放的圖片在原始圖片中的起始坐標和結束坐標,也就是說要從原始圖片中把將要播放的圖片扣出來,從而顯示在手機屏幕上。這種資源的排列方式程式需要編寫計算圖片坐標位置的演算法。
<ignore_js_op>
3.動畫編輯器處理動畫
游戲公司都會有自己的動畫編輯器 ,動畫編輯器的好處是
1.減少圖片大小節省記憶體空間
2. 縮短美工對坐標時間 ,因為如果沒有編輯器美工很痛苦的需要一張圖片一張圖片的對坐標,全是體力活。
3.完全數據驅動動畫 ,動畫出問題程式不用改代碼。BUG都是美術的 ,呵呵。
動畫編輯器生成出來的其實就是坐標 告訴圖片的每一個點 每個動畫的點 拼接起來的每一個坐標 程式須要編輯對動畫編輯器生成的xml文件 根據生成出來的坐標 進行解析然後繪製出游戲動畫。AuroraGT動畫編輯器是筆者使用最多的一款動畫編輯器它的功能非常強大可以編出任意動畫。由於考慮到商業用途 對於這個編輯器的解析與使用我不做任何解釋 。如果只是單純的想學習我把編輯器的下載地址貼出來,大家可以互相研究互相討論互相學習。
下載地址: <ignore_js_op> AuroraGT.rar
<ignore_js_op>
給大家看看生成出來的動畫效果很絢麗吧,是不是很給力呢 呵呵呵呵。
<ignore_js_op>
<ignore_js_op>
我用代碼詳細的說明一下第一種和第二種游戲動畫的代碼實現方法。
我自己寫了一個動畫類來處理播放動畫,需要調用動畫只需要new一個Animation對象傳入動畫所需要的參數通過調用 DrawAnimation 方法就可以按幀播放繪製動畫。如果是單純的學習的話我覺得這個類已經夠學習使用了。
- package cn.m15.xys;
- import java.io.InputStream;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- public class Animation {
- /** 上一幀播放時間 **/
- private long mLastPlayTime = 0;
- /** 播放當前幀的ID **/
- private int mPlayID = 0;
- /** 動畫frame數量 **/
- private int mFrameCount = 0;
- /** 用於儲存動畫資源圖片 **/
- private Bitmap[] mframeBitmap = null;
- /** 是否迴圈播放 **/
- private boolean mIsLoop = false;
- /** 播放結束 **/
- private boolean mIsend = false;
- /** 動畫播放間隙時間 **/
- private static final int ANIM_TIME = 100;
- /**
- * 構造函數
- * @param context
- * @param frameBitmapID
- * @param isloop
- */
- public Animation(Context context, int [] frameBitmapID, boolean isloop) {
- mFrameCount = frameBitmapID.length;
- mframeBitmap = new Bitmap[mFrameCount];
- for(int i =0; i < mFrameCount; i++) {
- mframeBitmap[i] = ReadBitMap(context,frameBitmapID[i]);
- }
- mIsLoop = isloop;
- }
- /**
- * 構造函數
- * @param context
- * @param frameBitmap
- * @param isloop
- */
- public Animation(Context context, Bitmap [] frameBitmap, boolean isloop) {
- mFrameCount = frameBitmap.length;
- mframeBitmap = frameBitmap;
- mIsLoop = isloop;
- }
- /**
- * 繪製動畫中的其中一幀
- * @param Canvas
- * @param paint
- * @param x
- * @param y
- * @param frameID
- */
- public void DrawFrame(Canvas Canvas, Paint paint, int x, int y,int frameID) {
- Canvas.drawBitmap(mframeBitmap[frameID], x, y, paint);
- }
- /**
- * 繪製動畫
- * @param Canvas
- * @param paint
- * @param x
- * @param y
- */
- public void DrawAnimation(Canvas Canvas, Paint paint, int x, int y) {
- //如果沒有播放結束則繼續播放
- if (!mIsend) {
- Canvas.drawBitmap(mframeBitmap[mPlayID], x, y, paint);
- long time = System.currentTimeMillis();
- if (time - mLastPlayTime > ANIM_TIME) {
- mPlayID++;
- mLastPlayTime = time;
- if (mPlayID >= mFrameCount) {
- //標誌動畫播放結束
- mIsend = true;
- if (mIsLoop) {
- //設置迴圈播放
- mIsend = false;
- mPlayID = 0;
- }
- }
- }
- }
- }
- /**
- * 讀取圖片資源
- * @param context
- * @param resId
- * @return
- */
- public Bitmap ReadBitMap(Context context, int resId) {
- BitmapFactory.Options opt = new BitmapFactory.Options();
- opt.inPreferredConfig = Bitmap.Config.RGB_565;
- opt.inPurgeable = true;
- opt.inInputShareable = true;
- // 獲取資源圖片
- InputStream is = context.getResources().openRawResource(resId);
- return BitmapFactory.decodeStream(is, null, opt);
- }
- }
大家看看我做的游戲demo 利用上下左右按鍵 播放向上 向下 向左 向右人物行走動畫。
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
最後由於代碼較多我就不貼在博客中了 , 下麵給出Demo源碼的下載地址歡迎大家下載閱讀互相學習,互相研究
<ignore_js_op> 第三講之幀動畫.rar
問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com
QQ群290551701 聚集很多互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!