卡馬克卷軸算法研究_第1頁(yè)
卡馬克卷軸算法研究_第2頁(yè)
卡馬克卷軸算法研究_第3頁(yè)
卡馬克卷軸算法研究_第4頁(yè)
卡馬克卷軸算法研究_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、卡馬克卷軸算法研究卡馬克卷軸算法研究摘要與關(guān)鍵詞摘要與關(guān)鍵詞中文摘要中文摘要對(duì)于 J2ME 框架下的手機(jī)游戲程序的開(kāi)發(fā),其地圖滾動(dòng)的重繪有多種算法,由于手機(jī)性能的限制和開(kāi)發(fā)周期等其他非技術(shù)條件,需要根據(jù)情況靈活選擇所需的技術(shù)。但在及其苛刻條件下,如系統(tǒng) CPU 資源不足,地圖塊尺寸較小等,會(huì)造成屏幕閃耀,幀數(shù)過(guò)低等情況,嚴(yán)重影響到游戲體驗(yàn)。在開(kāi)發(fā)中如此類問(wèn)題無(wú)法繞過(guò)以及避免(指通過(guò)修改策劃方案,以及程序使用的技術(shù)框架) ,則需要考慮使用地圖緩沖繪制技術(shù),卡馬克卷軸就是一種最經(jīng)典的地圖緩沖繪制技術(shù)??捎行У母纳圃诘貓D繪制中的屏幕閃耀,幀數(shù)過(guò)低等情況。English AbstractFor J2M

2、E Mobile Phone Games under the framework of the development process, and its rolling redraw the map has a variety of algorithms, because of restrictions on mobile phone performance and development cycle and other non-technical conditions required under the circumstances required the flexibility to c

3、hoose technologies. However, in its harsh conditions, such as system CPU resources are insufficient, and a smaller block size, etc., will cause the screen shine, low frames, etc., seriously affecting the gaming experience. At the development of such a category can not bypass the problem and to avoid

4、 (referring to the adoption of amendments to planning programs, as well as the technology used in the framework of the procedure), you need to consider the use of map rendering buffer, scroll Carmack is one of the most classic map buffer rendering. Can effectively improve the mapping of the screen s

5、hine, frames are too low and so on.關(guān)鍵詞關(guān)鍵詞卡馬克卷軸:一種經(jīng)典的地圖緩沖繪制技術(shù)。可有效的改善在地圖繪制中的屏幕閃耀,幀數(shù)過(guò)低等情況。Title:地圖的貼片,指在地圖繪制時(shí),系統(tǒng)重繪的最小地圖單元。一般為正方形,尺寸有8、16、24、32 Pixels 等。地圖重繪:在游戲中由于角色移動(dòng)造成的地圖顯示區(qū)域的改變,重新繪制地圖的顯示區(qū)域就稱為地圖重繪。緩沖:在內(nèi)存中建立一個(gè)區(qū)域,該區(qū)域等于或者略大于屏幕大小。在重繪時(shí),首先在緩沖區(qū)上重繪,再一次性把緩沖區(qū)畫(huà)到屏幕上。這種預(yù)先繪制的方式就是緩沖。目錄目錄摘要與關(guān)鍵詞摘要與關(guān)鍵詞.2中文摘要.2ENGLISH

6、ABSTRACT.2關(guān)鍵詞.2正文正文.4緒論緒論.4主體主體.4一、地圖繪制的常用算法和優(yōu)化.41.1無(wú)縫圖片滾動(dòng)畫(huà)法.4的裁剪區(qū)畫(huà)法.5的圖素切片畫(huà)法.71.4最常見(jiàn)的地圖繪制優(yōu)化只繪制當(dāng)前屏幕.81.5卡馬克卷軸算法的引入.8二、卡馬克卷軸算法原理.92.1X|Y單軸滾動(dòng)的卡馬克卷軸.92.2X&Y雙軸滾動(dòng)的卡馬克卷軸.10三、卡馬克卷軸的代碼實(shí)現(xiàn)方法.123.1問(wèn)題簡(jiǎn)化與算法步驟.123.2類CarMapBuffer設(shè)計(jì).123.3步驟一的實(shí)現(xiàn).143.4步驟二、三的實(shí)現(xiàn).143.5步驟四的實(shí)現(xiàn).153.6步驟五的實(shí)現(xiàn).17四、卡馬克卷軸的實(shí)際應(yīng)用項(xiàng)目分析.194.1項(xiàng)目測(cè)試概

