和李秀琪一起做了一个儿时玩的坦克大战的小游戏。

坦克大战的编程思想在主类开启一个线程,没50毫秒循环一次画方法(绘制整个界面内的所有东西)。

画的东西有敌我坦克(颜色区分)、子弹、墙、血块、爆炸。所以总共写出了几个类:Tank坦克类、Missile子弹类、Wall墙类、Blood血块类、TankClient主类。

在每一个类中均写有画方法实现本类属性的绘制功能。在主类中有键盘监听事件调用这Tank类的键盘监听事件。

通过键盘监听判断出对Tank做出相应的移动,而敌方Tank则是随机运动。并且每次刷新都有调用各类的碰撞方法,判断一些不该碰撞的对象的情况时做出处理。

而每个对象的创建例如子弹这些是在触发产生之后将新建子弹类加入一个子弹类集合之中,在绘制的时候判断集合中的数量进行绘制,出界或者打死坦克则在集合中删除。

其他类也均相似,不再详细说明。
代码中每步都注释有相应的解释。

  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 }
TankClient.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 }
Tank.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 }
136  
137 
138 Wall.java
Missile.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 }
Wall.java
 1 import java.awt.Color;
 2 import java.awt.Graphics;
 3  
 4  
 5 public class Explode {
 6   /*坦克爆炸属性*/
 7   int x,y;  //爆炸位置
 8   private boolean live = true;  //爆炸是否存在
 9   int step = 0;  //爆炸时间控制
10   int [] diameter = new int[] {4, 7, 12, 18, 26, 32, 49, 56, 65, 77, 80, 50, 40, 30, 14, 6};//爆炸范围
11    
12   private TankClient tc;  //主类权限
13   public Explode(int x, int y, TankClient tc) {  
14     super();
15     this.x = x;
16     this.y = y;
17     this.tc = tc;
18   }
19    
20   /*画爆炸*/
21   public void draw(Graphics g){
22     if(!live) return;  //如果爆炸死亡状态不画结束
23     /*如果爆炸时间结束爆炸不存在并在集合中删除*/
24     if(step == diameter.length){
25       live = false;  //爆炸死亡
26       step = 0;  //步骤时间归0
27       tc.explode.remove(this);  //集合中删除
28       return;
29     }
30     /*画爆炸*/
31     Color c = g.getColor();
32     g.setColor(Color.orange);
33     g.fillOval(x, y, diameter[step], diameter[step]);
34     g.setColor(c);
35      
36     step++;
37   }
38    
39 }
Explode.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 }
Blood.java

约定规范:

1用Java语言编写程序

2两人共同完成

3要求代码清晰,符合代码编写的标准,尽量使代码简单直白

心得体会:

与人合作确实提高完成的速度和质量,而且可以互相交流,从中获益

时间:

2016/9/24 10:52