畢業(yè)設計---基于j2me為平臺的坦克大戰(zhàn)游戲開發(fā)_第1頁
已閱讀1頁,還剩51頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  摘 要</b></p><p>  J2ME(Java 2 Micro Edition) 是近年來隨著各種不同設備,尤其是移動通信設備的飛速發(fā)展而誕生的一項新的開發(fā)技術。它定位在消費性電子產品的應用上,對設備的智能化、多樣化,提供了革命性的解決方案,并因其“Write Once, run anywhere”的Java特性而提高開發(fā)的效率。</p>

2、<p>  隨著手機的日益普及、Java功能在移動設備上的實現,Java應用程序產生的手機增值服務逐漸體現出其影響力,對豐富人們的生活內容、提供快捷的資訊起著不可忽視的作用。本論文著眼于J2ME技術的應用,開發(fā)一款可商用的手機游戲程序——坦克大戰(zhàn)。本程序的界面和運作方式繼承于日本任天堂公司在20世紀80年代開發(fā)的Battle City游戲,將老少皆宜的經典作品移植到手機上來,為更流行的硬件平臺提供應用軟件。</p>

3、;<p>  本論文介紹了任天堂紅白機的軟硬件特性、J2ME的相關技術及本程序的結構分析和具體功能的實現。</p><p>  關鍵字:J2ME,手機游戲, Java,坦克大戰(zhàn)</p><p><b>  ABSTRACT</b></p><p>  J2ME is a kind of fast developing techno

4、logy implemented on various devices especially mobile communication equipments. It focuses on application for consumptive electronic products, providing revolutionary solution to the intelligentization and diversificatio

5、n of the equipment. It improve the efficiency of the development process thanks to its “Write Once, run anywhere” nature.</p><p>  When cell phone is getting ever more popular nowadays, with the implementati

6、on of Java technology on mobile equipment, increment 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 imple

7、mentation of J2ME technology and has developed 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><

8、p>  This dissertation introduces the characteristic of Nintendo FC machine and its software, J2ME and its relative technology as well as this program’s structure and analysis of implementation in details. </p>

9、<p>  Key words: J2ME, mobile game, Java, tank, Battle City.</p><p><b>  引  言</b></p><p>  Java語言是美國Sun Microsystem的James Gosling、Pratrick Naughton及Mike Sheridan等人于1991年精心設計出來的計

10、算機編程語言,其構想在于實現使用同一種編程語言所寫出來的程序可以在不同的平臺上運作。這種架構對于消費性電子產品而言是具有革命性的,因為在消費性電子產品中的處理器及操作系統(tǒng)各不相同,要在這些平臺上開發(fā)程序必須要了解各個平臺的特性,以及其提供的API使用方式,分別開發(fā)不同的版本才能執(zhí)行,影響應用程序的普及性。</p><p>  近幾年,由于微處理器性能的大幅提升,加上無線通訊技術的突破,手持式移動設備開始受到大眾的

11、青睞。短短幾年內,手機已經升級了幾代產品,普及率逐年攀升,生產效率不斷上升,產品價格比個人電腦的摩爾定律有更驚人的下調,以至手機是大多是城市居民不可缺少的一件隨身設備。繼短信、彩信等服務之后,中國移動提供基于Java的百寶箱業(yè)務,應用產品遍及商務應用、信息獲取、英漢互譯、游戲娛樂等多媒體領域。根據官方公布的統(tǒng)計數據,我國移動電話用戶已突破3億。依托這樣的市場,一旦無線Java應用大規(guī)模開展起來,將會創(chuàng)造出比短信業(yè)務更為驚人的利潤。Jav

12、a語言原先的開發(fā)目的與市場的需求不謀而合,并且也已經成為手機應用程序開發(fā)的標準,國際大公司如Nokia、Motorola及Siemens等所設計的手機內都加入Java程序的支持,可見在不久的將來,Java將會成為移動設備上最熱門的語言。</p><p>  手機中將Java語言引入,作為一種通用的開發(fā)標準,并將向市場推廣普及僅僅短短幾年,J2ME仍是一種新型的技術,中文資料除臺灣出版過相關書籍外,國內相關介紹資源

13、很有限,國內J2ME開發(fā)商也屈指可數,名聲較響的Digital-Red公司也僅成立于1999年。本文可算是對新技術的一些嘗試,代表對無線平臺應用程序推廣的一些努力。</p><p>  本論文中第一章介紹游戲機軟硬件歷史、Java語言、J2ME及其相關技術;</p><p>  第二章介紹了開發(fā)工具和相關軟硬件環(huán)境的背景;</p><p>  第三章分析該作品設計的

14、思想和流程,介紹總體結構;</p><p>  第四章并詳細闡述有關重點實現細節(jié);</p><p>  第五章提及了開發(fā)過程、心得體會、經驗和感想。</p><p><b>  目 錄</b></p><p>  摘 要- I -</p><p>  Abstract - II -

15、</p><p>  引  言- 3 -</p><p>  第一章  緒 論- 1 -</p><p>  1.1 手機軟件現狀- 1 -</p><p>  1.2 游戲業(yè)務及J2ME概況- 1 -</p><p>  1.3 任天堂(Nintendo)的8位FC機器和Battle City背景介紹

16、- 3 -</p><p>  1.4 本章小結- 3 -</p><p>  第二章 開發(fā)環(huán)境及相關技術的介紹- 4 -</p><p>  2.1 開發(fā)環(huán)境- 4 -</p><p>  2.2 Java語言的特點- 4 -</p><p>  2.3 關于JBuilder9- 4 -</p&g

17、t;<p>  2.4 關于Wireless Tool Kit- 5 -</p><p>  2.5 Java Appication Manager- 5 -</p><p>  2.6 本章小結- 5 -</p><p>  第三章 程序結構、思想和相關技術- 6 -</p><p>  3.1 本程序需解決的

18、有關技術問題- 6 -</p><p>  3.2 程序流程- 7 -</p><p>  3.3 繪圖與MIDP2.0新增的GameCanvas包- 9 -</p><p>  3.3.1 提供低級繪制的Canvas類- 9 -</p><p>  3.3.2 Graphics類- 9 -</p><p&g