7、述.194.2事件查看器的數(shù)據(jù)比較.204.3內(nèi)存監(jiān)視器的數(shù)據(jù)比較.224.4真機(jī)測(cè)試比較.23結(jié)論結(jié)論.23致謝致謝.24參考文獻(xiàn)參考文獻(xiàn).24附錄附錄.24卡馬克卷軸的相關(guān)歷史卡馬克卷軸的相關(guān)歷史.24正文正文緒論緒論卡馬克卷軸是一種經(jīng)典的地圖緩沖繪制技術(shù)。可有效的改善在地圖繪制中的屏幕閃耀,幀數(shù)過(guò)低等情況。可以使用在性能受到限制的手機(jī)上,以提高地圖顯示質(zhì)量,防止屏幕閃耀,以及提高游戲時(shí)的幀數(shù)。研究方法及過(guò)程如下:首先分析比較幾種常見(jiàn)的地圖繪制方法,指出其優(yōu)劣,并引入地圖緩沖的重繪問(wèn)題。然后對(duì)卡馬克卷軸的算法原理做具體描述以及分析。之后使用 j2me 技術(shù)平臺(tái)實(shí)現(xiàn)卡馬克卷軸算法的 DEMO

8、,用于技術(shù)演示。最后在實(shí)際開(kāi)發(fā)的項(xiàng)目中,檢測(cè)和評(píng)估卡馬克卷軸的實(shí)際優(yōu)化效果,并給出結(jié)論。由于篇幅以及時(shí)間所限,對(duì)于卡馬克卷軸的多種變形寫(xiě)法,沒(méi)有做進(jìn)一步的分析。主體主體一、地圖繪制的常用算法和優(yōu)化一、地圖繪制的常用算法和優(yōu)化注:沒(méi)有討論 MIDP2.0 中的 GAMEAPI 下 TiledLayer 類畫(huà)法1.1 無(wú)縫圖片滾動(dòng)畫(huà)法無(wú)縫圖片滾動(dòng)畫(huà)法說(shuō)明:最簡(jiǎn)單的一種畫(huà)地圖方法,無(wú)需使用數(shù)組,使用一張無(wú)縫的背景圖片,在屏幕上繪制兩次,以此來(lái)實(shí)現(xiàn)最簡(jiǎn)單的地圖滾動(dòng)效果,和圖片的重復(fù)使用以節(jié)約資源。示意圖:紅色虛線部分為屏幕,使用一個(gè)偏移量在屏幕中錯(cuò)開(kāi)位置貼上兩次圖片,通過(guò)不斷改變偏移量的大小來(lái)實(shí)現(xiàn)動(dòng)畫(huà)

9、效果。代碼舉例:/imgBack 圖片對(duì)象/posX 圖片在 X 軸方向上的偏移量g.drawImage(imgBack, -posX, 0, 0);g.drawImage(imgBack, imgBack.getHeight()+posX, 0, 0);if(posX=-imgBack.getHeight()posX=0;優(yōu)點(diǎn)與局限:此算法非常簡(jiǎn)單,由于是單張圖片反復(fù)滾動(dòng)生成的背景圖片,所以對(duì)于美術(shù)人員的限制較少利于發(fā)揮,而已外觀效果好。但因?yàn)椴皇堑貓D Title 組成的,資源復(fù)用率不高,只能用于生成不太復(fù)雜的地圖。而且由于沒(méi)有 Title 的存在,無(wú)法針對(duì)不同的 Title 計(jì)算碰撞。最終

10、使得這種畫(huà)法只能用于繪制簡(jiǎn)單屏幕背景圖片,而無(wú)法用在有復(fù)雜物理碰撞的地圖層。1.2MIDP1.0 的裁剪區(qū)畫(huà)法的裁剪區(qū)畫(huà)法說(shuō)明:使用二維數(shù)組保存地圖信息,另外有一張圖片素材,根據(jù)地圖數(shù)組的不同下標(biāo),配合setClip(x,y,w,h)裁剪區(qū)方法,將對(duì)應(yīng)的 Title 顯示在正確的位置上。示意圖:紅色虛線部分為屏幕,紅色實(shí)線為裁剪區(qū),通過(guò)讀取地圖數(shù)組,將相應(yīng)的位置設(shè)置為裁剪區(qū),并用將圖片素材相對(duì)于裁剪區(qū)偏移一定 x,y 位置的方法,使得要繪制的 Title 正好對(duì)應(yīng)出現(xiàn)在裁剪區(qū)中。背景圖片背景圖片屏幕滾動(dòng)方向代碼舉例:/cellSize 一個(gè) title 的尺寸大小,寬高同/mapArray 地

