日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bada 2D游戏编程之八——逐帧动画

發(fā)布時間:2023/12/14 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bada 2D游戏编程之八——逐帧动画 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

bada 2D游戲編程之八——逐幀動畫 游戲就是由一個個動畫片段連接而成的,常見的有進入游戲時的加載動畫、游戲過程中精靈動畫、特效動畫和游戲的各界面之間切換時的過渡動畫等。可以說動畫在游戲中是無處不在,這樣在游戲開發(fā)中就不得不去實現(xiàn)各種動畫,但是只要了解了動畫的基本原理,實現(xiàn)起動畫來就非常方便了。其實動畫就是通過以一種連續(xù)貼圖的方式快速播放來實現(xiàn)的,同時根據(jù)貼圖的圖片產(chǎn)生的方式不同,又可以將動畫分為逐幀動畫和關(guān)鍵幀動畫。這篇文章主要對bada平臺上提供的逐幀動畫功能進行講解。 1,什么是逐幀動畫 逐幀動畫也稱為幀動畫,這是一種常見的動畫形式,它的主要特點是每一幀都需要提供一張圖片,并將組成動畫所需的一系列圖片分別放在不同的幀當中。當播放動畫時,是一幀一幀順序播放的,這樣通過一幀一幀顯示動畫的圖像序列來實現(xiàn)動畫效果。由于所有的圖片都是人工提供的,所以逐幀動畫具有非常大的靈活性,幾乎可以表現(xiàn)任何想表現(xiàn)的內(nèi)容。但同時由于每一幀圖片都需要我們動手操作產(chǎn)生,所以制作起來比較麻煩。 拿一個描述一株向日葵從苗芽狀態(tài)成長到綻放花朵的過程動畫來說,該向日葵由小變大,因此構(gòu)成該動畫的每一張圖片都是不一樣的,如下圖:

這樣順序播放這組圖片就是實現(xiàn)所需要的動畫了。 2,相關(guān)類和接口 bada平臺對實現(xiàn)逐幀動畫功能提供了很好的支持,主要由Osp::Ui::Controls::Animation,Osp::Ui::Controls::AnimationFrame和Osp::Ui::IAnimationEventListener來完成。 2.1,Osp::Ui::Controls:: AnimationFrame類 AnimationFrame表示動畫中的幀,由于逐幀動畫中每一幀都需要提供一張圖片,所以可以為每一幀添加圖片,并設(shè)定幀在屏幕上顯示的時長。下面是它的主要函數(shù):

函數(shù) 功能描述
AnimationFrame (void) 默認構(gòu)造函數(shù)
AnimationFrame (const Osp::Graphics::Bitmap &frame, long duration) 傳入位圖和持續(xù)時間值進行構(gòu)造
SetFrame (const Osp::Graphics::Bitmap &frame) 為幀添加位圖
SetDuration (long duration) 為幀設(shè)置顯示時長
2.2,Osp::Ui::Controls::Animation類 Animation類用于顯示和控制動畫播放,它將幀序列中的圖片一張一張的顯示出來形成動畫,這個幀序列是由加入了多個AnimationFrame的列表類來表示的。可以將Animation理解為動畫播放器,播放的內(nèi)容為一張張的圖片,并可以控制播放過程。下面是它的主要函數(shù):

函數(shù) 功能描述
Animation (void) 默認構(gòu)造函數(shù)
Construct (const Osp::Graphics::Rectangle &rect, const Osp::Base::Collection::IList &aniFrames) 通過矩形區(qū)域和幀序列進行初始化
AddAnimationEventListener (constOsp::Ui::IAnimationEventListener &listener) 加入事件監(jiān)聽器
Play (void) 開始播放
Pause (void) 暫停播放
Stop (void) 停止播放
SetRepeatCount (int count) 設(shè)置重復(fù)播放次數(shù)
2.3,Osp::Ui::IAnimationEventListener IAnimationEventListener用于對Animation的播放過程進行監(jiān)聽,當Animation播放結(jié)束時,通過IAnimationEventListener將結(jié)束事件通知出去,這樣注冊了的監(jiān)聽器就能夠接到事件通知了。尤其是用于當需要在動畫播放結(jié)束時進行相應(yīng)的事件處理的情況下會用到,例如開發(fā)者希望在動畫A播放結(jié)束或緊接著播放動畫B,就可以通過實行IAnimationEventListener的接口來做到。下面是它的主要函數(shù):

函數(shù) 功能描述
OnAnimationStopped (const Osp::Ui::Control &source) 事件監(jiān)聽函數(shù),用于接收動畫結(jié)束事件通知
3,動畫實現(xiàn) 接下來我們用上面提到的類來實現(xiàn)一個人物動畫,這個動畫表現(xiàn)的是人物角色在屏幕上走動的效果。 Step 1,準備動畫圖片 準備好需要添加到動畫幀中的圖片,每一幀對應(yīng)一張圖片。

