張 曉, 張艷青, 蘇 航
(1.華南理工大學 計算機科學與工程學院,廣東 廣州 510006;2.華南理工大學 軟件學院,廣東 廣州 510006)
隨著科技的發(fā)展,智能手機已經(jīng)與我們的日常生活密不可分,當前主流的智能終端操作系統(tǒng)有 Android,IOS和Windows Phone等,其中Android是Google公司推出的開源手機操作系統(tǒng)[1]。2012年11月數(shù)據(jù)顯示,Android占據(jù)全球智能手機操作系統(tǒng)市場76%的份額,中國市場占有率為90%。越來越多的人喜歡在閑暇時間玩手機游戲,中國手機游戲市場在近幾年也一直保持了較快的發(fā)展[2]。優(yōu)良的手機游戲不僅能給人們的生活帶來樂趣,也能給開發(fā)者帶來可觀的經(jīng)濟收益。游戲引擎是游戲的核心,選擇一款兼容性好、高效、容易使用的游戲引擎,能大大降低游戲開發(fā)的成本。libGDX游戲開發(fā)框架就是這樣一款備受開發(fā)者青睞的引擎。本文將介紹利用libGDX來快速的開發(fā)一款簡單、有趣的Android賽車游戲。
libGDX基于 Apache License,Version 2.0協(xié)議,由 Java/C/C++語言編寫而成,是一個免費并且高效的跨平臺的2D/3D的 游 戲 開 發(fā) 框 架 , 它 由 audio、files、graphics、math、physics、scenes、utils這些主要類庫所組成,分別對應了libGDX中的音頻操作,文件讀取,2D/3D渲染,libGDX繪圖相關(guān)運算,Box2D封裝,2D/3D游戲組件,以及l(fā)ibGDX內(nèi)置工具類,它們之間的關(guān)系如圖1所示。它使用JNI封裝了物理引擎Box2D的C++版本,使得其運行效率比其他同級的物理引擎要更快[3]。
圖1 libGDX框架架構(gòu)Fig.1 Framework architecture of libGDX
一般在Android開發(fā)中,一個頁面是一個Activity,一個應用中包含多個Activity。而在基于libGDX的Android應用中,只有一個Activity,而且是用一個繼承了Activity的Android Application來作為整個程序的父類。libGDX中把Screen當成頁面,通過Game的setScreen方法來實現(xiàn)不同頁面的切換。每個Screen又可包含多個Stage對象,同一個Screen中多個Stage的切換也可以達到頁面切換的效果。 而頁面中的物體稱為 Actor,在 Screen 的 show()方法中,調(diào)用 Stage.Add(Actor actor)方法將物體添加到Stage中,這樣就構(gòu)成一個游戲頁面。在Screen的render()方法中,可以不斷的更新各個Actor的狀態(tài),從而達到游戲運行時動態(tài)變化的效果。
賽車游戲的主要邏輯位于游戲主頁面中,在手機屏幕下方擺放一輛賽車,讓用戶通過手機的重力加速度感應器來控制左右移動,讓其他的賽車和背景賽道地圖像下滾動,可以給人一種相對的向前運動的感覺。用戶控制賽車向前行駛,會和屏幕上的其他Actor發(fā)生碰撞,所以必須要有碰撞檢測。
根據(jù)賽車游戲的特點,通過加載資源,進入游戲主菜單頁面,然后點擊“開始游戲”即可進入游戲主界面開始游戲了。當游戲結(jié)束時會進入成績排行榜頁面,顯示歷史成績,在排行榜頁面也可以返回到游戲主菜單或者直接重新開始游戲。游戲的設(shè)計流程圖如圖2所示。
圖2 賽車游戲流程圖Fig.2 Flow chart the racing game
要實現(xiàn)賽道地圖滾動的效果,一種比較簡單的方案是用兩張關(guān)于賽道的圖片放在一起,在屏幕中向下移動,一張圖片移出屏幕造成的空余由另一張圖片移進屏幕來填補,不斷循環(huán),這樣可以達到賽道滾動的效果,如圖3所示。libGDX中Actor的setY方法可以直接設(shè)置圖片的Y軸坐標,從而讓圖片不斷的移進、移出屏幕。
游戲主頁面中賽道上面包含的可移動的元素有賽車和道具等。這些元素都是作為Actor對象來添加到頁面的Stage中的。
賽車分為兩類,一類是用戶直接控制的賽車,取名為playerCar,另一類是由系統(tǒng)自動控制的賽車,取名為friendCar。playerCar位于屏幕中Y軸方向上的固定位置,通過重力加速傳感器來控制playerCar的左右移動。friendCar由系統(tǒng)控制運行,多輛friendCar不斷的放在屏幕上(賽道圖的頂端),并設(shè)置向下運行的速度。因此,playerCar在垂直方向上絕對位置不變,而多輛friendCar向下方移動,讓用戶感覺playerCar是在向前行駛。
圖3 地圖循環(huán)滾動過程Fig.3 Map cycle rolling process
為了提高程序運行的效率,可以用對象池來管理friendCar。即在程序初始化的時候,實例化多個friendCar對象,放到一個集合中構(gòu)成對象池,當需要添加賽車到屏幕上的時候,從對象池中取出一個friendCar,按照需要修改相應屬性,然后將它放到屏幕中上運行[4]。當這個friendCar要從屏幕上消失(被炸毀或者超出屏幕)的時候,可直接將這個對象放回到對象池中,如圖4所示。
圖4 利用對象池來管理賽車流程圖Fig.4 Flow chart of using object pool to manage the car
賽車對象池就是賽車對象的一個集合,libGDX中可以使用Group對象來表示這樣的一個集合,通過Group對象的getChildren()方法來得到該集合中的所有元素。
程序中可以添加一些道具,比如炸彈道具,playerCar得到這個道具之后,可以發(fā)射出炸彈,可以炸毀與之有接觸的friendCar。道具的添加和移動可以基本按照賽車添加和移動的方式來實現(xiàn)。
用戶控制賽車向前行駛,會和friendCar以及道具產(chǎn)生碰撞。playerCar與friendCar之間的碰撞檢測可以采用libGDX中已經(jīng)封裝好的Box2D物理引擎,Box2D可以很方便的檢測到碰撞,并根據(jù)設(shè)置剛體的各種屬性,讓碰撞的效果更加逼真。
而playerCar與道具的碰撞則不必采用Box2D,可以直接把賽車和道具看成兩個矩形,從而只需檢測兩個矩形是否有接觸[5],libGDX 中 Actor的 getX()和 getY()方法可以得到該Actor的所處位置,getWidth()和getHeight()可以得到該Actor的寬度和高度,這樣就能很容易的檢測兩個Actor代表的矩形是否相交,如果這兩個矩形有相交,則表示有碰撞。
用戶每玩一次游戲,都會根據(jù)游戲中相應的數(shù)據(jù)計算出一個得分作為本次游戲的成績。Android系統(tǒng)集成了SQLite,它是一款非常流行的嵌入式數(shù)據(jù)庫,支持SQL查詢,并且只占用很少的內(nèi)存[6]。可以用本地數(shù)據(jù)庫SQLite將成績保存起來,讓用戶能夠查看歷史成績,但是如果保存每次游戲的成績,那將勢必會使應用占據(jù)越來越多的手機存儲空間。從手機空間和用戶體驗的角度來看,可以只存前十名的成績。如果用戶成績數(shù)據(jù)表中已經(jīng)存了十條記錄,那么下一條前十的成績可以直接用來更新原來的第十名的成績。
Android手機種類繁多,對應的手機屏幕的尺寸也是大小不一。賽車游戲的UI需要盡量照顧到各種尺寸的手機屏幕。我們可以取當前比較普遍的手機屏幕分辨率800*480為基準,用本手機的高度除以800得到BX,用本手機的寬度除以480得到BY,將BX,BY作為一個基礎(chǔ)的比例,程序中布局時,設(shè)置圖片位置時,用相應的寬度和高度來分別乘以BX和BY,再進行設(shè)置,可以達到很好的屏幕適配效果。
libGDX中提供了Animation類,可以用來實現(xiàn)動畫效果,其實質(zhì)就是連續(xù)播放多張圖片。libGDX中用Sound來播放比較短暫的聲音如爆炸聲音,用Music來播放長時間的聲音比如背景音樂,通過Sound和Music可以很方便的播放游戲中需要的聲音。為了保證游戲的流暢性,動畫中包含的多張圖片和聲音資源都需要進行預加載。
整個應用實現(xiàn)完成以后,在LG Nexus4手機中得以成功運行。選取了游戲運行時主頁面的幾個運行畫面,運行結(jié)果充分顯示出程序運行良好,也基本符合設(shè)計要求。如圖5所示,在游戲主頁面中 playerCar是用戶控制的賽車,friendCar由系統(tǒng)控制,圖中出現(xiàn)了兩個道具,分別是能量道具和炸彈道具。如圖6所示,用戶通過點擊屏幕右半部分使playerCar發(fā)射炸彈,炸毀一輛friendCar時出現(xiàn)的爆炸動畫。
圖5 游戲主頁面Fig.5 Main page of racing game
圖6 爆炸效果Fig.6 The explosion effect
文中介紹了游戲開發(fā)框架libGDX,并基于此框架設(shè)計和開發(fā)了一款流暢、有趣的Android賽車游戲,玩家通過簡單的交互如點擊手機屏幕左側(cè)或右側(cè)、輕微搖晃手機就可以體驗本游戲。結(jié)果表明,libGDX提供了豐富且易用的接口,使用它來開發(fā)手機游戲,在保證功能得以實現(xiàn)的同時,又可以縮短開發(fā)時間、降低開發(fā)難度。
[1]黎忠文,覃志東,王全宇,等.基于Android平臺手機游戲引擎的設(shè)計與實現(xiàn)[J].計算機工程與設(shè)計,2014,35(1):119-124.LI Zhong-wen,QIN Zhi-dong,WANG Quan-yu,et al.Design and implementation of mobile game engine based on Android platform[J].Computer Engineering and Design,2014,35(1):119-124.
[2]崔浩然.基于Android平臺的手機游戲的設(shè)計與實現(xiàn)[D].西安:西安科技大學2011.
[3]吳慶林.基于libGDX的Android游戲研究與開發(fā)[D].廣州:華南理工大學,2012.
[4]水超,李慧.對象池模式的擴展與設(shè)計[J].計算機工程,2004,30(9):26-27.SHUI Chao,LIU Hui.Extension and implementation of object pool pattern[J].Computer Engineering,2004,30 (9):26-27.
[5]高春曉,劉玉樹.碰撞檢測技術(shù)綜述[J].計算機工程與應用, 2002(5):9-11.GAOChun-xiao,LIUYu-shu.A survey of collision detection[J].Computer Engineering and Applications,2002(5):9-11.
[6]彭艷,楊歐.Android平臺的數(shù)據(jù)存儲技術(shù)[J].計算機系統(tǒng)應用,2012,21(5):192-193.PENG Yan,YANG Ou.Analysis on the data storage of android application[J].Computer Systems&Applications,2012,21(5):192-193.