11、圖數(shù)組 ,保存地圖信息/leftTopX,leftTopY 地圖相對(duì)于屏幕位置的偏移量/picColNum,圖片素材的 title 列數(shù)forfor(intint i=0;imapArray.length;i+)forfor(intint j=0;jmapArray0length;j+)g.setClip(j*cellSize-leftTopX, i*cellSize -leftTopY, cellSize, cellSize);g.drawImage(imgMap, j* cellSize -(mapArrayij-1)%picColNum* cellSize -leftTopX, i* c

12、ellSize -(mapArrayij-1)/picColNum* cellSize -leftTopY, 0);g.setClip(0,0,GameCanvas.WIDTH,GameCanvas.HEIGHT);優(yōu)點(diǎn)與局限:相對(duì)于前一種畫(huà)法,圖片資源的利用率提高了很多,可以繪制很復(fù)雜的地圖。由于 Title 的存在,可以針對(duì)不同的 Title 計(jì)算碰撞,可以用于地圖物理層的繪制。但是由于 setClip 裁剪區(qū)本身的局限,實(shí)際上每次繪制都多畫(huà)了很多不會(huì)顯示的內(nèi)容(如上圖) ,因此會(huì)造成系統(tǒng)資源的浪費(fèi)。屏幕尺寸越大,cellSize 越小,資源浪費(fèi)就越大。屏幕裁剪區(qū)偏移 x,y1.3MIDP

13、2.0 的圖素切片畫(huà)法的圖素切片畫(huà)法說(shuō)明:在 MIDP2.0 的 Image 類中添加了 createImage(Image image, int x, int y, int width, int height, int transform)方法,使用該方法可以非常方便的在內(nèi)存中創(chuàng)建地圖 Title 的切片緩沖區(qū)(Image 對(duì)象數(shù)組) 。使用切片緩沖區(qū)中的 Title 我們可以很方便的在屏幕中繪制地圖元素。示意圖:紅色虛線部分為屏幕,紅色實(shí)線為當(dāng)前繪制的 title,通過(guò)讀取地圖數(shù)組,將內(nèi)存緩沖區(qū)中相對(duì)應(yīng)的 Title 繪制到屏幕上。代碼舉例:/省略了創(chuàng)建地圖 Title 的切片緩沖區(qū)cel

14、lImage的方法forfor (intint i = 0; i mapArray.length; i+) forfor (intint j = 0; j 0)g.drawImage(cellImagemapArrayij-1,j * cellSize -leftTopX,i * cellSize -leftTopY,0);屏幕內(nèi)存中地圖切片緩沖區(qū)(Image 對(duì)象數(shù)組)畫(huà)在對(duì)應(yīng)位置上優(yōu)點(diǎn)與局限:擁有 1.0 畫(huà)法的所有優(yōu)點(diǎn),繪制地圖十分方便。而且createImage(Image image, int x, int y, int width, int height, int transfor

15、m)方法所創(chuàng)建的圖片為透明圖片,在創(chuàng)建復(fù)雜的多重背景滾動(dòng)地圖時(shí)更加游刃有余。1.4 最常見(jiàn)的地圖繪制優(yōu)化最常見(jiàn)的地圖繪制優(yōu)化只繪制當(dāng)前屏幕只繪制當(dāng)前屏幕上面的繪制方法都是畫(huà)整個(gè)地圖的,對(duì)于游戲中地圖比屏幕大的情況,會(huì)造成很大的資源浪費(fèi)。在實(shí)際開(kāi)發(fā)中,常用的優(yōu)化方法就是只繪制當(dāng)前屏幕的地圖 Title。代碼舉例:/計(jì)算單元格起始位置下標(biāo)intint iStart=leftTopY/ cellSize;intint jStart=leftTopX/ cellSize;/計(jì)算單元格繪制寬度和高度intint iNum=GameCanvas.HEIGHT/ cellSize +1;intint jNu

16、m=GameCanvas.WIDTH/ cellSize +1;/防止下標(biāo)越界ifif(iStart+iNum=mapArray.length)iNum=mapArray.length-1-iStart;ifif(jStart+jNum=mapArray0.length)jNum=mapArray0.length-1-jStart;/再使用上面得到的數(shù)據(jù)修改雙循環(huán)繪制的條件即可,下略1.5 卡馬克卷軸算法的引入卡馬克卷軸算法的引入對(duì)于某些資源嚴(yán)重不足的手機(jī),或者由于 Title 比較小,循環(huán)次數(shù)過(guò)多而造成畫(huà)圖時(shí)屏幕閃耀。就需要針對(duì)畫(huà)圖時(shí)相關(guān)算法做進(jìn)一步的優(yōu)化算法了。不論哪種優(yōu)化算法,一個(gè)統(tǒng)一的