19、t;  3.3.3 PNG格式- 9 -</p><p>  3.3.4 Game包中的新功能- 10 -</p><p>  3.3.5 有關繪圖的一些技術- 11 -</p><p>  3.4 坦克的控制和敵方的智能運行- 11 -</p><p>  3.5 子彈的運行和控制- 12 -</p><

20、;p>  3.6 RMS數據庫系統(tǒng)- 13 -</p><p>  3.7 內存使用的最佳化- 14 -</p><p>  3.8 混淆器(Obfuscator)的使用- 15 -</p><p>  3.9 模擬器的相關調試- 15 -</p><p>  3.10 本章小結- 16 -</p>&l

21、t;p>  第四章 程序分析和具體實現- 17 -</p><p>  4.1 游戲進入前的選擇- 17 -</p><p>  4.2 主游戲邏輯及其涉及到的若干類- 18 -</p><p>  4.3 坦克的共同行為- 20 -</p><p>  4.4 玩家坦克的功能屬性- 21 -</p>

22、<p>  4.5 敵人坦克的功能屬性- 21 -</p><p>  4.6 子彈的運行和控制- 23 -</p><p>  4.7 記分系統(tǒng)- 24 -</p><p>  4.8 本章小結- 26 -</p><p>  第五章 總 結- 27 -</p><p>  5.

23、1 本程序的總結和展望- 27 -</p><p>  5.2 經驗和感想- 27 -</p><p>  致 謝- 29 -</p><p>  參考文獻- 30 -</p><p>  附錄 源程序代碼- 31 -</p><p><b>  第一章  緒 論</b>&

24、lt;/p><p>  1.1 手機軟件現狀</p><p>  在信息社會中,手機及其他無線設備越來越多的走進普通百姓的工作和生活,隨著信息網絡化的不斷進展,手機及其他無線設備上網絡勢在必行。但是傳統(tǒng)手機存在以下弊端:</p><p>  1. 傳統(tǒng)手機出廠時均由硬件廠商固化程序,程序不能增加、刪除,有了錯誤也不能更新、修改,若要增加新功能必須另換一部手機。<

25、;/p><p>  2. 傳統(tǒng)手機訪問互聯網是通過WAP(Wireless Application Protocal),所有網絡資源必須接通網絡才能在線訪問,非常耗時、費用亦很高。</p><p>  而Java技術在無線應用方面的優(yōu)勢非常明顯:</p><p>  1. 應用程序可按需下載,而不是購買由硬件商提供的套件,可升級空間大。</p><

26、;p>  2. Java技術提供了一個類庫,它使的應用開發(fā)商可以創(chuàng)建更為直覺、豐富的用戶界面(GUI);</p><p>  3. Java技術使網絡帶寬的應用更為有效,因為應用程序可以下載到器件上,并在本地運行,僅僅是在連接到服務器時才會占用網絡帶寬。</p><p>  基于以上分析,Java手機將是未來手機的發(fā)展方向,是業(yè)界的熱點。</p><p>

27、  1.2 游戲業(yè)務及J2ME概況</p><p>  雖然 Java 已經被用到許多企業(yè)級軟體上,可是其實骨子里面還是非常適合用在嵌入式系統(tǒng)之中。Java平臺演進到Java2后,Java平臺分別針對不同領域的需求被分成四個版本,亦即J2EE、J2SE、J2ME以及JavaCard(其結構示意圖見圖1-1)。其中J2ME定位在消費性電子產品的應用上。這個版本針對資源有限的電子消費產品的需求精簡核心類庫,并提供了模

28、塊化的架構讓不同類型產品能夠隨時增加支持的能力。這個版本的應用層面相當廣泛,會是未來Java平臺發(fā)展的重點項目。J2ME 在設計其規(guī)格的時候,遵循著“對各種不同的裝置而造出一個單一的開發(fā)系統(tǒng)是沒有意義的事”這個基本原則。于是 J2ME 先將所有的嵌入式裝置大體上區(qū)分為兩種:一種是運算功能有限、電力供應也有限的嵌入式裝置(比方說PDA 、手機);另外一種則是運算能力相對較佳、在電力供應上相對比較充足的嵌入式裝置 (比方說冷氣機、電冰箱、電

29、視機上盒 (set-top box))。因為這兩種型態(tài)的嵌入式裝置,所以Java 引入了一個叫做Configuration 的概念,把上述運算功能有限、電力有限的嵌入式裝置定義在Connected L</p><p>  縱觀IT產業(yè)的歷史,就像軍事的發(fā)展時常推動計算機的演化一樣,計算機游戲已經成為技術創(chuàng)新背后的動力之一。計算機游戲者渴望更加強大的硬件計算能力;渴望不受不同的軟件的限制——無論是將圖形強制在人工智

30、能(AI)上 還是網絡安全性。游戲開發(fā)者和玩家常常是前沿計算機技術的最早的采用者。由于他們的創(chuàng)新天性,游戲不再是由大型采購公司控制的技術產品——游戲領域總是有充足的空間給那些在這方面有天分的單個創(chuàng)新者。</p><p>  手機游戲的盈利主要是由于它們的涉及面很廣。手機已經與現代生活方式緊緊地結合在一起。他們是最普遍攜帶的個人用品中僅次于鑰匙和錢包的東西。傳統(tǒng)的臺式機游戲將目標鎖定在低級趣味的人和青少年身上,而手

31、機游戲則每個人都可以訪問的到——隨時,隨地。盡管每個手機游戲都不貴,但是巨大的使用量(如:每人每星期一個新游戲)將使得這個市場商機無限。但是,對于開發(fā)者來說,將控制臺游戲遷移到手機游戲工程很大。因為他們所面向的對象、生活方式和分布式模型都有著極大的區(qū)別。</p><p>  一個成功的手機游戲大多具有以下特征: </p><p>  ·易于學習: 既然手機游戲面向的是普通消費者而

32、不是計算機專家,那么他們不可能深入的學習游戲技巧。消費者不會花幾個小時去研究一個3元的手動操作的游戲。保持游戲的簡單是最基本的要求。 </p><p>  ·可中斷性: 多任務處理是手機生活方式的基本特征。手機用戶常常在任務(如等一個電子郵件或者等車)之間有一小段時間。而游戲、日歷管理、通訊和工作數據訪問使用的是同一個設備。所以一個好的手機游戲應該提供短時間的娛樂功能,并且允許用戶在游戲和工作模式之間順

