程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Java-坦克大戰,坦克大戰

Java-坦克大戰,坦克大戰

編輯:JAVA綜合教程

Java-坦克大戰,坦克大戰


利用Java語言中的集合、Swing、線程等知識點編寫一個坦克大戰游戲。
(1) 畫出敵我坦克的原理:
在坦克類裡面有一個布爾類型變量good。用於判斷坦克的陣營,在創建坦克對象時在Tank類的構造方法中傳入good的值。在畫坦克的時候判斷good的值,區分敵我坦克的顏色;
(2) 坦克運動的原理:
在坦克類裡寫入了監聽鍵盤摁鍵的響應事件,對監聽到的上下左右鍵進行記錄,並合成坦克移動的八個方向的變量。之後對應每個方向的不同對坦克坐標x,y的值做響應的更改實現我方坦克的移動。而敵方坦克則自動移動,通過隨機數對敵方坦克移動方向的隨機,並且隨機出每次移動的次數。兩個隨機值相結合即實現了敵方坦克的移動。
(3) 坦克發射子彈的原理:
通過鍵盤監聽,檢測到發射子彈命令後將主類的子彈類集合中添加一個子彈類。將炮筒的方向以及坦克的位置以及坦克的陣營傳入給子彈類,在主類paint畫方法中一直循環子彈類集合,如果集合內有子彈,就畫出來。這樣就實現了發射子彈。
(4) 坦克、子彈、牆的碰撞原理:
在坦克類子彈類牆類中分別getRect方法獲取自身的范圍,然後在每次畫坦克、子彈時都會進行相應的碰撞檢測(在坦克類裡有與牆和出自己外的坦克相撞的處理方法、在子彈類裡有與牆和坦克相碰撞的處理方法。),如果自身與不該碰撞的物體的范圍相重合,則代表兩物體相撞。
(5)坦克加血的原理:
在血塊類中有血塊與我方坦克相碰撞的處理方法,如果血塊范圍與坦克范圍重合則血塊類死亡,並且坦克類的血量回復置滿。
(6)坦克復活的原理:
通過鍵盤監聽,檢測到我方坦克復活命令後,如果我方坦克處於死亡狀態,則將我方坦克存貨狀態改為活著並且將我方坦克血量回置滿血。

 編程思想:

坦克大戰的編程思想在主類開啟一個線程,沒50毫秒循環一次畫方法(繪制整個界面內的所有東西)。畫的東西有敵我坦克(顏色區分)、子彈、牆、血塊、爆炸。所以總共寫出了幾個類:Tank坦克類、Missile子彈類、Wall牆類、Blood血塊類、TankClient主類。在每一個類中均寫有畫方法實現本類屬性的繪制功能。在主類中有鍵盤監聽事件調用這Tank類的鍵盤監聽事件。通過鍵盤監聽判斷出對Tank做出相應的移動,而敵方Tank則是隨機運動。並且每次刷新都有調用各類的碰撞方法,判斷一些不該碰撞的對象的情況時做出處理。而每個對象的創建例如子彈這些是在觸發產生之後將新建子彈類加入一個子彈類集合之中,在繪制的時候判斷集合中的數量進行繪制,出界或者打死坦克則在集合中刪除。其他類也均相似,不在細說。
代碼中每步都注釋有相應的解釋。