17、思路就是盡量減少繪制的次數(shù),從而減少系統(tǒng)資源的消耗??R克卷軸就是這樣算法的一個(gè)經(jīng)典例子。二、卡馬克卷軸算法原理二、卡馬克卷軸算法原理2.1X|Y 單軸滾動(dòng)的卡馬克卷軸單軸滾動(dòng)的卡馬克卷軸對(duì)于橫版游戲來(lái)說(shuō),如果角色向右側(cè)移動(dòng),則地圖向左側(cè)滾動(dòng)。由于角色每次移動(dòng)若干個(gè)pixel(步長(zhǎng)) ,因此地圖中新畫(huà)出的區(qū)域?qū)挾纫矠槿舾蓚€(gè) pixel,那么如果讓系統(tǒng)重繪所有屏幕區(qū)域,很明顯大部分區(qū)域都是和上一次屏幕區(qū)域相同的,如此造成成了資源的浪費(fèi)。這里有一個(gè)思路如果上一次繪制過(guò)的地圖也能夠部分重用到本次地圖繪制上來(lái)就好了。那么很容易想到在內(nèi)存中建立一個(gè)和屏幕一樣大的(或略大的)Image 緩沖區(qū)即可。地圖的

18、全部區(qū)域上一次屏幕位置當(dāng)前屏幕位置區(qū)域 B:相同的地圖區(qū)域區(qū)域 C:由于地圖滾動(dòng)而新出現(xiàn)的區(qū)域區(qū)域 A:由于地圖滾動(dòng)而被舍棄的區(qū)域地圖滾動(dòng)方向由上圖可以看到,區(qū)域 B 為相同的地圖區(qū)域,這個(gè)區(qū)域在下一次屏幕重繪時(shí),可以被重新利用。區(qū)域 A 是在下一次屏幕重繪中不被采用的區(qū)域,這區(qū)域應(yīng)當(dāng)被舍棄,但是如果稍微留意一下的話,不難發(fā)現(xiàn)區(qū)域 A 和區(qū)域 C 的面積大小其實(shí)居然是一樣的。那么如果建立一個(gè)和屏幕大小相同的緩沖,在其被舍棄掉的繪制區(qū)域 A 中畫(huà)上新的區(qū)域 C,再把區(qū)域 B 和區(qū)域 C 拼合到屏幕上,是不是就能達(dá)到減少系統(tǒng)資源消耗的目的了呢?卡馬克卷軸的基本原理正是如此。1212緩沖區(qū)屏幕拼合保

19、持不變繪制新內(nèi)容上圖顯示了卡馬克卷軸的最基本原理,首先在內(nèi)存中建立一塊和屏幕一樣大小(或略大)的緩沖區(qū)。然后在本應(yīng)由于地圖移動(dòng)而被舍棄掉的區(qū)域 1 上面繪制,由于地圖滾動(dòng)而出現(xiàn)的新地圖區(qū)域。最后把兩個(gè)區(qū)域按照地圖的實(shí)際位置拼合到屏幕上。2.2X&Y 雙軸滾動(dòng)的卡馬克卷軸雙軸滾動(dòng)的卡馬克卷軸對(duì)于俯視游戲,或者有 y 軸卷動(dòng)的游戲來(lái)說(shuō),單單一個(gè)方向的地圖卷動(dòng)并不夠用。那么如果是出現(xiàn)兩個(gè)方向的卷動(dòng)會(huì)如何呢。不必?fù)?dān)心,上面的思路算法一樣能適應(yīng)這種情況。上一次屏幕位置當(dāng)前屏幕位置區(qū)域 D:相同的地圖區(qū)域區(qū)域 C:由于地圖滾動(dòng)而新出現(xiàn)的區(qū)域區(qū)域 A:由于地圖滾動(dòng)而被舍棄的區(qū)域區(qū)域 B:由于地圖滾動(dòng)

