【Android遊戲開發二十二】(圖文詳解)遊戲中靈活實現動畫播放!簡述J2me的遊戲類庫與Android遊戲開發!

 李華明Himi 原創,轉載務必在明顯處註明:
轉載自 【黑米GameDev街區】 原文連接:  http://www.himigame.com/android-game/361.html


因爲寫書的緣故,博文更新緩慢,你們體諒,今天針對羣內常提出動畫實現的問題來進行一個詳細講述;css

此章節適合沒有作過遊戲開發的同窗學習!html

        作過Android軟件的童鞋們,在學習遊戲開發的時候,思惟老是被固定在了Android系統組件上!好比動畫實現總想着利用BitmapDrawable、Animation等系統提供的類和方法來實現!java

其實在本人之前作J2me開發的時候,J2me Api從MIDP2.0開始提供和封裝了Sprite類,通名:精靈類!這個類的幾種構造的時候只須要提供圖片的大小、寬高、等,就能夠生成一個精靈了,由於精靈類提供了碰撞檢測、動畫播放等方法,讓開發者在開發遊戲中非常方便。那麼其實在製做一些較爲複雜的、或者網遊開發中,公司內都不會利用這個精靈類來去作,拋開機型不說,由於每一個公司都會有其引擎和各類編輯器等等、那麼確定須要擴展,若是利用sprite來開發不只擴展不方便、不靈活以外並且和編輯器、引擎搭配開發也不適合。可是通常而言,精靈類足夠用!可是通常仍是利用MIDP1.0自定義完成這個2.0提供的Spirte類,這樣更容易維護和自定義擴展!android

並且J2me提供的遊戲開發包也是一個現成好用的引擎!因此這也能夠理解爲何在Android遊戲開發中,你們不少時候還總會看到Sprite類的影子!還有不少作過me的同窗會看到相似的代碼,總說「你這Android遊戲開發不仍是J2me的那套東西麼!」,呵呵,沒錯,可是請童鞋們先想一下,Android如今SDK 升級到了2.3 了,有據說哪一個版本中提供了相似meAPi中的「Game」專用於開發遊戲的開發包?答案是確定沒有。並且能把本身在me中的遊戲框架拿到android來,更快的進入開發也是很好的,固然這裏不是推薦把j2me的那幾個遊戲擴展包直接拿來用,這種屬於移植 - -。反而更加浪費遊戲的效率! canvas

        總結一句:不是你們不想拋開me的架構來作原生態的Android遊戲!而是Android如今沒有更好的適合遊戲的開發包;數組

 

        很少說別的了,今天主要爲各位童鞋講解在遊戲中如何實現動畫!架構

 

實現動畫,咱們通常都是本身去利用圖片數組、切片的變換造成的動畫。那麼下面給你們簡單介紹兩種實現方式:框架

 

第一種: 利用圖片數組,不斷改變畫在畫布上的圖片數組下標,從而實現動畫的造成!(每張圖片是動畫的一幀)編輯器

 

注意:下面這一段寫的是演示代碼!請自行整理;學習

變量:
 Bitmap bmp0,bmp1,bmp2;
 Bitmap[] bmp_array = new Bitmap[3];
 int bmpIndex;
 
初始化中:
bmp0 = BitmapFaxxxxxxxx;
bmp1 = BitmapFaxxxxxxxx;
bmp2 = BitmapFaxxxxxxxx;
bmp_array[0] =bmp0;
bmp_array[1] =bmp1;
bmp_array[2] =bmp2;
    
畫布中://一直在刷新畫布
canvas.drawBitmap(bmp_array[bmpIndex]);
   
邏輯中: //線程中一直在執行邏輯
bmpIndex++;
if(bmpIndex>=bmp_array.length)
   bmpIndex = 0;

 

邏輯中一直讓bmpIndex++,爲了讓圖片數組下標能向着下一張圖片索引,這樣一來在畫布中,就造成了動畫了。

有的童鞋說如何控制動畫的播放速度呢?有的說改變線程的休眠時間!!?

遊戲開發中通常都只要一個線程來控制,那麼若是你爲了控制動畫的快慢而輕率的去改變線程的休眠時間,那就大錯特錯了。咱們不該該去動主線程的刷新時間(休眠時間)而是想着去針對動畫去想辦法,這樣別的地方不會受到影響!

通常狀況下,刷新時間(線程休眠時間)很快,童鞋們確定是嫌動畫播放太快,那麼咱們能夠自定義一個計時器。 好比咱們定義一個變量去消耗掉一些時間!看如下代碼:

此段代碼仍然是演示代碼,請注意自行整理;

 變量: Bitmap bmp0,bmp1,bmp2; Bitmap[] bmp_array = new Bitmap[3]; int bmpIndex; int time; 初始化中: bmp0 = BitmapFaxxxxxxxx; bmp1 = BitmapFaxxxxxxxx; bmp2 = BitmapFaxxxxxxxx; bmp_array[0] =bmp0; bmp_array[1] =bmp1; bmp_array[2] =bmp2; 畫布中://一直在刷新畫布 canvas.drawBitmap(bmp_array[bmpIndex]); 邏輯中: //線程中一直在執行邏輯 time++; if(time%10==0){ bmpIndex++; } if(bmpIndex>=bmp_array.length) bmpIndex = 0;

 