TankClient.java

  1 import java.awt.Color;
  2 import java.awt.Font;
  3 import java.awt.Graphics;
  4 import java.awt.Image;
  5 import java.awt.event.KeyAdapter;
  6 import java.awt.event.KeyEvent;
  7 import java.awt.event.WindowAdapter;
  8 import java.awt.event.WindowEvent;
  9 import java.util.ArrayList;
 10 import java.util.List;
 11 
 12 import javax.swing.JFrame;
 13 
 14 public class TankClient extends JFrame{
 15     /**
 16      * @param args
 17      */
 18     Image OffScrennImage = null;    //雙緩沖內存圖片存儲
 19     /*游戲大小*/
 20     public static final int GAME_WIDTH = 800;    //界面寬
 21     public static final int GAME_HEIGTH = 600;    //界面高
 22     
 23     Tank myTank = new Tank(500,400,true,Color.red,Tank.Direction.STOP, this);//我方坦克類
 24     List<Missile> missiles = new ArrayList<Missile>();//子彈的集合
 25     List<Explode> explode = new ArrayList<Explode>();//爆炸集合
 26     List<Tank> tanks = new ArrayList<Tank>();    //坦克集合
 27     Wall wall1 = new Wall(150,200,20,300,this);    //牆1
 28     Wall wall2 = new Wall(250,500,300,20,this);    //牆2
 29     Wall wall3 = new Wall(650,200,20,300,this);    //牆2
 30     Wall wall4 = new Wall(250,300,300,20,this);    //牆2
 31     Wall wb = new Wall(750,550,40,40,this);    //牆2
 32     Blood b = new Blood();    //血類
 33     
 34     
 35     public static void main(String[] args) {
 36         // TODO Auto-generated method stub
 37         TankClient tc=new TankClient();
 38         tc.lauchFrame();
 39     }
 40 
 41     private void lauchFrame() {
 42         // TODO Auto-generated method stub
 43         for (int i = 0; i < 10; i++){
 44             tanks.add(new Tank(50+40*(i+1), 50, false,Color.blue,Tank.Direction.D, this));
 45         }
 46         this.setLocation(100, 100);    //窗口初始坐標點
 47         this.setSize(GAME_WIDTH, GAME_HEIGTH);        //窗口初始大小
 48         this.setTitle("TankWar");    //窗口名稱
 49         /*窗口監聽*/
 50         this.addWindowListener(new WindowAdapter() {
 51             @Override
 52             /*點退出叉之後運行*/
 53             public void windowClosing(WindowEvent e) {
 54                 // TODO Auto-generated method stub
 55                 System.exit(0);    //退出
 56             }
 57         });
 58         this.addKeyListener(new KeyMoniton());    //設置鍵盤監聽
 59         this.setVisible(true);    //設置窗口顯現
 60         this.setResizable(false);    //設置窗口不可改變大小
 61         this.getContentPane().setBackground(Color.green);    //設置窗口前景色為綠色
 62         new Thread(new PaintThread()).start();    //開始運行PaintThread類run
 63     }
 64 
 65     @Override
 66     public void paint(Graphics g) {
 67         // TODO Auto-generated method stub
 68         //Graphics為畫筆類
 69         super.paint(g);
 70         myTank.draw(g);
 71         wall1.draw(g);
 72         wall2.draw(g);
 73         wall3.draw(g);
 74         wall4.draw(g);
 75         wb.draw(g);
 76         b.draw(g);
 77         myTank.eatBlood(b);
 78         myTank.hitWall(wall1);
 79         myTank.hitWall(wall2);
 80         myTank.hitWall(wall3);
 81         myTank.hitWall(wall4);
 82         /*循環子彈集合*/
 83         for (int i = 0; i < missiles.size(); i++){
 84             Missile m = missiles.get(i);    //獲取當前子彈
 85             m.hitTanks(tanks);    //自己子彈打死敵方坦克
 86             m.hitWall(wall1);    //子彈與牆
 87             m.hitWall(wall2);
 88             m.hitWall(wall3);
 89             m.hitWall(wall4);
 90             m.hitTank(myTank);//敵人子彈打擊自己的坦克
 91             m.draw(g);    //畫子彈
 92         }
 93         for    (int i = 0; i < explode.size(); i++){
 94             explode.get(i).draw(g);    //畫爆炸
 95         }
 96         for (int i = 0; i < tanks.size(); i++){
 97             Tank t = tanks.get(i);
 98             t.draw(g);    //畫敵方坦克
 99             t.hitTanks(tanks);
100             t.hitWall(wall1);    //坦克與牆
101             t.hitWall(wall2);
102             t.hitWall(wall3);
103             t.hitWall(wall4);
104         }
105         //g.setFont(new Font("宋體",Font.BOLD,20));
106         g.drawString("missiles  count:"+missiles.size(), 10, 50);//顯示
107         g.drawString("explode  count:"+explode.size(), 10, 80);//顯示
108         g.drawString("tanks count:"+tanks.size(),10, 110);
109         g.drawString("myTank Life:"+myTank.getLife(), 10, 130);
110         g.drawString("回血:", 750, 540);
111         g.drawString("方向鍵移動方向;E:釋放移動血快", 10, 590);
112         g.drawString("z:發射東風-31;a:發射東風-41;", 10, 570);
113         g.drawString("F2:復活;F3:敵方復活(對多20)", 10, 550);
114         g.drawString("R:位置還原;Q:血量加滿", 10, 530);
115     }
116     
117     @Override
118     /*repaint-〉update->paint*/
119     public void update(Graphics g) {
120         // TODO Auto-generated method stub
121         super.update(g);
122         if(OffScrennImage == null)
123             OffScrennImage = this.createImage(GAME_WIDTH, GAME_HEIGTH);
124         Graphics goffscrenn = OffScrennImage.getGraphics();    //設置一個內存畫筆顏色為前景圖片顏色
125         Color c = goffscrenn.getColor();    //還是先保存前景顏色
126         goffscrenn.setColor(Color.green);    //設置內存畫筆顏色為綠色
127         goffscrenn.fillRect(0, 0, GAME_WIDTH, GAME_HEIGTH);    //畫成圖片,大小為游戲大小
128         goffscrenn.setColor(c);    //還原顏色
129         g.drawImage(OffScrennImage, 0, 0, null);    //在界面畫出保存的圖片
130         paint(goffscrenn);    //把內存畫筆調用給paint
131     }
132 
133     private class PaintThread implements Runnable{
134 
135         @Override
136         public void run() {
137             // TODO Auto-generated method stub
138             while(true){
139                 repaint();    //運行順序repaint->update->paint
140                 try{
141                     Thread.sleep(50);    //每隔50毫秒刷新畫面一次
142                 }catch(Exception e){
143                     e.printStackTrace();
144                 }
145             }
146         }
147         
148     }
149     /*鍵盤響應*/
150     private class KeyMoniton extends KeyAdapter{
151 
152         /*摁下鍵盤響應*/
153         @Override
154         public void keyPressed(KeyEvent e) {
155             // TODO Auto-generated method stub
156             super.keyPressed(e);
157             myTank.KeyPressed(e);
158         }
159         /*抬起鍵盤響應*/
160         @Override
161         public void keyReleased(KeyEvent e) {
162             // TODO Auto-generated method stub
163             super.keyReleased(e);
164             myTank.keyReleased(e);
165         }
166         
167     }
168 }

 