20、而被舍棄的區(qū)域區(qū)域 C:由于地圖滾動(dòng)而被舍棄的區(qū)域區(qū)域 A:由于地圖滾動(dòng)而新出現(xiàn)的區(qū)域區(qū)域 B:由于地圖滾動(dòng)而新出現(xiàn)的區(qū)域由上圖可以看到,區(qū)域 D 為相同的地圖區(qū)域,這個(gè)區(qū)域在下一次屏幕重繪時(shí),可以被重新利用。區(qū)域 ABC 是在下一次屏幕重繪中不被采用的區(qū)域,可以在這個(gè) 3 個(gè)區(qū)域上繪制上下一次需要重繪的區(qū)域 ABC。再將繪制好的四個(gè)區(qū)域拼合到屏幕的對(duì)應(yīng)位置。12341234緩沖區(qū)屏幕拼合保持不變繪制新內(nèi)容繪制新內(nèi)容繪制新內(nèi)容上圖顯示了 x&y 雙軸滾動(dòng)的卡馬克卷軸的基本繪制原理,需要特別注意的是:在緩沖區(qū)的繪地圖滾動(dòng)方向地圖的全部區(qū)域制順序和在屏幕上拼合的順序是完全相反的。三、卡馬克

21、卷軸的代碼實(shí)現(xiàn)方法三、卡馬克卷軸的代碼實(shí)現(xiàn)方法3.1 問(wèn)題簡(jiǎn)化與算法步驟問(wèn)題簡(jiǎn)化與算法步驟地圖卷軸會(huì)分成 8 個(gè)方向滾動(dòng),初看起來(lái)比較復(fù)雜。但左上、右上、左下、右下的四個(gè)方向又可以看成是 x 以及 y 兩個(gè)方向合成的。而不論地圖是在 x 軸卷動(dòng)還是在 y 軸卷動(dòng),無(wú)論是正方向還是負(fù)方向,其原理是完全相同。如此,算法的研究就變?yōu)槿绾卫L制在 x 軸方向的卷動(dòng),其他方向的以此類推即可??R克卷軸緩沖畫(huà)法的一般步驟如下:1.初始化所有地圖數(shù)據(jù),并且全屏繪制初始的地圖2.若人物移動(dòng),則調(diào)用攝像機(jī)算法,修正地圖偏移量3.地圖偏移量不滿足地圖的邊界條件,就重繪緩沖區(qū)4.重繪緩沖區(qū)5.后臺(tái)緩沖區(qū)的四個(gè)子區(qū)按照

22、順序畫(huà)到屏幕上3.2 類類 CarMapBuffer 設(shè)計(jì)設(shè)計(jì)字段定義/* 緩沖區(qū)寬高,命名方式為:Carmack width or height */privateprivate finalfinal intint carWidth, carHeight;/* 緩沖區(qū)寬的圖塊數(shù),與高的圖塊數(shù),命名方式為:Carmack title width or height */privateprivate finalfinal intint carTitleWidth, carTitleHeight;/* 屏幕寬高命名方式為:screen width or height */privateprivat

23、e finalfinal intint scrWidth, scrHeight;/* 緩沖切割線,命名方式為:Carmack x or y */privateprivate intint carx, cary;/* 地圖在緩沖區(qū)的X 、Y偏移量,命名方式為:map offset x or y */privateprivate intint mapOffx, mapOffy;/* 緩沖區(qū),命名方式為:Carmack buffer */privateprivate Image carBuffer;/* 緩沖區(qū)畫(huà)筆,命名方式為:Carmack Graphics */privateprivate Gr

24、aphics carGp;/* 緩沖區(qū)增大的大?。ㄉ舷麓笮∈且粯拥模?*/使用這個(gè)量讓緩沖區(qū)比屏幕大一些privateprivate finalfinal intint buffSize;/* 圖片寬度的所切割的圖塊數(shù)量。 */privateprivate intint imageTitleWidth;/ */ interim 臨時(shí)/* 地圖圖片 */privateprivate Image mapImage;/* 地圖數(shù)組 */privateprivate bytebyte mapArray;/* 圖塊大小,寬高一致 */privateprivate intint titleSize;/*

25、圖塊的寬度數(shù)量,與高度數(shù)量 */privateprivate intint titleW, titleH;/* 地圖的寬高 */偏移量的最遠(yuǎn)位置,用來(lái)修正mapOffx, mapOffyprivateprivate intint mapLastx, mapLasty;方法定義CarMapBuffer(int, int, int, int)構(gòu)造器CarMapBuffer(int, int, int)構(gòu)造器的代理setMap(Image, byte)設(shè)置地圖參數(shù)initBuffer()初始化繪制地圖scroll(int, int)卷動(dòng)地圖算法updateBuffer(int, int)繪制緩沖區(qū)g