33、利切換。 </p><p>  ·基于訂閱:手機游戲的盈利成功取決于他們巨大的使用量。一開始開發(fā)和設計每個游戲都是昂貴的。如果一個手機游戲開發(fā)者要贏利的話,重要的是:同一個游戲引擎,多個標題,基本的故事情節(jié)類似?;谟嗛喌挠螒蚴遣粩喈a生收入的最好方法。 </p><p>  ·豐富的社會交互: 不管一個游戲設計得多好,只要玩家找到了它的根本模式或者玩完了所有的游戲路徑很

34、快就會厭煩這個游戲。對于一個基于訂閱的游戲,重要的是與別的玩家合作以增強所玩游戲的智力和隨機性。在今天紛繁復雜的多玩家游戲中具有豐富社會交互的游戲證明是成功的。 </p><p>  ·利用手機技術的優(yōu)點: 巨額的手機技術研發(fā)費用都花在提高設備和網絡的可用性和可靠性上面。因此,手機設備硬件和網絡協(xié)議與桌面/控制臺世界(如全球定位系統(tǒng)(GPS)擴展、條形碼掃描儀、和短消息服務(SMS)/多媒體信息服務(M

35、MS)通訊)有著非常大的差別。好的手機游戲應該利用那些更新的設備特征和網絡基礎設備的優(yōu)點。 </p><p>  ·無違法內容:既然所有年齡/性別的人群都玩手機游戲并且常常在公共/工作場合,就應該避免明顯的暴力或者色情內容。</p><p>  1.3 任天堂(Nintendo)的8位FC機器和Battle City背景介紹</p><p>  FC(F

36、amily Computer)主機在歐美又稱Nintendo Entertainment System(可譯作任天堂娛樂平臺即NES)。FC主機在游戲業(yè)界造成的巨大沖擊眾所周知,這款主機在當時事實上幾乎占領了世界各地多個國家的整個游戲市場,并使得逐漸沒落的北美游戲市場再度復蘇。這款主機的性能比當時的多數主機都要強大,而價格上卻便宜得多。主機所采用得處理器為CMOS 6502,一款已經淘汰的70年代中期產品。由于其價格便宜且極易使用,經過

37、任天堂的改造后又煥發(fā)了全新活力。6502 芯片cpu 主頻為8 bit,12 MHz,內存8k,畫面 52色,同屏最多顯示其中的13色,聲音2個矩波,1個三角波,1個雜音,1個PCM音頻(見圖1-2)。</p><p>  Battle City是其發(fā)售卡帶中的一款力作,設置了35個關卡,可以雙人操縱,畫面設置了若干種類的建筑物和阻擋物,以消滅所有敵人為通關條件,并有接寶物等增加游戲效果的設置,畫面精美,音效杰出

38、,在PC機的80386處理器仍未面世的當時,能在硬件上運行這樣的2D程序不得不令人驚嘆,難怪常有人說游戲程序是最大限度發(fā)揮硬件水平的載體。其游戲界面如圖1-3所示。</p><p>  1.4 本章小結:</p><p>  引言和第一章中介紹了手機在無線應用方向的當今概況,并介紹了游戲業(yè)務在當前社會的發(fā)展?jié)摿?。分析了J2ME在手機軟件開發(fā)中起的重要作用,描述了本論文的相關背景。<

39、/p><p>  第二章 開發(fā)環(huán)境及相關技術的介紹</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 Edit

40、ion (build 1.4.1_02-b06) Sun Micro. J2ME Wireless Tool Kit 2.1</p><p>  IDE: Borland Jbuilder 9</p><p>  2.2 Java語言的特點</p><p><b>  1. 平臺無關性</b></p&g

41、t;<p>  Java引進虛擬機原理,并運行于虛擬機,實現不同平臺之間的Java接口。使用Java編寫的程序能在世界范圍內共享。Java的數據類型與機器無關。</p><p><b>  2. 安全性</b></p><p>  Java的編程類似C++,但舍棄了C++的指針對存儲器地址的直接操作,程序運行時,內存由操作系統(tǒng)分配,這樣可以避免病毒通過指

42、針入侵系統(tǒng)。它提供了安全管理器,防止程序的非法訪問。</p><p><b>  3. 面向對象</b></p><p>  Java吸收了C++面向對象的概念,將數據封裝于類中,實現了程序的簡潔性和便于維護性,使程序代碼可以只需一次編譯就可反復利用。</p><p><b>  4. 分布式</b></p>

43、<p>  Java建立在TCP/IP網絡平臺上,提供了用HTTP和FTP協(xié)議傳送和接收信息的庫函數,使用其相關技術可以十分方便的構建分布式應用系統(tǒng)。</p><p><b>  5. 健壯性</b></p><p>  Java致力與檢查程序在編譯和運行時的錯誤,并自動回收內存,減少了內存出錯的可能性。Java取消了C語言的結構、指針、#define語句

44、、多重繼承、goto語句、操作符、重載等不易被掌握的特性,提供垃圾收集器自動回收不用的內存空間。</p><p>  2.3 關于JBuilder9</p><p>  JBuilder是目前最好的Java開發(fā)工具之一,在協(xié)同管理、對J2EE和XML的支持等方面均走在其他產品的前面。JBuilder是遵循Sun公司J2EE標準的可視化集成開發(fā)工具。Jbuilder是一種處于市場領先地位的

45、跨平臺環(huán)境,主要用于構建具有行業(yè)實力的企業(yè)Java應用程序。JBuilder集成了Borland公司開發(fā)工具系列的優(yōu)秀特性,使得使用過C++Builder,Delphi的程序員很容易的過度到JBuilder的開發(fā)環(huán)境當中。由于Java技術的發(fā)展迅速,經常有新的組件推出或新的錯誤修正,致使JBuilder的版本升級很快。當兩年前還是JBuilder6時,現今已推出了9、10的版本。</p><p>  2.4 關

46、于Wireless Tool Kit</p><p>  WTK(Wireless Tool Kit)是Sun公司針對J2ME推出的用于手機和Palm等移動設備的開發(fā)包,是除手機廠商的專用開發(fā)包外唯一的手機模擬器開發(fā)包。它通用性高,開發(fā)出的應用程序可保證能運行在大部分設備上,而不像專用廠商具有一定的不兼容性。雖然它沒有強大的功能和完善的調試手段,但它提供運行模擬器的最基本組件,是其他IDE需集成采用的必備元素。&