Tank.java

  1 import java.awt.Color;
  2 import java.awt.Graphics;
  3 import java.awt.Image;
  4 import java.awt.Rectangle;
  5 import java.awt.event.KeyEvent;
  6 import java.util.List;
  7 import java.util.Random;
  8 
  9 import javax.swing.ImageIcon;
 10 
 11 
 12 public class Tank {
 13     /*坦克本身數據*/
 14     int x, y;//坦克坐標
 15     private int oldX, oldY;    //坦克上一步坐標
 16     public static final int Whith = 30;    //坦克寬
 17     public static final int Higth = 30;    //坦克高
 18     public static final int XSPEED = 5;    //橫向移動速度
 19     public static final int YSPEED = 5;    //縱向移動速度
 20     private Color color;    //坦克顏色
 21     private boolean bL=false, bU=false, bR=false, bD=false;    //四個方向控制值
 22     enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};    //由四個方向值合成八個方向的移動
 23     private Direction dir = Direction.STOP;    //出場方向
 24     private Direction ptDir = Direction.D;    //炮筒初始方向 
 25     private boolean good;    //判斷坦克的陣營
 26     private boolean live = true;    //判斷坦克是否存活
 27     private static Random r = new Random();//設置一個隨機值變量
 28     private static int step = r.nextInt(12)+3;    //敵方坦克隨機移動步驟3-14步
 29     private int Life = 100;    //血量
 30     private BloodBar bb = new BloodBar();    //血塊類
 31     
 32 //    ImageIcon icon = new ImageIcon("res\\myTank.jpg");
 33 //    ImageIcon icon2 = new ImageIcon("res\\enemyTank.jpg");
 34 //    Image image = icon.getImage();
 35 //    Image image2 = icon2.getImage();
 36     
 37     
 38     private TankClient tc;    //主類權限
 39 
 40     public Tank(int x, int y, boolean good, Color color) {
 41         super();
 42         this.x = x;
 43         this.y = y;
 44         this.color = color;
 45         this.good = good;
 46     }
 47     public Tank(int x, int y, boolean good,Color color,Direction dir,TankClient tc){
 48         this(x,y,good,color);
 49         this.dir = dir;
 50         this.tc = tc;
 51     }
 52     /*獲取坦克生命值*/
 53     public int getLife() {
 54         return Life;
 55     }
 56     /*設置坦克生命值*/
 57     public void setLife(int Life) {
 58         this.Life = Life;
 59     }
 60 
 61     /*獲取坦克陣營*/
 62     public boolean isGood() {
 63         return good;
 64     }
 65     /*設置坦克陣營*/
 66     public void setGood(boolean good) {
 67         this.good = good;
 68     }
 69     /*獲取坦克存活狀態*/
 70     public boolean isLive() {
 71         return live;
 72     }
 73     /*設置坦克存活狀態*/
 74     public void setLive(boolean live) {
 75         this.live = live;
 76     }
 77     /*畫坦克*/
 78     public void draw(Graphics g){
 79         if(!live){    
 80             if(!good){
 81                 tc.tanks.remove(this);    //敵方坦克死亡時在集合中刪除
 82                 //tc.tanks.add(new Tank(r.nextInt(700),r.nextInt(500),false,Color.blue,Direction.D,this.tc));
 83             }
 84             return;
 85         }
 86         /*先保存之前的畫筆顏色,畫完之後再還原畫筆顏色*/
 87         Color c = g.getColor();    //獲取當前畫筆顏色
 88         g.setColor(color);    //設置畫筆顏色為紅色
 89         /*畫坦克*/
 90         g.fillOval(x, y, Whith, Higth);
 91         /*兩種方法繪制敵我坦克,運用之前加入的圖片或者顏色區分*/
 92 //        if(good)
 93 //            g.drawImage(image, x, y,Whith,Higth,null);
 94 //        else
 95 //            g.drawImage(image2, x, y, Whith, Higth, null);
 96         if(good)    
 97             bb.draw(g);    //我方坦克畫血條
 98         g.setColor(Color.black);
 99         /*通過炮筒方向畫出炮筒*/
100         switch(ptDir){
101         case L:
102             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth/2);
103             break;
104         case LU:
105             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y);
106             break;
107         case U:
108             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y);
109             break;
110         case RU:
111             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y);
112             break;
113         case R:
114             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth/2);
115             break;
116         case RD:
117             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth);
118             break;
119         case D:
120             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y+Tank.Higth);
121             break;
122         case LD:
123             g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth);
124             break;
125         }
126         g.setColor(c);    //還原畫筆顏色
127         move();//移動
128     }
129     
130     /*鍵盤監聽;摁鍵*/
131     public void KeyPressed(KeyEvent e){
132         int key = e.getKeyCode();    //將鍵盤監聽到的摁鍵以整數保存
133         /*鍵盤移動坦克*/
134         switch(key){
135         /*移動摁鍵*/
136         case KeyEvent.VK_UP:
137             bU=true;
138             break;
139         case KeyEvent.VK_DOWN:
140             bD=true;
141             break;
142         case KeyEvent.VK_RIGHT:
143             bR=true;
144             break;
145         case KeyEvent.VK_LEFT:
146             bL=true;
147             break;
148         }
149         locateDirection();
150     }
151     
152     /*鍵盤監聽;抬起鍵*/
153     public void keyReleased(KeyEvent e){
154         int key = e.getKeyCode();    //將鍵盤監聽到的摁鍵以整數保存
155         /*鍵盤移動坦克*/
156         switch(key){
157         case KeyEvent.VK_UP:
158             bU=false;
159             break;
160         case KeyEvent.VK_DOWN:
161             bD=false;
162             break;
163         case KeyEvent.VK_RIGHT:
164             bR=false;
165             break;
166         case KeyEvent.VK_LEFT:
167             bL=false;
168             break;
169         case KeyEvent.VK_Z:    //單發子彈
170             if(live)
171                 fire();
172             break;
173         case KeyEvent.VK_F2:    //我方復活
174             if(!this.live){
175                 this.live=true;
176                 this.setLife(100);
177             }
178             break;
179         case KeyEvent.VK_F3:    //敵方復活
180             fuhuo();
181             break;
182         case KeyEvent.VK_A:        //無敵導彈
183             superFire();
184             break;
185         case KeyEvent.VK_Q:        //回血
186             if(this.live)
187                 this.Life = 100;
188             break;
189         case KeyEvent.VK_E:        //釋放血塊
190             tc.b.fh();
191             break;
192         /*還原位置鍵*/
193         case KeyEvent.VK_R:
194             x = 50;
195             y = 50;
196             break;
197         }
198         locateDirection();    //合成方向
199     }
200     /*合成移動方向*/
201     void locateDirection(){
202         if(bL&&!bU&&!bR&&!bD) dir=Direction.L;
203         else if(bL&&bU&&!bR&&!bD) dir=Direction.LU;
204         else if(!bL&&bU&&!bR&&!bD) dir=Direction.U;
205         else if(!bL&&bU&&bR&&!bD) dir=Direction.RU;
206         else if(!bL&&!bU&&bR&&!bD) dir=Direction.R;
207         else if(!bL&&!bU&&bR&&bD) dir=Direction.RD;
208         else if(!bL&&!bU&&!bR&&bD) dir=Direction.D;
209         else if(bL&&!bU&&!bR&&bD) dir=Direction.LD;
210         else if(!bL&&!bU&&!bR&&!bD) dir=Direction.STOP;
211     }
212     
213     void move(){ //移動
214         /*記錄上一步的位置*/
215         oldX = x;
216         oldY = y;
217         switch(dir){
218         case L:
219             x-=XSPEED;
220             break;
221         case LU:
222             x-=XSPEED;
223             y-=YSPEED;
224             break;
225         case U:
226             y-=YSPEED;
227             break;
228         case RU:
229             x+=XSPEED;
230             y-=YSPEED;
231             break;
232         case R:
233             x+=XSPEED;
234             break;
235         case RD:
236             x+=XSPEED;
237             y+=YSPEED;
238             break;
239         case D:
240             y+=YSPEED;
241             break;
242         case LD:
243             x-=XSPEED;
244             y+=YSPEED;
245             break;
246         case STOP:
247             break;
248         }
249         /*判斷坦克移動越界情況(游戲邊界)*/
250         if(x < 5)    x = 5;
251         if(y < 25)    y = 25;
252         if(x+Whith > tc.GAME_WIDTH-5)    x = tc.GAME_WIDTH-Whith-5;
253         if(y+Higth > tc.GAME_HEIGTH-5) y = tc.GAME_HEIGTH-Higth-5;
254         
255         if(dir != Direction.STOP)    //如果坦克不靜止就改變炮筒方向
256             ptDir = dir;
257         
258         /*敵方坦克自動移動*/
259         if(!good){
260             Direction[] dirs = Direction.values();    //將方向變量設為數組
261             if(step == 0){
262                 step = r.nextInt(12)+3;    //隨機移動步驟
263                 int randomNumber = r.nextInt(dirs.length);    //隨機移動方向
264                 dir = dirs[randomNumber];
265             }
266             step--;
267             if(r.nextInt(40)>30) this.fire();    //隨機是否發射炮彈
268         }
269     }
270     /*敵方坦克復活*/
271     public void fuhuo(){
272         if(tc.tanks.size() < 20)
273             while(true){
274                 int x = r.nextInt(700);
275                 int y = r.nextInt(500);
276                 Tank t = new Tank(x,y,false,Color.blue,Direction.D,tc);
277                 /*如果坦克與牆重合則重新隨機位置直到不重合為止才將新坦克加入集合*/
278                 if(t.getRect().intersects(tc.wall1.getRect())||t.getRect().intersects(tc.wall2.getRect())
279                         ||t.getRect().intersects(tc.wall3.getRect())
280                         ||t.getRect().intersects(tc.wall4.getRect())){
281                     continue;
282                 }
283                 else{
284                     tc.tanks.add(t);
285                     break;
286                 }
287         }
288     }
289     /*子彈發射*/
290     public void fire(){
291         int x = this.x + Whith/2 - Missile.Whith/2;    //控制子彈方向為坦克中間
292         int y = this.y + Higth/2 - Missile.Higth/2;
293         tc.missiles.add(new Missile(ptDir,color,x,y,good,tc)); //創建新的子彈類加入到子彈集合中
294     }
295     /*碰撞;獲取坦克的范圍*/
296     public Rectangle getRect(){
297         return new Rectangle(x,y,Whith,Higth);
298     }
299     /*回執上一步位置*/
300     private void stay(){
301         x = oldX;
302         y = oldY;
303     } 
304     /*如果撞牆,調用stay方法,返回上一步位置*/
305     public boolean hitWall(Wall w){ 
306         if(this.live&&this.getRect().intersects(w.getRect())){
307             this.stay();
308             return true;
309         }
310         return false;
311     }
312     /*坦克互相撞擊事件*/
313     public boolean hitTanks(List<Tank> tanks){ 
314         for(int i=0;i<tanks.size();i++){
315             Tank t=tanks.get(i);
316             if(this!=t){//自己與自己不可相撞
317                 /*如果相撞返回上一步位置*/
318                 if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){
319                     this.stay();
320                     t.stay();
321                     return true;
322                 }
323             }
324         }
325         return false;
326     }
327     /*帶開火方向的發射函數*/
328     public Missile fire(Direction dir){
329         if(!live) return null;
330         int x=this.x+Whith/2-Missile.Whith/2;
331         int y=this.y+Higth/2-Missile.Higth/2;
332         Missile m=new Missile(dir,color,x, y,good, this.tc);
333         tc.missiles.add(m);
334         return m;
335     }
336     /*超級射擊導彈*/
337     private void superFire(){
338         Direction[] dirs=Direction.values();
339         for(int i=0;i<8;i++){
340             fire(dirs[i]);//循環調用八個方向
341         }
342     }
343     /*新增血塊類*/
344     private class BloodBar{
345         /*畫血條*/
346         public void draw(Graphics g){
347             Color c=g.getColor();
348             g.setColor(Color.red);
349             g.drawRect(x, y-10, Whith, 10);
350             int w=Whith*Life/100;
351             g.fillRect(x, y-10, w, 10);
352             g.setColor(c);
353         }
354     }
355     /*吃血方法*/
356     public boolean eatBlood(Blood b){
357         if(this.live&&b.isLive()&&this.isGood()&&this.getRect().intersects(b.getRect())){
358             this.setLife(100);
359             b.setLive(false);
360             return true;
361         }
362         if(this.getRect().intersects(tc.wb.getRect()))
363             this.Life = 100;
364         return false;
365     }
366 }

 