26、etIndexCarX()獲得切割線所在的圖塊索引 XgetIndexCarY()獲得切割線所在的圖塊索引 YgetBufferCarX()獲得切割線在 Buffer 中的 X 位置getBufferCarY()獲得切割線在 Buffer 中的 Y 位置getIndexBuffLastX()獲得緩沖區(qū)后面的 X 索引getIndexBuffLastY()獲得緩沖區(qū)后面的 Y 索引getTitleHeight()獲得當(dāng)前要繪制的圖塊高度的數(shù)量getTitelWidth()獲得當(dāng)前要繪制的圖塊寬度的數(shù)量copyBufferX(int, int, int, int, int) 由于 x 方向卷動(dòng)造成

27、的重繪copyBufferY(int, int, int, int, int) 由于 y 方向卷動(dòng)造成的重繪getMapX(int, int) 獲得地圖圖片的 X 坐標(biāo)偏移getMapY(int, int) 獲得地圖圖片的 Y 坐標(biāo)偏移paint(Graphics, int, int)將緩沖區(qū)的內(nèi)容分成 4 塊依次拼合到屏幕上drawBuffer(Graphics, int, int)繪制緩沖區(qū)方法drawRegion(Graphics, Image, int, int, int, int, int, int, int, int)封裝的 drawRegion()方法getGraphics()獲

28、得緩沖區(qū)畫(huà)筆getImage()獲得緩沖區(qū) Image 對(duì)象3.3 步驟一的實(shí)現(xiàn)步驟一的實(shí)現(xiàn)初始化所有地圖數(shù)據(jù),并且全屏繪制初始的地圖此步驟和普通的地圖繪制基本相同,略過(guò)3.4 步驟二、三的實(shí)現(xiàn)步驟二、三的實(shí)現(xiàn)若人物移動(dòng),則調(diào)用攝像機(jī)算法,修正地圖偏移量,若偏移量在0,maplast移動(dòng)范圍內(nèi)移動(dòng),則有可能發(fā)生重繪/* * 卷軸滾動(dòng) * paramparam x X軸滾動(dòng) * paramparam y Y軸滾動(dòng) */publicpublic voidvoid scroll(intint x, intint y) x += mapOffx;y += mapOffy;/ */ 邊界檢測(cè)ifif (

29、x 0 | y mapLastx) mapOffx = mapLastx;returnreturn;ifif (y mapLasty) mapOffy = mapLasty;returnreturn;updateBuffer(x, y);/若在0,maplast移動(dòng)范圍內(nèi)移動(dòng),則有可能發(fā)生重繪3.5 步驟四的實(shí)現(xiàn)步驟四的實(shí)現(xiàn)重繪緩沖區(qū),地圖的 x 方向卷動(dòng)會(huì)造成列方向上的重繪(調(diào)用copyBufferX()方法) ,地圖的 y方向上的卷動(dòng)會(huì)造成行方向上的重繪(調(diào)用copyBufferY()方法) 。updateBuffer()方法用于針對(duì)不同的四個(gè)方向上的卷動(dòng)進(jìn)行copyBuffer()參數(shù)的