Step 2,解析圖片 將圖片解析成系統(tǒng)支持的位圖。 Bitmap* pBitmap1 = pAppRes->GetBitmapN("grossini_1.png"); Bitmap* pBitmap2 = pAppRes->GetBitmapN("grossini_2.png"); Bitmap* pBitmap3 = pAppRes->GetBitmapN("grossini_3.png"); Bitmap* pBitmap4 = pAppRes->GetBitmapN("grossini_4.png"); Bitmap* pBitmap5 = pAppRes->GetBitmapN("grossini_5.png"); Bitmap* pBitmap6 = pAppRes->GetBitmapN("grossini_6.png"); Step 3,創(chuàng)建動畫幀 通過AnimationFrame來創(chuàng)建動畫幀,在其中傳入位圖并設(shè)置持續(xù)時長。 AnimationFrame* pAniFrame1 = new AnimationFrame(*pBitmap1, 100) ; AnimationFrame* pAniFrame2 = new AnimationFrame(*pBitmap2, 100) ; AnimationFrame* pAniFrame3 = new AnimationFrame(*pBitmap3, 100) ; AnimationFrame* pAniFrame4 = new AnimationFrame(*pBitmap4, 100) ; AnimationFrame* pAniFrame5 = new AnimationFrame(*pBitmap5, 100) ; AnimationFrame* pAniFrame6 = new AnimationFrame(*pBitmap6, 100) ; Step 4,創(chuàng)建幀序列 通過將表示動畫幀的AnimationFrame對象添加到列表中來實現(xiàn)幀序列。 __pFrameArray = new ArrayList(); __pFrameArray->Construct(); __pFrameArray->Add(*pAniFrame1); __pFrameArray->Add(*pAniFrame2); __pFrameArray->Add(*pAniFrame3); __pFrameArray->Add(*pAniFrame4); __pFrameArray->Add(*pAniFrame5); __pFrameArray->Add(*pAniFrame6); Step 5,創(chuàng)建動畫對象 由于Animation是一個控件類,所以需要為它設(shè)置顯示的坐標和區(qū)域,同時將幀序列傳進去,通過它來控制幀序列的顯示。 __pAnimation = new Animation(); __pAnimation->Construct(Rectangle(0, 50, 128, 128), *__pFrameArray); __pAnimation->SetRepeatCount(100); __pAnimation->AddAnimationEventListener(*this); AddControl(*__pAnimation); Step 6,控制動畫播放 最后就可以通過Animation提供的Play(),Pause(),Stop()等函數(shù)來控制動畫的播放了。 __pAnimation->Play(); Step 7,實現(xiàn)走動效果 實現(xiàn)完前面的基本,基本的動畫功能就已經(jīng)實現(xiàn)了。但是此時的人物是原地踏步的,沒有進行移動,那么如何實現(xiàn)移動的效果呢?很簡單,因為Animation是一個控件類,所以可以通過改變它的X軸和Y軸的坐標來實現(xiàn)移動的效果,別忘了刷新屏幕。 結(jié)合我們前面的文章用到的模塊代碼,只需要在UpdateLogic(int frameInterval) 函數(shù)中更新Animation的X軸和Y軸坐標就可以了。 下面的代碼是實現(xiàn)人物按照每個游戲幀間隔時間沿著X軸的正方向移動2個像素。 int xPos,yPos; __pAnimation->GetPosition(xPos,yPos); __pAnimation->SetPosition(xPos+2,yPos); 4,不足之處 這樣就實現(xiàn)了一個人物移動的動畫。但在這里大家可能會發(fā)現(xiàn)一個問題,在這里出現(xiàn)了2個幀間隔。一個是給Animation中的幀設(shè)置的間隔,可以稱為“動畫幀間隔”,還有一個是游戲的幀間隔時間,可以稱為“游戲幀間隔”。這兩個幀間隔會引入畫面不同步的問題。 (1)動畫幀間隔 > 游戲幀間隔 假定動畫幀間隔為100毫秒,游戲幀間隔為20毫秒。這樣一秒鐘中小人可以移動50次,而動畫中的圖片一秒鐘只會播放10張圖片,這樣游戲中就會出現(xiàn)動畫中的某一張圖片在移動而沒有伴隨的動作的情況,人物的移動沒有和人物的動作保持一致。 (2)動畫幀間隔 < 游戲幀間隔 假定動畫幀間隔為20毫秒,游戲幀間隔為100毫秒。這樣一秒鐘中小人可以移動10次,而動畫中的圖片一秒鐘只會播放50張圖片,這種情況下就會出現(xiàn)動畫中動作不連貫的情況發(fā)生,比如第一次移動時人物動作是1,而進行第二次移動時,此時的動作已經(jīng)到第5個了。這樣中間的動作就跳過了。 那么如果這兩個幀間隔相等呢?前面的《bada 2D游戲編程之四——設(shè)計游戲循環(huán)》中也提到過,幀間隔時間有時可能會大于設(shè)定的值,所以這個也沒法保證。但是還好一般的游戲不會要求這么嚴格,上面提到的問題在大都是可以接受的,這樣通過采用Animation進行動畫開發(fā)也是個非常不錯的選擇,這樣可以節(jié)省很多工作量。 5,最佳方案 雖然現(xiàn)在我們沒法看到bada的源代碼,但是可以猜到Animation類里面應(yīng)該是有一個定時器的,這個定時器會根據(jù)AnimationFrame中設(shè)定的時長來進行延時,從而實現(xiàn)等待多長時間后播放下一張圖片,通過這樣定時更換幀序列中的圖片就形成了動畫。但正是由于Animation類也有自己的定時器才會和游戲中的定時器相沖突,產(chǎn)生出2個幀間隔的問題。所以最好的解決辦法就是自己實現(xiàn)一個動畫類,但這個動畫類不需要自帶定時器來進行時間設(shè)定,它直接利用游戲中的幀間隔,讓動畫的播放頻率和游戲的刷新頻率保持一致或者成相應(yīng)的倍數(shù)關(guān)系,這樣就可以完全避免前面出現(xiàn)的問題了。

?

轉(zhuǎn)載于:https://blog.51cto.com/badaeva/978564

總結(jié)

以上是生活随笔為你收集整理的bada 2D游戏编程之八——逐帧动画的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。