畢業(yè)設(shè)計--基于java的游戲設(shè)計_第1頁
已閱讀1頁,還剩40頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p>  基于JAVA的游戲設(shè)計</p><p><b>  摘要</b></p><p>  J2SE(Java 2 Simple Edition) 定位在客戶端,主要用于桌面應(yīng)用軟件的編程,J2SE包含于J2EE中,J2ME包含了J2SE的核心類,但新添加了一些專有類。因其擁有“Write Once, run anywhere”的Java特性而提高開發(fā)

2、的效率。</p><p>  隨著JAVA應(yīng)用的日益普及、Java在各種平臺上的的實現(xiàn),Java應(yīng)用程序一次編譯到處運行的特點逐漸體現(xiàn)出其影響力,對減少重復(fù)編程、提供快捷的跨平臺應(yīng)用起著不可忽視的作用。本論文著眼于JAVA技術(shù)的應(yīng)用,開發(fā)一款可用于各種平臺之上的游戲程序——坦克大戰(zhàn)。本程序的思路來自于日本任天堂公司在20世紀80年代開發(fā)的Battle City游戲,將老少皆宜的經(jīng)典作品重新用JAVA進行了呈現(xiàn),為

3、更流行的硬件平臺提供應(yīng)用軟件。</p><p>  關(guān)鍵詞 JAVA;J2SE;游戲;坦克大戰(zhàn)</p><p><b>  Abstract</b></p><p>  J2SE is a kind of fast developing technology implemented on various devices especially

4、mobile communication equipments. It focuses on application for consumptive electronic products, providing revolutionary solution to the intelligentization and diversification of the equipment. It improve the efficiency o

5、f the development process thanks to its “Write Once, run anywhere” nature.</p><p>  When cell phone is getting ever more popular nowadays, with the implementation of Java technology on mobile equipment, incr

6、ement of capital on communication service exhibits its force on people’s everyday life, providing them ever fast information just in hand. This dissertation focuses on implementation of J2SE technology and has developed

7、a commercial game suite run on mobile phones—Tank. This application inherits many characters of the old fashioned game Battle City which developed by Nintend</p><p>  Keywords Java;J2SE;Game;TankWord</p&g

8、t;<p><b>  目錄</b></p><p><b>  摘要I</b></p><p>  AbstractII</p><p><b>  第1章 緒論1</b></p><p>  第2章 開發(fā)環(huán)境及相關(guān)技術(shù)的介紹3</p>&

9、lt;p><b>  2.1開發(fā)環(huán)境3</b></p><p>  2.2 Java語言的特點3</p><p>  2.3關(guān)于ECLIPSE4</p><p>  第3章 程序結(jié)構(gòu)、思想和相關(guān)技術(shù)5</p><p>  3.1 本程序需解決的有關(guān)技術(shù)問題5</p><p>  3

10、.2 程序截圖7</p><p>  3.3 程序流程8</p><p>  3.4 相關(guān)技術(shù)8</p><p>  3.4.1 多態(tài)8</p><p>  3.4.2 單例模式9</p><p>  3.4.3 責任鏈模式9</p><p>  3.4.4 工廠模式9</p

11、><p>  3.4.5 簡單工廠模式10</p><p>  3.4.6 抽象工廠模式10</p><p>  3.4.7 策略模式11</p><p>  3.4.8 調(diào)停者模式11</p><p>  3.4.9 門面模式11</p><p>  3.4.10 PNG格式11<

12、;/p><p>  3.4.11 AWT繪制的基本原理12</p><p>  3.4.12 雙緩沖12</p><p>  3.5 程序思路13</p><p>  3.5.1 坦克的控制和敵方的智能運行13</p><p>  3.5.2 子彈的運行和控制14</p><p>  第4

13、章 程序分析和具體實現(xiàn)16</p><p>  4.1 主游戲邏輯及其涉及到的若干類16</p><p>  4.2 坦克的共同行為19</p><p>  4.3 玩家坦克的功能屬性19</p><p>  4.4 敵人坦克的功能屬性20</p><p>  4.5 子彈的運行和控制24</p>

14、;<p><b>  結(jié)論26</b></p><p><b>  致謝28</b></p><p><b>  參考文獻29</b></p><p><b>  附錄A30</b></p><p><b>  附錄B34

15、</b></p><p><b>  第1章 緒論</b></p><p>  現(xiàn)在流行的游戲似乎都是用C或C++來開發(fā)的。在Java平臺上幾乎沒有很大型及可玩的流行游戲。由于Java是個新生語言,他的許多特性還有待大家的發(fā)掘,但是我們不能否認Java在游戲編程方面的強大性。本文將帶領(lǐng)大家一步一步學習編寫Java游戲。最終打造屬于自己的Java游戲。<

16、;/p><p>  Java是由Sun Microsystems公司于1995年5月推出的Java程序設(shè)計語言(以下簡稱Java語言)和Java平臺的總稱。用Java實現(xiàn)的Hot Java瀏覽器(支持Java applet)顯示了Java的魅力:跨平臺、動態(tài)的Web、Internet計算。從此,Java被廣泛接受并推動了Web的迅速發(fā)展,常用的瀏覽器現(xiàn)在均支持Java applet。另一方面,Java技術(shù)也不斷更新。

17、</p><p>  Java平臺由Java虛擬機(Java Virtual Machine)和Java 應(yīng)用編程接口(Application Programming Interface、簡稱API)構(gòu)成。Java 應(yīng)用編程接口為Java應(yīng)用提供了一個獨立于操作系統(tǒng)的標準接口,可分為基本部分和擴展部分。在硬件或操作系統(tǒng)平臺上安裝一個Java平臺之后,Java應(yīng)用程序就可運行?,F(xiàn)在Java平臺已經(jīng)嵌入了幾乎所有的操

18、作系統(tǒng)。這樣Java程序可以只編譯一次,就可以在各種系統(tǒng)中運行。Java應(yīng)用編程接口已經(jīng)從1.1x版發(fā)展到1.2版。目前常用的Java平臺基于Java1.4,最近版本為Java1.7(本文應(yīng)用的JDK1.7版本)。</p><p>  雖然 Java 已經(jīng)被用到許多企業(yè)級軟體上,可是其實骨子里面還是非常適合用在嵌入式系統(tǒng)之中。Java平臺演進到Java2后,Java平臺分別針對不同領(lǐng)域的需求被分成四個版本,亦即J

19、2EE、J2SE、J2ME以及Java Card(其結(jié)構(gòu)示意圖見圖1.1)。 </p><p>  圖1.1 Java結(jié)構(gòu)圖</p><p>  J2SE就是Java2的標準版,主要用于桌面應(yīng)用軟件的編程;J2ME主要應(yīng)用于嵌入是系統(tǒng)開發(fā),如手機和PDA的編程;J2EE是Java2的企業(yè)版,主要用于分布式的網(wǎng)絡(luò)程序的開發(fā),如電子商務(wù)網(wǎng)站和ERP系統(tǒng)。<

