寫在開始:如果您沒時間詳細閱讀,可直接選讀加粗文字和圖片淆九;或先收藏本文,作為今后參考毛俏。
我們已經(jīng)知道炭庙,在Android應(yīng)用中,圖片不僅可以使用ImageView來顯示煌寇,也可作為Button焕蹄、Window的背景。圖片的格式包括不限于*png阀溶、*.jpg腻脏、*.gif等各種格式的位圖鸦泳。
除了已有的圖片外,android應(yīng)用還常需要在運行時動態(tài)生成圖片永品,例如一個手機游戲做鹰。
而所謂的游戲動畫,其實就是不斷地重復調(diào)用View組件的onDraw(Canvas canva)方法鼎姐,如果每次在View組件上繪制的圖形不相同钾麸,那么就成了我們常說的動畫。
這是我上一學期(大二)學習Win32編程時的課程設(shè)計作業(yè)炕桨,加入了雙緩沖饭尝、游戲循環(huán)等小技能。做這個游戲也是為了懷念小學時玩的第一個游戲——QQ堂献宫。
如今加入android開發(fā)學習钥平,當然要嘗試開發(fā)android游戲啦。開發(fā)前遵蚜,先來了解android繪圖的常用基礎(chǔ)API(應(yīng)用程序編程接口):Canvas帖池、Path。
Canvas:
重寫onDraw()方法時首先涉及一個繪圖API:Canvas吭净,Canvas代表“依附”于指定View的畫布睡汹,它提供了一系列方法用作繪制點、線寂殉、圓囚巴、矩形、位圖等各種圖形友扰,部分方法如下:
除此之外彤叉,Canvas還提供了一些方法進行坐標轉(zhuǎn)換,如旋轉(zhuǎn)村怪、縮放變換秽浇,感興趣的讀者可以查閱安卓官方文檔。
Canvas提供的方法還涉及一個API:Paint甚负,Paint代表Canvas上的畫筆柬焕,相當于Win32中的HPEN。所以Paint類主要用于設(shè)置繪制風格梭域,包括畫筆顏色斑举、畫筆筆觸粗細、填充風格等病涨。Paint提供了如下所示的方法:
Path:
在Canvas提供的繪制方法中還用到了一個API:Path富玷。Android提供的Path是一個非常有用的類,它可以預先在View上將N個點連成一條“路徑”,然后調(diào)用Canvas的drawPath(path,paint)方法即可沿著路徑繪制圖形赎懦。
Android還為路徑繪制提供了PathEffect來定義繪制效果雀鹃,這里不再贅余。
繪制游戲動畫:
之前已經(jīng)提到铲敛,在android應(yīng)用中繪制幾何圖形褐澎,關(guān)鍵在于自定義一個View組件,并重寫View組件的onDraw(Canvas)方法伐蒋。
游戲動畫無非是在此基礎(chǔ)上讓View組件上繪制的圖形發(fā)生改變(位置工三、大小、角度等等)先鱼,這就需要程序采用變量“記住”這些狀態(tài)數(shù)據(jù)俭正。
1)如果需要游戲動畫隨用戶操作而改變,就為用戶的動作編寫事件監(jiān)聽器(如按鍵觸發(fā)事件)焙畔,在監(jiān)聽器中修改這些數(shù)據(jù)掸读。
2)如果需要游戲動畫隨時間的流逝“自動”改變,那就需要使用定時器(Timer)宏多,讓Timer控制這些狀態(tài)數(shù)據(jù)定期改變儿惫。
無論使用哪種方式,每次View組件上的圖形狀態(tài)數(shù)據(jù)發(fā)生改變時伸但,都應(yīng)該通知View調(diào)用onDraw(Canvas canvas)方法重繪該組件肾请。通知View重繪可調(diào)用invalidate(在UI線程中)或postInvalidate(在非UI線程中)。
下面開發(fā)一個簡單的彈球游戲更胖,通過這個實例來對android游戲動畫有一個直觀的認識铛铁。
小球和球拍分別以圓形區(qū)域和矩形區(qū)域代替,小球開始以隨即速度向下運動却妨,遇到邊框或球拍時反彈饵逐;球拍則由用戶控制,當用戶按下左彪标、右鍵倍权,球拍會左、右移動捞烟。
MainActivity代碼已上傳:彈球游戲源碼 具體我們分以下五部分細講账锹。
·1 變量初始化
程序最開始,我們先做初始化操作坷襟,定義一些全局變量,如桌面大小生年、小球速度婴程、運動方向等,均已詳細注釋抱婉。
·2 工作空間初始化
接著我們在onCreate()中加入邏輯處理档叔,首先是創(chuàng)建GameView組件桌粉,在setContentView()中替代原來的activity_main布局。
然后獲取窗口管理器管理當前窗口衙四,并將屏幕的寬铃肯、高賦給變量tableWidth、tableHeight传蹈。這里還定義了一個Handler接受子線程發(fā)送的數(shù)據(jù)來更新UI押逼,這是為了在定時器中修改小球坐標后進行重繪(刷新)。
·3 響應(yīng)鍵盤消息
這部分code非常簡單惦界,先獲取用戶觸發(fā)的按鍵挑格,然后對全局變量做相應(yīng)的處理;如果按enter鍵就退出程序沾歪。記得在處理完后一定要調(diào)用invalidate()函數(shù)對View進行重繪漂彤。
·4 設(shè)置定時器
Timer是一種定時器工具,用來在后臺線程計劃執(zhí)行指定任務(wù)灾搏。
在Timer中存放對小球坐標的操作挫望,讓小球自己能夠“動起來”。同時對游戲是否結(jié)束做邏輯判斷狂窑,最后發(fā)送一條消息通知系統(tǒng)重繪組件坦康,timer.schedule()第三個參數(shù)“100”表示100毫秒重繪一次蜡秽。
·5 重寫onDraw方法
繪圖繼承自View組件,并重寫onDraw方法。在onDraw方法中亿驾,定義畫筆Paint的屬性,并繪制小球舶斧、球拍尿赚,最終在畫布Canvas上顯示出來。我們直接看到的圖形效果就產(chǎn)生自這一方法采呐。
本實例完整代碼到此結(jié)束若锁。當前的彈球游戲還略顯粗糙,但我們只要找一些精美圖片替換程序中的小球斧吐、球拍又固,再設(shè)置一些障礙物以及小球碰撞邊界、球拍時的音效煤率,游戲就會變得生動起來仰冠。
當然,以上內(nèi)容只是android龐大的圖形與圖像處理技術(shù)中的冰山一角蝶糯,作為第一個練手的android游戲倒是不錯洋只。
我常調(diào)侃自己,從玩第一個游戲到開發(fā)第一個游戲(都是QQ堂)用了10年。隨著編程基礎(chǔ)的累積识虚,今后的開發(fā)之路依舊充滿荊棘但注定暢通光明肢扯。本學期個人打算再做一個類似的經(jīng)典游戲,例如合金彈頭担锤、黃金礦工蔚晨,再加上網(wǎng)絡(luò)技術(shù)....
總之,邊學習邊充實最終代碼化肛循。
今后铭腕,我會繼續(xù)深入學習android開發(fā)知識,并盡己所能把相關(guān)知識分享給更多的讀者育拨。歡迎您持續(xù)關(guān)注谨履。
作者:葉琛
一只癡迷旅行的大三程序狗