47、lt;/p><p>  2.5 Java Appication Manager</p><p>  手機中負責調配程序運行資源的管理后臺是Java Application Manager。它所使用的傳輸媒體可以是紅外線、網絡、以及其他可用來傳輸的媒體。Java Application Manager 會從網絡上下載代表該Application Suite 的JAR 檔,接著在手機上安裝此MI

48、Dlet Suite,然后在手機開始執(zhí)行該應用程序。整個詳細的運作流程如圖2-1所示。</p><p>  2.6 本章小結:</p><p>  第二章介紹了Java語言的特點、本程序的開發(fā)環(huán)境及其相關工具的原理和使用。</p><p>  第三章 程序結構、思想和相關技術</p><p>  3.1 本程序需解決的有關技術問題<

49、/p><p>  1. 游戲程序是一項精度要求很高的程序系統(tǒng),因為其代碼利用率很高。一個實時運行的最終作品,每秒都會運行成千上萬行程序,繪圖事件、鍵盤事件都會以極高的頻率在后臺等待響應,若有絲毫的差別都將很容易導致程序在運行不久后可能出現嚴重錯誤,甚至死循環(huán)。因此,其邏輯設計應當相當嚴謹,需將所有可能發(fā)生的事件及意外情況考慮在設計中。</p><p>  2. 游戲中為了美觀,適用性強,可

50、能需要采用外部文件引入的圖片貼圖,有關貼圖,在MIDP2.0中提供了用于增強游戲功能的game包,使得解決靜態(tài)或動態(tài)、畫面背景、屏幕刷新的雙緩沖等都有較好的解決方案。</p><p>  3. 己方坦克的運行可以通過鍵盤響應事件控制,但敵方則因為是自動運行,就需要有一定其一定的智能性;同時,出現在屏幕上的敵方可能會有較多的數量,這需要為每個敵方開辟一個線程以便能讓其獨立運行。Java的多線程能力為實現這樣的游戲

51、提供了可能。敵人坦克的運行算法也需要進行適當的設置,以免游戲過于簡單,單調。</p><p>  4. 對于雙方坦克發(fā)出的子彈的控制也需要對其跟蹤控制,子彈也需要處在獨立的線程中。敵方子彈僅需要掃描用戶坦克,而用戶坦克需要在每一步掃描所有的敵方坦克。這需要對所有的對象有較好的控制。另外,子彈在運行過程中也需要實時掃描是否碰撞到了相關障礙物或屏幕邊界。如此過多的線程同時在本來效率就不高的KVM虛擬機上運行,也許會

52、導致程序的緩慢。</p><p>  5. 雙方的坦克在前進時也需要考慮到是否碰撞到相關物體或對方坦克,以免重疊運行,造成許多物理上不可能的情況,缺乏真實感。每一次刷新頁面、每前進一步都需要將所有的周圍環(huán)境都進行掃描。</p><p>  6. 游戲的結束、開始、動態(tài)信息畫面作為構成一個完美程序都是必不可少的重要部分。良好的用戶界面更是吸引用戶的硬指標,相關的美術構圖也需要有一定的考慮

53、。</p><p>  7. 游戲的地圖不可能通過繪圖來解決。否則,不僅難于控制和處理過多的元素,也會因過多的大型圖片而不能限制程序的大小,失去手機上程序的原則和Java的優(yōu)勢。同時,地圖關卡不宜保存在手機有限的內存中,而最好采取外部文件的讀入讀出方法。</p><p>  8. 用戶運行游戲時需要有分數記錄的可能。如何采用合理的記分標準,需要進行適當的設計。記錄分數的存儲方式也需要有

54、較好的解決方案。手機中由于處理器和內存空間、存儲空間都十分有限,其數據庫系統(tǒng)與普通PC大相徑庭。其數據庫結構較為簡單,被稱之為RMS系統(tǒng)。</p><p>  9. Java是基于虛擬機的半解釋型編譯系統(tǒng),其執(zhí)行效率較C++等完全編譯后的程序會低很多,程序如果不進行精簡和優(yōu)化,將可能導致運行的不流暢。除開發(fā)過程中對結構上的控制、變量的使用、算法的優(yōu)化等優(yōu)化外,還可以使用混淆器(Obfuscator)進行程序打包

55、后的優(yōu)化。</p><p>  以上相關技術細節(jié)和整體流程將分別在以下小節(jié)闡述。</p><p><b>  3.2 程序流程</b></p><p>  MIDlet suite是MIDP應用程序的最小單位,JAM負責將手機內的MIDlet suite以圖形化的方式呈現,讓用戶能夠選取欲執(zhí)行的MIDlet suite,一旦選取了某個MIDl

56、et suite,操作系統(tǒng)就會激活KVM執(zhí)行里面的MIDlet。MIDlet及相關的支持類組成了MIDP應用程序的實際內容。</p><p>  每個MIDlet都必須繼承javax.microedition.midlet.MIDlet這個抽象類。在MIDP規(guī)格中定義了MIDlet的生命周期,以及可以存在的三種狀態(tài),包括Paused、Active以及Destroyed,每一個MIDlet在任何時刻只可能處于其中的

57、一個狀態(tài)。這三種狀態(tài)的轉換關系如圖所示:</p><p>  本程序采用面向對象的設計模式,對游戲中的所有物體賦予對象的概念和屬性。運行程序后允許用戶選擇執(zhí)行選項菜單,在開始游戲后將先從外部文件載入地圖文件,對背景的所有物體進行繪圖。在主程序運行的線程中,畫面刷新將以一定的頻率采用雙緩沖技術對屏幕重繪,實時反映整個游戲的進行狀態(tài)。用戶控制的坦克運行在主線程中,隨屏幕刷新的頻率而步進。敵方坦克將在游戲開始時逐漸新增