Missile.java

  1 import java.awt.Color;
  2 import java.awt.Graphics;
  3 import java.awt.Rectangle;
  4 import java.util.List;
  5 
  6 public class Missile {
  7     /*子彈本身數據*/
  8     Tank.Direction dir;    //子彈方向
  9     Color c;    //子彈顏色
 10     int x,y;    //子彈位置
 11     public static final int XSPEED = 15;    //橫向移動速度
 12     public static final int YSPEED = 15;    //縱向移動速度
 13     public static final int Whith = 10;        //子彈寬
 14     public static final int Higth = 10;        //子彈高
 15     private boolean live = true;    //判斷子彈的存活
 16     private boolean good;    //判斷子彈和陣營
 17     
 18     private TankClient tc;//主類權限
 19     
 20 
 21     public Missile(Tank.Direction dir,Color c, int x, int y) {
 22         super();
 23             this.dir = dir;
 24             this.x = x;
 25             this.y = y;
 26             this.c = c;
 27     }
 28     public Missile(Tank.Direction dir,Color c, int x, int y,boolean good,TankClient tc){
 29         this(dir,c,x,y);
 30         this.good = good;
 31         this.tc = tc;
 32     }
 33     
 34     /*獲取子彈的存活*/
 35     public boolean isLive() {
 36         return live;
 37     }
 38     /*設置子彈的存活*/
 39     public void setLive(boolean live) {
 40         this.live = live;
 41     }
 42     public void draw(Graphics g){
 43         /*如果子彈死亡狀態將這個子彈在子彈集合中刪除*/
 44         if(!live){
 45             tc.missiles.remove(this);    //集合中刪除
 46             return;
 47         }
 48         /*先保存之前的畫筆顏色,畫完之後再還原畫筆顏色*/
 49         Color d = g.getColor();    //獲取當前畫筆顏色
 50         g.setColor(c);    //設置畫筆顏色為紅色
 51         /*畫子彈*/
 52         g.fillOval(x, y, Whith, Higth);    
 53         
 54         g.setColor(d);    //還原畫筆顏色
 55         move();    //移動
 56     }
 57     
 58     public void move(){
 59         /*判斷移動方向移動坦克位置*/
 60         switch(dir){
 61         case L:
 62             x-=XSPEED;
 63             break;
 64         case LU:
 65             x-=XSPEED;
 66             y-=YSPEED;
 67             break;
 68         case U:
 69             y-=YSPEED;
 70             break;
 71         case RU:
 72             x+=XSPEED;
 73             y-=YSPEED;
 74             break;
 75         case R:
 76             x+=XSPEED;
 77             break;
 78         case RD:
 79             x+=XSPEED;
 80             y+=YSPEED;
 81             break;
 82         case D:
 83             y+=YSPEED;
 84             break;
 85         case LD:
 86             x-=XSPEED;
 87             y+=YSPEED;
 88             break;
 89         case STOP:
 90             break;
 91         }
 92         /*判斷子彈的越界情況;出界則子彈死亡,在子彈集合中刪去*/
 93         if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGTH)
 94             live = false;
 95     }
 96     /*碰撞;獲取子彈的范圍*/
 97     public Rectangle getRect(){
 98         return new Rectangle(x,y,Whith,Higth);
 99     }