這段代碼和以前那一段惟一的差異就是新增長了一個變量 time ,咱們假定咱們刷新時間(線程休眠時間)爲 100毫秒,那麼time++;

if(time%10==0)成立的時候理論上確定就是正好是一秒鐘,【10(time)*100(線程休眠時間)=1000(正好1秒)】這樣一來就OK,解決了!

 

第二種:利用切片來實現動畫;(全部幀數都放在同一張圖片中)

開發過遊戲的確定很熟悉下面這兩張圖:

圖1 :


圖2:

 

圖1,是個規則的幀數組成的一張圖片,圖2則是動做編輯器生成的圖片。

遊戲中通常經常使用的是規則的如圖1同樣的圖片,這樣的圖片比咱們第一種實現動畫的方式爲內存剩下了很多,那麼圖2由動做編輯器生成的固然更省! 這裏針對圖2這個我就先很少講了。由於關聯到編輯器等、你們能夠自行百度下;

 

咱們來看圖1,若是常常看我博客的會發現圖1很熟悉,嘿嘿,對的,這個是《【Android遊戲開發之四】Android簡單遊戲框架》中一我的物行走的demo,第四章我講解的是一我的物行走的demo,可是關於細節代碼當時沒有作特別註釋和說明,今天正好用在這裏,爲各位童鞋詳解講解下:

 

先上段代碼:

 

/**
 *@author Himi
 * 
 	//爲了讓童鞋們更容易理解,我這裏是把圖片分割出來,
 	//分爲上下左右四我的物方向的數組
 	private int animation_up[] = { 3, 4, 5 };    
    private int animation_down[] = { 0, 1, 2 };    
    private int animation_left[] = { 6, 7, 8 };    
    private int animation_right[] = { 9, 10, 11 }; 
public void draw() {    
        canvas = sfh.lockCanvas();    
        canvas.drawRect(0, 0, SW, SH, p);  
        canvas.save();  
        canvas.drawText("Himi", bmp_x-2, bmp_y-10, p2);    
         //這裏的clipRect是設置可視區域,記得要 canvas.save();   canvas.restore();
        //若是不懂請看【Android遊戲開發之四】 ,這裏我主要介紹canvas.clipRect() 
        //以及canvas.drawBitmap()兩個方法中的幾個參數!
        canvas.clipRect(bmp_x, bmp_y, bmp_x + bmp.getWidth() / 13, bmp_y+bmp.getHeight()); 
        //bmp_x:圖片的x座標
        //bmp_y:圖片的y座標
        //bmp_x + bmp.getWidth() / 13 :圖片的x座標+每一幀的寬度
        //bmp_y+bmp.getHeight()  :圖片的y座標+每一幀的高度 
        if (animation_init == animation_up) {    
            canvas.drawBitmap(bmp, bmp_x - animation_up[frame_count] * (bmp.getWidth() / 13), bmp_y, p); 
            //bmp:有不少幀在一塊兒的這張圖片(圖1)
            //bmp_x - animation_up[frame_count] * (bmp.getWidth() / 13) :
            //圖片的x座標 - 每一幀的X座標(這裏看備註1)
        	//bmp_y:圖片的y座標
        	//p:畫筆
        } else if (animation_init == animation_down) {    
            canvas.drawBitmap(bmp, bmp_x - animation_down[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        } else if (animation_init == animation_left) {    
            canvas.drawBitmap(bmp, bmp_x - animation_left[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        } else if (animation_init == animation_right) {    
            canvas.drawBitmap(bmp, bmp_x - animation_right[frame_count] * (bmp.getWidth() / 13), bmp_y, p);    
        }    
        canvas.restore();  //備註3  
        sfh.unlockCanvasAndPost(canvas);    
    }    
    public void cycle() {    
        if (DOWN) {    
            bmp_y += 5;    
        } else if (UP) {    
            bmp_y -= 5;    
        } else if (LEFT) {    
            bmp_x -= 5;    
        } else if (RIGHT) {    
            bmp_x += 5;    
        }    
        if (DOWN || UP || LEFT || RIGHT) {    
            if (frame_count < 2) {    
                frame_count++;    
            } else {    
                frame_count = 0;    
            }    
        }    
        if (DOWN == false && UP == false && LEFT == false && RIGHT == false) {    
            frame_count = 0;    
        }    
    }   
    */
 

備註1:解釋爲何要 「圖片的x座標 - 每一幀的X座標」:

    你們先看下圖:

假設:咱們如今把可視區域設定在(0,0)點,但是區域大小正好是圖片每一幀的寬高;那麼此時咱們先在可視區域中顯示下標爲0的幀,咱們只要把整張圖片畫在(0,0)便可,如上圖中畫的同樣,如今只有第一幀能看到,那麼咱們若是想看第二張呢?固然是用圖片的x座標 - 每一幀的X座標,就能看到下標爲1的這一幀!以下圖;

 

 

OK,這裏我要強調一下:必定要理解這種思路,由於咱們這裏圖1的高正好是每幀的高,可能之後有高寬都不同!因此這裏我在向你們介紹這種思路,千萬要學以至用!!!OK,今天就講到這,繼續忙着寫書啦。謝謝你們一直的支持!

 

         Thx everybody! 娃哈哈~

 

 

 

 

 

 

 

 


原文連接: http://blog.csdn.net/xiaominghimi/article/details/6221581
相關文章
相關標籤/搜索