58、線程,每增加一個敵方對象就新增加一條線程,一旦線程數滿到最大值(本程序暫設置為6),就不允許敵人再繼續(xù)出現。用戶坦克自誕生之時起將擁有一發(fā)子彈,子彈雖然開在單獨的線程中,但運行結束后(比如撞到相關物體或敵方坦克時)并不結束子彈對象,只是將其線程終止。用戶再次發(fā)射子彈時只是將終止的線程再次激活。在屏幕重繪的主程序中,將在每次的循環(huán)中判斷若干事件。如:用戶坦克的生命是否已完全用盡,敵方坦克數是否已經為零,屏幕上的坦克數量是否少于仍剩下的坦克

59、數量等。以便程序進入相關的分支執(zhí)行相關的反應代碼,結束游戲或統(tǒng)計分數等。主程序流程如圖3-2所示:</p><p>  程序為需要完成獨立功能的需顯示的模塊設置了單獨的類。TankMain類是繼承自MIDlet的控制主程序啟動的首先被載入系統(tǒng)的部分。載入程序后首先啟動的是程序介紹的信息畫面。閃過后載入StartChoice類,為用戶提供可選擇的選項。在選擇開始后,將運行BattleCanvas類中的總流程控制。它

60、決定了游戲何時該結束,何時分配敵人數量,GameOver字樣的閃現規(guī)則,地圖的繪制及整個游戲的調度。</p><p>  圖3-3是程序中類之間的UML分析圖。敵方坦克與用戶坦克的相關功能和具體行為分別定義在EnemySprite和UserSprite類中,它們都繼承自TankSprite公共類,以簡化程序的代碼、理清結構。</p><p>  在每關的結束或死亡后都將載入ScoreScr

61、een類,統(tǒng)計當前的分數。如果已死亡或完成所有的關數,程序將用戶所得的分數記載到RMS數據庫中,進行永久性保存。載入過程中將對所得分數與以往歷史比較,放置到合適的位置中,形成排序。</p><p>  3.3 繪圖與MIDP2.0新增的GameCanvas包</p><p>  3.3.1 提供低級繪制的Canvas類</p><p>  為了能有程序開發(fā)人員控制

62、接口的外觀和行為,需要使用大量的初級用戶接口類,尤其在游戲程序中,幾乎完全依賴的就是Canvas抽象類進行繪圖。從程序開發(fā)的觀點看,Canvas類可與高級Screen類交互,程序可在需要時在Canvas中摻入高級類的組件。Canvas提供了鍵盤事件、指點桿事件(如果設備支持),并定義了允許將鍵盤按鍵映射為游戲控制鍵的函數。鍵盤事件由鍵代碼指定,但這樣控制游戲會導致缺乏通用性,并不是每個設備的鍵盤布局都適合游戲的操作。應當將鍵代碼轉換為游

63、戲鍵的代碼,以便硬件開發(fā)商能定義他們自己的游戲鍵布局。本程序中,操縱用戶坦克運行的按鍵都定義為游戲控制鍵,這樣便能適應所有的機器。</p><p>  3.3.2 Graphics類</p><p>  Graphics類提供了簡單的2D繪圖功能。它具有24位深度色彩的繪制能力,以三原色分別各占一個字節(jié)表示其顏色。程序只能在paint()函數中使用Graphics繪制,GameCanvas

64、可調用getGraphics()函數直接繪制在緩沖區(qū)上,可以在任何時間請求傳輸到前臺。其對象會被傳給Canvas的paint()函數,以便最終顯示。</p><p>  3.3.3 PNG格式</p><p>  PNG(Portable Network Graphics)格式是MIDlet唯一支持的圖象格式,PNG具體格式由PNG Specification,Version 1.0定義的

65、。PNG格式提供透明背景的圖象,這對繪制游戲畫面和被操縱主角極有幫助。坦克之間或與障礙物碰撞時就不會因為背景有特定的顏色,顯示出的效果像貼上的圖片而缺乏真實感,物體之間輕微重疊時最上層圖片也不會覆蓋超過其有效象素外的部分。</p><p>  PNG格式圖片中包含許多定義其圖片特性的冗余部分(Chunks)。這些代碼包含在每一個單獨的png格式圖象中,然而如果將多個png圖象合并在一張幅面稍大一些的整圖中,多個c

66、hunks就可以得到精簡,圖片的大小可以得到控制。使用Image類中的createImage函數可從整圖中分割出所需要的元素。在Game包中的TiledLayer和Sprite類都整合了這樣的功能。本程序中的地圖元素都集成在一張tile.png圖片中,實現了方便的管理和程序體積的精簡。</p><p>  3.3.4 Game包中的新功能</p><p>  MIDP自2.0以后新增了G

67、ame包,為游戲的開發(fā)帶來了極大的便利。地圖繪制、主角的動態(tài)顯示、按鍵的檢測、圖層的控制等游戲專屬的特性都得到了在移動設備上最大的發(fā)揮。</p><p>  LayerManager(以下簡稱LM)提供控制整體畫面層的控制。它包括了一系列自動獲取了代號和位置的層,簡化了各層加入游戲畫面的過程,提供了自動排序和繪制的能力。</p><p>  LM存儲了一個層的列表,新的層可以用append

68、函數附加、刪除和插入。層的序號相當于坐標的Z軸,0層表示最接近用戶視覺,層數越高,離用戶越遠。層號總是連續(xù)的,即使有中間的層被移除,其他層的序號會作相應的調整以保持整體的完整性。LM中的View Window控制著與LM相對坐標的可視區(qū)域。改變View Window的位置可以制造出滾動屏幕的效果。</p><p>  本程序中所有的地圖、坦克都采用LM控制,敵方坦克的生成由附加一個EnemySprite對象得到。

69、唯有界面右側的計分欄由Graphics類繪制。</p><p>  Sprite類是繼承自Layer的用于存儲多楨的基本可視元素。不同的frame可交相顯示,構成動態(tài)的效果。圖片可翻轉、顛倒、由一個主角圖片就可以方便的得到所有方向的顯示狀態(tài),相比原先只能使用Canvas繪圖,需要將所有方向的主角圖象都繪制在png圖象中簡化了許多。Sprite也可以從整合的圖象中讀圖,讀圖時將把大圖分解為若干等寬等高的小圖。每個小