100     /*子彈與坦克碰撞過程*/
101     public boolean hitTank(Tank t){
102         /*如果子彈與坦克在同一范圍則子彈和坦克同時死亡;且子彈只能殺死對方坦克*/
103         if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()){
104             if(t.isGood()){ //好坦克
105                 /*我方坦克子彈射中會減少生命值,生命值0的時候會死亡*/
106                 t.setLife(t.getLife()-20);
107                 if(t.getLife()<=0) 
108                     t.setLive(false);
109             }else{ //壞坦克
110                 t.setLive(false);//死亡
111             }
112             this.live=false;//子彈死亡
113             tc.explode.add(new Explode(x, y, tc));//新建爆炸加入集合
114             return true;
115         }
116         return false;
117     }
118     /*循環坦克集合分別進行判斷子彈碰撞*/
119     public boolean hitTanks(List<Tank> tanks){
120         for    (int i = 0; i < tanks.size(); i++){
121             if(hitTank(tanks.get(i)))
122                 return true;
123         }
124         return false;
125     }
126     /*子彈與牆的碰撞過程*/
127     public boolean hitWall(Wall w){
128         /*如果子彈與牆的范圍重合子彈死亡*/
129         if(this.live&&this.getRect().intersects(w.getRect())){
130             this.live=false;    //子彈死亡
131             return true;
132         }
133         return false;
134     }
135 }

 