20、/p><p>  Standard Edition(標準版) J2SE 包含那些構(gòu)成Java語言核心的類。比如:數(shù)據(jù)庫連接、接口定義、輸入/輸出、網(wǎng)絡(luò)編程。</p><p>  Enterprise Edition(企業(yè)版) J2EE 包含J2SE 中的類,并且還包含用于開發(fā)企業(yè)級應(yīng)用的類。比如:EJB、Servlet、JSP、XML、事務(wù)控制。</p><p>  M

21、icro Edition(微縮版) J2ME 包含J2SE中一部分類,用于消費類電子產(chǎn)品的軟件開發(fā)。比如:呼機、智能卡、手機、PDA、機頂盒。</p><p>  通過本次設(shè)計可以綜合運用J2SE所擁有的API,初步掌握面向?qū)ο缶幊痰幕舅枷?,掌握Eclipse開發(fā)J2SE程序的基本方法。掌握Eclipse調(diào)試程序的方法。簡單的應(yīng)用了設(shè)計模式等概念。</p><p>  第2章 開發(fā)環(huán)境及

22、相關(guān)技術(shù)的介紹</p><p><b>  2.1開發(fā)環(huán)境</b></p><p>  操作系統(tǒng):Microsoft Windows XP</p><p>  程序語言:Java 2</p><p>  開發(fā)包: Java(TM) 2 Standard Edition (build 1.7.1)Sun Micro.&l

23、t;/p><p>  IDE: Eclipse -SDK-3.4.1</p><p>  2.2 Java語言的特點</p><p><b>  1、 平臺無關(guān)性</b></p><p>  Java引進虛擬機原理,并運行于虛擬機,實現(xiàn)不同平臺之間的Java接口。使用Java編寫的程序能在世界范圍內(nèi)共享。Java的

24、數(shù)據(jù)類型與機器無關(guān)。</p><p><b>  2、 安全性</b></p><p>  Java的編程類似C++,但舍棄了C++的指針對存儲器地址的直接操作,程序運行時,內(nèi)存由操作系統(tǒng)分配,這樣可以避免病毒通過指針入侵系統(tǒng)。它提供了安全管理器,防止程序的非法訪問。</p><p><b>  3、 面向?qū)ο?lt;/b>&l

25、t;/p><p>  Java吸收了C++面向?qū)ο蟮母拍?,將?shù)據(jù)封裝于類中,實現(xiàn)了程序的簡潔性和便于維護性,使程序代碼可以只需一次編譯就可反復(fù)利用。</p><p><b>  4、 分布式</b></p><p>  Java建立在TCP/IP網(wǎng)絡(luò)平臺上,提供了用HTTP和FTP協(xié)議傳送和接收信息的庫函數(shù),使用其相關(guān)技術(shù)可以十分方便的構(gòu)建分布式應(yīng)

26、用系統(tǒng)。</p><p><b>  5、 健壯性</b></p><p>  Java致力與檢查程序在編譯和運行時的錯誤,并自動回收內(nèi)存,減少了內(nèi)存出錯的可能性。Java取消了C語言的結(jié)構(gòu)、指針、#define語句、多重繼承、goto語句、操作符、重載等不易被掌握的特性,提供垃圾收集器自動回收不用的內(nèi)存空間。</p><p>  2.3 關(guān)于

27、ECLIPSE</p><p>  Eclipse 是一個開放源代碼的、基于 Java 的可擴展開發(fā)平臺。就其本身而言,它只是一個框架和一組服務(wù),用于通過插件組件構(gòu)建開發(fā)環(huán)境。幸運的是,Eclipse 附帶了一個標準的插件集,包括 Java 開發(fā)工具(Java Development Tools,JDT)。</p><p>  雖然大多數(shù)用戶很樂于將 Eclipse 當作 Java IDE

28、 來使用,但 Eclipse 的目標不僅限于此。Eclipse 還包括插件開發(fā)環(huán)境(Plug-in Development Environment,PDE),這個組件主要針對希望擴展 Eclipse 的軟件開發(fā)人員,因為它允許他們構(gòu)建與 Eclipse 環(huán)境無縫集成的工具。由于 Eclipse 中的每樣東西都是插件,對于給 Eclipse 提供插件,以及給用戶提供一致和統(tǒng)一的集成開發(fā)環(huán)境而言,所有工具開發(fā)人員都具有同等的發(fā)揮場所。<

29、;/p><p>  這種平等和一致性并不僅限于 Java 開發(fā)工具。盡管 Eclipse 是使用 Java 語言開發(fā)的,但它的用途并不限于 Java 語言;例如,支持諸如 C/C++、COBOL 和 Eiffel 等編程語言的插件已經(jīng)可用,或預(yù)計會推出。Eclipse 框架還可用來作為與軟件開發(fā)無關(guān)的其他應(yīng)用程序類型的基礎(chǔ),比如內(nèi)容管理系統(tǒng)。Eclipse 是一個開放源代碼的、基于 Java 的可擴展開發(fā)平臺。就其本

30、身而言,它只是一個框架和一組服務(wù),用于通過插件組件構(gòu)建。</p><p>  第3章 程序結(jié)構(gòu)、思想和相關(guān)技術(shù)</p><p>  3.1 本程序需解決的有關(guān)技術(shù)問題</p><p>  1、 游戲程序是一項精度要求很高的程序系統(tǒng),因為其代碼利用率很高。一個實時運行的最終作品,每秒都會運行成千上萬行程序,繪圖事件、鍵盤事件都會以極高的頻率在后臺等待響應(yīng),若有絲毫的

31、差別都將很容易導致程序在運行不久后可能出現(xiàn)嚴重錯誤,甚至死循環(huán)。因此,其邏輯設(shè)計應(yīng)當相當嚴謹,需將所有可能發(fā)生的事件及意外情況考慮在設(shè)計中。</p><p>  2、 游戲中為了美觀,適用性強,可能需要采用外部文件引入的圖片貼圖,有關(guān)貼圖,在MIDP2.0中提供了用于增強游戲功能的game包,使得解決靜態(tài)或動態(tài)、畫面背景、屏幕刷新的雙緩沖等都有較好的解決方案。</p><p>  3、

32、 己方坦克的運行可以通過鍵盤響應(yīng)事件控制,但敵方則因為是自動運行,就需要有一定其一定的智能性;同時,出現(xiàn)在屏幕上的敵方可能會有較多的數(shù)量,這需要為每個敵方開辟一個線程以便能讓其獨立運行。Java的多線程能力為實現(xiàn)這樣的游戲提供了可能。敵人坦克的運行算法也需要進行適當?shù)脑O(shè)置,以免游戲過于簡單,單調(diào)。</p><p>  4、 對于雙方坦克發(fā)出的子彈的控制也需要對其跟蹤控制,子彈也需要處在獨立的線程中。敵方子彈僅需