70、圖按照其排列順序有相應的序號,在程序中調用其序號,就可以繪制出相應的圖片。本程序中的雙方坦克、子彈都由Sprite繼承得到。在有些情況下,控制主角的翻轉,尤其是多幅圖片配合顯示的過程,如果將多圖的共享定位點設置在通常的左上角,將很不容易控制,因為許多翻轉都是以其他點為參考電的(比如,中心點)。由此,引入參考點的概念。參考點由defineReferencePixel函數確定未翻轉圖片狀態(tài)時的坐標。默認是(0,0)點,如果需要,可將參考點設

71、置在畫面邊界之外。本程序中的坦克的參考點定義在圖片正中,以便簡便的實現轉向等功能。子彈的參考點設置在子彈底部的中心,因為子彈一出炮筒的時候緊挨著坦克的象素就是其底部中心。</p><p>  TiledLayer是有一組圖象格元素(grid of cells)組成的整塊虛擬圖象。該類使不需要高分辨率的圖象就能創(chuàng)建大幅圖面成為可能。這項技術通常應用在2D游戲平臺的滾動背景的繪圖。一塊整圖可被分割成等大小的圖象格,每

72、塊格有其對應的序號,按照行列遞增。多塊格可由大塊同時替換組合而模擬動態(tài)的背景,這不需要逐塊替換所有的靜態(tài)圖象格而顯得非常方便。</p><p>  本程序中的地圖即為游戲背景。每塊障礙物都有其響應的代號,其中,用戶需保護的總部因為體積稍大,使用了四塊圖象格顯示。地圖背景分為20*22個圖象格,每個格使用一個字節(jié)表示其中的障礙物,圖象文件存儲在外部文件中,以16進制的整數串表示,因此每個地圖的大小為固定的440字節(jié)

73、。如果整塊地圖均由繪圖產生,將導致體積迅速增加,且對坦克與障礙物的碰撞也難以檢測。J2ME中并沒有J2SE中的File類,獲取外部文件的手段很有限,僅僅在Class類中提供了一個getResourceAsStream函數,將外部文件獲取為輸入流,再由InputStream的繼承類讀出。</p><p>  3.3.5 有關繪圖的一些技術</p><p>  在沒有MIDP2.0前,進行游

74、戲繪圖一般需要手動編程使用雙緩沖。需要在paint()方法內所想要畫的圖形畫在一張預先準備好的背景,等所有繪圖操作都完成后再將背景的數據拷貝到實際的屏幕上。Image類提供了一個建立背景的靜態(tài)方法createImage(int width, int height),再利用getGraphics()方法取得屬于這個背景的Graphics對象,所進行的繪圖操作都會作用在背景上,等到全部的繪圖操作完成后,再調用drawImage()方法將背景

75、的數據復制到實際顯示的屏幕上。</p><p>  這樣的技術在繪制動畫時特別有用。繪制動畫時經常需要不斷地更新畫面,而更新畫面的操作就是先將屏幕以fillRect()的方式清除,再將下一張圖片畫在屏幕上,然而反復的清除及重繪會造成屏幕的閃爍現象(flicker),因此使用雙重緩沖的好處就是在背景進行這個清除及重繪的操作,再將完成的繪圖拷貝到屏幕上,由于用戶看不到清除的操作,因此就不會出現閃爍的現象了。不過在某些

76、MIDP的實現上已經加上了雙重緩沖的支持,因此在處理前應先利用Canvas類的isDoubleBuffer()方法來判斷。</p><p>  3.4 坦克的控制和敵方的智能運行</p><p>  GameCanvas中提供了與以往MIDP1.0不同的鍵盤采樣功能。Canvas類中采取響應鍵盤事件的方法,每次執(zhí)行周期時會讀取keyPressed函數中需執(zhí)行的代碼。這樣的機制并不適合某

77、些游戲場合。在某些不支持keyRepeat功能的設備上,反復執(zhí)行的按鍵,比如發(fā)射子彈,將不能因為長時間按壓而自動重復,這樣就需要用戶高頻率的手動擊鍵,這在操縱空間非常有限的移動設備上是非常困難的。同時,事件的執(zhí)行周期也并不一定適合游戲的場合,也許需要更高頻率執(zhí)行的按鍵卻只能在指定的周期內規(guī)律的響應。對此,針對游戲的開發(fā),Game包提供的鍵盤狀態(tài)功能將顯得十分有效。</p><p>  GameCanvas提供ge

78、tKeyStates函數可獲取當前鍵盤上的信息。將以位的形式返回鍵盤上所有鍵的按與釋放的狀態(tài),當bit為1時,鍵就是被按下的狀態(tài),為0時則為釋放狀態(tài)。只需要此一個函數的返回值就可以返回所有鍵的狀態(tài)。這保證了快速的按鍵和釋放也會被循環(huán)所捕捉。同時,這樣的機制也可檢測到幾個鍵同時按下的狀態(tài),從而提供斜向運行等相應功能。</p><p>  敵方按照規(guī)則不能和用戶坦克重合,則它每行走一步就需要把用戶坦克掃描一次,判斷其

79、是否碰撞到了用戶的坦克。Sprite類中提供了collidesWith函數,用于判斷是否與某個TiledLayer、Sprite、Image的對象有圖象上的重合(即游戲中的碰撞)。然而不能僅僅將用戶坦克作為其Sprite參數傳遞給敵人的類進行判斷。因為如果發(fā)生碰撞,collidesWith成立,則兩輛坦克已經發(fā)生了圖象重合,違反了規(guī)則,甚至若再進行collidesWith判斷的話,其結果將永為真。為了提前預知碰撞,可以將所有坦克的碰撞范

80、圍設定為一個比坦克圖片稍大一些的矩形,此矩形僅在坦克前方比坦克圖形多出一個象素。在多出的11個象素中,按照每個象素依次檢查此象素是否于外界發(fā)生碰撞,如果不是按照象素檢查,則當坦克與障礙物錯位并同時與兩種物體接觸時將有可能忽略檢測其中的一樣物體。這樣,就可以提前一步判斷。如果發(fā)生碰撞,則坦克應當選擇掉轉方向,此時,兩輛碰撞的坦克又因為其矩形區(qū)域不重合而不符合collidesWith的條件,就可以繼續(xù)正常運行了。</p>&l

