版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、項(xiàng)目編號(hào) 創(chuàng)新實(shí)驗(yàn)報(bào)告實(shí)驗(yàn)項(xiàng)目名稱 基于Android手機(jī)操作系統(tǒng)的游戲軟件開發(fā)學(xué) 生 姓 名 石皓程 樊峰辰 學(xué)生學(xué)號(hào) 021112218/021112230 所在學(xué)院 電子電氣工程學(xué)院 指導(dǎo)教師 施一萍 目錄實(shí)驗(yàn)?zāi)康膶?shí)驗(yàn)方案2.1總體設(shè)計(jì)思想 2.2實(shí)驗(yàn)流程(步驟) 2.3實(shí)驗(yàn)環(huán)境 2.4實(shí)驗(yàn)分工實(shí)驗(yàn)過(guò)程3.1Andriod軟件開發(fā)環(huán)境搭建3.2模塊劃分3.3游戲主界面模塊3.4游戲控制模塊3.5模塊實(shí)現(xiàn)原理3.51游戲界面模塊實(shí)現(xiàn)3.52游戲控制模塊實(shí)現(xiàn)3.6游戲界面具體實(shí)現(xiàn) 3.61蛇身、食物和墻的實(shí)現(xiàn) 3.62處理鍵盤事件 3.63 TileView類的設(shè)計(jì) 3.64 SnakeVi
2、ew類的設(shè)計(jì) 3.65 RefreshHandler類的設(shè)計(jì)3.7程序調(diào)試與運(yùn)行實(shí)驗(yàn)結(jié)果和分析參考文獻(xiàn)附錄一 代碼清單附錄二 環(huán)境搭建和運(yùn)行 實(shí)驗(yàn)?zāi)康呢澇陨哂螒蛞豢罘浅=?jīng)典的手機(jī)游戲,因?yàn)樗容^簡(jiǎn)單有趣,無(wú)論老少都比較適合。貪吃蛇的設(shè)計(jì)對(duì)每一個(gè)Java語(yǔ)言設(shè)計(jì)者進(jìn)行語(yǔ)言提高和進(jìn)階都是一個(gè)很好的鍛煉機(jī)會(huì)。 貪吃蛇游戲的設(shè)計(jì)比較復(fù)雜,它涉及面廣、牽涉方面多,如果不好好考慮和設(shè)計(jì),將難以成功開發(fā)出這個(gè)游戲。在這個(gè)游戲的設(shè)計(jì)中,牽涉到圖形界面的顯示與更新、數(shù)據(jù)的收集與更新,并且在這個(gè)游戲的開發(fā)中,還要應(yīng)用類的繼承機(jī)制以及一些設(shè)計(jì)模式。因此,如何設(shè)計(jì)和開發(fā)好這個(gè)貪吃蛇游戲,對(duì)于提高Java開發(fā)水平和系統(tǒng)
3、的設(shè)計(jì)能力有極大的幫助。在設(shè)計(jì)開發(fā)過(guò)程中,需要處理好各個(gè)類之間的繼承關(guān)系,還要處理各個(gè)類相應(yīng)的封裝,并且還要協(xié)調(diào)好各個(gè)模塊之間的邏輯依賴關(guān)系和數(shù)據(jù)通信關(guān)系。本項(xiàng)目在Android平臺(tái)下,使用Java語(yǔ)言,Android開發(fā)技術(shù)開發(fā)一款界面友好,功能齊全的貪吃蛇游戲。實(shí)驗(yàn)方案2.1總體設(shè)計(jì)思想 本軟件是針對(duì)貪吃蛇小游戲的JAVA程序,利用上、下、左、右方向鍵來(lái)改變蛇的運(yùn)動(dòng)方向,長(zhǎng)按某個(gè)方向鍵后,蛇的運(yùn)動(dòng)速度會(huì)加快,在隨機(jī)的地方產(chǎn)生食物,吃到食物就變成新的蛇體,碰到壁或自身則游戲結(jié)束,否則正常運(yùn)行游戲,在到達(dá)固定的分?jǐn)?shù)后,游戲速度會(huì)加快。2.2實(shí)驗(yàn)流程Java編程語(yǔ)言Android軟件的開發(fā)環(huán)境搭
4、建(Eclipse開發(fā)軟件、Android SDK開發(fā)框架、Android Development Tool開發(fā)環(huán)境)Android程序的框架結(jié)構(gòu)游戲軟件的開發(fā)2.3實(shí)驗(yàn)環(huán)境 實(shí)驗(yàn)地點(diǎn)在實(shí)訓(xùn)樓1號(hào)樓計(jì)算中心。計(jì)算中心具有較好的實(shí)驗(yàn)設(shè)備,擁有較高配置的PC機(jī)300臺(tái)(Intel酷睿2 Q8300四核處理器、2G內(nèi)存),都可以接入校園網(wǎng)和Inter網(wǎng),完全能滿足該創(chuàng)新實(shí)驗(yàn)項(xiàng)目的需要。2.4實(shí)驗(yàn)分工 李 琦:環(huán)境的搭建和游戲的編譯 邵彧韜:截圖和后期的制作實(shí)驗(yàn)過(guò)程3.1Andriod軟件開發(fā)環(huán)境搭建 采用eclipse開發(fā)工具在windows7下進(jìn)行,基于安卓2.2操作系統(tǒng)。 環(huán)境搭建:1. JDK
5、安裝 2. Eclipse安裝 3. Android SDK安裝 4. ADT安裝創(chuàng)建AVD軟件總體設(shè)計(jì) 工程中包括4個(gè)Activity,分別為Snake(主界面)、Game(游戲界面)、Help(游戲說(shuō)明界面)、AuthorView(作者信息界面),通過(guò)不同Activity之間的轉(zhuǎn)換實(shí)現(xiàn)不同界面之間的切換。Snake(Activity)繼承了SnakeView類,SnakeView類繼承了TileView類。TileView類繼承了View其實(shí) Snake的工程蠻簡(jiǎn)單的,源文件就三個(gè): Snake.java SnakeView.java TileView.java。 Snake類是這個(gè)游戲的
6、入口點(diǎn), TitleView類進(jìn)行游戲的繪畫, SnakeView類則是對(duì)游戲控制操作的處理。 Coordinate, RefreshHandler是 2個(gè)輔助類,也是 SnakeView類中的內(nèi)部類。其中, Coordinate是一個(gè)點(diǎn)的坐標(biāo)( x, y), RefreshHandler將 RefreshHandler對(duì)象綁定某個(gè)線程并給它發(fā)送消息。如下圖: 圖3.13.2模塊劃分從面向?qū)ο蟪绦蛟O(shè)計(jì)的角度,本項(xiàng)目總體地可以分為游戲界面模塊、數(shù)據(jù)存儲(chǔ)模塊和控制模塊。如下圖所示:游戲數(shù)據(jù)存儲(chǔ)模塊貪吃蛇游戲游戲主界面模塊游戲控制模塊圖3.2游戲總體模塊3.3游戲主界面模塊游戲界面主框架主要包括游戲
7、圖形區(qū)域界面、游戲的開始按鈕、暫停按鈕、游戲的退出按鈕。游戲界面主框架的主要結(jié)構(gòu)圖如圖3.3所示。游戲的主界面架游戲圖形區(qū)域界面(即游戲畫布)游戲控制按鈕界面圖3.3 游戲主界面3.4 游戲控制模塊 游戲控制模塊主要通過(guò)手機(jī)鍵盤上的按鈕來(lái)控制游戲的開始、游戲的暫停、游戲的退出這三個(gè)功能以及控制游戲分?jǐn)?shù)變化。在這個(gè)模塊中,需要給各個(gè)按鈕添加響應(yīng)事件代碼,來(lái)對(duì)上述的功能加以進(jìn)一步的實(shí)現(xiàn)。游戲控制模塊的主要框架如圖3.4所示。游戲控制模塊游戲的移動(dòng)速度功能能游戲的暫停功能游戲的重新開始圖3.4 游戲控制模塊框架3.5模塊實(shí)現(xiàn)原理3.5.1游戲界面模塊實(shí)現(xiàn)1.實(shí)現(xiàn)游戲背景本游戲采用Activity作為
8、游戲背景的載體,在Android中一個(gè)Activity就相當(dāng)于windows中的一個(gè)窗口,Activity上可以放置許多類型的控件。一個(gè)activity主要有三個(gè)狀態(tài):當(dāng)在屏幕前臺(tái)時(shí)(位于當(dāng)前任務(wù)堆棧的頂部),它是活躍或運(yùn)行的狀態(tài)。它就是相應(yīng)用戶操作的activity。 當(dāng)它失去焦點(diǎn)但仍然對(duì)用戶可見時(shí),它處于暫停狀態(tài)。即是:在它之上有另外一個(gè)activity。這個(gè)activity也許是透明的,或者未能完全遮蔽全屏,所以被暫停的activity仍對(duì)用戶可見。暫停的activity仍然是存活狀態(tài)(它保留著所有的狀態(tài)和成員信息并連接至窗口管理器),但當(dāng)系統(tǒng)處于極低內(nèi)存的情況下,仍然可以殺死這個(gè)act
9、ivity。如果它完全被另一個(gè)activity覆蓋是,它處于停止?fàn)顟B(tài)。它仍然保留所有的狀態(tài)和成員信息。然而它不在為用戶可見,所以它的窗口將被隱藏,如果其它地方需要內(nèi)存,則系統(tǒng)經(jīng)常會(huì)殺死這個(gè)activity。如果一個(gè)activity處于暫?;蛲V?fàn)顟B(tài),系統(tǒng)可以通過(guò)要求它結(jié)束(調(diào)用它的 finish() 方法)或直接殺死它的進(jìn)程來(lái)將它驅(qū)出內(nèi)存。當(dāng)它再次為用戶可見的時(shí)候,它只能完全重新啟動(dòng)并恢復(fù)至以前的狀態(tài)。當(dāng)一個(gè)activity從這個(gè)狀態(tài)轉(zhuǎn)變到另一個(gè)狀態(tài)時(shí),它被以下列protected方法所通知:void onCreate(Bundle savedInstanceState) 、void onSt
10、art() 、void onRestart() 、void onResume() 、void onPause() 、void onStop() 、void onDestroy()實(shí)現(xiàn)蛇的身體蛇可以看做是一個(gè)個(gè)節(jié)點(diǎn)組成的,因此可以用一個(gè)鏈表來(lái)存儲(chǔ)蛇身的元素,在畫蛇時(shí)遍歷這個(gè)鏈表講里面的元素一一畫出,這樣就實(shí)現(xiàn)了一條蛇.實(shí)現(xiàn)蛇的移動(dòng)用一個(gè)timer(定時(shí)器)來(lái)不斷地刷新游戲畫面,每刷新一次就再蛇頭的前面(鏈表的尾部)增加一個(gè)新元素,同時(shí)把蛇尾的一個(gè)元素刪掉,這樣從視覺(jué)上看起來(lái)就實(shí)現(xiàn)了蛇的移動(dòng).實(shí)現(xiàn)蛇吃食物 蛇移動(dòng)的過(guò)程中如果蛇頭的坐標(biāo)與食物出現(xiàn)的坐標(biāo)重合了,那么就在蛇頭的位置增加一個(gè)元素同時(shí)不刪除
11、蛇尾的最后一個(gè)元素,這樣蛇每遲到一個(gè)食物身體就會(huì)變長(zhǎng)一截.3.5.2 游戲控制模塊實(shí)現(xiàn)實(shí)現(xiàn)操作蛇的移動(dòng)方向在Android系統(tǒng)中,手機(jī)上的每個(gè)按鈕都會(huì)有一個(gè)對(duì)應(yīng)的鍵值跟它對(duì)應(yīng),所在可以給對(duì)應(yīng)的按鈕設(shè)置監(jiān)聽器OnClickListener,監(jiān)聽器是一個(gè)接口,該接口中有一個(gè)方法onClick(View v)。當(dāng)按鈕被點(diǎn)擊的時(shí)候系統(tǒng)會(huì)自動(dòng)調(diào)用該監(jiān)聽器的onClick(View v)方法。所以實(shí)現(xiàn)游戲控制的具體代碼將被寫到該方法中。因?yàn)楸居螒蛑胁辉试S蛇向與蛇頭相反的方向移動(dòng),所以當(dāng)用戶操作時(shí)需要判斷用戶操作的方向是不是跟規(guī)則沖突,若沖突則無(wú)視該操作,若不沖突則響應(yīng)該操作,所以需要用一個(gè)變量來(lái)記錄蛇頭的
12、當(dāng)前方向。實(shí)現(xiàn)游戲暫停 在Activity的生命周期中,有一個(gè)onPause()方法.該方法在Activity變得不可見的時(shí)候被系統(tǒng)自動(dòng)調(diào)用.在玩游戲過(guò)程中,如果有來(lái)電或是其它事件中斷,這時(shí)應(yīng)該把當(dāng)前狀態(tài)保存。以便返回時(shí),還可以繼續(xù)玩游戲。這就使用onSaveInstanceState實(shí)現(xiàn)保存當(dāng)前狀態(tài)。實(shí)現(xiàn)游戲恢復(fù)Activity生命周期的onResume()方法.該方法在Activity從不可見的狀態(tài)下變得可見時(shí)被系統(tǒng)自動(dòng)調(diào)用.在用戶接完電話或者在暫停狀態(tài)下觸摸屏幕后可以在該生命周期方法中對(duì)游戲進(jìn)行恢復(fù).實(shí)現(xiàn)游戲退出當(dāng)一個(gè)Activity退出或者被調(diào)用finish()方法后,系統(tǒng)會(huì)調(diào)用其生命
13、周期方法onDestroy().當(dāng)用戶退出游戲時(shí),可以在這個(gè)方法中對(duì)資源進(jìn)行釋放.3.6游戲界面具體實(shí)現(xiàn)3.6.1 蛇身、食物和墻的實(shí)現(xiàn)前面已經(jīng)提過(guò),蛇身的數(shù)據(jù)用一個(gè)鏈表來(lái)存儲(chǔ),具體我使用ArrayList來(lái)實(shí)現(xiàn)。蛇身的每個(gè)元素、食物和墻都是一個(gè)坐標(biāo)對(duì)象,畫這些東西的時(shí)候只需要把它們的坐標(biāo)傳給畫的方法就行了。這里需要引進(jìn)一個(gè)坐標(biāo)類Coordinate,這是一個(gè)包括兩個(gè)參數(shù),用于記錄X軸和Y軸簡(jiǎn)單類,其中包括一個(gè)比較方法,該方法用于判斷蛇頭于食物或者墻是否重合.該類的代碼如下:class Coordinate public int x; public int y; public Coordina
14、te(int newX, int newY) x = newX; y = newY; public boolean equals(Coordinate other) if (x = other.x & y = other.y) return true; return false; public String toString() return Coordinate: + x + , + y + ; 蛇身的初始長(zhǎng)度我設(shè)置為5,new 5個(gè)Coordinate的對(duì)象放入ArrayList中。整個(gè)屏幕可以看做是有很多個(gè)網(wǎng)格組成的,而蛇就在這些網(wǎng)格中移動(dòng)。用一個(gè)二維數(shù)組int mTileGrid來(lái)存儲(chǔ)
15、網(wǎng)格的坐標(biāo),將蛇身、食物或者墻的坐標(biāo)傳到該數(shù)組中,onDraw方法按照該數(shù)組中的坐標(biāo)將屏幕相應(yīng)位置的網(wǎng)格填充成位圖。畫蛇身、食物、墻的方法為: public void onDraw(Canvas canvas) super.onDraw(canvas); for (int x = 0; x mXTileCount; x +) for (int y = 0; y 0) canvas.drawBitmap(mTileArraymTileGridxy, mXOffset + x * mTileSize, mYOffset + y * mTileSize, mPaint); 3.6.2處理鍵盤事件使用
16、View類的onKeyDown方法,該方法由系統(tǒng)監(jiān)聽調(diào)用。根據(jù)按鍵的值處理響應(yīng)事件,該方法中解決了反向移動(dòng)的問(wèn)題。mDirection 為當(dāng)前蛇頭的方向,mNextDirection 為按鍵對(duì)應(yīng)的方向,按鍵按下后會(huì)先判斷當(dāng)前方向是否跟下一方向相反,若相反則不響應(yīng)事件。具體代碼如下: public boolean onKeyDown(int keyCode, KeyEvent msg) if (keyCode = KeyEvent.KEYCODE_DPAD_UP) if (mMode = READY | mMode = LOSE) initNewGame(); setMode(RUNNING);
17、 update(); return (true); if (mMode = PAUSE) setMode(RUNNING); update(); return (true); if (mDirection != SOUTH) mNextDirection = NORTH; return (true); if (keyCode = KeyEvent.KEYCODE_DPAD_DOWN) if (mDirection != NORTH) mNextDirection = SOUTH; return (true); if (keyCode = KeyEvent.KEYCODE_DPAD_LEFT)
18、if (mDirection != EAST) mNextDirection = WEST; return (true); if (keyCode = KeyEvent.KEYCODE_DPAD_RIGHT) if (mDirection != WEST) mNextDirection = EAST; return (true); return super.onKeyDown(keyCode, msg); if (direction != currentDirection) & !needUpdate)/ 取出列表中的最后一個(gè)元素(蛇的頭部)WormLink sl = (WormLink)wo
19、rm.lastElement();int x = sl.getEndX();int y = sl.getEndY();/ 不同的運(yùn)動(dòng)方向坐標(biāo)的改變也不一樣switch (direction) case UP: / 當(dāng)這段向上運(yùn)動(dòng)的時(shí)候if (currentDirection != DOWN) y-; needUpdate = true; break;case DOWN: / 當(dāng)這段向下運(yùn)動(dòng)的時(shí)候if (currentDirection != UP) y+; needUpdate = true; break;case LEFT: / 當(dāng)這段向左運(yùn)動(dòng)的時(shí)候if (currentDirection
20、!= RIGHT) x-; needUpdate = true; break;case RIGHT: / 當(dāng)這段向右運(yùn)動(dòng)的時(shí)候if (currentDirection != LEFT) x+; needUpdate = true; break; / 當(dāng)更改方向后需要更新if (needUpdate = true) worm.addElement (new WormLink (x, y, 0, direction);currentDirection = direction; 3.6.3 TileView類的設(shè)計(jì)TileView是游戲的界限,即蛇頭若觸碰到界限則游戲結(jié)束。因?yàn)榻缦抟残枰滑F(xiàn)實(shí)到屏幕
21、上,所以TileView需要繼承android.view.View類。android.view.View類是描繪塊狀視圖的基類。View會(huì)繪制一個(gè)包含Drawing是event事件的方形塊。View是所有與用戶交互的組件的Widgets的基類(Buttons,textField等),View的子類ViewGroup是layouts類的基類,layouts類可以包含其他的View/ViewGroup組件并且定義展示的屬性。實(shí)現(xiàn)一個(gè)View,首先需要實(shí)現(xiàn)框架中一些所有Views公用的方法。不必重寫所有所有的方法,可以僅僅重寫onDraw(android.graphics.Canvas)3.6.4
22、SnakeView類的設(shè)計(jì)SnakeView是本游戲的業(yè)務(wù)邏輯類,該類中包含了游戲數(shù)據(jù)和一些處理數(shù)據(jù)的方法以及一些內(nèi)部類。SnakeView的方法摘要:判斷按鍵的方法在Android手機(jī)上,每個(gè)按鍵都會(huì)有一個(gè)唯一的鍵值與它對(duì)應(yīng),可以通過(guò)獲得鍵值來(lái)判斷哪個(gè)鍵被按下了并采取相應(yīng)的動(dòng)作。設(shè)置提示信息的方法通過(guò)程序判斷動(dòng)態(tài)地設(shè)置用戶提示信息,如游戲結(jié)束。在隨機(jī)位置出現(xiàn)食物的方法通過(guò)隨機(jī)數(shù)在屏幕范圍內(nèi)隨機(jī)出現(xiàn)一個(gè)食物,但是不允許同一時(shí)刻有兩個(gè)食物存在。刷新蛇的當(dāng)前位置的方法主要用于刷新蛇的當(dāng)前位置判斷蛇是否吃到食物的方法因?yàn)槭澄锖蜕叨紩?huì)有一個(gè)坐標(biāo),所以可以通過(guò)判斷蛇頭坐標(biāo)是否跟食物坐標(biāo)相等的方法來(lái)判斷蛇
23、是否吃到了食物。3.6.5 RefreshHandler類的設(shè)計(jì)RefreshHandler類需要處理是否需要重繪Snake,所以需要繼承繼承android.os.Handler類。Handler類允許你發(fā)送和處理和當(dāng)前MessageQueue相關(guān)的Message類和Runnable類。每一個(gè)Handler類都和一個(gè)唯一的線程(以及這個(gè)線程的MessageQueue)關(guān)聯(lián)。當(dāng)你創(chuàng)建一個(gè)新的Handler類的時(shí)候,它就和創(chuàng)建它的Thread/Message Queue綁定,也就是說(shuō)這個(gè)Handler類會(huì)向它所關(guān)聯(lián)的MessageQueue遞送Messages/Runnables并且在該Messa
24、ge/Runnable從MessageQueue出列時(shí)候執(zhí)行它。在這里我用來(lái)調(diào)度可能會(huì)被執(zhí)行的Messages和Runnables。3.6.7邏輯處理開始始初化蛇和蘋果屏幕顯示蛇和蘋果位置蛇開始移動(dòng),后坐標(biāo)覆蓋前坐標(biāo)是否有按鍵否根據(jù)上次方向更新坐標(biāo)是根據(jù)按鍵不同在原坐標(biāo)基礎(chǔ)上改變蛇的坐標(biāo)位置更新方向是否吃到蘋果是蛇身加1否是否越界或撞到蛇身是游戲結(jié)束否圖3.53.7程序調(diào)試與運(yùn)行(1)游戲功能測(cè)試經(jīng)過(guò)在模擬器上的測(cè)試,本軟件能書案例實(shí)現(xiàn)其功能,達(dá)到了小蛇在屏幕上的移動(dòng),小蛇吃蘋果,蘋果隨機(jī)出現(xiàn)的功能,當(dāng)小蛇頭尾相撞或與墻相撞時(shí),游戲結(jié)束.這些均在測(cè)試中得到驗(yàn)證。(2)游戲控制測(cè)試在測(cè)試過(guò)程中,
25、也著重對(duì)游戲的控制功能進(jìn)行了測(cè)試,游戲是通過(guò)方向鍵的控制來(lái)實(shí)現(xiàn)的,在游戲剛開始的階段,上下左右四個(gè)方位的控制都很成功,但隨著蛇移動(dòng)的速度越來(lái)越快,按鍵的控制反應(yīng)會(huì)出現(xiàn)滯后,通過(guò)分析,可能是由于蛇的運(yùn)動(dòng)速度超過(guò)了鍵盤的反應(yīng)速度造成的,與軟件無(wú)關(guān),所以得出結(jié)論,游戲的控制設(shè)計(jì)也是成功的。(3)游戲界面測(cè)試游戲運(yùn)行之后,就是在畫面中出現(xiàn)蛇和兩個(gè)蘋果的初始位置,并且是靜止的,并且在畫面上還會(huì)出現(xiàn)操作提示“按上鍵開始游戲”,游戲運(yùn)行過(guò)程中,除了蛇的運(yùn)動(dòng)之外,界面大題沒(méi)有變化,分別由綠色矩形塊的圍墻,黃色矩形塊的蘋果和紅色矩形塊的蛇身(蛇頭為黃色)組成。游戲結(jié)束后,界面處于暫停狀態(tài),提示游戲結(jié)束并顯示分?jǐn)?shù)
26、。(4)測(cè)試結(jié)果通過(guò)對(duì)游戲軟件的功能測(cè)試,控制測(cè)試和界面測(cè)試。詳細(xì)說(shuō)是對(duì)游戲的開始新游戲、退出、查看最高成績(jī)、計(jì)時(shí)、統(tǒng)計(jì)分?jǐn)?shù)等功能進(jìn)行測(cè)試,并測(cè)試程序的鼠標(biāo)點(diǎn)擊事件、菜單的響應(yīng)及按鍵響應(yīng)等事件,結(jié)論是該游戲軟件能正確實(shí)現(xiàn)功能要求。要求輸出的效果與預(yù)期的輸出效果完全一致。 圖3.6 游戲前畫面圖3.7 游戲中界面圖3.8 游戲結(jié)束時(shí)畫面實(shí)驗(yàn)結(jié)果與分析(1)測(cè)試結(jié)果通過(guò)對(duì)游戲軟件的功能測(cè)試,控制測(cè)試和界面測(cè)試。詳細(xì)說(shuō)是對(duì)游戲的開始新游戲、 退出、 查看最高成績(jī)、 計(jì)時(shí)、 統(tǒng)計(jì)分?jǐn)?shù)等功能進(jìn)行測(cè)試, 并測(cè)試程序的鼠標(biāo)點(diǎn)擊事件、菜單的響應(yīng)及按鍵響應(yīng)等事件,結(jié)論是該游戲軟件能正確實(shí)現(xiàn)功能要求。要求輸出的效
27、果與預(yù)期的輸出效果完全 一致。(2)分析回顧這個(gè)設(shè)計(jì)過(guò)程,我學(xué)到了許多書本上沒(méi)有學(xué)到的知識(shí)。通過(guò)這次自己制作的軟件,豐富了自己的實(shí)踐技能,擴(kuò)展了本專業(yè)的知識(shí)面,使我受益非淺,同時(shí) 也體驗(yàn)到了搞軟件開發(fā)的困難度。 在這次設(shè)計(jì)的同時(shí),我又從中學(xué)到了許多東西。 但由于我對(duì)這樣的軟件開發(fā)還只是一個(gè)開始,了解的不多,這其中或許還有很多 的不足,有些模塊做得不是很好,界面的設(shè)計(jì)及整體的布局還比較簡(jiǎn)單,沒(méi)有突 出特色出來(lái),這也可能是我這個(gè)系統(tǒng)的不足之處,在這里也懇請(qǐng)老師能夠?qū)?我的作品指明不足并加以改正。 我所做的設(shè)計(jì)功能并不算強(qiáng)大,但是這些結(jié)合了本學(xué)期所學(xué)習(xí)的內(nèi)容,主要是界面的設(shè)計(jì),并改寫了兩個(gè)類。通過(guò)自
28、己寫代碼,我更進(jìn)一步清楚了android工程的框架及設(shè)計(jì)的步驟,以及每個(gè)文件的作用,稍微掌握了一些View類的方法,同時(shí)也學(xué)到了更多的界面設(shè)計(jì)的方法,比如如何實(shí)現(xiàn)一個(gè)TextView里顯示多行數(shù)據(jù),如何自定義視圖等。但同時(shí)我也遇到了問(wèn)題,比如在編寫控制模塊代碼的時(shí)候,如何何時(shí)按鍵監(jiān)聽這一塊讓我很頭疼,另外在設(shè)計(jì)界面整體布局的時(shí)候,如何編寫XML文件,這也是很大的問(wèn)題后來(lái)通過(guò)查閱資料,對(duì)這些問(wèn)題都做到了很好的解決總之,在這一次的課程設(shè)計(jì)過(guò)程中,我查閱了大量的資料,對(duì) Java 有了一 點(diǎn)初步的認(rèn)識(shí),對(duì)于軟件工程這些輔助性的教材也鞏固了不少,為我這次的課設(shè) 提供了很大的幫助,鍛煉了我的能力讓我掌握
29、了一門新的程序設(shè)計(jì)語(yǔ)言:java 語(yǔ)言,系統(tǒng)地學(xué)習(xí)了數(shù)據(jù)庫(kù)方面的知識(shí),并更進(jìn)一步提高了我在程序設(shè)計(jì)、調(diào)試 方面的技巧。更重要的是,它還讓我認(rèn)識(shí)到了自己的不足,在編程方面,我僅僅 是剛剛?cè)腴T而已,以后的道路任重道遠(yuǎn),需要我不斷的豐富自己、充實(shí)自己,這 樣才能在程序設(shè)計(jì)方面有所收獲。五、參考文獻(xiàn):1 沈澤剛,秦玉平.Java 語(yǔ)言程序設(shè)計(jì)M.清華大學(xué)出版社,2009 2 陳昊鵬同譯者作品 .Java 編程思想(第 4 版).機(jī)械工業(yè)出版社,20073 耿祥義,張躍平. Java 實(shí)用教程(第三版).清華大學(xué)出版社,2006六、附錄一 代碼清單TiltView.java/* * Copyright
30、(C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * /licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writ
31、ing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.android.snake;import
32、 android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;/* * TileView: a View-variant designed for ha
33、ndling arrays of icons or other * drawables. * */public class TileView extends View /* * Parameters controlling the size of the tiles and their range within view. * Width/Height are in pixels, and Drawables will be scaled to fit to these * dimensions. X/Y Tile Counts are the number of tiles that wil
34、l be drawn. */ protected static int mTileSize; protected static int mXTileCount; protected static int mYTileCount; private static int mXOffset; private static int mYOffset; /* * A hash that maps integer handles specified by the subclasser to the * drawable that will be used for that reference */ pri
35、vate Bitmap mTileArray; /* * A two-dimensional array of integers in which the number represents the * index of the tile that should be drawn at that locations */ private int mTileGrid; private final Paint mPaint = new Paint(); public TileView(Context context, AttributeSet attrs, int defStyle) super(
36、context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView); mTileSize = a.getInt(R.styleable.TileView_tileSize, 12); a.recycle(); public TileView(Context context, AttributeSet attrs) super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs
37、, R.styleable.TileView); mTileSize = a.getInt(R.styleable.TileView_tileSize, 12); a.recycle(); /* * Rests the internal array of Bitmaps used for drawing tiles, and * sets the maximum index of tiles to be inserted * * param tilecount */ public void resetTiles(int tilecount) mTileArray = new Bitmaptil
38、ecount; Override protected void onSizeChanged(int w, int h, int oldw, int oldh) mXTileCount = (int) Math.floor(w / mTileSize); mYTileCount = (int) Math.floor(h / mTileSize); mXOffset = (w - (mTileSize * mXTileCount) / 2); mYOffset = (h - (mTileSize * mYTileCount) / 2); mTileGrid = new intmXTileCount
39、mYTileCount; clearTiles(); /* * Function to set the specified Drawable as the tile for a particular * integer key. * * param key * param tile */ public void loadTile(int key, Drawable tile) Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas
40、(bitmap); tile.setBounds(0, 0, mTileSize, mTileSize); tile.draw(canvas); mTileArraykey = bitmap; /* * Resets all tiles to 0 (empty) * */ public void clearTiles() for (int x = 0; x mXTileCount; x+) for (int y = 0; y mYTileCount; y+) setTile(0, x, y); /* * Used to indicate that a particular tile (set
41、with loadTile and referenced * by an integer) should be drawn at the given x/y coordinates during the * next invalidate/draw cycle. * * param tileindex * param x * param y */ public void setTile(int tileindex, int x, int y) mTileGridxy = tileindex; Override public void onDraw(Canvas canvas) super.on
42、Draw(canvas); for (int x = 0; x mXTileCount; x += 1) for (int y = 0; y 0) canvas.drawBitmap(mTileArraymTileGridxy, mXOffset + x * mTileSize, mYOffset + y * mTileSize, mPaint); SnakeView.javapackage com.example.android.snake;import java.util.ArrayList;import java.util.Random;import android.content.Co
43、ntext;import android.content.res.Resources;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.os.Bundle;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.widget.TextView;/* * SnakeView: implementation of a si
44、mple game of Snake * * */public class SnakeView extends TileView private static final String TAG = SnakeView; /* * Current mode of application: READY to run, RUNNING, or you have already * lost. static final ints are used instead of an enum for performance * reasons. */ private int mMode = READY; pu
45、blic static final int PAUSE = 0; public static final int READY = 1; public static final int RUNNING = 2; public static final int LOSE = 3; /* * Current direction the snake is headed. */ private int mDirection = NORTH; private int mNextDirection = NORTH; private static final int NORTH = 1; private st
46、atic final int SOUTH = 2; private static final int EAST = 3; private static final int WEST = 4; /* * Labels for the drawables that will be loaded into the TileView class */ private static final int RED_STAR = 1; private static final int YELLOW_STAR = 2; private static final int GREEN_STAR = 3; /* *
47、mScore: used to track the number of apples captured mMoveDelay: number of * milliseconds between snake movements. This will decrease as apples are * captured. */ private long mScore = 0; private long mMoveDelay = 600; /* * mLastMove: tracks the absolute time when the snake last moved, and is used *
48、to determine if a move should be made based on mMoveDelay. */ private long mLastMove; /* * mStatusText: text shows to the user in some run states */ private TextView mStatusText; /* * mSnakeTrail: a list of Coordinates that make up the snakes body * mAppleList: the secret location of the juicy apple
49、s the snake craves. */ private ArrayList mSnakeTrail = new ArrayList(); private ArrayList mAppleList = new ArrayList(); /* * Everyone needs a little randomness in their life */ private static final Random RNG = new Random(); /* * Create a simple handler that we can use to cause animation to happen.
50、We * set ourselves as a target and we can use the sleep() * function to cause an update/invalidate to occur at a later date. */ private RefreshHandler mRedrawHandler = new RefreshHandler(); class RefreshHandler extends Handler Override public void handleMessage(Message msg) SnakeView.this.update();
51、SnakeView.this.invalidate(); public void sleep(long delayMillis) this.removeMessages(0); sendMessageDelayed(obtainMessage(0), delayMillis); ; /* * Constructs a SnakeView based on inflation from XML * * param context * param attrs */ public SnakeView(Context context, AttributeSet attrs) super(context
52、, attrs); initSnakeView(); public SnakeView(Context context, AttributeSet attrs, int defStyle) super(context, attrs, defStyle); initSnakeView(); private void initSnakeView() setFocusable(true); Resources r = this.getContext().getResources(); resetTiles(4); loadTile(RED_STAR, r.getDrawable(R.drawable
53、.redstar); loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar); loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar); private void initNewGame() mSnakeTrail.clear(); mAppleList.clear(); / For now were just going to load up a short default eastbound snake / thats just turned north mSnakeTr
54、ail.add(new Coordinate(7, 7); mSnakeTrail.add(new Coordinate(6, 7); mSnakeTrail.add(new Coordinate(5, 7); mSnakeTrail.add(new Coordinate(4, 7); mSnakeTrail.add(new Coordinate(3, 7); mSnakeTrail.add(new Coordinate(2, 7); mNextDirection = NORTH; / Two apples to start with addRandomApple(); addRandomAp
55、ple(); mMoveDelay = 600; mScore = 0; /* * Given a ArrayList of coordinates, we need to flatten them into an array of * ints before we can stuff them into a map for flattening and storage. * * param cvec : a ArrayList of Coordinate objects * return : a simple array containing the x/y values of the co
56、ordinates * as x1,y1,x2,y2,x3,y3. */ private int coordArrayListToArray(ArrayList cvec) int count = cvec.size(); int rawArray = new intcount * 2; for (int index = 0; index count; index+) Coordinate c = cvec.get(index); rawArray2 * index = c.x; rawArray2 * index + 1 = c.y; return rawArray; /* * Save g
57、ame state so that the user does not lose anything * if the game process is killed while we are in the * background. * * return a Bundle with this views state */ public Bundle saveState() Bundle map = new Bundle(); map.putIntArray(mAppleList, coordArrayListToArray(mAppleList); map.putInt(mDirection,
58、Integer.valueOf(mDirection); map.putInt(mNextDirection, Integer.valueOf(mNextDirection); map.putLong(mMoveDelay, Long.valueOf(mMoveDelay); map.putLong(mScore, Long.valueOf(mScore); map.putIntArray(mSnakeTrail, coordArrayListToArray(mSnakeTrail); return map; /* * Given a flattened array of ordinate p
59、airs, we reconstitute them into a * ArrayList of Coordinate objects * * param rawArray : x1,y1,x2,y2,. * return a ArrayList of Coordinates */ private ArrayList coordArrayToArrayList(int rawArray) ArrayList coordArrayList = new ArrayList(); int coordCount = rawArray.length; for (int index = 0; index
60、coordCount; index += 2) Coordinate c = new Coordinate(rawArrayindex, rawArrayindex + 1); coordArrayList.add(c); return coordArrayList; /* * Restore game state if our process is being relaunched * * param icicle a Bundle containing the game state */ public void restoreState(Bundle icicle) setMode(PAU
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 第13課 五四運(yùn)動(dòng)
- 《企業(yè)及管理》課件
- 項(xiàng)目里程碑成果展
- 秋分習(xí)俗的地理解讀
- 大班月份工作計(jì)劃
- 2023年-2024年項(xiàng)目管理人員安全培訓(xùn)考試題答案標(biāo)準(zhǔn)卷
- 《電流跟電壓》課件
- 隧道隧道內(nèi)環(huán)境監(jiān)測(cè)-洞察分析
- 性別平等與人口質(zhì)量的關(guān)系-洞察分析
- 宇宙微波背景輻射的精細(xì)結(jié)構(gòu)分析-洞察分析
- 2025年1月山西、陜西、寧夏、青海普通高等學(xué)校招生考試適應(yīng)性測(cè)試(八省聯(lián)考)政治
- 《廣東省智慧高速公路建設(shè)指南(試行)》
- 護(hù)理年終個(gè)人工作總結(jié)
- 《臨床顱內(nèi)壓增高》課件
- 2024老師聘用合同范本
- 國(guó)開電大《建筑結(jié)構(gòu)試驗(yàn)》形考任務(wù)1-4參考答案
- 年度分析報(bào)告格式范文
- 浙江省2023年1月學(xué)業(yè)考試物理物理試題(解析版)
- 2024電力建設(shè)工程質(zhì)量問(wèn)題通病防止手冊(cè)
- 【初中地理】世界的聚落+課件-2024-2025學(xué)年七年級(jí)地理上學(xué)期(湘教版2024)
- 辯論英文課件教學(xué)課件
評(píng)論
0/150
提交評(píng)論