33、要掃描用戶坦克,而用戶坦克需要在每一步掃描所有的敵方坦克。這需要對所有的對象有較好的控制。另外,子彈在運行過程中也需要實時掃描是否碰撞到了相關(guān)障礙物或屏幕邊界。如此過多的線程同時在本來效率就不高的KVM虛擬機上運行,也許會導致程序的緩慢。</p><p>  5、 雙方的坦克在前進時也需要考慮到是否碰撞到相關(guān)物體或?qū)Ψ教箍耍悦庵丿B運行,造成許多物理上不可能的情況,缺乏真實感。每一次刷新頁面、每前進一步都需要將

34、所有的周圍環(huán)境都進行掃描。</p><p>  6、 游戲的結(jié)束、開始、動態(tài)信息畫面作為構(gòu)成一個完美程序都是必不可少的重要部分。良好的用戶界面更是吸引用戶的硬指標,相關(guān)的美術(shù)構(gòu)圖也需要有一定的考慮。</p><p>  7、 游戲的地圖不可能通過繪圖來解決。否則,不僅難于控制和處理過多的元素,也會因過多的大型圖片而不能限制程序的大小,失去程序的原則和Java的優(yōu)勢。同時,地圖關(guān)卡不宜保

35、存占用過多的內(nèi)存,而最好采取外部文件的讀入讀出方法。</p><p>  8、 用戶運行游戲時需要有分數(shù)記錄的可能。如何采用合理的記分標準,需要進行適當?shù)脑O(shè)計。記錄分數(shù)的存儲方式也需要有較好的解決方案。手機中由于處理器和內(nèi)存空間、存儲空間都十分有限,其數(shù)據(jù)庫系統(tǒng)與普通PC大相徑庭。其數(shù)據(jù)庫結(jié)構(gòu)較為簡單,被稱之為RMS系統(tǒng)。</p><p>  9、 本程序應(yīng)用的技術(shù)</p>

36、<p>  多態(tài)Polymorphism;單例模式Singleton;責任鏈模式Chain of Responsibility;工廠模式Factory Method;簡單工廠模式Simple Factory;抽象工廠模式Abstract Factory;策略模式Strategy;調(diào)停者模式Mediator;門面模式Facade等概念與技術(shù)并將一些屬性信息抽象了除了以配置文件的方式出現(xiàn),從而方便用戶更改。以上相關(guān)技術(shù)細節(jié)和整

37、體流程將分別在以下小節(jié)闡述。</p><p><b>  3.2 程序截圖</b></p><p><b>  圖3.1 程序截圖</b></p><p><b>  3.3 程序流程</b></p><p>  本程序采用面向?qū)ο蟮脑O(shè)計模式,對游戲中的所有物體賦予對象的概念和

38、屬性。運行程序后允許用戶選擇執(zhí)行選項菜單,在開始游戲后將先從外部文件載入地圖文件,對背景的所有物體進行繪圖。在主程序運行的線程中,畫面刷新將以一定的頻率采用雙緩沖技術(shù)對屏幕重繪,實時反映整個游戲的進行狀態(tài)。用戶控制的坦克運行在主線程中,隨屏幕刷新的頻率而步進。敵方坦克將在游戲開始時逐漸新增線程,每增加一個敵方對象就新增加一條線程,一旦線程數(shù)滿到最大值,就不允許敵人再繼續(xù)出現(xiàn)。用戶坦克自誕生之時起將擁有一發(fā)子彈,子彈雖然開在單獨的線程中,

39、但運行結(jié)束后(比如撞到相關(guān)物體或敵方坦克時)并不結(jié)束子彈對象,只是將其線程終止。用戶再次發(fā)射子彈時只是將終止的線程再次激活。在屏幕重繪的主程序中,將在每次的循環(huán)中判斷若干事件。如:用戶坦克的生命是否已完全用盡,敵方坦克數(shù)是否已經(jīng)為零,屏幕上的坦克數(shù)量是否少于仍剩下的坦克數(shù)量等。以便程序進入相關(guān)的分支執(zhí)行相關(guān)的反應(yīng)代碼,結(jié)束游戲或統(tǒng)計分數(shù)等。主程序流程如圖3.2所示。</p><p><b>  3.4

40、相關(guān)技術(shù)</b></p><p><b>  3.4.1 多態(tài)</b></p><p>  多態(tài)性是繼數(shù)據(jù)抽象和繼承后,面向?qū)ο笳Z言的第三個特征。Java的多態(tài)性它的突出優(yōu)點是使程序具有良好的擴展性。它通過繼承,可以派生出任意多個新類型,或向基類增加更多方法時,無須修改原有對基礎(chǔ)類進行處理的相關(guān)程序。就是擴展性好。</p><p>

41、  3.4.2 單例模式</p><p>  作為對象的創(chuàng)建模式[GOF95], 單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。這個類稱為單例類。</p><p>  圖3.3 單例模式圖</p><p>  顯然單例模式的要點有三個;一是某各類只能有一個實例;二是它必須自行創(chuàng)建這個實例;三是它必須自行向整個系統(tǒng)提供這個實例。在下面的對象

42、圖中,有一個"單例對象",而"客戶甲"、"客戶乙" 和"客戶丙"是單例對象的三個客戶對象??梢钥吹?,所有的客戶對象共享一個單例對象。而且從單例對象到自身的連接線可以看出,單例對象持有對自己的引用。如圖3.3所示。</p><p>  3.4.3 責任鏈模式</p><p>  多個對象都有機會處理請求,從而避免

43、請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。</p><p><b>  適用范圍:</b></p><p>  1、 有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。</p><p>  2、 你想在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。

44、 </p><p>  3、 可處理一個請求的對象集合應(yīng)被動態(tài)指定。com.cz.tank包下的ColliderChain類用責任鏈模式遍歷所有游戲物體 做碰撞檢測。</p><p>  3.4.4 工廠模式</p><p>  工廠模式為系統(tǒng)結(jié)構(gòu)提供了靈活的動態(tài)擴展機制,減少工作量方便維護,方便維護。com.cz.tank 類 GameFactoryMgr應(yīng)用了

45、工廠模式。</p><p>  3.4.5 簡單工廠模式</p><p>  專門定義一個類來負責創(chuàng)建其他類的實例,被創(chuàng)建的實例通常都具有共同的父類。它又稱為靜態(tài)工廠方法模式,屬于類的創(chuàng)建型模式。簡單工廠模式的UML類圖如圖3.4所示:</p><p>  圖3.4 簡單工廠模式</p><p>  簡單工廠模式的實質(zhì)是由一個工廠類根據(jù)傳入的