81、t;p>  敵方坦克由于需要具有一定的智能性,以便對玩家攻擊,使之具有一定的可玩性。敵人可以自動行走,但是應當在以下適當的情況下轉向:首先是是否超出界面的邊界,其次是是否與地圖障礙物發(fā)生了碰撞,再次是是否與用戶坦克發(fā)生了碰撞。需要指出的是,當發(fā)生阻礙不能在不變方向的情況下繼續(xù)行走時,并不一定立即需要采取轉向的對策。如果一定發(fā)生轉向,試想,當敵方碰到玩家時,如果它立即轉向,將不會對玩家發(fā)射射向他的子彈,就不構成任何威脅,當然,也不能

82、永遠不轉向。本程序設置為:當碰撞到障礙物或邊界時立即轉向,但碰到玩家坦克時需要有一個等待的時間,這個時間由碰撞前隨機取得的在某方向上的持續(xù)行走步數決定,當發(fā)生坦克間碰撞時,此隨機數將在下一次循環(huán)前減少為原來的2/3,這樣就實現了加快轉向的時間,避免死鎖在一個方向上靜止的停留過長的時間。另外,坦克的發(fā)炮間隔和轉后的具體方向都由隨機數決定。坦克之間由以上道理也不會發(fā)生重疊,但當某坦克正從上方生成而正巧有另一輛阻礙在其生成點處,這將導致不可避

83、免的重合。這是允許的,但需要對他們標注狀態(tài),即當坦克剛出現時暫時允許重合,一旦在某個時間他們脫離了重合狀態(tài),就不能在允許重合,如果不設置這</p><p>  3.5 子彈的運行和控制</p><p>  每一個坦克都有他自己的一顆子彈,這顆子彈在任何一輛坦克被構造時就一直存在,直至此坦克生命的結束,子彈的再次只是將屏幕上暫時掩蓋的圖象重新置于坦克炮筒才恰當位置,并使其顯示出來,這與現實中

84、每個子彈都是單獨的個體有所不同。</p><p>  子彈所需要完成的任務有:</p><p>  它是一個繼承了Runnable虛類的可運行單獨線程的對象。在其出現在屏幕上的運行周期中,每一步都需要循環(huán)檢測以下條件:</p><p>  是否與某坦克發(fā)生了碰撞,即擊中了這輛坦克。子彈使用的是象素級的碰撞檢測,因為子彈的圖片形狀不規(guī)則,如果使用矩形碰撞檢測,將有可能

85、在子彈尚未接觸到物體時就已返回碰撞的真值。分為兩種情況,如果此子彈來自于敵方,將只檢測玩家坦克,因為敵方之間的子彈必須允許可以透明的穿過,以保證不會在敵人之間發(fā)生子彈的消減。如果來自玩家,則每一步需掃描所有的敵方坦克,檢查是否發(fā)生碰撞,這可能會花費不少的CPU時間。</p><p>  其次,子彈之間需要檢測是否碰撞。敵人之間顯然,如上已經提過,不需要檢測,但敵人與玩家之間應當可以互相消除子彈,以便在狹窄的路口中

86、仍有存活的機會。玩家的子彈需要在每一步檢測所有敵人的子彈的運行狀態(tài)。這樣較多的運算也將不可避免的耗費大量CPU時間。</p><p>  子彈對不同障礙物將有不同的反映。對磚墻將有能力將其擊毀,使之在畫面上消失;對水泥鋼筋將不能發(fā)生作用,子彈也不能通過;對于河流,坦克不可以通過,但子彈可以;對于草叢,子彈和坦克都可以通過。</p><p>  3.6 RMS數據庫系統(tǒng)</p>

87、<p>  MIDP為MIDlets提供了一種永久存儲和后來讀出數據的數據庫解決方案,被稱為Record Managerment System(RMS),是一種類簡單的基于記錄的數據庫。</p><p>  很顯然,手機上的數據庫系統(tǒng)不可能有PC上的強大功能。微小的存儲空間也限制了它們的結構不能過于復雜。RMS是專門針對移動設備的服務的。</p><p>  RMS包中包括Re

88、cordStore類。在一個MIDlet suite包里的所有MIDlet都允許創(chuàng)建多個記錄集,只要它們賦有不同的名稱。當MIDlet包從平臺中被移除后,所有與該包有關的的記錄集都同時會被移除。同一個包內的MIDlets可以直接互相訪問它們的記錄集,不同包內也可產生共享,但這需要有包的授權屬性決定。訪問模式會在準備提供共享的RecordStore被建立時被創(chuàng)建。訪問模式允許私有使用或訪問。</p><p>  R

89、ecordStore的API采用了時間戳的概念,其長整型變量由System的currentTimeMillis()函數返回決定。Record store 每次被修改后都會自動在其屬性上附加上時間戳,這為同步化引擎和程序的控制都極為有效。</p><p>  記錄是字節(jié)數組。開發(fā)者可以利用InputStream的派生類DataInputStream、DataOutputStream以及ByteArrayInputS

90、tream、ByteArrayOutputStream將不同種類的數據類型打包,以字節(jié)流的形式發(fā)送和接收。</p><p>  區(qū)別記錄的唯一標記是他們的ID值,作為記錄集的主鍵。第一項記錄的ID是1,其后的每個記錄ID遞增。</p><p>  Record是以字節(jié)為基本單位來存放的,所以所有要寫入record的數據都必須先將其轉為字節(jié)才能寫入,從record所讀出來的數據也是字節(jié),必須

91、將其轉換為原先寫入時的數據類型才有意義。</p><p>  然而讀取或寫入的字節(jié)數組都只能代表一個字段的信息,如果需要讀取或寫入多個字段就必須要將數據轉換成字節(jié)信息,并且提供適當的機制來分隔這些信息。主要有兩種方法:</p><p><b>  標記法。</b></p><p>  將所有要存放的數據用字符串表示,但是在字段和字段之間以一個特

92、殊的符號作為分隔。符號不能和字段內的數據相同的字符。</p><p>  2.利用輸入/輸出流</p><p>  這一種方法較上一種復雜,但是較為實用。方法一中所有的字段只能以字符串的形式存儲,要對這些字段作進一步的處理非常麻煩。利用輸入輸出流可以寫入及讀取不同數據類型的數據,做法是在寫入數據時先將一個DataOutputStream數據流對象串接到一個ByteArrayOutStrea