30、初始化。/* * 更新緩沖區(qū) * paramparam x 緩沖區(qū)新的地圖X坐標(biāo) * paramparam y 緩沖區(qū)新的地圖Y坐標(biāo) */privateprivate voidvoid updateBuffer(intint x, intint y) mapOffx = x;/確定了地圖移動(dòng),那么記錄新的偏移位置mapOffy = y;/ 右移 x軸正向ifif (x carx + buffSize) /因?yàn)榫彌_區(qū)比屏幕大了一些,所以還需要判斷當(dāng)前緩沖區(qū)的內(nèi)容是否夠用intint indexMapLastX = getIndexBuffLastX();ifif (indexMapLastX t

31、itleW) copyBufferX(indexMapLastX, getIndexCarY(), getTitleHeight(),getBufferCarX(), getBufferCarY();carx += titleSize;/ 左移 x軸負(fù)向ifif (x cary + buffSize) intint indexMapLastY = getIndexBuffLastY();ifif (indexMapLastY titleH) copyBufferY(getIndexCarX(), indexMapLastY, getTitelWidth(),getBufferCarX(), g

32、etBufferCarY();cary += titleSize;/ 上移 y軸負(fù)向ifif (y cary) cary -= titleSize;copyBufferY(getIndexCarX(), getIndexCarY(), getTitelWidth(),getBufferCarX(), getBufferCarY();重繪緩沖區(qū)的具體方法,該方法涉及到大量的坐標(biāo)運(yùn)算,而且由于卡馬克點(diǎn)的存在經(jīng)常會(huì)分成兩個(gè)區(qū)域分兩次進(jìn)行重繪。見(jiàn)下圖:title3124緩沖區(qū)保持不變繪制新內(nèi)容繪制新內(nèi)容保持不變地圖滾動(dòng)方向destxdestyindexMapx indexMapytitleHeight

33、下面以 x方向卷動(dòng)為例舉例/* * 由于x方向卷動(dòng)造成的重繪 * paramparam indexMapx 重繪區(qū)域左上角的title的j號(hào) * paramparam indexMapy 重繪區(qū)域左上角的title的i號(hào) * paramparam titleHeight 重繪區(qū)域的高度title數(shù),由這個(gè)量來(lái)控制兩次重繪的區(qū)域高度 * paramparam destx 重繪區(qū)域在緩沖區(qū)的相對(duì)位置x * paramparam desty 重繪區(qū)域在緩沖區(qū)的相對(duì)位置y */privateprivate voidvoid copyBufferX(intint indexMapx, intint in

34、dexMapy, intint titleHeight,intint destx, intint desty) intint mapImagex, mapImagey, vy;/ 繪制緩沖區(qū)下面部分 和地圖的上面部分對(duì)應(yīng)forfor (intint j = 0; j titleHeight; j+) mapImagex = getMapX(indexMapy + j, indexMapx);mapImagey = getMapY(indexMapy + j, indexMapx);vy = j * titleSize + desty;carGp.setClip(destx, vy, title

35、Size, titleSize);carGp.drawImage(mapImage, destx - mapImagex, vy - mapImagey, 0);/ 繪制緩沖區(qū)上面部分 和地圖的下面部分對(duì)應(yīng)forfor (intint k = titleHeight; k carTitleHeight; k+) mapImagex = getMapX(indexMapy + k, indexMapx);mapImagey = getMapY(indexMapy + k, indexMapx);vy = (k - titleHeight) * titleSize;carGp.setClip(de

36、stx, vy, titleSize, titleSize);carGp.drawImage(mapImage, destx - mapImagex, vy - mapImagey, 0);3.6 步驟五的實(shí)現(xiàn)步驟五的實(shí)現(xiàn)將后臺(tái)緩沖區(qū)的四個(gè)子區(qū)按照順序畫(huà)到屏幕上,這一步很簡(jiǎn)單,原理之前已經(jīng)詳細(xì)講述過(guò),不再贅述。/* * 繪畫(huà)緩沖 * paramparam g 屏幕畫(huà)筆 * paramparam x 繪畫(huà)X點(diǎn) * paramparam y 繪畫(huà)Y點(diǎn) */publicpublic voidvoid paint(Graphics g, intint x, intint y) / 地圖在緩沖中的坐標(biāo)i

37、ntint tempx = mapOffx % carWidth;intint tempy = mapOffy % carHeight;/ 切割線右下角的寬與高intint rightWidth = carWidth - tempx;intint rightHeight = carHeight - tempy;/ 畫(huà)左上drawRegion(g, carBuffer, tempx, tempy, rightWidth, rightHeight, 0, x,y, 0);/ 畫(huà)右上drawRegion(g, carBuffer, 0, tempy, scrWidth - rightWidth, r

38、ightHeight,0, x + rightWidth, y, 0);/ 畫(huà)左下drawRegion(g, carBuffer, tempx, 0, rightWidth, scrHeight - rightHeight,0, x, y + rightHeight, 0);/ 畫(huà)右下drawRegion(g, carBuffer, 0, 0, scrWidth - rightWidth, scrHeight- rightHeight, 0, x + rightWidth, y + rightHeight, 0);四、卡馬克卷軸的實(shí)際應(yīng)用項(xiàng)目分析四、卡馬克卷軸的實(shí)際應(yīng)用項(xiàng)目分析4.1 項(xiàng)目測(cè)試

39、概述項(xiàng)目測(cè)試概述下面以手機(jī)游戲FC 惡魔城手機(jī)復(fù)刻版為例實(shí)際檢測(cè)一下卡馬克卷軸的繪制優(yōu)化效果。測(cè)試環(huán)境如下:硬件環(huán)境: Intel(R) Pentium(R) Dual E2140 1.60GHz 1.60GHz , 2.00G 內(nèi)存 , NVIDIA GeForce 8500 GT軟件環(huán)境:windowsXpSp2,eclipse3.2+eclipseME1.5 插件,wtk2.2,jdk,使用DefaultColorPhone 模擬器代碼環(huán)境:Title 大小 8pixels,繪制區(qū)域 Title 數(shù)量 30*12,普通繪制方法下,每幀繪制 Title 的循環(huán)次數(shù) 30*12=360 次;

40、卡馬克卷軸緩沖繪制方法下,每次更新緩沖區(qū)時(shí),繪制 Title 的循環(huán)次數(shù)1224 次測(cè)試內(nèi)容以及測(cè)試方法為:讓主角移動(dòng)直到走過(guò)第一關(guān)的第一個(gè)小場(chǎng)景為結(jié)束。使用 wtk 的事件查看器和內(nèi)存監(jiān)控器來(lái)進(jìn)行系統(tǒng)后臺(tái)數(shù)據(jù)的分析。數(shù)據(jù)分為兩個(gè)組,一個(gè)組使用卡馬克卷軸優(yōu)化算法,一個(gè)組使用普通的地圖繪制算法。比較兩組數(shù)據(jù)得出結(jié)論。4.2 事件查看器的數(shù)據(jù)比較事件查看器的數(shù)據(jù)比較首先是卡馬克卷軸繪制地圖組的數(shù)據(jù)截圖然后是對(duì)照組普通繪制地圖時(shí)的數(shù)據(jù)截圖從上面的數(shù)據(jù)可以看出,使用了卡馬克卷軸算法后,繪制地圖的方法所占用的 CPU 時(shí)間的比率大幅度下降,從 55.83%下降到了 9.04%,降幅達(dá)到 46.79%,效

41、果十分明顯。兩種情況下的方法調(diào)用次數(shù)則差不多,分別是 184 次和 182 次。4.3 內(nèi)存監(jiān)視器的數(shù)據(jù)比較內(nèi)存監(jiān)視器的數(shù)據(jù)比較同樣的,首先是卡馬克卷軸繪制地圖組的數(shù)據(jù)截圖然后是對(duì)照組普通繪制地圖時(shí)的數(shù)據(jù)截圖從上面看出兩者的最大內(nèi)存消耗基本一致,但是由于卡馬克卷軸涉及到很多坐標(biāo)運(yùn)算,所以在當(dāng)前內(nèi)存消耗中,有時(shí)候會(huì)多占用一些內(nèi)存資源。4.4 真機(jī)測(cè)試比較真機(jī)測(cè)試比較采用手機(jī)為 nokia6288兩組都能正常運(yùn)行。普通繪制下,地圖卷動(dòng)時(shí)屏幕暴閃,嚴(yán)重影響游戲感受??R克卷軸緩沖繪制下,地圖卷動(dòng)時(shí)屏幕僅有很輕微閃耀(據(jù)多方了解,應(yīng)為 6288 手機(jī)的性能所限) 。結(jié)論結(jié)論卡馬克算法是在進(jìn)行游戲地圖卷

42、動(dòng)的算法中內(nèi)存痕跡最小、效率適中的算法之一其核心的思想就是把地圖卷動(dòng)過(guò)程中移出屏幕(不需要在顯示的部分)所占用的 buffer 區(qū)域,繪制上新的需要圖塊,在往真實(shí)屏幕上繪制的時(shí)候,通過(guò)四次繪制 buffer 把完整的地圖重現(xiàn)我們?cè)趯?shí)際的代碼編寫(xiě)中按以下的方式進(jìn)行根據(jù)上面的基本思想,把地圖分為四個(gè)塊(十字形的將 buffer 劃分為四塊) ,用 carx 和 cary 來(lái)記錄十字分區(qū)的中心坐標(biāo)(相對(duì)于 buffer 的坐標(biāo),我把這個(gè)點(diǎn)叫卡馬克分區(qū)點(diǎn)) 當(dāng)?shù)貓D向右移動(dòng)的時(shí)候這時(shí)把卡馬克分區(qū)點(diǎn)的坐標(biāo)方向加上一個(gè) tile的 width,然后在從現(xiàn)在的卡馬克分區(qū)點(diǎn)的坐標(biāo)開(kāi)始繪制提取出來(lái)的 tile對(duì)應(yīng)的圖象,注意是從當(dāng)前的卡馬克分區(qū)點(diǎn)的坐標(biāo)開(kāi)始繪制,當(dāng)超出 carHeight 時(shí)在從開(kāi)始繪制直到結(jié)束,這樣就完成了在水平方向上的更新還有就是在水平移動(dòng)卡馬克分區(qū)點(diǎn)的時(shí)候是在 buffer 中循環(huán)的,也就是從到 carWidth 的一個(gè)循環(huán)過(guò)程,Y 方向上完全一致最后是繪制過(guò)程,也就是將四個(gè)分區(qū)繪制出來(lái),口訣就是左變右上變下,掌握好卡馬克算法對(duì)手游開(kāi)發(fā)很有幫助的致謝致謝指導(dǎo)老師:老鄭 網(wǎng)站站

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論