Java坦克大戰(zhàn)游戲設(shè)計說明書_第1頁
Java坦克大戰(zhàn)游戲設(shè)計說明書_第2頁
Java坦克大戰(zhàn)游戲設(shè)計說明書_第3頁
Java坦克大戰(zhàn)游戲設(shè)計說明書_第4頁
Java坦克大戰(zhàn)游戲設(shè)計說明書_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

.../北方民族大學(xué)大作業(yè)報告〔游戲程序設(shè)計系〔部、中心計算機科學(xué)與工程學(xué)院姓名王鑫學(xué)號20122201專業(yè)軟件工程班級2012級軟件三班課程名稱Java語言程序設(shè)計作業(yè)題目名稱《簡易版坦克大戰(zhàn)游戲程序設(shè)計》起止時間20XX4月21日——20XX5月21日成績指導(dǎo)教師簽名賈艷波、林淑飛簡易版坦克大戰(zhàn)游戲程序設(shè)計一、游戲的基本規(guī)則坦克種類分為敵方坦克和我方坦克,敵方有n輛藍色坦克〔n值可以自己設(shè)定,我方有一輛紅色坦克,我方坦克發(fā)射子彈,擊中敵人坦克后,敵方坦克消失,并產(chǎn)生爆炸效果,同理,敵方坦克擊中我之后,我方坦克消失并爆炸。游戲結(jié)束。二、主要實現(xiàn)思想和算法gui圖形界面顯示:界面的顯示是通過TankGame類〔繼承了JFrame和MyPanel〔繼承了JPanel類實現(xiàn)。其中,MyPanel重寫了paint方法,利用畫筆Graphics繪制活動區(qū)域、坦克和子彈。畫坦克的思想:選擇一個參考點,如右圖,首先參照參考點,畫出參考點參考點圓形,直線和右邊的矩形。這些形狀組合起來就形成了一輛坦克。然后將畫坦克的步驟封裝成一個方法。我的坦克發(fā)射子彈的思想:首先創(chuàng)建一個Shot類,他擁有坐標〔根據(jù)坦克的坐標換算得到、方向、速度和是否存活的屬性,因為,子彈的坐標要不斷的改變,所以將它做成一個線程。然后,在我的坦克里面定義了一個vactor〔因為他是線程安全的類集框架存放我的坦克的子彈。然后在pannel的paint方法中繪制。讓MyPanel實現(xiàn)KeyListener接口,將TankGame注冊讓MyPanel監(jiān)聽,這樣的話我按下j鍵,就在vactor里面添加一個子彈,然后讓Shot實現(xiàn)Runnable接口,然后重寫run方法,在run方法中通過改變子彈的坐標實現(xiàn)子彈的運動。我的坦克移動的思想:讓MyPanel實現(xiàn)KeyListener接口,將TankGame注冊讓MyPanel監(jiān)聽,這樣我按下相應(yīng)的鍵,就相應(yīng)的改變坦克的坐標,利用repaint重新繪制坦克。敵人坦克移動的思想:將敵人的坦克做成一個線程,然后在run方法中改變坦克坐標,重繪坦克。里隨機數(shù)生成不同的方向,從而讓敵人的坦克自主選擇方向移動。實現(xiàn)動態(tài)畫面的思想:將MyPanel做成一個線程,然后將repaint函數(shù)方將run函數(shù)中,這樣repaint函數(shù)就會被不斷的調(diào)用,從而不斷地刷新畫面,達到動態(tài)效果。判斷子彈是否擊中坦克的算法:獲得子彈的坐標和坦克的坐標,如果子彈坐標進入坦克坐標范圍,就判為擊中。讓已經(jīng)死亡的坦克和子彈消失的方法:被擊中的坦克的isLive和子彈isLive的設(shè)置為false,這樣,在繪制的時候會首先判斷要繪制對象的isLive的值,如果為true才繪制,這樣死亡的坦克和子彈就消失了。讓敵人坦克和子彈自動移動的思想:將敵人坦克和子彈做成一個線程,然后分別在各自的run函數(shù)中添加一個修改坐標的程序段。然后在MyPanel中啟動對應(yīng)的線程。坐標不斷的自動修改,另一方面,paint函數(shù)不斷的重新繪制,從而讓坦克和子彈自動的移動了起來。讓坦克和子彈在規(guī)定的區(qū)域內(nèi)移動的方法:通過比較坦克坐標和區(qū)域坐標范圍,如果坦克坐標達到區(qū)域坐標范圍邊界,就不讓坦克的坐標繼續(xù)修改,從而將坦克控制在規(guī)定的范圍。通過比較子彈坐標和區(qū)域坐標范圍,如果子彈坐標超出區(qū)域坐標范圍,就將子彈的isLive置為false,這樣在paint函數(shù)中就不再繪制這個子彈了,從而超出區(qū)域的子彈就消失了。顯示爆炸效果的方法:首先我準備了一張爆炸的圖片,然后創(chuàng)建一個爆炸的類Bomb,它擁坐標屬性,和生命值屬性。還有減少生命的方法,當(dāng)子彈擊中坦克后,就坦克的坐標傳遞給Bomb,當(dāng)做Bomb的坐標,然后開始繪制炸彈,同時讓炸彈的生命不斷減小,paint函數(shù)根據(jù)炸彈不同的生命值繪制不同大小的爆炸效果,不同的爆炸效果組合起來就形成了一個完整的爆炸。三、游戲軟件系統(tǒng)的設(shè)計四、程序關(guān)鍵類的實現(xiàn)Tank類,擁有坐標X,Y和方向,速度屬性,以及對應(yīng)的set和get方法。還有判斷坦克是否死亡的isLive屬性。Hero類,繼承了Tank類,有子彈屬性,有shotEnemy方法,和上下左右移動的方法Shot類,實現(xiàn)了線程接口,run方法里面放置了修改子彈坐標和判斷子彈是否處境的算法。有坐標、速度、方向、和是否活著的屬性。炸彈類,有坐標、生命值和是否存活的屬性。有生命減少的方法。EenmyTank類,繼承了Tank類,實現(xiàn)了線程接口,在run方法中添加了修改坦克坐標的程序段,從而讓坦克自動移動。MyPanel類,是本游戲最主要的類,他繼承了JPanel實現(xiàn)了keylistener和runnable接口,他的paint函數(shù)繪制了游戲中的坦克和子彈以及活動范圍。keyPressed函數(shù)監(jiān)聽鍵盤輸入,run函數(shù)里面放了repaint和比較是否擊中坦克的代碼。TankGame類,是本游戲的入口,其構(gòu)造方法包含將面板添加到JFrame,設(shè)置窗口大小、可見性和默認的關(guān)閉方式。五、游戲軟件的主要界面截圖六、程序代碼:importjavax.swing.*;publicclassTankGameextendsJFrame{//面板 MyPanelmp=null;publicstaticvoidmain<String[]args>{//創(chuàng)建窗口 TankGametankegame=newTankGame<>; }//構(gòu)造函數(shù)publicTankGame<>{//創(chuàng)建面板對象mp=newMyPanel<>;//將面板添加到JFramethis.add<mp>;this.addKeyListener<mp>;//啟動面板線程,讓其paint方法不斷調(diào)用,從而不斷刷新,達到動態(tài)效果 Threadt=newThread<mp>; t.start<>;//設(shè)置窗口大小this.setSize<400,300>;//設(shè)置小圖標this.setIconImage<newImageIcon<"image/tk.png">.getImage<>>;this.setDefaultCloseOperation<JFrame.EXIT_ON_CLOSE>;this.setVisible<true>; }}**********************************************publicclassTank{//坦克的很坐標intx;//坦克的縱坐標inty;//坦克的方向//0表示上,1右,2下,3表示左intdirect=0;//坦克的速度intspeed=4;//坦克的外觀intcolor=0;//坦克是否死亡booleanisLive=true;publicintgetColor<>{returncolor; }publicvoidsetColor<intcolor>{this.color=color; }publicintgetSpeed<>{returnspeed; }publicvoidsetSpeed<intspeed>{this.speed=speed; }publicintgetDirect<>{returndirect; }publicvoidsetDirect<intdirect>{this.direct=direct; }publicTank<intx,inty>{this.x=x;this.y=y; }publicintgetX<>{returnx; }publicvoidsetX<intx>{this.x=x; }publicintgetY<>{returny; }publicvoidsetY<inty>{this.y=y; }}***********************************************importjava.util.Vector;publicclassHeroextendsTank{//放置子彈的類集框架 Vector<Shot>ss=newVector<Shot><>;//子彈 Shots=null;publicHero<intx,inty>{super<x,y>; }//開火publicvoidshotEnemy<>{switch<this.direct>{case0:s=newShot<x+10,y,0>;ss.add<s>;break;case1:s=newShot<x+30,y+10,1>;ss.add<s>;break;case2:s=newShot<x+10,y+30,2>;ss.add<s>;break;case3:s=newShot<x,y+10,3>;ss.add<s>;break; }//啟動子彈線程 Threadt=newThread<s>; t.start<>; }//坦克向上移動publicvoidmoveUp<>{y-=speed; }//坦克向右移動publicvoidmoveRiget<>{x+=speed; }//坦克向下移動publicvoidmoveDown<>{y+=speed; }//坦克向左移動publicvoidmoveLeft<>{x-=speed; }}*******************************************************************************importjava.awt.*;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.util.Vector;importjavax.swing.*;publicclassMyPanelextendsJPanelimplementsKeyListener,Runnable{//定義一個我的坦克 Herohero=null;//定義敵人的坦克組,用Vector,因為他是線程安全的 Vector<EnemyTank>ets=newVector<EnemyTank><>;//敵人坦克的初始量intenSize=2;//定義炸彈集合 Vector<Bomb>bombs=newVector<Bomb><>;//定義爆炸圖片 Imageimage1=null; Imageimage2=null; Imageimage3=null;//定義背景圖片 Imageimagebg=null;//MyPanel構(gòu)造函數(shù)publicMyPanel<>{//初始化我的坦克hero=newHero<200,200>;//初始化敵人的坦克for<inti=0;i<enSize;i++>{ EnemyTanket=newEnemyTank<<i+1>*50,0>;//設(shè)置顏色 et.setColor<1>;//設(shè)置方向 et.setDirect<2>;//啟動敵人坦克 Threadt=newThread<et>; t.start<>;//給敵人坦克添加子彈 Shots=newShot<et.x+10,et.y+30,2>; et.ss.add<s>; Threadt2=newThread<s>; t2.start<>;//加入類集框架ets.add<et>; }//初始化爆炸圖片image1=Toolkit.getDefaultToolkit<>.getImage<Panel.class.getResource<"/bom.png">>;image2=Toolkit.getDefaultToolkit<>.getImage<Panel.class.getResource<"/bom.png">>;image3=Toolkit.getDefaultToolkit<>.getImage<Panel.class.getResource<"/bom.png">>;//初始化背景圖片imagebg=Toolkit.getDefaultToolkit<>.getImage<Panel.class.getResource<"/bg.jpg">>; }//重寫paint〔必須的步驟publicvoidpaint<Graphicsg>{super.paint<g>;//畫一個活動區(qū)域 g.drawImage<imagebg,0,0,400,300,this>;if<hero.isLive==true>{//畫我的坦克this.drawTank<hero.getX<>,hero.getY<>,g,this.hero.getDirect<>,this.hero.getColor<>>; }//從ss中取出每顆子彈,并繪制for<inti=0;i<this.hero.ss.size<>;i++>{ ShotmyShot=this.hero.ss.get<i>;//畫一顆子彈,要先判斷是否為空,因為坦克剛創(chuàng)建的時候,沒有按J的時候,子彈是空的,這個時候不能畫,要不然會異常if<myShot!=null&&myShot.isLive==true>{ g.draw3DRect<myShot.x,myShot.y,1,1,false>; }//判斷子彈是否死亡,如果死亡,就從Vocetor中移除if<myShot.isLive==false>{hero.ss.remove<myShot>; } }//畫出敵人的坦克for<inti=0;i<ets.size<>;i++>{ EnemyTanket=ets.get<i>;if<et.isLive>{this.drawTank<et.getX<>,et.getY<>,g,et.getDirect<>,et.getColor<>>;//畫出敵人的子彈for<intj=0;j<et.ss.size<>;j++>{//取出子彈 ShotenemyShot=et.ss.get<j>;//開始畫if<enemyShot.isLive>{ g.draw3DRect<enemyShot.x,enemyShot.y,1,1,false>; }else{//如果子彈死亡,就把子彈移除 et.ss.remove<enemyShot>; } } } }//畫出炸彈for<inti=0;i<bombs.size<>;i++>{//取出炸彈 Bombb=bombs.get<i>;//畫炸彈。根據(jù)不同的生命值爆炸不同的大小if<b.life>6>{ g.drawImage<image1,b.x,b.y,30,30,this>; }elseif<b.life>3>{ g.drawImage<image2,b.x,b.y,15,15,this>; }else{ g.drawImage<image3,b.x,b.y,5,5,this>; }//減小炸彈的生命值 b.lifeDown<>;//如果炸彈死亡,就移除數(shù)組if<b.life==0>{bombs.remove<b>; } } }//判斷敵人是否擊中我publicvoidhitMe<>{//取出每一個敵人for<inti=0;i<this.ets.size<>;i++>{//取出坦克 EnemyTanket=ets.get<i>;//取出每一輛坦克的子彈for<intj=0;j<et.ss.size<>;j++>{//取出子彈 ShotenemyShot=et.ss.get<j>;this.hitTank<enemyShot,hero>; } } }//判斷我的子彈是否擊中敵人的坦克publicvoidhitEnemyTank<>{//判斷是否擊中for<inti=0;i<hero.ss.size<>;i++>{//取出子彈 ShotmyShot=hero.ss.get<i>;//判斷子彈是否還活著if<myShot.isLive>{//遍歷敵人坦克,判斷子彈和坦克坐標for<intj=0;j<ets.size<>;j++>{//取出坦克 EnemyTanket=ets.get<j>;if<et.isLive>{this.hitTank<myShot,et>; } } } } }//判斷子彈是否碰撞到坦克的函數(shù)publicvoidhitTank<Shots,Tanket>{//判斷敵軍坦克的方向switch<et.direct>{//向上或者向下的情況下case0:case2:if<s.x>et.x&&s.x<et.x+20&&s.y>et.y&&s.y<et.y+30>{//擊中//子彈死亡 s.isLive=false;//坦克死亡 et.isLive=false;//創(chuàng)建一個炸彈,放入Vector Bombb=newBomb<et.x,et.y>;bombs.add<b>; }//向左或者向右的情況下case1:case3:if<s.x>et.x&&s.x<et.x+30&&s.y>et.y&&s.y<et.y+20>{//擊中//子彈死亡 s.isLive=false;//坦克死亡 et.isLive=false;//創(chuàng)建一個炸彈,放入Vector Bombb=newBomb<et.x,et.y>;bombs.add<b>; } } }//畫坦克的函數(shù)。四個參數(shù)分別為:起始畫的坐標,方向,類型publicvoiddrawTank<intx,inty,Graphicsg,intdirect,inttype>{//判斷坦克的類型switch<type>{case0: g.setColor<Color.RED>;//我的坦克break;case1: g.setColor<Color.blue>;//敵軍坦克break; }switch<direct>{case0://炮筒向上//畫坦克//第一步畫左邊的那條履帶 g.fill3DRect<x,y,5,30,false>;//四個參數(shù)分別表示起始點和大小//第二步畫出右邊的那條履帶 g.fill3DRect<x+15,y,5,30,false>;//第三部畫出中間的駕駛艙 g.fill3DRect<x+5,y+5,10,20,false>;//第四部畫出中間的炮塔 g.fillOval<x+5,y+9,10,10>;//第五步畫出炮筒 g.drawLine<x+10,y+15,x+10,y>;//四個參數(shù)分別表示起始點和終止點break;case1://炮筒向右//畫坦克//第一步畫上邊的那條履帶 g.fill3DRect<x,y,30,5,false>;//四個參數(shù)分別表示起始點和大小//第二步畫出下邊的那條履帶 g.fill3DRect<x,y+15,30,5,false>;//第三部畫出中間的駕駛艙 g.fill3DRect<x+5,y+5,20,10,false>;//第四部畫出中間的炮塔 g.fillOval<x+9,y+5,10,10>;//第五步畫出炮筒 g.drawLine<x+15,y+10,x+30,y+10>;//四個參數(shù)分別表示起始點和終止點break;case2://炮筒向下//第一步畫左邊的那條履帶 g.fill3DRect<x,y,5,30,false>;//四個參數(shù)分別表示起始點和大小//第二步畫出右邊的那條履帶 g.fill3DRect<x+15,y,5,30,false>;//第三部畫出中間的駕駛艙 g.fill3DRect<x+5,y+5,10,20,false>;//第四部畫出中間的炮塔 g.fillOval<x+5,y+9,10,10>;//第五步畫出炮筒 g.drawLine<x+10,y+15,x+10,y+30>;//四個參數(shù)分別表示起始點和終止點break;case3://炮筒向左//第一步畫上邊的那條履帶 g.fill3DRect<x,y,30,5,false>;//四個參數(shù)分別表示起始點和大小//第二步畫出下邊的那條履帶 g.fill3DRect<x,y+15,30,5,false>;//第三部畫出中間的駕駛艙 g.fill3DRect<x+5,y+5,20,10,false>;//第四部畫出中間的炮塔 g.fillOval<x+9,y+5,10,10>;//第五步畫出炮筒 g.drawLine<x+15,y+10,x,y+10>;//四個參數(shù)分別表示起始點和終止點 } }@OverridepublicvoidkeyTyped<KeyEvente>{//TODOAuto-generatedmethodstub }//本游戲用到這個方法,就來處理這個方法,其他的先不管//鍵按下//W表示向上,A表示向左,S表示向下,D表示向右publicvoidkeyPressed<KeyEvente>{if<e.getKeyCode<>==KeyEvent.VK_W>{//設(shè)置我的坦克的方向this.hero.setDirect<0>;if<this.hero.y>0>{this.hero.moveUp<>; } }elseif<e.getKeyCode<>==KeyEvent.VK_D>{//向右this.hero.setDirect<1>;if<this.hero.x<370>{this.hero.moveRiget<>; } }elseif<e.getKeyCode<>==KeyEvent.VK_S>{//向下this.hero.setDirect<2>;if<this.hero.y<270>{this.hero.moveDown<>; } }elseif<e.getKeyCode<>==KeyEvent.VK_A>{//向左this.hero.setDirect<3>;if<this.hero.x>0>{this.hero.moveLeft<>; } }//判斷是否玩家按下j開火if<e.getKeyCode<>==KeyEvent.VK_J>{//開火//if語句控制屏幕上同時最多只有多少顆子彈if<this.hero.ss.size<><5>{this.hero.shotEnemy<>; } }this.repaint<>; }@OverridepublicvoidkeyReleased<KeyEvente>{//TODOAuto-generatedmethodstub }@Overridepublicvoidrun<>{//TODOAuto-generatedmethodstubwhile<true>{try{ Thread.sleep<100>; }catch<Exceptione>{//TODO:handleexception }//調(diào)用判斷我的子彈是否擊中敵人的函數(shù)this.hitEnemyTank<>;//調(diào)用判斷敵人子彈是否擊中我的函數(shù)this.hitMe<>;//判斷是否要加子彈for<inti=0;i<ets.size<>;i++>{ EnemyTanket=ets.get<i>;if<et.isLive>{if<et.ss.size<><1>{ Shots=null;switch<et.direct>{case0: s=newShot<et.x+10,et.y,0>; et.ss.add<s>;break;case1: s=newShot<et.x+30,et.y+10,1>; et.ss.add<s>;break;case2: s=newShot<et.x+10,et.y+30,2>; et.ss.add<s>;break;case3: s=newShot<et.x,et.y+10,3>; et.ss.add<s>;break; }//啟動子彈線程 Threadt=newThread<s>; t.start<>; } } }//重繪this.repaint<>; } }}**********************************************importjava.util.Random;importjava.util.Vector;publicclassEnemyTankextendsTankimplementsRunnable{//定義一個類集框架,存放敵人的子彈 Vector<Shot>ss=newVector<Shot><>;publicEnemyTank<intx,inty>{super<x,y>; }@Overridepublicvoidrun<>{//TODOAuto-generatedmethodstubwhile<true>{try{ Thread.sleep<50>; }catch<Exceptione>{//TODO:handleexception }switch<this.direct>{case0:for<inti=0;i<30;i++>{if<y>0>y=y-speed;try{ Thread.sleep<50>; }catch<Exceptione>{//TODO:handleexception } }break;case1:for<inti=0;i<30;i++>{if<x<370>x=x+speed;try{ Thread.sleep<50>; }catch<Exceptione>{//TODO:handleexception } }break;case2:for<inti=0;i<30;i++>{

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論