46、參數(shù),動態(tài)決定應(yīng)該創(chuàng)建哪一個產(chǎn)品類(這些產(chǎn)品類繼承自一個父類或接口)的實例。該模式中包含的角色及其職責。用戶在使用時可以直接根據(jù)工廠類去創(chuàng)建所需的實例,而無需了解這些對象是如何創(chuàng)建以及如何組織的。有利于整個軟件體系結(jié)構(gòu)的優(yōu)化。</p><p>  3.4.6 抽象工廠模式</p><p>  抽象工廠模式可以向客戶端提供一個接口,使得客戶端在不必指定產(chǎn)品具體類型的情況下,創(chuàng)建多個產(chǎn)品族中的

47、產(chǎn)品對象。這就是抽象工廠模式的用意。</p><p>  每個模式都是針對一定問題的解決方案。抽象工廠模式面對的問題是多產(chǎn)品等級結(jié)構(gòu)的系統(tǒng)設(shè)計。</p><p>  3.4.7 策略模式</p><p>  策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。本程序的坦克外觀使用了策略模式。com

48、.cz.tank.strategies的DrawTankStrategy類。</p><p>  3.4.8 調(diào)停者模式</p><p>  用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。com.cz.tank 類 Game Mediator使用了調(diào)停者模式。</p><p>  3.4

49、.9 門面模式</p><p>  外部與一個子系統(tǒng)的通信必須通過一個統(tǒng)一的門面(Facade)對象進行,這就是門面模式。</p><p>  3.4.10 PNG格式</p><p>  PNG具體格式由PNG Specification Version 1.0定義的。PNG格式提供透明背景的圖像,這對繪制游戲畫面和被操縱主角極有幫助。坦克之間或與障礙物碰撞時就不

50、會因為背景有特定的顏色,顯示出的效果像貼上的圖片而缺乏真實感,物體之間輕微重疊時最上層圖片也不會覆蓋超過其有效象素外的部分。</p><p>  PNG格式圖片中包含許多定義其圖片特性的冗余部分(Chunks)。這些代碼包含在每一個單獨的PNG格式圖像中,然而如果將多個PNG圖像合并在一張幅面稍大一些的整圖中,多個chunks就可以得到精簡,圖片的大小可以得到控制。使用Image類中的create Image函數(shù)

51、可從整圖中分割出所需要的元素。在Game包中的Tiled Layer和Sprite類都整合了這樣的功能。本程序中的地圖元素都集成在一張MAP.png圖片中,實現(xiàn)了方便的管理和程序體積的精簡。</p><p>  3.4.11 AWT繪制的基本原理</p><p>  AWT的繪制與界面更新使用了一個單獨的線程,稱為AWT線程。paint、repaint、update 三個方法關(guān)系如圖3.5

52、所示 :</p><p>  圖3.5 雙緩沖原理示意圖</p><p>  3.4.12 雙緩沖</p><p>  進行游戲繪圖一般需要手動編程使用雙緩沖。需要在paint()方法內(nèi)所想要畫的圖形畫在一張預(yù)先準備好的背景,等所有繪圖操作都完成后再將背景的數(shù)據(jù)拷貝到實際的屏幕上。Image類提供了一個建立背景的靜態(tài)方法createImage(int width,

53、int height),再利用getGraphics()方法取得屬于這個背景的Graphics對象,所進行的</p><p>  繪圖操作都會作用在背景上,等到全部的繪圖操作完成后,再調(diào)用paint()方法將背景的數(shù)據(jù)復(fù)制到實際顯示的屏幕上。</p><p>  這樣的技術(shù)在繪制動畫時特別有用。繪制動畫時經(jīng)常需要不斷地更新畫面,而更新畫面的操作就是先將屏幕以fillRect()的方式清除,

54、再將下一張圖片畫在屏幕上,然而反復(fù)的清除及重繪會造成屏幕的閃爍現(xiàn)象(flicker),因此使用雙重緩沖的好處就是在背景進行這個清除及重繪的操作,再將完成的繪圖拷貝到屏幕上,由于用戶看不到清除的操作,因此就不會出現(xiàn)閃爍的現(xiàn)象了。</p><p><b>  3.5 程序思路</b></p><p>  3.5.1 坦克的控制和敵方的智能運行</p><

55、;p>  GameCanvas中提供了與以往不同的鍵盤采樣功能。GameMediator類中采取響應(yīng)鍵盤事件的方法,每次執(zhí)行周期時會讀取keyPressed函數(shù)中需執(zhí)行的代碼。這樣的機制并不適合某些游戲場合。在某些不支持keyRepeat功能的設(shè)備上,反復(fù)執(zhí)行的按鍵,比如發(fā)射子彈,將不能因為長時間按壓而自動重復(fù),這樣就需要用戶高頻率的手動擊鍵,這在操縱空間非常有限的移動設(shè)備上是非常困難的。同時,事件的執(zhí)行周期也并不一定適合游戲的場

56、合,也許需要更高頻率執(zhí)行的按鍵卻只能在指定的周期內(nèi)規(guī)律的響應(yīng)。對此,針對游戲的開發(fā),Game包提供的鍵盤狀態(tài)功能將顯得十分有效。</p><p>  GameCanvas提供getKeyStates函數(shù)可獲取當前鍵盤上的信息。將以位的形式返回鍵盤上所有鍵的按與釋放的狀態(tài),當bit為1時,鍵就是被按下的狀態(tài),為0時則為釋放狀態(tài)。只需要此一個函數(shù)的返回值就可以返回所有鍵的狀態(tài)。這保證了快速的按鍵和釋放也會被循環(huán)所捕捉

57、。同時,這樣的機制也可檢測到幾個鍵同時按下的狀態(tài),從而提供斜向運行等相應(yīng)功能。</p><p>  敵方按照規(guī)則不能和用戶坦克重合,則它每行走一步就需要把用戶坦克掃描一次,判斷其是否碰撞到了用戶的坦克。Sprite類中提供了collidesWith函數(shù),用于判斷是否與某個TiledLayer、Sprite、Image的對象有圖象上的重合(即游戲中的碰撞)。然而不能僅僅將用戶坦克作為其Sprite參數(shù)傳遞給敵人的類

58、進行判斷。因為如果發(fā)生碰撞,collidesWith成立,則兩輛坦克已經(jīng)發(fā)生了圖象重合,違反了規(guī)則,甚至若再進行collidesWith判斷的話,其結(jié)果將永為真。為了提前預(yù)知碰撞,可以將所有坦克的碰撞范圍設(shè)定為一個比坦克圖片稍大一些的矩形,此矩形僅在坦克前方比坦克圖形多出一個象素。在多出的11個象素中,按照每個象素依次檢查此象素是否于外界發(fā)生碰撞,如果不是按照象素檢查,則當坦克與障礙物錯位并同時與兩種物體接觸時將有可能忽略檢測其中的一樣

59、物體。這樣,就可以提前一步判斷。如果發(fā)生碰撞,則坦克應(yīng)當選擇掉轉(zhuǎn)方向,此時,兩輛碰撞的坦克又因為其矩形區(qū)域不重合而不符合collidesWith的條件,就可以繼續(xù)正常運行了。</p><p>  敵方坦克由于需要具有一定的智能性,以便對玩家攻擊,使之具有一定的可玩性。敵人可以自動行走,但是應(yīng)當在以下適當?shù)那闆r下轉(zhuǎn)向:首先是是否超出界面的邊界,其次是是否與地圖障礙物發(fā)生了碰撞,再次是是否與用戶坦克發(fā)生了碰撞。需要指

60、出的是,當發(fā)生阻礙不能在不變方向的情況下繼續(xù)行走時,并不一定立即需要采取轉(zhuǎn)向的對策。如果一定發(fā)生轉(zhuǎn)向,試想,當敵方碰到玩家時,如果它立即轉(zhuǎn)向,將不會對玩家發(fā)射射向他的子彈,就不構(gòu)成任何威脅,當然,也不能永遠不轉(zhuǎn)向。本程序設(shè)置為:當碰撞到障礙物或邊界時立即轉(zhuǎn)向,但碰到玩家坦克時需要有一個等待的時間,這個時間由碰撞前隨機取得的在某方向上的持續(xù)行走步數(shù)決定,當發(fā)生坦克間碰撞時,此隨機數(shù)將在下一次循環(huán)前減少為原來的2/3,這樣就實現(xiàn)了加快轉(zhuǎn)向的

61、時間,避免死鎖在一個方向上靜止的停留過長的時間。另外,坦克的發(fā)炮間隔和轉(zhuǎn)后的具體方向都由隨機數(shù)決定。坦克之間由以上道理也不會發(fā)生重疊,但當某坦克正從上方生成而正巧有另一輛阻礙在其生成點處,這將導致不可避免的重合。這是允許的,但需要對他們標注狀態(tài),即當坦克剛出現(xiàn)時暫時允許重合,一旦在某個時間他們脫離了重合狀態(tài),就不能在允許重合,如果不設(shè)置這</p><p>  3.5.2 子彈的運行和控制</p>&

62、lt;p>  每一個坦克都有他自己的一顆子彈,這顆子彈在任何一輛坦克被構(gòu)造時就一直存在,直至此坦克生命的結(jié)束,子彈的再次只是將屏幕上暫時掩蓋的圖象重新置于坦克炮筒才恰當位置,并使其顯示出來,這與現(xiàn)實中每個子彈都是單獨的個體有所不同。</p><p>  子彈所需要完成的任務(wù)有:</p><p>  它是一個繼承了Runnable虛類的可運行單獨線程的對象。在其出現(xiàn)在屏幕上的運行周期中

63、,每一步都需要循環(huán)檢測以下條件:</p><p>  是否與某坦克發(fā)生了碰撞,即擊中了這輛坦克。子彈使用的是象素級的碰撞檢測,因為子彈的圖片形狀不規(guī)則,如果使用矩形碰撞檢測,將有可能在子彈尚未接觸到物體時就已返回碰撞的真值。分為兩種情況,如果此子彈來自于敵方,將只檢測玩家坦克,因為敵方之間的子彈必須允許可以透明的穿過,以保證不會在敵人之間發(fā)生子彈的消減。如果來自玩家,則每一步需掃描所有的敵方坦克,檢查是否發(fā)生碰撞

64、,這可能會花費不少的CPU時間。</p><p>  其次,子彈之間需要檢測是否碰撞。敵人之間顯然,如上已經(jīng)提過,不需要檢測,但敵人與玩家之間應(yīng)當可以互相消除子彈,以便在狹窄的路口中仍有存活的機會。玩家的子彈需要在每一步檢測所有敵人的子彈的運行狀態(tài)。這樣較多的運算也將不可避免的耗費大量CPU時間。</p><p>  子彈對不同障礙物將有不同的反映。對磚墻將有能力將其擊毀,使之在畫面上消失

65、;對水泥鋼筋將不能發(fā)生作用,子彈也不能通過;對于河流,坦克不可以通過,但子彈可以;對于草叢,子彈和坦克都可以通過。</p><p>  第4章 程序分析和具體實現(xiàn)</p><p>  4.1 主游戲邏輯及其涉及到的若干類</p><p>  TankClient主管著所有類之間的協(xié)調(diào),決定何時死亡,何時分配新的敵人,及控制敵人出現(xiàn)處的閃光圖標、游戲結(jié)束后的動態(tài)Gam

66、e over字樣。它運行在獨立的線程中,以恒定的頻率刷新畫面。刷新速度需大于30/秒才能使畫面顯示因人眼的暫時停留效應(yīng)流暢運行。本程序設(shè)置為20毫秒。其主邏輯如圖4.1所示。</p><p>  程序中建立了另外的兩個包,分別表述了敵人坦克和玩家坦克的功能。它們分別為:EnemySprite和UserSprite。這兩個類均在TankClient中建立了對象,以便進行統(tǒng)一調(diào)度。BattleCanvas包括了Lay

67、erManager,這樣所有靜態(tài)和動態(tài)的圖象都不需要手動刷新,只需要在LayerManager中加入所有的需控制的元素,再統(tǒng)一由LayerManager刷新即可。因此,有必要在其中創(chuàng)立一個LayerManager的對象。</p><p>  其他,如Sprite類的gameover字樣、記分統(tǒng)計畫面也都需在此主邏輯中建立相應(yīng)對象。還需保存的變量有,游戲開始時間、結(jié)束時間(用于統(tǒng)計分數(shù))、敵人的總數(shù)、屏幕上敵人的數(shù)

68、量、下一個敵人需要出現(xiàn)的位置(總共允許在三個不同的位置出現(xiàn),分別位于屏幕的左、中、右方)、游戲是否已成功結(jié)束或是否已死亡。</p><p>  構(gòu)造函數(shù)中,需初始化地圖。地圖實際即為TiledLayer的一個對象,可調(diào)用setCell設(shè)置其具體的圖象格內(nèi)容。地圖由外部文件讀入。外部文件分別命名為level*.png,利用MIDP中唯一獲取外部文件為程序內(nèi)資源的getResourceAsStream()函數(shù)將地圖文

69、件讀入程序。在創(chuàng)建了InputStream類的map對象后,使用read()函數(shù)可將流中的下一個字節(jié)讀出,并返回此字節(jié)代表的整數(shù)。每個整數(shù)代表一種障礙物。用二維循環(huán)將讀出的每個整數(shù),通過setCell()將整幅地圖畫出即可。地圖文件可用十六進制的文本編輯器生成,如本程序使用的Ultraedit。</p><p>  繪出地圖后,可用LayerManager的append()將地圖放置在第一層。這是很有必要的。因為

70、地圖上的障礙物之一——草,在坦克運行中時是必須處于坦克的上層的,否則將失去真實性。為此,地圖必須首先載入。</p><p>  由于敵人將依次出現(xiàn)在屏幕上,同時出現(xiàn)的數(shù)量應(yīng)當受到控制。本程序設(shè)置為6。所以在構(gòu)造函數(shù)中,也應(yīng)當分配6個EnemySprite對象的內(nèi)存空間。構(gòu)造坦克時,將把坦克的png圖片作為參數(shù)傳遞給EnemySprite和UserSprite,BattleCanvas中創(chuàng)建坦克僅調(diào)用createE

71、nemy()和createUser()實現(xiàn)。</p><p>  在構(gòu)造函數(shù)自己調(diào)用了線程的start后,程序?qū)㈤_始循環(huán)運行,直至跳出while的循環(huán)。每次循環(huán)中將檢測是否死亡,屏幕上坦克的數(shù)量,是否該過關(guān)統(tǒng)計分數(shù),檢測用戶輸入的按鍵、重繪整個屏幕及回收垃圾內(nèi)存(Garbage Collection)。</p><p>  當敵人坦克完全死亡時(enemyNum為0),需調(diào)用System類

72、的currentTimeMillis()賦值給結(jié)果的時間。接著調(diào)用setCurrent()顯示統(tǒng)計分數(shù)的畫面,為了進入下一關(guān),統(tǒng)計畫面只是停留四秒,就重新轉(zhuǎn)回BattleCanvas畫面。當然,如果當前已是最后一關(guān),就不會再轉(zhuǎn)回。進入下一關(guān)時,許多變量需要重新被初始化,如地圖的繪制、敵人出現(xiàn)位置的重置、敵人的數(shù)量、玩家坦克的當前位置。</p><p>  如果游戲未結(jié)束,則需判斷屏上坦克是否已小于還剩坦克的總數(shù),

73、如果是這樣,就需要再提供一輛坦克。提供新坦克之前,在屏幕上設(shè)置了一個專用指示的閃光符號,它繼承了Sprite,運行在單獨的線程中。以在兩秒鐘內(nèi)反復(fù)閃現(xiàn)兩次為一個生命周期。當它閃光完畢后,敵人就會從閃光位置出現(xiàn)。這樣可提示玩家具體敵人將在什么時刻出現(xiàn),以便做好準備。閃光位置設(shè)置了三處坐標,由于敵人不能同時出現(xiàn),便設(shè)置了enemyOutDelay的倒數(shù)計時,每次屏幕刷新會減少一次計數(shù),直到為0時就準備一輛坦克。本程序設(shè)置的兩次坦克出現(xiàn)的最小

74、間隔為2秒。</p><p>  如果玩家已經(jīng)死亡,就需要使用LayerManager的insert()將gameover字樣插入到最上層,以免被其他物體覆蓋。</p><p>  在檢測用戶輸入的input()函數(shù)中,當按方向鍵時,玩家坦克就將向不同的方向運行,這調(diào)用了UserSprite的go()函數(shù);當開炮時,就調(diào)用其fire()函數(shù),作出相應(yīng)的行為。</p><

75、;p>  在出現(xiàn)正式畫面前設(shè)置了一個loading state*字樣的單獨屏幕,調(diào)用了loadinglevel()函數(shù),并停滯了1500毫秒,提示用戶做好準備。</p><p>  在繪圖的render()過程中,除了要重繪坦克、地圖、子彈外,還會在右邊空白處繪出一個生命統(tǒng)計欄。并反復(fù)使用Graphics的drawLine()、drawImage()繪畫出一個三維的效果,增強視覺感。該三維欄的上方為白色,下

76、方為黑色,就創(chuàng)造了立體感。在每次刷新繪圖頁面時,應(yīng)使用GameCanvas的flushGraphics()將屏幕后臺的緩沖區(qū)內(nèi)的圖象刷新到前臺來。</p><p>  在允許敵人出現(xiàn)前,需要檢測給即將出現(xiàn)的敵人分配一個數(shù)組序號。在程序中調(diào)用了getNullEnemyIndex()進行測試,當返回為-1時說明沒有序號可以分配,否則,將返回空的序號。</p><p>  4.2 坦克的共同行為

77、</p><p>  在TankSprite中定義了所有坦克(包括敵方坦克和玩家坦克)的共同行為和屬性。EnemeySprite和UserSprite都繼承了該類以簡化結(jié)構(gòu)。在transformDirection[]中定義了坦克四個方向分別應(yīng)將原始圖片旋轉(zhuǎn)的角度,分別為TRANS_NONE,TRANS_ROT90,TRANS_ROT180,TRANS_ROT270,以便在后來的setTransform()中將這些

78、常量代入。構(gòu)造函數(shù)中創(chuàng)建了每個坦克必須擁有的一顆子彈,這些子彈就將只跟隨自己的坦克調(diào)動。</p><p>  為了能提前預(yù)測碰撞,調(diào)用了defineCollisionRectangle(0,-1,11,12)將碰撞矩形向前設(shè)置了一個象素,具體原理見第二章。</p><p>  在setBulletDirection()中,將根據(jù)坦克當前的方向確定子彈出膛后的方向,其中setRefPixel

79、Position()將子彈的參考點設(shè)置在其未變形狀態(tài)的底部,setXY()將其放置到炮口的位置,setTransform()將其圖片方向轉(zhuǎn)到需要使用的位置。</p><p>  canPass()函數(shù)將返回坦克是否能夠向前前進,考慮到的因素有邊界、障礙物。它返回一個boolean值,提供給go()函數(shù),做進一步的判斷。getTileIndex()將檢測傳遞來的象素處是什么類型的障礙物,它將象素除以8(即障礙物的象

80、素寬度),取整,再通過getCell()得到。在得到障礙物屬性后,判斷其序號是否與草相同,或是否為空(序號為0)。因為所有的障礙物中只有草不會阻礙坦克的向前運行。</p><p>  4.3 玩家坦克的功能屬性</p><p>  構(gòu)造函數(shù)中需要將坦克方向設(shè)置為向上,因為剛出現(xiàn)時就是這樣的狀態(tài)。當開炮時,調(diào)用BulletSprite的setLayerManager()將子彈與layerMa

81、nager聯(lián)系起來。需要聯(lián)系的還有自身坦克、地圖。這些都由坦克傳遞給子彈。因為子彈是屬于坦克的,它的屬性需要跟當前的坦克保持一致。接著使用append()將子彈貼到layerManager上顯示出來。最終調(diào)用其start()開始子彈自己的線程。子彈一旦開始運行,就脫離了當前坦克的控制,直到其生命周期終止。</p><p>  無論子彈是屬于敵人還是玩家的,它都必須記錄自己的來源和攻擊的對象。在玩家坦克發(fā)射的子彈中

82、,就必須將攻擊對象設(shè)置為所有的敵人。這樣,它才能有掃描的目標。在setShootCheck()的參數(shù)中,傳給子彈的是敵人的數(shù)組,子彈的對象就被確定了。</p><p>  die()、resetPosition()、getLife()都是很簡短的函數(shù),但卻提供必不可少的功能。他們可被外部調(diào)用,以取得生命值、死亡記數(shù)、重置位置。</p><p>  在go()函數(shù),每個方向在走前都須用if