Wall.java

 1 import java.awt.Graphics;
 2 import java.awt.Rectangle;
 3 
 4 
 5 public class Wall {
 6     /*牆數據*/
 7     int x,y,w,h;    //位置和寬高
 8     private TankClient tc;    //主類權限
 9     
10     public Wall(int x, int y, int w, int h, TankClient tc) {
11         super();
12         this.x = x;
13         this.y = y;
14         this.w = w;
15         this.h = h;
16         this.tc = tc;
17     }
18     /*獲取牆的范圍*/
19     public Rectangle getRect(){
20         return new Rectangle(x,y,w,h);
21     }
22     /*畫牆*/
23     public void draw(Graphics  g){
24         g.fillRect(x, y, w, h);
25     }
26 }

 

Explode.java

import java.awt.Color;
import java.awt.Graphics;


public class Explode {
    /*坦克爆炸屬性*/
    int x,y;    //爆炸位置
    private boolean live = true;    //爆炸是否存在
    int step = 0;    //爆炸時間控制
    int [] diameter = new int[] {4, 7, 12, 18, 26, 32, 49, 56, 65, 77, 80, 50, 40, 30, 14, 6};//爆炸范圍
    
    private TankClient tc;    //主類權限
    public Explode(int x, int y, TankClient tc) {    
        super();
        this.x = x;
        this.y = y;
        this.tc = tc;
    }
    