93、m數據流對象,然后再依字段的數據類型用writeInt()、writeBoolean()等方法寫入,最后把ByteArrayOutputStream內的元素數據寫入record中。反之若要讀取數據,則先要串接一個DataInputStream對象和ByteArrayInputStream,依字段的數據類用readInt()、readBoolean()等方法讀取。</p><p>  本程序中主要存放在永久區(qū)的內容

94、為用戶得到的最高分數的記錄。一共可以存儲10條最高分。每次有新的更高的記錄就會插入進相應的位置,將最低一名排擠出記錄。在輸入記錄前,要求用戶在TextField框中寫入他自己的名字。返回的getString可以將名字輸送給字節(jié)流。因為每個記錄包括用戶名和分數,因此需要使用多字段的方式編入。打印到屏幕上時,記錄ID號即為排名,因此將顯示三項數據。</p><p>  3.7 內存使用的最佳化</p>

95、<p>  通常在MIDP應用程序的手機執(zhí)行環(huán)境中,所牽涉的內存有下列三種:</p><p><b>  ﹡應用程序存儲內存</b></p><p>  ﹡RecordStore存儲內存</p><p>  ﹡執(zhí)行時期內存(Java Heap)</p><p>  其中前兩種是持久性的內存,關閉電源后還能保持

96、數據的正確性,通常這兩種內存所能存儲的容量是合并計算的,這個上限對每種手機都不一樣,大部分在一兩百KB內。在這樣的情況下需要在不影響原有功能的情況下適當的縮減JAR文件的大小,除了可以克服內存空間的限制外,也能大幅度縮短下載的時間(費用也降低了),勢必會有更多的人愿意下載所開發(fā)的程序。其方法有:</p><p>  第一,就是盡量縮短命名的長度。在應用程序內,對于所建立的類、接口、方法及變量名而言,都需要賦予一個

97、識別的名稱,所命名的名稱每多一個字符就會在類文件內多產生一個字節(jié),對于一個較復雜的應用程序而言就會增加為數不小的數據量。所有這些可以借助混淆器來幫助實現。</p><p>  第二是減少復雜的程序結構,為一些共同的行為建立一個抽象類(Abstract Class) 來表示繼承的子類的共通性。</p><p>  第三是減少圖形數據的大小。將PNG格式的小分辨率圖象合并在一張大的高分辨率圖象

98、中,由于減少了chunks,將比合并前的總大小減少許多。</p><p>  3.8 混淆器(Obfuscator)的使用</p><p>  Java 語言并沒有完全編譯成二進制可執(zhí)行文件,編譯出的.class文件是一種介于源程序和二進制之間的一中基于半解釋的字節(jié)碼,需要虛擬機來執(zhí)行。它包括了所有的信息。然而這樣會導致.class很容易被反編譯為源代碼,從而不能保護作者的知識成果。目前

99、流行的如decode,JAD等反編譯工具可以以很快的速度生成源文件。如果不加以施行有效的措施,將造成嚴重的后果。</p><p>  由此引入混淆器的概念?;煜鲗⒋a中的所有變量、函數、類的名稱變?yōu)楹喍痰挠⑽淖帜复枺绻狈ο鄳暮瘮得甘竞统绦蜃⑨?,即使被反編譯,也將難以閱讀。</p><p>  混淆器的作用不僅僅是保護代碼,它也有精簡編譯后程序大小的作用。由于以上介紹的減少變量、

100、函數的命名長度的關系,編譯后也會從.class文件中減少這些冗余的信息?;煜?,體積大約能減少25%,這對當前費用較貴的無線網絡傳輸是有一定意義的。</p><p>  為了能與各種IDE集成,就像Java2 SDK一樣,混淆器采用命令行參數的形式,以便可被其調用。目前流行的Obfuscator有RetroGuard等。</p><p>  3.9 模擬器的相關調試</p>

101、<p>  IDE整合的Wireless Tool Kit提供了許多在運行時監(jiān)視運行狀態(tài)的工具。 包括內存狀況的檢測(手機上的內存空間十分有限,必須時刻關注機載內存是否大于程序所能使用到的最大可能的內存空間),網絡狀況的檢測,運行函數的跟蹤等。如圖3-4,是內存跟蹤測試隨時間變化的調試器。其中,允許強制垃圾回收(Garbage Collection)。由于Java語言中,不像許多其他的如C++語言,不需要指定回收函數中特定不

102、使用的資源,資源回收機制將自動清空無效變量占用的空間。在程序運行中也可以調用System類的gc()函數手動收回廢棄的內存。</p><p>  3.10 本章小結:</p><p>  第三章中介紹了程序的流程、相關技術的思想及其在本程序中的應用。分別對繪圖、數據庫、游戲基本算法等做了詳細敘述。具體算法的代碼實現和詳細流程將在下章介紹。</p><p>  第四

103、章 程序分析和具體實現</p><p>  4.1 游戲進入前的選擇</p><p>  每個MIDlet程序都必須有一個主類,該類必須繼承自MIDlet。它控制著整個程序的運行,并且可以通過相應函數從程序描述文件中獲取相關的信息。該類中擁有可以管理程序的創(chuàng)建、開始、暫停(手機中很可能有正在運行程序卻突然來電的情況,這時應進入暫停狀態(tài)。)、結束的函數。</p><p&

104、gt;  進入時,首先載入畫面的不是游戲運行狀態(tài),而是提供選項,當再次選擇Start Game時才正式運行。運行畫面如圖4-1所示。因此,在TankMain的構造函數中分配了StartChoice類,即選項畫面的內存空間。在startApp()函數中,隨即調用了Displable的setCurrent()函數將當前屏幕設置為startChoice。在顯示高級用戶界面前,建造了一個Alert類。Alert對象用于顯示提示、警告等告之用戶信

105、息的臨時閃現的屏幕,它可作為setCurrent的參數,提前顯示在最終需要顯示的屏幕前。當將FOREVER作為Alert的參數時,將永久顯示,直到用戶點擊相應按鈕手動結束。但是當顯示的畫面元素超過一屏大小時,將自動轉換為永久狀態(tài)。在此,由于貼在Alert上的圖片大小超出了其范圍,故已成為永久狀態(tài)。效果如圖4-2所示。</p><p>  startChoice繼承了接口commandListener,這樣,就可以

溫馨提示

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

評論

0/150

提交評論