83、(canPass(UP)&&!collidesEnemy())</p><p>  檢測是否可以行走。canPass()檢測是否有障礙物及是否到邊界。collidesEnenmy檢測是否前方有坦克阻礙行動。當可以行走時,就在當前方向的坐標上增加或減少一個象素。</p><p>  在collidesEnemy()函數(shù)中,將有一個for循環(huán)按照敵人數(shù)組的序號依次檢測6次。有一

84、點非常重要:在檢測前,需要將敵人的檢測矩形區(qū)域設(shè)置為與原來圖片一樣大小。否則,當玩家向上走,而有敵人從左方向右走,并且已經(jīng)碰撞到玩家坦克時,玩家坦克會因為被判定已與敵人發(fā)生碰撞而不允許前進。事實上,敵人坦克此時并沒有阻礙玩家前進。這樣的判斷必須排除在考慮范圍外。當然,在設(shè)置完成后,必須將將檢測區(qū)域設(shè)置回原先的狀態(tài),否則敵人在往后自己的檢測中將發(fā)生錯誤。</p><p>  4.4 敵人坦克的功能屬性</p&

85、gt;<p>  由于和UserSrite同屬于一個TankSprite的繼承類,其功能就與UserSprite有很大的相似之處,但也有其自身的特別屬性。其主要功能流程圖如圖4.2所示。</p><p>  首先,EnemySprite繼承了Runable接口。因為敵人的運行是自動的,需要有設(shè)定的程序讓它可自己控制,而不像UserSprite完全通過每次輸入的鍵盤信號來做出反映。因此,它可以運行在單

86、獨的線程中。</p><p>  setEnemyShootCheck()函數(shù)與UserSprite中的一樣,設(shè)置了攻擊的對象,并且此函數(shù)將繼續(xù)把參數(shù)傳遞給自身的子彈,以便子彈可以識別攻擊對象。此函數(shù)由BattleCanvas調(diào)用。</p><p>  getRandomDirection()以當前系統(tǒng)時間作為種子,調(diào)用了Random類的nextInt()產(chǎn)生一個隨機的整數(shù),此整數(shù)取除4的

87、余數(shù)的絕對值作為隨機的方向。</p><p>  Random random=new Random(System.currentTimeMillis());</p><p>  return Math.abs(random.nextInt())%4+1;</p><p>  此時返回的值的范圍就確定在1~4之間,正好對應(yīng)四個方向。將他們代入需要使用方向的函數(shù)中就可以

88、使用了。</p><p>  getRandomStep()的原理類似:</p><p>  Random random=new Random(System.currentTimeMillis());</p><p>  return (Math.abs(random.nextInt())%4)*50;</p><p>  只是需要乘以每秒會

89、刷新的屏幕的次數(shù)。這樣就相當于允許在某一個方向運行0~3秒鐘的時間。</p><p>  每個敵人還需要擁有一個內(nèi)部的所有敵人的數(shù)組元素。這樣,它們才可以自動檢測自己是否與同伴發(fā)生了碰撞,以便采取躲避、轉(zhuǎn)向等行動。 </p><p>  collidesWithOtherTank()將檢測是否與其他坦克(包括敵人和玩家)。一個循環(huán)將依據(jù)敵人的序號查找5次。if(i==number)brea

90、k ;語句將避免檢測到自己,永遠返回真。</p><p>  collidesInOtherTank()雖與上面的函數(shù)很相似,但仍有一些細微不同,那就是不需要在檢測前設(shè)置被檢測方的矩形區(qū)域。因為不需要進行預(yù)先檢測。此函數(shù)用來檢測是否在剛出現(xiàn)時就與其他坦克發(fā)生碰撞的。如果一出現(xiàn),出口就被堵死,顯然,不能永遠不出現(xiàn),那就應(yīng)采取其他的辦法,否則兩輛坦克將因為都處在碰撞狀態(tài)中而無法移出。</p><p

91、>  在運行的線程中,需在每前進的一步驟中循環(huán)做下列事件:</p><p>  如果坦克已死亡,立刻退出。(由boolean值destroyed決定)。</p><p>  如果不是剛出現(xiàn)(由isBeginner決定),判斷是否與將其他坦克發(fā)生碰撞,就向當前方向前進一步驟,否則,將需要循環(huán)檢測的當前隨機步數(shù)減少為原先的2/3(為了加速離開的時間)。如果剛出現(xiàn),就直接走一步,具體如何行

92、走將在go()函數(shù)中決定,并且此go()與UserSprite中的有所區(qū)別。</p><p>  當隨機發(fā)炮數(shù)減少到0時,就進行發(fā)炮的動作。發(fā)炮后應(yīng)立即重新賦值給隨機發(fā)炮數(shù),以便重新倒數(shù)計算。</p><p>  當所有的步驟走完后,因為需要轉(zhuǎn)動方向,于是,調(diào)用一次隨機取得方向的函數(shù)再次獲值。其他的隨機值也應(yīng)當重置。</p><p>  在go()函數(shù)中首先檢測是否

93、正處于碰撞狀態(tài)中,如果不是,就需要取消Beginner的狀態(tài),因為不需要Beginner這樣的特殊身份,讓別的坦克不檢測了。</p><p>  在運行在某個方向上,當確定為canPass時,應(yīng)再檢測是否為Beginner。如果是,就不應(yīng)該受到其他坦克的影響而直接改變坐標,但若不是,就應(yīng)當遠地不動。</p><p>  4.5 子彈的運行和控制</p><p>  

94、子彈繼承了Runnable,運行在獨立的線程中。它擁有一個很重要的變量,isFromEnemy。它標識了該子彈是屬于玩家的,還是敵人的,這樣可以控制子彈在脫離坦克管束后的運行狀態(tài)中的行為。其主要功能流程圖如圖4.3所示。</p><p>  checkHit(int x,int y)調(diào)用了getTileIndex(x,y)獲取當前子彈擊中的是什么障礙物,如果返回了false就表示沒有擊中任何東西。當擊中了需要作出

95、反映的物體時,就分別采取措施:擊中草時,由于沒有定義相關(guān)函數(shù),就不會有任何反映,會重合在草上正常通過;擊中磚塊時,將產(chǎn)生爆炸,調(diào)用setCell將當前塊置為空,并產(chǎn)生爆炸效果。爆炸效果由tileExplode(x,y)根據(jù)需要爆炸的坐標點生成,其中將一個Sprite圖片在界面上閃現(xiàn)150毫秒。爆炸效果需要將圖片insert進第0層,這樣才不至于被其他景物所覆蓋,爆炸結(jié)束后layerManager會自動相應(yīng)調(diào)整。擊中鋼筋時,將只產(chǎn)生爆炸效

96、果。</p><p>  setShootCheck(EnemySprite enemySprite[]);setUserSprite(UserSprite userSprite);</p><p>  setEnemySprite(EnemySprite enemySprite)都是將相關(guān)的坦克傳入到子彈類里來,以便確認來源或攻擊目標。</p><p>  在線程

97、的循環(huán)中while ( (x < 155) && (x >=5) && (y >=5) && (y < 171))作為循環(huán)的條件可以控制子彈出界的范圍。這幾項參數(shù)在編寫時很容易出錯。它們反映了象素級處理的技巧。如果程序在子彈已經(jīng)到達X軸的155坐標時仍允許子彈繼續(xù)運行,子彈將一次性向右運行2個象素,到達157點。在隨后的checkHit(RIGHT)調(diào)用中,它將檢測

98、它是否在x+3點,即160點擊中了某個障礙物,但是160/8=20。地圖的tiledLayer對象中并不存在序號為20的塊,最大只為19。此時ArrayOutOfBoundException異常就會拋出,程序終止運行。</p><p>  子彈運行中,將用collidesWith(tiledLayer,true)測試是否碰撞上了地圖。如果為真,就繼續(xù)檢測碰撞上了什么樣的物體。這將針對四個不同的方向分別以象素級檢測

99、。如果擊中了某樣物體,那么checkHit自然會處理,子彈的生命周期結(jié)束,以break退出循環(huán)。</p><p>  如果沒有擊中物體,就繼續(xù)檢測是否擊中了某輛坦克。這根據(jù)子彈的來源分為兩種情況。當來自玩家時,將首先檢測所有的敵人發(fā)出的子彈,當發(fā)生子彈間的碰撞時,用戶的子彈將被移除,雖然按照道理敵人的子彈同時也應(yīng)被移除,但敵人子彈是運行在另一線程中的,應(yīng)當由它自己來控制為好,用戶的子彈只需要管理好自己的狀態(tài)就可以

100、了。如果沒有和子彈發(fā)生碰撞,就檢測是否與敵人碰撞,發(fā)生碰撞時,將敵人從layerManager中移除,并置為null,產(chǎn)生爆炸效果,敵人數(shù)量減少一位,敵人屏幕上數(shù)量減少一位。</p><p>  如果是來自敵人的子彈,將同樣檢測與玩家子彈的碰撞,及與玩家坦克的碰撞如有碰撞,玩家生命數(shù)減少一位,位置重置。如果玩家生命已死亡殆盡,就需要在進行以上操作的同時將玩家坦克的位置放置到屏幕外的部分。因為layerManage

101、r的remove函數(shù)并不會真正將層移除。只是用戶看不見而已。如果不放置到屏外,敵人坦克仍會被阻擋,子彈仍會再次擊中用戶坦克。這將會是很荒唐的場面。</p><p>  為了能控制一輛坦克在同一時間只能發(fā)射一發(fā)子彈,在子彈生命運行結(jié)束時候,將調(diào)用userSprite.enableShoot()恢復(fù)坦克繼續(xù)發(fā)炮的能力。因為在發(fā)炮期間,坦克的再次發(fā)炮的功能是被鎖定的。</p><p><b

102、>  結(jié)論</b></p><p>  本程序設(shè)計實現(xiàn)使用J2SE為工具的坦克大戰(zhàn)游戲的開發(fā),采用從外部文件讀取配置文件、自動控制敵人坦克運行的方式進行控制,具有一定的可玩性和復(fù)雜性。經(jīng)過了細心的調(diào)試和排錯解決了絕大部分的問題。</p><p>  但幾乎每一個計算機程序都會有這樣那樣的不足,尤其是未經(jīng)過精心維護的非商業(yè)軟件。即使是作為操作系統(tǒng)的各種版本的Windows也

103、時常會發(fā)生許多類型的錯誤和漏洞。本游戲程序?qū)τ诔跎娲祟I(lǐng)域的畢業(yè)設(shè)計課題來說,尤其在開始初期,感覺邏輯復(fù)雜,難以控制,因此至今還有一些未能解決的bug。</p><p>  目前發(fā)現(xiàn)的bug和未完善的功能列表如下:</p><p>  1、敵人的人工智能變化較少,不夠理想。</p><p>  2、子彈和敵人經(jīng)常會與畫面的刷新的線程不同步,造成畫面閃爍。</p&

104、gt;<p>  3、 由于每次子彈發(fā)射和每次坦克的移動的一個像素都會對所有坦克和所有子彈進行一次循環(huán)檢查,并由于同時開的線程比較多,使得本來運行效率就不高的JVM運行異常緩慢。即使刷屏沒有間隔也不會提高速度。尤其在坦克比較多,炮彈比較多情況下尤為明顯。</p><p>  4、有的時候開始LOGO不能正常顯示。</p><p>  已經(jīng)解決的重要bug:</p>

105、<p>  1、當發(fā)出子彈到達邊界并同時還在草叢中時會拋出數(shù)組邊界異常。</p><p>  2、有時會莫名其妙的死機。 </p><p>  本科期間做過很多課程設(shè)計,大多規(guī)模很小。在各種應(yīng)用軟件和游戲中,我仍覺得對游戲的設(shè)計有極大的熱情。因為其各個模塊間的聯(lián)系十分緊密,代碼重復(fù)執(zhí)行率高,當經(jīng)過無數(shù)次的調(diào)試、修改后,能最終看到成品,有無比自豪的心情。大學期間做過銀行取款機

106、、圖書館管理程序等簡單的數(shù)據(jù)庫管理系統(tǒng)的課程設(shè)計,思想大致相似,變化范圍有限,沒有太多自己可發(fā)揮的余地。大家作品的最終結(jié)果都離不開同一個模式。相比一些數(shù)據(jù)庫軟件,游戲的設(shè)計有很多人情色彩和藝術(shù)思想的發(fā)揮,正式商業(yè)的軟件的人性化界面和各個游戲間迥異的結(jié)構(gòu)每每會讓人有去開發(fā)的沖動。</p><p>  游戲程序最大限度的利用了硬件條件,因此展現(xiàn)出的畫面往往多彩絢麗、效果驚人。成功的游戲融合了三維運算、人工智能、音效處

107、理等計算機多媒體的精華部分。本畢業(yè)設(shè)計建立在Java平臺上,是本人以前未曾接觸過的領(lǐng)域。憑著探索新知識的熱情,我選擇了該設(shè)計題目。</p><p>  學習該平臺背景和功能的時間遠遠超出了我想象的時間。在設(shè)計初期,為了畫出一個簡單的圖形,需要花費一天的時間,為了使圖形產(chǎn)生動態(tài)效果又會花費幾天的努力。很多相關(guān)的技術(shù),如需要使用到的線程、設(shè)計模式、Game包的新功能、高級、低級圖形界面的使用、時鐘的控制、貼圖,每一項

溫馨提示

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

評論

0/150

提交評論