    /*畫爆炸*/
    public void draw(Graphics g){
        if(!live) return;    //如果爆炸死亡狀態不畫結束
        /*如果爆炸時間結束爆炸不存在並在集合中刪除*/
        if(step == diameter.length){
            live = false;    //爆炸死亡
            step = 0;    //步驟時間歸0
            tc.explode.remove(this);    //集合中刪除
            return;
        }
        /*畫爆炸*/
        Color c = g.getColor();
        g.setColor(Color.orange);
        g.fillOval(x, y, diameter[step], diameter[step]);
        g.setColor(c);
        
        step++;
    }
    
}

 

Blood.java

 1 import java.awt.Color;
 2 import java.awt.Graphics;
 3 import java.awt.Rectangle;
 4 import java.util.Random;
 5 
 6 
 7 public class Blood {
 8     /*血塊數據*/
 9     int x, y, w, h;//血塊位置和大小
10     private TankClient tc;    //主類權限
11     private boolean live=true;//血塊的存活
12     private static Random r = new Random();//設置一個隨機值變量
13     /*獲取血塊的存活狀態*/
14     public boolean isLive() {
15         return live;
16     }
17     /*設置血塊的存活狀態*/
18     public void setLive(boolean live) {
19         this.live = live;
20     }
21     /*血塊位置初值隨機一個數值*/
22     public Blood(){
23         x=r.nextInt(600)+100;
24         y=r.nextInt(400)+100;
25         w=h=15;
26     }
27     /*畫血塊*/
28     public void draw(Graphics g){
29         if(!live) return;
30         Color c=g.getColor();
31         g.setColor(Color.magenta);
32         g.fillRect(x, y, w, h);
33         g.setColor(c);
34     }
35     /*釋放血塊*/
36     public void fh(){
37         if(!live){
38             x = r.nextInt(600)+100;
39             y = r.nextInt(400)+100;
40             live = true;
41         }
42     }
43     /*獲取血塊范圍*/
44     public Rectangle getRect(){
45         return new Rectangle(x, y, w, h);
46     }
47 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved