作者:HTML5遊戲開發者社區-白澤
轉載請註明出處:http://html5gamedev.or
HTML5 2D遊戲引擎研發系列 第四章 <Canvas技術篇-畫布技術-基於手動切片動畫>
作者:HTML5遊戲開發者社區-白澤
轉載請註明出處:http://html5gamedev.org/
目錄
- HTML5 2D遊戲引擎研發系列 第一章 <一切的開始>
- HTML5 2D遊戲引擎研發系列 第二章 <磨劍>
- HTML5 2D遊戲引擎研發系列 第三章 <Canvas技術篇-畫布技術-顯示圖片>
- HTML5 2D遊戲引擎研發系列 第四章 <Canvas技術篇-畫布技術-基於手動切片動畫>
- HTML5 2D遊戲引擎研發系列 第五章 <Canvas技術篇-畫布技術-紋理集複雜動畫>
- HTML5 2D遊戲引擎研發系列 第六章 <Canvas技術篇-畫布技術-混色特效和粒子>
- HTML5 2D遊戲引擎研發系列 第七章 <Canvas技術篇-畫布技術-鼠標偵聽器>
- HTML5 2D遊戲引擎研發系列 第八章 <Canvas技術篇-基於頂點繪製與變形>
- WEBGL 2D遊戲引擎研發系列 第一章 <新的開始>
- WEBGL 2D遊戲引擎研發系列 第二章 <顯示圖片>
- WEBGL 2D遊戲引擎研發系列 第三章 <正交視口>
- WEBGL 2D遊戲引擎研發系列 第四章 <感想以及矩陣>
- WEBGL 2D遊戲引擎研發系列 第五章 <操作顯示對象>
- WEBGL 2D遊戲引擎研發系列 第六章 <第一次封裝>
- WEBGL 2D遊戲引擎研發系列 第七章 <混色>
- WEBGL 2D遊戲引擎研發系列 第八章 <批處理(影分身之術)>
- WEBGL 2D遊戲引擎研發系列 第九章 <基於UV的模擬切片>
- WEBGL 2D遊戲引擎研發系列 第十章 <紋理集動畫>
- WEBGL 2D遊戲引擎研發系列 第十一章 <着色器-shader>
- WEBGL 2D遊戲引擎研發系列 第十二章 <粒子發射器>
- WEBGL 2D遊戲引擎研發系列 第十三章 <Shader分享>
- 遊戲技法 2D遊戲引擎研發系列 第一章 <優化技巧>
- 遊戲技法 2D遊戲引擎研發系列 第二章 <計時器>
- 遊戲技法 2D遊戲引擎研發系列 第三章 <基於UV的無縫圖像滾動>
- 遊戲技法 2D遊戲引擎研發系列 第四章 <基於形狀的碰撞檢測>
HI,大家好,前幾天加班很晚加上5.4新版本(你們懂的),所以停了2天,今天準時11點開寫,我們這一章要開始一個遊戲中重要的環節,就是基於手動切片的動畫,不知道有沒有人保留上一章節的代碼呢,如果沒有保留建議去上一章下載代碼
複製粘貼一下,我們這一章就不從頭開始了,而是基於上一章的代碼進行功能添加,現在我們可能需要一張素材,我已經給你準備了,右鍵保存吧.
如果沒有出現其他問題的話,它應該是一個384*256的圖片尺寸,現在讓我們替換昨天的素材,把它先顯示出來,在網頁中看起來應該是這個樣子,別忘記改變座標和刪除多餘的圖像.
每次看到這樣的素材我心裏都有小小的激動,彷彿一個生動的遊戲準備運行一樣,不是知道你有沒有這樣的感覺呢,爲了讓它運動起來我們需要做下面的一些工作,首先我們要確定幾個關鍵點,這非常關鍵關鍵得我需要用紅色標記出來.
動畫相對於原始圖像的裁切X位置
動畫相對於原始圖像的裁切Y位置
動畫對象的寬度
動畫對象的高度
動畫對象的X偏移信息
動畫對象的Y偏移信息
動畫的最大寬度
動畫的最大高度
現在我們的先從簡單的開始,我們只需要前4個參數也就是裁切的XY和裁切的寬度和高度就好了,看到這裏是不是想起了我們上一章節的一個函數?drawImage,沒錯了,就是它,現在讓我們讓我們的IDE切換到DisplayObject.js中,尋找MovieClip2D動畫類中的paint函數,我們做如下修改:
看到了嗎,我們只是把上一章節的繪圖函數註釋掉了,然後加了4個變量,爲什麼是32?因爲這個圖片中的小人寬度和高度正好是32,現在讓我們上傳代碼,看看發生了什麼事情.
沒錯了,這就是我們想要的效果,我們成功的顯示出了動畫的第一幀,現在我們如果需要播放動畫怎麼辦呢?我們只需要改變mcX,或者mcY就可以了,爲了方便擴展,我打算把寫在paint函數中的零時變量改成MovieClip的成員變量,就像其他屬性一樣.
現在爲了讓動畫能循環播放,我們需要知道動畫的播放長度,也就是有多少幀,所以還需要另外二個成員變量.
爲了讓動畫的邏輯信息和繪製信息分離開來,所以我們還需要一個動畫的更新函數。
當然,這樣更改之後別忘記在繪圖函數裏的參數加上this指向.
現在,讓我們把upFrameData函數添加到渲染函數裏去.
怎麼樣,思路是不是清晰了,我們的繪畫函數只負責繪圖,而不用去關心動畫的邏輯,而我們的upFrameData函數只關心動畫的邏輯而不用關心如何去繪製,現在讓我們把剛纔新建的變量放到這個邏輯塊中試試,我們先嚐試着改變mcY的爲32,如果沒有出錯的話,它應該顯示圖片的第二行的第一個動畫幀,就像這樣.
我好像又發現了什麼,我們是不是可以用mcY來控制人物的朝向?實際上是動畫場景的不同,注意,我們的動畫場景一般指一個獨立的動畫對象,現在我們可以注意到這個動畫場景的總長度是3,也就是3幀走路的動畫,那麼我們可以試試讓這個小人動起來,我們對upFrameData函數做如下修改:
在這裏,我們先強行設置了動畫幀的長度,和mcY的值,因爲人物動畫是32*32的,所以我們以mcX做爲動畫播放的依據,現在的邏輯是3幀循環播放,如果沒有出任何問題的話,你的小人現在應該已經行動起來了,細心的你一定發現了什麼,沒錯,我們現在這樣寫很不方便操作,我們需要把動畫的信息提取出去做爲一個參數,並且可以手動輸入這個值,所以我們需要做一個設計和規則來制定這個動畫標準,我們使用mcY來控制動畫的上下移動,mcY控制動畫的左右移動,並且以3幀爲一個循環,所以我們需要設置一個動畫幀的播放頭,也就是這個動畫的起始幀的位置,這個播放頭需要2個參數,動畫播放頭所在的mcX位置和mcY位置,現在讓我們添加新的2個成員變量,然後修改upFrameData的邏輯,如下.
看到了嗎,實際上我們設置播放頭時不需要再關心這個動畫的尺寸是多少了,所以我們讓播放頭乘以動畫的寬度和高度,現在讓我們回到Main.js,試試在外部修改他們的參數吧.
基於剛纔的封裝,我們可以毫不關心它的內部邏輯了,我們只要輸入動畫需要播放的參數即可,現在讓我們試試把這個小人添加到整個場景上,並且隨機播放某一段動畫吧,
因爲動畫是3幀一段,所以圖片的橫向排列一共是4段,我們取了一個隨機數然後取整再乘以3,縱向排列只需要去8段中的其中一段就好了,現在讓我們看看發生了什麼.
50個不同動畫段的小人運動着,哇,我突然有一個想法,我們加入地圖和建築吧,現在你可能還需要另外一張圖片資源,沒關係,我也已經給你準備好了,右鍵查看原圖保存吧.
到目前爲止,我們只是加載了一張圖像資源而已,現在我們可能需要寫一個簡易的隊列加載器允許我們加載N張圖片,那麼我們只需要在Main.js中加入以下代碼.
我們讓圖像加載完畢後存入imageStart數組方便我們之後的調用,現在我們需要更改一下游戲啓動的函數,就像這樣.
現在我們的圖像資源訪問應該改成這樣
好了,一切準備就緒,在我們開始拼接地板前,我們可能需要對DisplayObject.js做一點修改,因爲目前來說我們把裁切封裝成動畫專屬了,而很多情況下我們是不需要動畫的而只是裁切而已,所以我們需要加一個開關,就像這樣
默認是開啓動畫的,而我們不需要是手動關閉,然後裁切的屬性又迴歸我們所有了,爲了拼接地面我們新建了一個函數.
關閉了它的動畫自動裁切功能,我們手動設置了裁切位置,裁切的寬度和高度爲32,位置爲0,0因爲草地的圖片就在原始圖像的0,0點,以左上角爲原點.然後把它添加到人物初始化之前,因爲它的顯示層級最低
現在,提交代碼,別忘記上傳新的map圖片,然後刷新頁面看一下吧,沒有出錯它應該是這個樣子
哇,50個小人在草地上,有點遊戲的感覺了,我又熱血沸騰了,我需要加入建築,讓他們看來有個家,下面是3個建築的代碼.
然後我們把他們加入到一個新的函數裏.
然後添加到我們的主初始化函數裏
如果沒有出錯的話,測試頁面應該是這個樣子
哈哈,有點意思了,但還是感覺很空,加點裝飾物吧,代碼我就不貼了和建築一樣只是參數不同,如果沒出錯它看起來應該是這個樣子了
呼,只是添加了6個元素而已,已經把我累壞了,細心的你一定發現了切片的數據是一個固定值,沒錯,那是我開着軟件看着圖片一個一個數出來的,如果換做是你我想應該需要一個地圖編輯器去做這樣的事情,它看起來應該是這個樣
如果你正好沒有的話,可以先用用我的這個簡易的編輯器,實際上我們切片只需要知道切片的XY和寬度高度就好了,所以可以把這些屬性記錄到一個XML,下面是這個編輯器的在線地址 :
到這裏爲止,基於切片的動畫已經結束了,但是我們會發現還有很多地方不足,比如動畫幀率,如果是切片不是基於寬度高度都是可數的數呢?比如播放暫停動畫等等,這些我希望把它放在下一章,基於紋理集的動畫來講解,因爲它纔是我們最終遊戲需要用到的動畫,有了它我們纔可以做出任何不規則的動畫和不規則的切片,不過在此之前,你可以先好好玩玩這章的DEMO,試試優化一下,不要讓小人踩到屋頂去了,或者加一個鍵盤控制他們的座標移動?下章見.
轉載請註明:HTML5遊戲開發者社區 » HTML5 2D遊戲引擎研發系列 第四章