Java__线程---基础知识全面实战---坦克大战系列为例

简介: 今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战。

     今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战。

     每个程序版本代码中,都附有相关注释,看完注释大家就可以对本程序设计有个很明显的思路。真的很有趣,想对java重新温习的同学完全不必再对厚厚的java基础书籍进行阅读了,在跟着本次代码练习并分析后,大家一定会对java各方面基础知识 尤其是线程的知识有更深一步的了解!!!

     本次坦克大战系列的各个版本都是在一步步的升级改进,难度逐渐加大,功能愈加完善;话不多说,先给大家分享一下代码(●ˇ∀ˇ●)

Tank大战 version1.0

实现功能:
  1.绘制出我方Tank;

  2.可以通过键盘上下左右键 控制移动;

  1 package com.test;
  2 
  3 import java.awt.Color;
  4 import java.awt.Graphics;
  5 import java.awt.event.*;
  6 
  7 import javax.swing.*;
  8 
  9 
 10 public class MyTankGame extends JFrame {
 11     Mypanel mp=null;
 12     public static void main(String[] args) {
 13         // TODO 自动生成的方法存根
 14        MyTankGame mtg=new MyTankGame();
 15     }
 16     //构造函数
 17     public MyTankGame()
 18     {
 19         mp=new Mypanel();
 20         this.add(mp);
 21         this.setSize(800,600);
 22         this.setVisible(true);
 23         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 24         
 25     }
 26 
 27 }
 28 
 29 //坦克类
 30 class Tank
 31 {
 32      //表示坦克横坐标
 33     int x=0;
 34     public int getX() {
 35         return x;
 36     }
 37 
 38     public void setX(int x) {
 39         this.x = x;
 40     }
 41 
 42     public int getY() {
 43         return y;
 44     }
 45 
 46     public void setY(int y) {
 47         this.y = y;
 48     }
 49 
 50     //表示坦克纵坐标
 51     int y=0;
 52     
 53     public Tank(int x,int y)
 54     {
 55         this.x=x;
 56         this.y=y;
 57     }
 58 }
 59 
 60 //我的Tank
 61 class Hero extends Tank
 62 {
 63 
 64     public Hero(int x, int y) {
 65         super(x, y);
 66         // TODO 自动生成的构造函数存根
 67     }
 68     
 69 }
 70 
 71 
 72 //我的面板
 73 class Mypanel extends JPanel
 74 {
 75     //定义一个我的坦克
 76     Hero hero=null;
 77     
 78     //构造函数
 79     public Mypanel()
 80     {
 81         hero=new Hero(100,100);
 82     }
 83     public void paint(Graphics g)
 84     {
 85         super.paint(g);
 86         //设置面板背景色,全部填充即可,默认为黑色
 87         g.fillRect(0, 0, 800, 600);
 88         //画出我的tank,放到paint函数中
 89         this.DrawTank(hero.getX(), hero.getY(), g,0,0);//hero.getX(), hero.getY()就将x,y传过去了
 90     }
 91     
 92     //画出tank
 93     public void DrawTank(int x,int y,Graphics g,int direct,int type)
 94     {
 95         //判断是什么类型坦克
 96         switch(type)
 97         {
 98         case 0://我的tank
 99             g.setColor(Color.cyan);
100             break;
101         case 1://敌人的tank
102             g.setColor(Color.orange);
103             break;
104         }
105         //判断坦克的方向
106         switch(direct)
107         {
108         //向上
109         case 0:
110             //画出左边矩形
111             g.fill3DRect(x, y, 5, 30, false);
112             //画出右边矩形
113             g.fill3DRect(x+15, y, 5, 30, false);
114             //画出中间矩形
115             g.fill3DRect(x+5, y+5, 10, 20, false);
116             //画出中间圆形
117             g.fillOval(x+5, y+10, 10, 10);
118             //画出中间直线
119             g.fillRect(x+9, y, 2, 10);
120             break;
121         }
122     }
123 }
124 
125 /*
126                           画出左边矩形
127             g.fill3DRect(hero.getX(), hero.getY(), 5, 30, false);
128             //画出右边矩形
129             g.fill3DRect(hero.getX()+15, hero.getY(), 5, 30, false);
130             //画出中间矩形
131             g.fill3DRect(hero.getX()+5, hero.getY()+5, 10, 20, false);
132             //画出中间圆形
133             g.fillOval(hero.getX()+5, hero.getY()+10, 10, 10);
134             //画出中间直线
135             g.drawLine(hero.getX()+10, hero.getY()+15, 10, 20);
136             break;
137 
138  */
139  

 

Tank大战 version2.0

java练习---->坦克大战2.0------>引入多线程

实现功能:
  1.有敌方tank与我方tank;

  2.我方tank可以控制移动;

  3.我方tank可以发射炮弹;

  4.敌方tank未作处理;

  1 package TankGame2;
  2 
  3 import java.awt.*;
  4 import java.awt.event.KeyEvent;
  5 import java.awt.event.KeyListener;
  6 import java.util.*;
  7 import javax.swing.*;
  8 public class MyTankGame2  extends JFrame
  9 {
 10  MyPanel mp=null;
 11  public static void main(String[] args)
 12  {
 13   MyTankGame2 mytankgame1=new MyTankGame2();  
 14  }
 15  
 16  public MyTankGame2()
 17  {
 18   mp=new MyPanel();
 19   //启动mp线程
 20   
 21   Thread t=new Thread(mp);
 22   t.start();
 23   
 24   this.add(mp);
 25   this.addKeyListener(mp);
 26   
 27   this.setSize(400,300);
 28   this.setVisible(true);
 29   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
 30  }
 31 }
 32 
 33 
 34 class MyPanel extends JPanel implements KeyListener,Runnable
 35 {
 36  //定义我的坦克,成员变量
 37  Hero hero=null;
 38  
 39  //定义敌人的坦克组
 40  
 41  Vector<EnemyTank> ets=new Vector<EnemyTank>();
 42  int enSize=3;
 43  
 44  public void paint (Graphics g)
 45  {
 46    super.paint(g);
 47    g.fillRect(0,0,400,300);
 48   
 49    //画出自己的坦克
 50    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
 51   
 52    //画出子弹
 53    if (hero.s!=null&&hero.s.isLive==true)
 54    {
 55     g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false);
 56    
 57    }
 58   
 59   
 60    //画出敌人的坦克
 61    for(int i=0;i<ets.size();i++)
 62    {
 63    
 64     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
 65    
 66    }
 67  
 68  }
 69  
 70  //画出坦克函数(扩展)
 71  public void drawTank(int x,int y,Graphics g,int direct,int type)
 72  {
 73   //判断类型
 74   switch (type)
 75   {
 76   case 0:
 77    g.setColor(Color.cyan);break;
 78   case 1:
 79    g.setColor(Color.yellow);break;  
 80   }
 81   //判断方向
 82   
 83   switch(direct)
 84   {
 85   //向上
 86   case 0:
 87     //画出我的坦克(到时候再封装成一个函数)
 88     //1.画出左面的矩形
 89     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
 90     g.fill3DRect(x,y,5,30,false);
 91    
 92     //2.画出右边的矩形
 93     g.fill3DRect(x+15,y,5,30,false);
 94    
 95     //3.画出坦克的中间矩形
 96     g.fill3DRect(x+5, y+5, 10, 20,false);
 97     //画出中间的圆
 98     g.fillOval(x+4, y+10,10,10);
 99     //画出线
100     g.drawLine(x+9, y+15, x+9, y);
101     break; 
102   case 1:
103    //炮筒向右
104    //画出上面的矩形
105    g.fill3DRect(x,y,30, 5, false);
106    g.fill3DRect(x, y+15, 30, 5, false);
107    g.fill3DRect(x+5, y+5, 20, 10, false);
108    g.fillOval(x+10, y+5, 10, 10);
109    g.drawLine(x+15, y+10, x+30, y+10);
110    
111    break;
112   case 2:
113    //向下
114    g.fill3DRect(x,y,5,30,false);
115    g.fill3DRect(x+15,y,5,30,false);
116    g.fill3DRect(x+5, y+5, 10, 20,false);
117    g.fillOval(x+4, y+10,10,10);
118    g.drawLine(x+10, y+15, x+10, y+30);
119    break;
120    
121   case 3:
122    //向左  
123    g.fill3DRect(x,y,30, 5, false);
124    g.fill3DRect(x, y+15, 30, 5, false);
125    g.fill3DRect(x+5, y+5, 20, 10, false);
126    g.fillOval(x+10, y+5, 10, 10);
127    g.drawLine(x+15, y+10, x, y+10);
128    break;   
129   } 
130   
131  }
132  
133  
134  public MyPanel()
135  {
136   hero=new Hero(100,100);
137   
138   //初始化敌人的坦克
139   for(int i=0;i<enSize;i++)
140   {
141    //创建敌人的坦克对象   
142    EnemyTank et=new EnemyTank((i+1)*50,0);
143    et.setColor(0);
144    et.setDirect(2);
145    ets.add(et);   
146   }
147   
148  }
149  
150  //键按下处理a表示左,s表示向下,w表示向上,d表示向右
151  public void keyPressed(KeyEvent e)
152  {
153   if(e.getKeyCode()==KeyEvent.VK_UP)
154   {
155    // 设置我的坦克的方向
156    this.hero.setDirect(0); 
157    this.hero.moveUp();
158   }
159  
160   else if (e.getKeyCode()==KeyEvent.VK_DOWN)
161   {
162    this.hero.setDirect(2);   
163    this.hero.moveDown();   
164   }
165  
166   else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
167   {
168    this.hero.setDirect(1);   
169    this.hero.moveRight();
170    
171   }  
172   else if (e.getKeyCode()==KeyEvent.VK_LEFT)
173   {
174    this.hero.setDirect(3);   
175    this.hero.moveLeft();   
176   }
177   
178   if (e.getKeyCode()==KeyEvent.VK_SPACE)
179   {
180    this.hero.shotEnemy();
181    
182   }
183   
184  
185   //必须重新绘制Panel
186   this.repaint(); 
187  }
188  
189  public void keyReleased(KeyEvent e)                      //有什么用?!!!!!!!!!!!
190  {
191   
192  }
193  public void keyTyped(KeyEvent e)
194  {
195   
196  }
197  public void run()
198  {
199  //每个一百毫秒去重画子弹
200   while(true)
201   {
202    try {
203     Thread.sleep(100);
204    } catch (InterruptedException e) {
205     // TODO Auto-generated catch block
206     e.printStackTrace();
207    }
208    this.repaint();
209    
210   }
211  }
212   
213 }
214 
215
216 class Tank
217 {
218  
219  //设置坦克的速度
220  int speed=1;
221  public int getSpeed()
222  {
223   return speed;
224  }
225  public void setSpeed(int speed)
226  {
227   this.speed = speed;
228  }
229  //表示坦克的横坐标
230  int x=0;
231  //坦克的纵坐标
232  int y=0;
233  int direct=0;
234  int color;
235  
236  //坦克方向,0表示上,1表示右,2表示下,3表示左
237  public int getColor() {
238   return color;
239  }
240  public void setColor(int color) {
241   this.color = color;
242  }
243  public int getDirect()
244  {
245   return direct;
246  }
247  
248  public void setDirect(int direct)
249  {
250   this.direct = direct;
251  }
252  public Tank(int x,int y)
253  {
254   this.x=x;
255   this.y=y;  
256  }
257  
258  public int getX()
259  {
260   return x;
261  }
262  public void setX(int x)
263  {
264   this.x = x;
265  }
266  public int getY()
267  {
268   return y;
269  }
270  public void setY(int y)
271  {
272   this.y = y;
273  }
274  
275 }
276 
277 class EnemyTank extends Tank
278 {
279  public EnemyTank(int x,int y)
280  {
281   super(x,y);                                                            //super的用法???
282   
283  }
284 }
285  
286 
287 //我的坦克
288 class Hero extends Tank
289 {
290  //子弹
291  Shot s=null;
292  public Hero(int x, int y)
293  {
294   super(x,y);
295  }
296  //坦克向上移动
297  
298  //坦克的开火的能力和动作
299  public void shotEnemy()
300  {
301   switch(this.direct)
302   {
303    case 0:
304     s=new Shot(x+9,y-1,0);
305     break;
306    case 1:
307     s=new Shot(x+30,y+10,1);
308     break;
309    case 2:
310     s=new Shot(x+9,y+30,2);
311     break;
312    case 3:
313     s=new Shot(x-1,y+9,3);
314     break;
315   }
316  
317   Thread t=new Thread(s);
318   t.start();
319   
320  }
321  
322  
323  public void moveUp()
324  {
325   this.y-=speed;  
326  }
327  public void moveRight()
328  {
329   this.x+=speed;  
330  }
331  
332  public void moveDown()
333  {
334   this.y+=speed;  
335  } 
336  public void moveLeft()
337  {
338   this.x-=speed;  
339  } 
340 }
341 
342 
343 class Shot implements Runnable                                        //runnable的用法????
344 {
345  int x;
346  int y;
347  int direct;
348  int speed=1;
349  //是否活着
350  
351  boolean isLive=true;
352  public  Shot(int x,int y,int direct)
353  {
354   this.x=x;
355   this.y=y;
356   this.direct=direct;
357  }
358  public void run()
359  {
360   while(true)
361   {
362    try {
363     Thread.sleep(50);
364    } catch (InterruptedException e) {
365     e.printStackTrace();
366    }
367    
368    switch(direct)
369    {
370    case 0:
371    //向上
372     y-=speed;break;
373    case 1:
374     x+=speed;break;
375    case 2:
376     y+=speed;break;
377    case 3:
378     x-=speed;break;    
379    
380    }
381    
382    383    //判断该子弹是否碰到边缘
384    if(x<0||x>400||y<0||y>300)
385    {
386     this.isLive=false;
387     break;
388     
389    }
390    
391   }
392   
393  }
394 }

 

Tank大战 version3.0

java练习---->坦克大战3.0

实现功能:
  1.有敌方tank与我方tank;

  2.我方tank可以控制移动,可以发射炮弹;

  3.写一个函数专门判断子弹是否击中敌人坦克;

  4.判断tank是否活着;

(注:本版本中,Tank是不可以发射炮弹的······)

  1 package TankGame3;
  2 
  3 import java.awt.*;
  4 import java.awt.event.KeyEvent;
  5 import java.awt.event.KeyListener;
  6 import java.util.*;
  7 import javax.swing.*;
  8 import java.util.Vector;
  9 public class MyTankGame4  extends JFrame
 10 {
 11  MyPanel mp=null;
 12  public static void main(String[] args)
 13  {
 14   MyTankGame4 mytankgame1=new MyTankGame4();  
 15  }
 16  
 17  public MyTankGame4()
 18  {
 19   mp=new MyPanel();
 20   //启动mp线程
 21   
 22   Thread t=new Thread(mp);
 23   t.start();
 24   
 25   this.add(mp);
 26   this.addKeyListener(mp);
 27   
 28   this.setSize(400,300);
 29   this.setVisible(true);
 30   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
 31  }
 32 }
 33 class MyPanel extends JPanel implements KeyListener,Runnable
 34 {
 35  //定义我的坦克,成员变量
 36  Hero hero=null;
 37  
 38  //定义敌人的坦克组
 39  
 40  Vector<EnemyTank> ets=new Vector<EnemyTank>();
 41  int enSize=3;
 42  
 43  public void paint (Graphics g)
 44  {
 45    super.paint(g);
 46    g.fillRect(0,0,400,300);
 47   
 48    //画出自己的坦克
 49    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
 50   
 51    //从Vector ss中取出每一颗子弹,并画出
 52    for(int i=0;i<this.hero.ss.size();i++)
 53    {
 54     Shot myShot=hero.ss.get(i);   
 55   
 56   
 57     //画出子弹,只画一颗子弹
 58     if (myShot!=null&&myShot.isLive==true)
 59     {
 60      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
 61     
 62     }
 63     if (myShot.isLive==false)
 64     {
 65      //从ss中删除该子弹
 66      hero.ss.remove(myShot);
 67     
 68     }
 69    }
 70   
 71    //画出敌人的坦克
 72    for(int i=0;i<ets.size();i++)
 73    {
 74     EnemyTank et=ets.get(i);
 75     if(et.isLive) 
 76     {
 77     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
 78     }
 79    }
 80  
 81  }
 82  
 83  //写一个函数专门判断子弹是否击中敌人坦克
 84  public void hitTank(Shot s,EnemyTank et)
 85  {
 86   //判断该坦克的方向
 87   switch(et.direct)
 88   {
 89   //如果敌人的方向是上或者是下
 90   case 0:
 91   case 2:
 92    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
 93    {
 94     //击中了
 95     //子弹死亡
 96     s.isLive=false;
 97      //敌人坦克也要死亡
 98     et.isLive=false;
 99    }
100   case 1:
101   case 3:
102    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
103    {
104     //击中了
105     //子弹死亡
106     s.isLive=false;
107      //敌人坦克也要死亡
108     et.isLive=false;
109     
110    }
111   
112   }
113   
114  }
115  
116  //画出坦克函数(扩展)
117  public void drawTank(int x,int y,Graphics g,int direct,int type)
118  {
119   //判断类型
120   switch (type)
121   {
122   case 0:
123    g.setColor(Color.cyan);break;
124   case 1:
125    g.setColor(Color.yellow);break;  
126   }
127   //判断方向
128   
129   switch(direct)
130   {
131   //向上
132   case 0:
133     //画出我的坦克(到时候再封装成一个函数)
134     //1.画出左面的矩形
135     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
136     g.fill3DRect(x,y,5,30,false);
137    
138     //2.画出右边的矩形
139     g.fill3DRect(x+15,y,5,30,false);
140    
141     //3.画出坦克的中间矩形
142     g.fill3DRect(x+5, y+5, 10, 20,false);
143     //画出中间的圆
144     g.fillOval(x+4, y+10,10,10);
145     //画出线
146     g.drawLine(x+9, y+15, x+9, y);
147     break; 
148   case 1:
149    //炮筒向右
150    //画出上面的矩形
151    g.fill3DRect(x,y,30, 5, false);
152    g.fill3DRect(x, y+15, 30, 5, false);
153    g.fill3DRect(x+5, y+5, 20, 10, false);
154    g.fillOval(x+10, y+5, 10, 10);
155    g.drawLine(x+15, y+10, x+30, y+10);
156    
157    break;
158   case 2:
159    //向下
160    g.fill3DRect(x,y,5,30,false);
161    g.fill3DRect(x+15,y,5,30,false);
162    g.fill3DRect(x+5, y+5, 10, 20,false);
163    g.fillOval(x+4, y+10,10,10);
164    g.drawLine(x+10, y+15, x+10, y+30);
165    break;
166    
167   case 3:
168    //向左  
169    g.fill3DRect(x,y,30, 5, false);
170    g.fill3DRect(x, y+15, 30, 5, false);
171    g.fill3DRect(x+5, y+5, 20, 10, false);
172    g.fillOval(x+10, y+5, 10, 10);
173    g.drawLine(x+15, y+10, x, y+10);
174    break;   
175   } 
176   
177  }
178  
179  
180  public MyPanel()
181  {
182   hero=new Hero(100,100);
183   
184   //初始化敌人的坦克
185   for(int i=0;i<enSize;i++)
186   {
187    //创建敌人的坦克对象   
188    EnemyTank et=new EnemyTank((i+1)*50,0);
189    et.setColor(0);
190    et.setDirect(2);
191    ets.add(et);   
192   }
193   
194  }
195  
196  //键按下处理a表示左,s表示向下,w表示向上,d表示向右
197  public void keyPressed(KeyEvent e)
198  {
199   if(e.getKeyCode()==KeyEvent.VK_W)
200   {
201    // 设置我的坦克的方向
202    this.hero.setDirect(0); 
203    this.hero.moveUp();
204   }
205  
206   else if (e.getKeyCode()==KeyEvent.VK_S)
207   {
208    this.hero.setDirect(2);   
209    this.hero.moveDown();   
210   }
211  
212   else if (e.getKeyCode()==KeyEvent.VK_D)
213   {
214    this.hero.setDirect(1);   
215    this.hero.moveRight();
216    
217   }  
218   else if (e.getKeyCode()==KeyEvent.VK_A)
219   {
220    this.hero.setDirect(3);   
221    this.hero.moveLeft();   
222   }
223   
224   if (e.getKeyCode()==KeyEvent.VK_J)
225   {   
226    this.hero.shotEnemy();   
227   }  
228  
229   //必须重新绘制Panel
230   this.repaint(); 
231  }
232  public void keyReleased(KeyEvent e)
233  {
234   
235  }
236  public void keyTyped(KeyEvent e)
237  {
238   
239  }
240  public void run()
241  {
242  //每个一百毫秒去重画子弹
243   while(true)
244   {
245    try {
246     Thread.sleep(100);
247    } catch (InterruptedException e) {
248     // TODO Auto-generated catch block
249     e.printStackTrace();
250    }
251    
252    for(int i=0;i<hero.ss.size();i++)
253    {
254     Shot myShot=hero.ss.get(i);
255     //判断子弹是否有效
256     if(myShot.isLive)
257     {
258      //取出每个坦克,与它判断
259      for(int j=0;j<ets.size();j++)
260      {
261       //取出坦克
262       EnemyTank et=ets.get(j);
263       if(et.isLive)
264       {
265        this.hitTank(myShot,et);
266        
267       }
268       
269      }
270      
271     }
272    }
273    
274    this.repaint();
275    
276   }
277  }
278   
279 }
280 
281 //package MyTankGame4;
282 //import java.util.Vector;
283 //import MyTankGame4.Shot;
284 //import MyTankGame4.Tank;
285 class Tank
286 {
287  
288  //设置坦克的速度
289  int speed=1;
290  public int getSpeed()
291  {
292   return speed;
293  }
294  public void setSpeed(int speed)
295  {
296   this.speed = speed;
297  }
298  //表示坦克的横坐标
299  int x=0;
300  //坦克的纵坐标
301  int y=0;
302  int direct=0;
303  int color;
304  
305  //坦克方向,0表示上,1表示右,2表示下,3表示左
306  public int getColor() {
307   return color;
308  }
309  public void setColor(int color) {
310   this.color = color;
311  }
312  public int getDirect()
313  {
314   return direct;
315  }
316  
317  public void setDirect(int direct)
318  {
319   this.direct = direct;
320  }
321  public Tank(int x,int y)
322  {
323   this.x=x;
324   this.y=y;  
325  }
326  
327  public int getX()
328  {
329   return x;
330  }
331  public void setX(int x)
332  {
333   this.x = x;
334  }
335  public int getY()
336  {
337   return y;
338  }
339  public void setY(int y)
340  {
341   this.y = y;
342  }
343  
344 }
345 
346 class EnemyTank extends Tank
347 {
348  boolean isLive=true;
349  public EnemyTank(int x,int y)
350  {
351   super(x,y);
352   
353  }
354 }
355  
356 
357 //我的坦克
358 class Hero extends Tank
359 {
360  //子弹
361  //Shot s=null;
362  Vector<Shot>  ss=new Vector<Shot>();
363  Shot s=null;
364  
365  public Hero(int x, int y)
366  {
367   super(x,y);
368  }
369  //坦克向上移动
370  
371  //坦克的开火的能力和动作
372  public void shotEnemy()
373  {
374   switch(this.direct)
375   {
376    case 0:
377     s=new Shot(x+9,y-1,0);
378     ss.add(s);
379     break;
380    case 1:
381     s=new Shot(x+30,y+10,1);
382     ss.add(s);
383     break;
384    case 2:
385     s=new Shot(x+9,y+30,2);
386     ss.add(s);
387     break;
388    case 3:
389     s=new Shot(x-1,y+9,3);     ss.add(s);
390     ss.add(s);
391     break;
392   }
393  
394   Thread t=new Thread(s);
395   t.start();
396   
397  }
398  
399  
400  public void moveUp()
401  {
402   this.y-=speed;  
403  }
404  public void moveRight()
405  {
406   this.x+=speed;  
407  }
408  
409  public void moveDown()
410  {
411   this.y+=speed;  
412  } 
413  public void moveLeft()
414  {
415   this.x-=speed;  
416  } 
417 }
418 class Shot implements Runnable
419 {
420  int x;
421  int y;
422  int direct;
423  int speed=1;
424  //是否活着
425  
426  boolean isLive=true;
427  public  Shot(int x,int y,int direct)
428  {
429   this.x=x;
430   this.y=y;
431   this.direct=direct;
432  }
433  public void run()
434  {
435   while(true)
436   {
437    try {
438     Thread.sleep(50);
439    } catch (InterruptedException e) {
440     e.printStackTrace();
441    }
442    
443    switch(direct)
444    {
445    case 0:
446    //向上
447     y-=speed;break;
448    case 1:
449     x+=speed;break;
450    case 2:
451     y+=speed;break;
452    case 3:
453     x-=speed;break;    
454    
455    }
456    
457    //判断该子弹是否碰到边缘
458    if(x<0||x>400||y<0||y>300)
459    {
460     this.isLive=false;
461     break;
462     
463    }
464    
465   }
466   
467  }
468 }

 

Tank大战 version4.0

java练习---->坦克大战4.0

实现功能:
  1.有敌方tank与我方tank;

  2.双方都可以控制移动,可以发射炮弹;

  3.敌方坦克可以被击中消失

  4.有爆炸效果;

  5.可以计算生命值和炸弹生命;

  1 package TankGame4;
  2 //package MyTankGame4;
  3 import java.util.Vector;
  4 import java.awt.*;
  5 import java.awt.event.KeyEvent;
  6 import java.awt.event.KeyListener;
  7 import java.util.*;
  8 import javax.swing.*;
  9 public class MyTankGame4  extends JFrame
 10 {
 11  MyPanel mp=null;
 12  public static void main(String[] args)
 13  {
 14   MyTankGame4 mytankgame1=new MyTankGame4();  
 15  }
 16  
 17  public MyTankGame4()
 18  {
 19   mp=new MyPanel();
 20   //启动mp线程
 21   
 22   Thread t=new Thread(mp);
 23   
 24   t.start();
 25   
 26   this.add(mp);
 27   this.addKeyListener(mp);
 28   
 29   this.setSize(400,300);
 30   this.setVisible(true);
 31   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
 32  }
 33 }
 34 class MyPanel extends JPanel implements KeyListener,Runnable
 35 {
 36  //定义我的坦克,成员变量
 37  Hero hero=null;
 38  
 39  //定义敌人的坦克组
 40  
 41  Vector<EnemyTank> ets=new Vector<EnemyTank>();
 42  int enSize=5;
 43  
 44  //定义炸弹集合
 45  Vector<Bomb> bombs=new Vector<Bomb>();
 46  
 47  public void run()
 48  {
 49  //每个一百毫秒去重画子弹
 50   while(true)
 51   {
 52    try {
 53     Thread.sleep(100);
 54    } catch (InterruptedException e) {
 55     // TODO Auto-generated catch block
 56     e.printStackTrace();
 57    }
 58    
 59    for(int i=0;i<hero.ss.size();i++)
 60    {
 61     Shot myShot=hero.ss.get(i);
 62     //判断子弹是否有效
 63     if(myShot.isLive)
 64     {
 65      //取出每个坦克,与它判断
 66      for(int j=0;j<ets.size();j++)
 67      {
 68       //取出坦克
 69       EnemyTank et=ets.get(j);
 70       if(et.isLive)
 71       {
 72        this.hitTank(myShot,et);
 73        
 74       }      
 75      }
 76      
 77     }
 78    }
 79    
 80    this.repaint();
 81    //判断是否需要给坦克加入新的子弹
 82    for(int i=0;i<ets.size();i++)
 83    {
 84     EnemyTank et=ets.get(i);
 85     if(et.isLive)
 86     {
 87      if (et.ss.size()<5&&(int)(100*Math.random())>75)
 88      {
 89       //每辆坦克的子弹少于5发的话
 90       //添加
 91       Shot s=null;
 92       switch(et.direct)
 93       {
 94       case 0:
 95        s=new Shot(et.x+9,et.y-1,0);
 96        et.ss.add(s);
 97        break;
 98       case 1:
 99        s=new Shot(et.x+30,et.y+10,1);
100        et.ss.add(s);
101        break;
102       case 2:
103        s=new Shot(et.x+9,et.y+30,2);
104        et.ss.add(s);
105        break;
106       case 3:
107        s=new Shot(et.x-1,et.y+9,3);    
108        et.ss.add(s);
109        break;            
110       }
111       
112       //启动子弹线程
113       Thread t=new Thread(s);
114       t.start();
115       
116      }
117   
118     }
119    }
120    
121   }
122  
123  }
124  
125  public void paint (Graphics g)
126  {
127    super.paint(g);
128    g.fillRect(0,0,400,300);
129   
130    //画出自己的坦克
131    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
132   
133    //从Vector ss中取出每一颗子弹,并画出
134    for(int i=0;i<this.hero.ss.size();i++)
135    {
136     Shot myShot=hero.ss.get(i);   
137   
138   
139     //画出子弹,只画一颗子弹
140     if (myShot!=null&&myShot.isLive==true)
141     {
142      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
143     
144     }
145     if (myShot.isLive==false)
146     {
147      //从ss中删除该子弹
148      hero.ss.remove(myShot);
149     
150     }
151    }
152   
153    //画出炸弹
154    for(int i=0;i<bombs.size();i++)
155    {
156    // 取出炸弹
157    Bomb b=bombs.get(i);
158    
159    if(b.life>6)
160    {
161     g.drawImage(image1, b.x, b.y, 30,30,this);
162    }
163    else if(b.life>3)
164    {
165     g.drawImage(image2, b.x, b.y, 30,30,this);
166    }
167    else
168    {
169     g.drawImage(image3, b.x, b.y, 30,30,this);
170    }
171    //让b的生命值减小
172    b.lifeDown();
173    //如果炸弹的生命值为0,我们就剔除
174    if(b.life==0) bombs.remove(b);
175    
176    
177    }
178   
179   
180    //画出敌人的坦克
181    for(int i=0;i<ets.size();i++)
182    {
183     EnemyTank et=ets.get(i);
184     if(et.isLive) 
185     {
186     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
187     //画出敌人的子弹
188    
189     for(int j=0;j<et.ss.size();j++)
190     {
191      //取出子弹
192      Shot enemyShot=et.ss.get(j);
193      if(enemyShot.isLive)
194      {
195       g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
196      }
197      else
198      {
199      //如果敌人的坦克死亡就从Vector去掉
200       et.ss.remove(enemyShot);
201      
202      }
203      
204     }
205     }
206    }
207  
208  }
209  
210  //写一个函数专门判断子弹是否击中敌人坦克
211  public void hitTank(Shot s,EnemyTank et)
212  {
213   //判断该坦克的方向
214   switch(et.direct)
215   {
216   //如果敌人的方向是上或者是下
217   case 0:
218   case 2:
219    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
220    {
221     //击中了
222     //子弹死亡
223     s.isLive=false;
224      //敌人坦克也要死亡
225     et.isLive=false;
226     //创建一个炸弹,放入Vector
227     Bomb b=new Bomb(et.x,et.y);
228     //放入Vector
229     bombs.add(b);
230    }
231   case 1:
232   case 3:
233    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
234    {
235     //击中了
236     //子弹死亡
237     s.isLive=false;
238      //敌人坦克也要死亡
239     et.isLive=false;
240     //创建一个炸弹,放入Vector
241     Bomb b=new Bomb(et.x,et.y);
242     //放入Vector
243     bombs.add(b);    
244    }
245   
246   }
247   
248  }
249  
250  //画出坦克函数(扩展)
251  public void drawTank(int x,int y,Graphics g,int direct,int type)
252  {
253   //判断类型
254   switch (type)
255   {
256   case 0:
257    g.setColor(Color.cyan);break;
258   case 1:
259    g.setColor(Color.yellow);break;  
260   }
261   //判断方向
262   
263   switch(direct)
264   {
265   //向上
266   case 0:
267     //画出我的坦克(到时候再封装成一个函数)
268     //1.画出左面的矩形
269     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
270     g.fill3DRect(x,y,5,30,false);
271    
272     //2.画出右边的矩形
273     g.fill3DRect(x+15,y,5,30,false);
274    
275     //3.画出坦克的中间矩形
276     g.fill3DRect(x+5, y+5, 10, 20,false);
277     //画出中间的圆
278     g.fillOval(x+4, y+10,10,10);
279     //画出线
280     g.drawLine(x+9, y+15, x+9, y);
281     break; 
282   case 1:
283    //炮筒向右
284    //画出上面的矩形
285    g.fill3DRect(x,y,30, 5, false);
286    g.fill3DRect(x, y+15, 30, 5, false);
287    g.fill3DRect(x+5, y+5, 20, 10, false);
288    g.fillOval(x+10, y+5, 10, 10);
289    g.drawLine(x+15, y+10, x+30, y+10);
290    
291    break;
292   case 2:
293    //向下
294    g.fill3DRect(x,y,5,30,false);
295    g.fill3DRect(x+15,y,5,30,false);
296    g.fill3DRect(x+5, y+5, 10, 20,false);
297    g.fillOval(x+4, y+10,10,10);
298    g.drawLine(x+10, y+15, x+10, y+30);
299    break;
300    
301   case 3:
302    //向左  
303    g.fill3DRect(x,y,30, 5, false);
304    g.fill3DRect(x, y+15, 30, 5, false);
305    g.fill3DRect(x+5, y+5, 20, 10, false);
306    g.fillOval(x+10, y+5, 10, 10);
307    g.drawLine(x+15, y+10, x, y+10);
308    break;   
309   } 
310   
311  }
312  
313  //定义三张图片,三张图片切换组成一颗炸弹
314  Image image1=null;
315  Image image2=null;
316  Image image3=null;
317  
318  //构造函数
319  public MyPanel()
320  {
321   hero=new Hero(100,100);
322   
323   //初始化敌人的坦克
324   for(int i=0;i<enSize;i++)
325   {
326    //创建敌人的坦克对象   
327    EnemyTank et=new EnemyTank((i+1)*50,0);
328    et.setColor(0);
329    et.setDirect(2);
330    //启动敌人的坦克
331    
332    Thread t=new Thread(et);
333    t.start();
334    //给敌人坦克添加一颗子弹
335    Shot s=new Shot(et.x+10,et.y+30,2);
336    et.ss.add(s);
337    Thread t2=new Thread(s);
338    t2.start();
339    //加入
340    
341    ets.add(et);   
342   }
343   
344   image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));
345   image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
346   image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg"));
347   
348  }
349  
350 //键按下处理向左,向下,向上,向右
351 public void keyPressed(KeyEvent e)
352 {
353  if(e.getKeyCode()==KeyEvent.VK_UP)
354  {
355   // 设置我的坦克的方向
356   this.hero.setDirect(0); 
357   this.hero.moveUp();
358  }
359 
360  else if (e.getKeyCode()==KeyEvent.VK_DOWN)
361  {
362   this.hero.setDirect(2);   
363   this.hero.moveDown();   
364  }
365 
366  else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
367  {
368   this.hero.setDirect(1);   
369   this.hero.moveRight();
370   
371  }  
372  else if (e.getKeyCode()==KeyEvent.VK_LEFT)
373  {
374   this.hero.setDirect(3);   
375   this.hero.moveLeft();   
376  }
377  
378  if (e.getKeyCode()==KeyEvent.VK_J)
379  {
380   this.hero.shotEnemy();
381   
382  }
383   //必须重新绘制Panel
384   this.repaint(); 
385  }
386  public void keyReleased(KeyEvent e)
387  {
388   
389  }
390  public void keyTyped(KeyEvent e)
391  {
392   
393  }
394   
395 }
396  
397 
398 class Tank
399 {
400  
401  //设置坦克的速度
402  int speed=3;
403  public int getSpeed()
404  {
405   return speed;
406  }
407  public void setSpeed(int speed)
408  {
409   this.speed = speed;
410  }
411  //表示坦克的横坐标
412  int x=0;
413  //坦克的纵坐标
414  int y=0;
415  int direct=0;
416  int color;
417  
418  //坦克方向,0表示上,1表示右,2表示下,3表示左
419  public int getColor() {
420   return color;
421  }
422  public void setColor(int color) {
423   this.color = color;
424  }
425  public int getDirect()
426  {
427   return direct;
428  }
429  
430  public void setDirect(int direct)
431  {
432   this.direct = direct;
433  }
434  public Tank(int x,int y)
435  {
436   this.x=x;
437   this.y=y;  
438  }
439  
440  public int getX()
441  {
442   return x;
443  }
444  public void setX(int x)
445  {
446   this.x = x;
447  }
448  public int getY()
449  {
450   return y;
451  }
452  public void setY(int y)
453  {
454   this.y = y;
455  }
456  
457 }
458 
459 class EnemyTank extends Tank implements Runnable
460 {
461  boolean isLive=true;
462  
463  //定义一个向量,可以存放敌人的子弹
464  
465  Vector<Shot> ss=new Vector<Shot>();
466  //敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后
467  
468  
469  
470  public EnemyTank(int x,int y)
471  {
472   super(x,y);
473   
474  }
475  public void run() {
476   while(true)
477   {  //移动前进
478    switch(this.direct)
479    {
480    case 0:
481     for(int i=0;i<(int)(100*Math.random());i++)
482     {
483      try
484      {
485       Thread.sleep(50);  
486      }
487      catch (Exception e)
488      {
489       e.printStackTrace();
490      }
491      if(y>=speed)
492      {
493       y-=speed;
494      }
495     }
496     break;
497    case 1:
498     for(int i=0;i<(int)(100*Math.random());i++)
499     {
500      try
501      {
502       Thread.sleep(50);  
503      }
504      catch (Exception e)
505      {
506       e.printStackTrace();
507      }
508      if(x<=400-(speed+30))
509      {
510       x+=speed;
511      }
512     }
513     break;
514    case 2:
515     for(int i=0;i<(int)(100*Math.random());i++)
516     {
517      try
518      {
519       Thread.sleep(50);  
520      }
521      catch (Exception e)
522      {
523       e.printStackTrace();
524      }
525      if(y<=300-(speed+30))
526      {
527       y+=speed;
528      }
529     }
530     break;
531    case 3:
532     for(int i=0;i<(int)(100*Math.random());i++)
533     {
534      try
535      {
536       Thread.sleep(50);  
537      }
538      catch (Exception e)
539      {
540       e.printStackTrace();
541      }
542      if(x>=speed)
543      {
544       x-=speed;
545      }
546     
547     }
548     break;
549     
550    }
551    
552    //让坦克随机产生一个新的方向
553    if(Math.random()>0.50)
554    this.direct=(int)(Math.random()*4);
555    
556    //判断敌人坦克是否死亡
557    if(this.isLive==false)
558    {
559     //让坦克死亡后,退出线程
560     break;
561    }
562    
563   }
564   
565  }
566 }
567  
568 
569 //我的坦克
570 class Hero extends Tank
571 {
572  //子弹
573  //Shot s=null;
574  Vector<Shot>  ss=new Vector<Shot>();
575  Shot s=null;
576  
577  public Hero(int x, int y)
578  {
579   super(x,y);
580  }
581  //坦克向上移动
582  
583  //坦克的开火的能力和动作
584  public void shotEnemy()
585  {
586   switch(this.direct)
587   {
588    case 0:
589     s=new Shot(x+9,y-1,0);
590     ss.add(s);
591     break;
592    case 1:
593     s=new Shot(x+30,y+10,1);
594     ss.add(s);
595     break;
596    case 2:
597     s=new Shot(x+9,y+30,2);
598     ss.add(s);
599     break;
600    case 3:
601     s=new Shot(x-1,y+9,3);     ss.add(s);
602     ss.add(s);
603     break;
604   }
605  
606   Thread t=new Thread(s);
607   t.start();
608   
609  }
610  
611  
612  public void moveUp()
613  {
614   this.y-=speed;  
615  }
616  public void moveRight()
617  {
618   this.x+=speed;  
619  }
620  
621  public void moveDown()
622  {
623   this.y+=speed;  
624  } 
625  public void moveLeft()
626  {
627   this.x-=speed;  
628  } 
629 }
630  
631 class Shot implements Runnable
632 {
633  int x;
634  int y;
635  int direct;
636  int speed=1;
637  //是否活着
638  
639  boolean isLive=true;
640  public  Shot(int x,int y,int direct)
641  {
642   this.x=x;
643   this.y=y;
644   this.direct=direct;
645  }
646  public void run()
647  {
648   while(true)
649   {
650    try {
651     Thread.sleep(50);
652    } catch (InterruptedException e) {
653     e.printStackTrace();
654    }
655    
656    switch(direct)
657    {
658    case 0:
659    //向上
660     y-=speed;break;
661    case 1:
662     x+=speed;break;
663    case 2:
664     y+=speed;break;
665    case 3:
666     x-=speed;break;    
667    
668    }
669    
670    //子弹何时死亡?
671    //判断该子弹是否碰到边缘
672    if(x<0||x>400||y<0||y>300)
673    {
674     this.isLive=false;
675     break;
676     
677    }
678    
679   }
680   
681  }
682 }
683 class Bomb
684 {
685  //定义炸弹的坐标
686  int x,y;
687  //炸弹的生命
688  int life=9;
689  boolean isLive=true;
690  public  Bomb(int x,int y)
691  {
692   this.x=x;
693   this.y=y;  
694  }
695  //减少生命值
696  public void lifeDown()
697  {
698   if(life >0) {life--;}
699   else {this.isLive=false;}
700   
701  }
702  
703 }

 

Tank大战 version5.0

java练习---->坦克大战5.0

实现功能:
  1.在原有基础啊上进行优化和功能完善;

  2.增加闯关功能等;

  3.完结版!!!!!

   1 package TankGame5;
   2 
   3 import java.awt.*;
   4 import java.awt.event.ActionEvent;
   5 import java.awt.event.ActionListener;
   6 import java.awt.event.KeyEvent;
   7 import java.awt.event.KeyListener;
   8 import java.io.BufferedReader;
   9 import java.io.BufferedWriter;
  10 import java.io.File;
  11 import java.io.FileReader;
  12 import java.io.FileWriter;
  13 import java.io.IOException;
  14 import java.util.*;
  15 import java.io.*;
  16 import java.util.Vector;
  17 import javax.imageio.ImageIO;
  18 import javax.swing.*;
  19 
  20 
  21 public class MyTankGame5  extends JFrame implements ActionListener
  22 {
  23     //声明一个标志
  24  int  flag=0;
  25 // 声明一个运行面板
  26  MyPanel mp=null;
  27  //定义一个开始的面板
  28  MyStartPanel msp=null;
  29  
  30  //做出我需要的菜单
  31  JMenuBar jmb=null;
  32  //开始游戏
  33  JMenu jm1=null;
  34  JMenuItem jmi1=null;
  35     //退出系统
  36  JMenuItem jmi2=null;
  37  JMenuItem jmi3=null;
  38  JMenuItem jmi4=null;
  39  
  40  public static void main(String[] args)
  41  {
  42   MyTankGame5 mytankgame1=new MyTankGame5(); 
  43   mytankgame1.setLocationRelativeTo(null);//将JFrame设置在中间
  44 //  mytankgame1.setLocation(210,140);//设置JFrame的位置
  45  }
  46  
  47  public MyTankGame5() //构造
  48  {//初始化菜单栏
  49   jmb=new JMenuBar();
  50   jm1=new JMenu("游戏(G)");
  51   
  52   //设置快捷方式
  53   jm1.setMnemonic('G');
  54   jmi1=new JMenuItem("开始新游戏(N)");
  55   jmi2=new JMenuItem("退出游戏(E)");
  56   jmi3=new JMenuItem("存盘退出(C)");
  57   jmi4=new JMenuItem("继续上次游戏(L)");
  58 
  59   jmi1.setMnemonic('N');
  60   jmi2.setMnemonic('E');
  61   jmi3.setMnemonic('C');
  62   jmi4.setMnemonic('L');
  63 
  64   //对jmi1响应,注册监听,标记消息源
  65   jmi1.addActionListener(this);
  66   jmi1.setActionCommand("new game");
  67   
  68   jmi2.addActionListener(this);
  69   jmi2.setActionCommand("exit");
  70   
  71   jmi3.addActionListener(this);
  72   jmi3.setActionCommand("save and exit");
  73   
  74   jmi4.addActionListener(this);
  75   jmi4.setActionCommand("continue game");
  76   
  77   jm1.add(jmi1);
  78   jm1.add(jmi2);
  79   jm1.add(jmi3);
  80   jm1.add(jmi4);
  81   jmb.add(jm1);
  82   
  83 //  声明初始化面板
  84     
  85   msp=new MyStartPanel();
  86   
  87   Thread t=new Thread(msp);
  88   t.start();
  89 //  初始化窗口,构造函数的重点
  90   this.setJMenuBar(jmb);//千万注意啊!!!!
  91   
  92   this.add(msp);
  93   this.setSize(400,300);
  94   this.setVisible(true);
  95   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
  96  }
  97  public void actionPerformed(ActionEvent e)
  98  {
  99   //对用户不同的点击做出不同的处理
 100 //     首先得到command字符串,判断消息源
 101   if(e.getActionCommand().equals("new game"))
 102   {
 103    this.setSize(600,500);
 104    mp=new MyPanel(flag);
 105    //启动mp线程
 106    
 107    Thread t1=new Thread(mp);
 108   
 109    t1.start();
 110    //先删除旧的面板
 111    this.remove(msp);
 112    
 113    this.add(mp);
 114    //注册监听
 115    this.addKeyListener(mp);
 116    //显示
 117    this.setVisible(true);
 118   }
 119   else if(e.getActionCommand().equals("exit"))
 120   {
 121    //用户退出   
 122    //保存击毁敌人数量
 123    Recorder.keepRecording();
 124    System.exit(0);   
 125   }
 126   
 127   else if(e.getActionCommand().equals("save and exit"))
 128   {
 129    Recorder.keepRecAndEnemyTank(mp.ets);
 130    if(this.mp.hero.isLive==true)
 131    {
 132     Recorder.keepRecAndMyTank(this.mp.hero);
 133     
 134    }
 135    System.exit(0);   
 136   }
 137   else if(e.getActionCommand().equals("continue game"))
 138   {
 139    this.setSize(600,500);
 140    flag=1;
 141    mp=new MyPanel(flag);
 142    //启动mp线程
 143    
 144    Thread t1=new Thread(mp);
 145   
 146    t1.start();
 147    //先删除旧的面板
 148    this.remove(msp);
 149    
 150    this.add(mp);
 151    //注册监听
 152    this.addKeyListener(mp);
 153    //显示
 154    this.setVisible(true);
 155   }
 156  }
 157 }
 158 
 159 
 160 //开始面板起一个提示的作用
 161 class MyStartPanel extends JPanel implements Runnable
 162 {
 163  int times=0;
 164  public void paint(Graphics g)
 165  {
 166   super.paint(g);
 167   g.fillRect(0, 0, 400, 300);
 168   //提示信息
 169   if(times%2==0)
 170   {
 171    g.setColor(Color.yellow);
 172    //开关信息的字体
 173    try{
 174    Font myFont=new Font("华文新魏",Font.BOLD,30);
 175    g.setFont(myFont);
 176    }   catch(Exception e){e.printStackTrace();}
 177    
 178    g.drawString("stage:1", 150, 150);
 179   }
 180  }
 181  public void run()
 182  {  
 183   while(true)
 184   {
 185    try {
 186     Thread.sleep(500);
 187    } catch (Exception e) {
 188     // TODO Auto-generated catch block
 189     e.printStackTrace();
 190    }
 191    this.repaint();
 192    times++;
 193    if(times==1000) times=0;
 194   }
 195  }
 196   
 197 }
 198 
 199 
 200 class MyPanel extends JPanel implements KeyListener,Runnable
 201 {
 202  //定义我的坦克,成员变量
 203  Hero hero=null;
 204  
 205  //判断是续上局还是新的游戏
 206  String flag="newGame";
 207   
 208  //定义敌人的坦克组
 209  
 210  Vector<EnemyTank> ets=new Vector<EnemyTank>();
 211 // 全局变量,声明,敌人坦克数量 
 212  static int enSize=5;
 213  public static int getEnSize() {
 214   return enSize;
 215  }
 216  //定义炸弹集合
 217  Vector<Bomb> bombs=new Vector<Bomb>();
 218 // paint 方法被面板适时自动调用
 219  public void paint (Graphics g)
 220  {
 221    super.paint(g);
 222    g.fillRect(0,0,400,300);
 223   
 224    //画出提示信息
 225    this.showInfo(g);
 226   
 227    //画出自己的坦克
 228    if(hero.isLive==true)
 229    {
 230    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
 231    }
 232    //从Vector ss中取出每一颗子弹,并画出,如果有子弹
 233    for(int i=0;i<this.hero.ss.size();i++)
 234    {
 235     Shot myShot=hero.ss.get(i);     
 236   
 237     //画出子弹,只画一颗子弹
 238     if (myShot!=null&&myShot.isLive==true)
 239     {
 240      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
 241     
 242     }
 243     if (myShot.isLive==false)
 244     {
 245      //从ss中删除该子弹
 246      hero.ss.remove(myShot);
 247     
 248     }
 249    }
 250   
 251    //画出炸弹
 252    for(int i=0;i<bombs.size();i++)
 253    {
 254    // 取出炸弹
 255    Bomb b=bombs.get(i);
 256    
 257    if(b.life>6)
 258    {
 259     g.drawOval(b.x, b.y, 30, 30);
 260 //       g.drawImage(image1, b.x, b.y, 30,30,this);
 261    }
 262    else if(b.life>3)
 263    {
 264        g.drawOval(b.x, b.y, 20, 20);
 265 //    g.drawImage(image2, b.x, b.y, 30,30,this);
 266  
 267    }
 268    else
 269    {
 270        g.drawOval(b.x, b.y, 10, 10);
 271 //    g.drawImage(image3, b.x, b.y, 30,30,this);
 272    }
 273    //让b的生命值减小
 274    b.lifeDown();
 275    //如果炸弹的生命值为0,我们就剔除
 276    if(b.life==0) bombs.remove(b);
 277       
 278    }
 279   
 280   
 281    //画出敌人的坦克
 282    for(int i=0;i<ets.size();i++)
 283    {
 284     EnemyTank et=ets.get(i);
 285     if(et.isLive) 
 286     {
 287     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
 288     //画出敌人的子弹
 289    
 290     for(int j=0;j<et.ss.size();j++)
 291     {
 292      //取出子弹
 293      Shot enemyShot=et.ss.get(j);
 294      if(enemyShot.isLive)
 295      {
 296       g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
 297      }
 298      else
 299      {
 300      //如果敌人的坦克死亡就从Vector去掉
 301       et.ss.remove(enemyShot);
 302      
 303      }
 304      
 305     }
 306     }
 307    }
 308  
 309  }
 310  //判断我是否被击中了
 311  public void hitMe()
 312  {
 313   //取出敌人的每一颗子弹
 314   
 315   for(int i=0;i<this.ets.size();i++)
 316   {
 317    //取出坦克
 318    EnemyTank et=ets.get(i);
 319    
 320    //取出每一颗子弹
 321    for (int j=0;j<et.ss.size();j++)
 322    {
 323     //取出子弹
 324     Shot enemyShot=et.ss.get(j);
 325     if(hero.isLive)//&&Recorder.getMyLife()>=1
 326     {
 327      this.hitTank(enemyShot, hero);  
 328      //Recorder.setMyLife(Recorder.getMyLife()-1);
 329     }
 330     
 331    }
 332    
 333   }
 334   
 335  }
 336  
 337  
 338  //判断我的子弹是否击中敌人的坦克
 339  public void hitEnemyTank()
 340  {
 341   for(int i=0;i<hero.ss.size();i++)
 342   {
 343    Shot myShot=hero.ss.get(i);
 344    //判断子弹是否有效
 345    if(myShot.isLive)
 346    {
 347     //取出每个坦克,与它判断
 348     for(int j=0;j<ets.size();j++)
 349     {
 350      //取出坦克
 351      EnemyTank et=ets.get(j);
 352      if(et.isLive)
 353      {
 354       this.hitTank(myShot,et);
 355       
 356      }      
 357     }
 358     
 359    }
 360   }
 361   
 362  }
 363 
 364  //写一个函数专门判断子弹是否击中敌人坦克
 365  public void hitTank(Shot s,Tank et)
 366  {
 367   //判断该坦克的方向
 368   switch(et.direct)
 369   {
 370   //如果敌人的方向是上或者是下
 371   case 0:
 372   case 2:
 373    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
 374    {
 375     //击中了
 376     //子弹死亡
 377     s.isLive=false;
 378      //敌人坦克也要死亡
 379     et.isLive=false;
 380     //减少敌人数量
 381     if (et.getClass()==EnemyTank.class)//反射机制
 382     {
 383      Recorder.reduceEnNum();
 384      //增加我的记录
 385      Recorder.addEnNumRec();
 386     }
 387     
 388     if (et.getClass()==Hero.class)//反射机制
 389     {
 390      
 391     }
 392     //创建一个炸弹,放入Vector
 393     Bomb b=new Bomb(et.x,et.y);
 394     //放入Vector
 395     bombs.add(b);
 396    }
 397   case 1:
 398   case 3:
 399    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
 400    {
 401     //击中了
 402     //子弹死亡
 403     s.isLive=false;
 404      //敌人坦克也要死亡
 405     et.isLive=false;
 406     //减少敌人数量
 407     if (et.getClass()==EnemyTank.class)//反射机制
 408     {
 409      Recorder.reduceEnNum();
 410      //增加我的记录
 411      Recorder.addEnNumRec();
 412     }
 413     
 414     if (et.getClass()==Hero.class)//反射机制
 415     {
 416      Recorder.setMyLife(Recorder.getMyLife() - 1);
 417     }
 418     //创建一个炸弹,放入Vector
 419     Bomb b=new Bomb(et.x,et.y);
 420     //放入Vector
 421     bombs.add(b);    
 422    }
 423   
 424   }
 425   
 426  }
 427  
 428  //画出坦克函数(扩展)
 429  public void drawTank(int x,int y,Graphics g,int direct,int type)
 430  {
 431   //判断类型
 432   switch (type)
 433   {
 434   case 0:
 435    g.setColor(Color.cyan);break;
 436   case 1:
 437    g.setColor(Color.yellow);break;  
 438   }
 439   //判断方向
 440   
 441   switch(direct)
 442   {
 443   //向上
 444   case 0:
 445     //画出我的坦克(到时候再封装成一个函数)
 446     //1.画出左面的矩形
 447     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
 448     g.fill3DRect(x,y,5,30,false);
 449    
 450     //2.画出右边的矩形
 451     g.fill3DRect(x+15,y,5,30,false);
 452    
 453     //3.画出坦克的中间矩形
 454     g.fill3DRect(x+5, y+5, 10, 20,false);
 455     //画出中间的圆
 456     g.fillOval(x+4, y+10,10,10);
 457     //画出线
 458     g.drawLine(x+9, y+15, x+9, y);
 459     break; 
 460   case 1:
 461    //炮筒向右
 462    //画出上面的矩形
 463    g.fill3DRect(x,y,30, 5, false);
 464    g.fill3DRect(x, y+15, 30, 5, false);
 465    g.fill3DRect(x+5, y+5, 20, 10, false);
 466    g.fillOval(x+10, y+5, 10, 10);
 467    g.drawLine(x+15, y+10, x+30, y+10);
 468    
 469    break;
 470   case 2:
 471    //向下
 472    g.fill3DRect(x,y,5,30,false);
 473    g.fill3DRect(x+15,y,5,30,false);
 474    g.fill3DRect(x+5, y+5, 10, 20,false);
 475    g.fillOval(x+4, y+10,10,10);
 476    g.drawLine(x+10, y+15, x+10, y+30);
 477    break;
 478    
 479   case 3:
 480    //向左  
 481    g.fill3DRect(x,y,30, 5, false);
 482    g.fill3DRect(x, y+15, 30, 5, false);
 483    g.fill3DRect(x+5, y+5, 20, 10, false);
 484    g.fillOval(x+10, y+5, 10, 10);
 485    g.drawLine(x+15, y+10, x, y+10);
 486    break;   
 487   } 
 488   
 489  }
 490  
 491  
 492  public void run()
 493  {
 494  //每个一百毫秒去重画子弹
 495   while(true)
 496   {
 497    try {
 498     Thread.sleep(100);
 499    } catch (InterruptedException e) {
 500     e.printStackTrace();
 501    }
 502    
 503   
 504    this.hitEnemyTank();
 505    
 506    //函数,判断敌人的子弹是否击中我了
 507    this.hitMe();
 508    
 509    this.repaint();
 510    //判断是否需要给坦克加入新的子弹
 511    for(int i=0;i<ets.size();i++)
 512    {
 513     EnemyTank et=ets.get(i);
 514     if(et.isLive)
 515     {
 516      if (et.ss.size()<3)
 517      {
 518       //没有子弹了
 519       //添加
 520       Shot s=null;
 521       switch(et.direct)
 522       {
 523       case 0:
 524        s=new Shot(et.x+9,et.y-1,0);
 525        et.ss.add(s);
 526        break;
 527       case 1:
 528        s=new Shot(et.x+30,et.y+10,1);
 529        et.ss.add(s);
 530        break;
 531       case 2:
 532        s=new Shot(et.x+9,et.y+30,2);
 533        et.ss.add(s);
 534        break;
 535       case 3:
 536        s=new Shot(et.x-1,et.y+9,3);    
 537        et.ss.add(s);
 538        break;            
 539       }
 540       
 541       //启动子弹线程
 542       Thread t=new Thread(s);
 543       t.start();      
 544      }  
 545     }
 546    }   
 547   } 
 548  }
 549  //定义三张图片,三张图片切换组成一颗炸弹
 550  Image image1=null;
 551  Image image2=null;
 552  Image image3=null;
 553  int flagOfContinue;
 554  //构造函数
 555  public MyPanel(int flag)
 556  {  
 557   
 558   this.flagOfContinue=flag;
 559   //恢复记录
 560   Recorder.getRecording();
 561   
 562   
 563   if(this.flagOfContinue==0)
 564   {
 565    //如果不是继续上次就直接建一个
 566    hero=new Hero(100,100);
 567    //初始化敌人的坦克
 568    for(int i=0;i<enSize;i++)
 569    {
 570     //创建敌人的坦克对象   
 571     EnemyTank et=new EnemyTank((i+1)*60,0);
 572     et.setColor(0);
 573     et.setDirect(2);
 574     //将MyPanel的敌人坦克向量交给该敌人坦克
 575     et.setEts(ets);
 576     
 577     
 578     //启动敌人的坦克
 579     
 580     Thread t=new Thread(et);
 581     t.start();
 582     //给敌人坦克添加一颗子弹
 583     Shot s=new Shot(et.x+10,et.y+30,2);
 584     et.ss.add(s);
 585     Thread t2=new Thread(s);
 586     t2.start();
 587     //加入
 588     
 589     ets.add(et);   
 590    }
 591   }
 592   else if(this.flagOfContinue==1)
 593   {
 594    //如果是继续上次的就读取坐标
 595    Vector<Node> nodes1=new Vector<Node>();
 596    nodes1=Recorder.getNodes();
 597  
 598     //初始化敌人的坦克
 599     for(int i=0;i<nodes1.size();i++)
 600     {
 601      if(nodes1.get(i).type==0)
 602      { 
 603       //创建敌人的坦克对象   
 604       EnemyTank et=new EnemyTank(nodes1.get(i).x,nodes1.get(i).y);
 605       et.setColor(0);
 606       et.setDirect(nodes1.get(i).direct);
 607       //将MyPanel的敌人坦克向量交给该敌人坦克
 608       et.setEts(ets);
 609       
 610       
 611       //启动敌人的坦克
 612       
 613       Thread t=new Thread(et);
 614       t.start();
 615       //给敌人坦克添加一颗子弹
 616       Shot s=new Shot(et.x+10,et.y+30,2);
 617       et.ss.add(s);
 618       Thread t2=new Thread(s);
 619       t2.start();
 620       //加入
 621       
 622       ets.add(et);   
 623      }
 624      else if(nodes1.get(i).type==1)
 625      {
 626       //如果保存有我上次的坦克的信息,就按照信息保存
 627       hero=new Hero(nodes1.get(i).x,nodes1.get(i).y);
 628       hero.setDirect(nodes1.get(i).direct);
 629      }
 630     }
 631     
 632   }
 633  
 634 //  image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));//文件应该放在src文件夹里面
 635 //  image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
 636 //  image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg"));
 637   //关于图像我们使用好一点的方法,引入java.io.File;和java.io.IOException;
 638   try
 639   {
 640    image1=ImageIO.read(new File("33.jpg"));//此时文件应该放在工程的根目录里面
 641    image2=ImageIO.read(new File("22.jpg"));
 642    image3=ImageIO.read(new File("11.jpg"));
 643   }
 644   catch (IOException e)
 645   {
 646    e.printStackTrace();
 647   }
 648   
 649  }
 650  //画出提示信息
 651  public void showInfo(Graphics g)
 652  {
 653    //画出提示信息的坦克 ,该坦克不参加战斗
 654    this.drawTank(80,330,g,0,0);  
 655    g.setColor(Color.black);  
 656    g.drawString(Recorder.getEnNum()+"",110,350);
 657   
 658    this.drawTank(150,330,g,0,1);
 659    g.setColor(Color.black);  
 660    g.drawString(Recorder.getMyLife()+"",180,350);
 661    //画出玩家的总成绩
 662   
 663    g.setColor(Color.black);
 664 try{
 665    Font f=new Font("宋体",Font.BOLD,20);
 666    g.setFont(f);
 667 }catch(Exception e){    e.printStackTrace();}
 668    g.drawString("您的总成绩:",420,40);
 669   
 670    this.drawTank(420, 60, g, 0, 0);
 671   
 672    g.setColor(Color.BLACK);
 673    g.drawString(Recorder.getAllEnemy()+"",460,80);
 674   
 675  }
 676  
 677  //键按下处理a表示左,s表示向下,w表示向上,d表示向右
 678  public void keyPressed(KeyEvent e)
 679  {
 680   if(hero.isLive)
 681   {
 682    if(e.getKeyCode()==KeyEvent.VK_UP&&hero.getY()>0)
 683    {
 684     // 设置我的坦克的方向
 685     this.hero.setDirect(0); 
 686     this.hero.moveUp();
 687    }
 688   
 689    else if (e.getKeyCode()==KeyEvent.VK_DOWN&&hero.getY()<270)
 690    {
 691     this.hero.setDirect(2);   
 692     this.hero.moveDown();   
 693    }
 694   
 695    else if (e.getKeyCode()==KeyEvent.VK_RIGHT&&hero.getX()<370)
 696    {
 697     this.hero.setDirect(1);   
 698     this.hero.moveRight();
 699     
 700    }  
 701    else if (e.getKeyCode()==KeyEvent.VK_LEFT&&hero.getX()>0)
 702    {
 703     this.hero.setDirect(3);   
 704     this.hero.moveLeft();   
 705    }
 706    
 707    if (e.getKeyCode()==KeyEvent.VK_SPACE)
 708    {   
 709     this.hero.shotEnemy();   
 710    }  
 711   
 712    //必须重新绘制Panel
 713    this.repaint(); 
 714   }
 715  }
 716  public void keyReleased(KeyEvent e)
 717  {
 718   
 719  }
 720  public void keyTyped(KeyEvent e)
 721  {
 722   
 723  }
 724   
 725 }
 726 
 727 
 728 //----------------------------------------------------
 729 
 730 class Node
 731 {
 732  int x;
 733  int y;
 734  int direct;
 735  int type;
 736  public Node(int x,int y,int direct,int type)
 737  {
 738   this.x=x;
 739   this.y=y;
 740   this.direct=direct; 
 741   this.type=type;
 742  } 
 743  
 744 }
 745 
 746 
 747 
 748 //记录类
 749 class Recorder
 750 {
 751  public static int getEnNum() {
 752   return enNum;
 753  }
 754  public static void setEnNum(int enNum) {
 755   Recorder.enNum = enNum;
 756  }
 757  public static int getMyLife() {
 758   return myLife;
 759  }
 760  public static void setMyLife(int myLife) {
 761   Recorder.myLife = myLife;
 762  }
 763  //记录每关多少敌人
 764  private static int enNum=MyPanel.getEnSize();
 765  //设置我有多少可以用的人
 766  public static int myLife=3;
 767  //记录总共消灭了多少敌人
 768  private static  int  allEnNum=0;
 769  //从文件中恢复记录点
 770  static Vector<Node> nodes=new Vector<Node>();
 771  private static FileWriter fw=null;
 772  private static BufferedWriter bw=null;
 773  private static FileReader fr=null;
 774  private static BufferedReader br=null;
 775  
 776  public static Vector<Node> getNodes()
 777  {
 778   try {
 779    fr=new FileReader("d:\\myRecording.txt");  
 780    br=new BufferedReader(fr);
 781    String n="";
 782   
 783    n=br.readLine();//读第一行
 784    allEnNum=Integer.parseInt(n);
 785    while((n=br.readLine())!=null)
 786    {
 787     String []xyz=n.split(" ");//按照空格返回数组,新技能
 788     Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]),Integer.parseInt(xyz[3]));
 789     nodes.add(node);
 790    } 
 791   }
 792   
 793   catch (Exception e)
 794   {
 795    e.printStackTrace();
 796   }
 797   finally
 798   {   
 799    try {
 800     br.close();
 801     fr.close();
 802    } catch (Exception e) {
 803     e.printStackTrace();
 804    }
 805   }
 806   return nodes;
 807  }
 808  public static void keepRecAndEnemyTank(Vector<EnemyTank> ets)
 809  {
 810   try
 811   {
 812    //创建
 813    fw=new FileWriter("d:\\myRecording.txt");
 814    bw=new BufferedWriter(fw);
 815    
 816    bw.write(allEnNum+"\r\n");
 817    
 818    //保存当前还活着的敌人坐标和方向
 819    for(int i=0;i<ets.size();i++)
 820    {
 821     //取出第一个坦克
 822     EnemyTank et=ets.get(i);
 823     if(et.isLive)
 824     {
 825      //活着的保存
 826      String record=et.x+" "+et.y+" "+et.direct+" "+0;    
 827      //写入
 828      bw.write(record+"\r\n");    
 829     }   
 830    }
 831    
 832   }
 833   catch (Exception e)
 834   {
 835    e.printStackTrace();
 836   }
 837   finally
 838   {
 839    //关闭流
 840    try {
 841     //谁先开谁后关
 842     bw.close();
 843     fw.close();
 844    } catch (Exception e2) {
 845    }   
 846   }
 847   
 848  }
 849  
 850  public static void keepRecAndMyTank(Hero hero)
 851  {
 852   try
 853   {
 854    //创建
 855    fw=new FileWriter("d:\\myRecording.txt",true);//追加
 856    bw=new BufferedWriter(fw);
 857       
 858    //保存当前我的坐标和方向
 859    String record=hero.x+" "+hero.y+" "+hero.direct+" "+1;    
 860    //写入
 861    bw.write(record+"\r\n");    
 862   
 863   }
 864    
 865   catch (Exception e)
 866   {
 867    e.printStackTrace();
 868   }
 869   finally
 870   {
 871     //关闭流
 872    try
 873    {
 874     //谁先开谁后关
 875     bw.close();
 876     fw.close();
 877    }
 878    catch (Exception e2)
 879    {
 880     e2.printStackTrace();
 881    }   
 882   }
 883   
 884  }
 885   
 886  //从文件中读取记录
 887  public static void getRecording()
 888  {
 889   try {
 890    fr=new FileReader("d:\\myRecording.txt");  
 891    br=new BufferedReader(fr);
 892    String n=br.readLine();
 893    allEnNum=Integer.parseInt(n);
 894   }
 895   catch (Exception e)
 896   {
 897    e.printStackTrace();
 898   }
 899   finally
 900   {   
 901    try {
 902     br.close();
 903     fr.close();
 904    } catch (Exception e) {
 905     e.printStackTrace();
 906    }
 907   }
 908   
 909  }
 910  //把玩家击毁敌人的坦克数量保存到文件中
 911  public static void keepRecording()
 912  {
 913   try
 914   {
 915    //创建
 916    fw=new FileWriter("d:\\myRecording.txt");
 917    bw=new BufferedWriter(fw);
 918    
 919    bw.write(allEnNum+"\r\n");
 920   }
 921   catch (Exception e)
 922   {
 923    e.printStackTrace();
 924   }
 925   finally
 926   {
 927    //关闭流
 928    try {
 929     //谁先开谁后关
 930     bw.close();
 931     fw.close();
 932    } catch (Exception e2) {
 933    }   
 934   }  
 935  }
 936  
 937  public static int getAllEnemy() {
 938   return allEnNum;
 939  }
 940  public static void reduceEnNum()
 941  {
 942   enNum--;  
 943  }
 944  
 945  //消灭敌人
 946  public static void addEnNumRec()
 947  {
 948   allEnNum++;
 949  }
 950  
 951 }
 952 
 953 
 954 class Bomb
 955 {
 956  //定义炸弹的坐标
 957  int x,y;
 958  //炸弹的生命
 959  int life=9;
 960  boolean isLive=true;
 961  public  Bomb(int x,int y)
 962  {
 963   this.x=x;
 964   this.y=y;  
 965  }
 966  //减少生命值
 967  public void lifeDown()
 968  {
 969   if(life >0) {life--;}
 970   else {this.isLive=false;}
 971   
 972  }
 973 }
 974 
 975 
 976 class Tank
 977 {
 978  
 979  //设置坦克的速度
 980  int speed=3;
 981  public int getSpeed()
 982  {
 983   return speed;
 984  }
 985  public void setSpeed(int speed)
 986  {
 987   this.speed = speed;
 988  }
 989  //表示坦克的横坐标
 990  int x=0;
 991  //坦克的纵坐标
 992  int y=0;
 993  int direct=0;
 994  int color;
 995  boolean isLive=true;
 996  
 997  //坦克方向,0表示上,1表示右,2表示下,3表示左
 998  public int getColor() {
 999   return color;
1000  }
1001  public void setColor(int color) {
1002   this.color = color;
1003  }
1004  public int getDirect()
1005  {
1006   return direct;
1007  }
1008  
1009  public void setDirect(int direct)
1010  {
1011   this.direct = direct;
1012  }
1013  public Tank(int x,int y)
1014  {
1015   this.x=x;
1016   this.y=y;  
1017  }
1018  
1019  public int getX()
1020  {
1021   return x;
1022  }
1023  public void setX(int x)
1024  {
1025   this.x = x;
1026  }
1027  public int getY()
1028  {
1029   return y;
1030  }
1031  public void setY(int y)
1032  {
1033   this.y = y;
1034  }
1035  
1036 }
1037 
1038 
1039 class EnemyTank extends Tank implements Runnable
1040 {
1041  //定义一个向量,可以访问到MyPanel上所有敌人的坦克
1042  Vector<EnemyTank> ets=new Vector<EnemyTank>();
1043  
1044  //定义一个向量,可以存放敌人的子弹
1045  
1046  Vector<Shot> ss=new Vector<Shot>();
1047  //敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后
1048  public EnemyTank(int x,int y)
1049  {
1050   super(x,y);  
1051  }
1052  
1053  //得到MyPanel的敌人坦克向量
1054  public void setEts(Vector<EnemyTank> vv)
1055  {
1056   this.ets=vv;
1057   
1058  }
1059  
1060  
1061  //判断是否碰到了别人的坦克
1062  public boolean isTouchOtherEnemy()
1063  {
1064   boolean b=false;
1065   
1066   switch(this.direct)
1067   {
1068   case 0:
1069   
1070    //我的坦克向上
1071    //取出所有的敌人坦克
1072    for(int i=0;i<ets.size();i++)
1073    {
1074     //取出第一个坦克
1075     EnemyTank et=ets.get(i);
1076     //如果不是自己
1077     if(et!=this)
1078     {
1079      //如果敌人的方向向上或者是向下
1080      if(et.direct==0||et.direct==2)
1081      {
1082       if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
1083       {
1084        return true; 
1085       }
1086       if(this.x+20>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
1087       {
1088        return true;
1089       }
1090       
1091      }
1092     
1093      if(et.direct==1||et.direct==3)
1094      {
1095       if(this.x>=et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
1096       {
1097        return true; 
1098       }
1099       if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y>=et.y&&this.y<=et.y+30)
1100       {
1101        return true;
1102       }
1103      }
1104     }
1105  
1106    }
1107    
1108    break;
1109   case 1:
1110    //坦克向右
1111    //取出所有的敌人坦克
1112    for(int i=0;i<ets.size();i++)
1113    {
1114     //取出第一个坦克
1115     EnemyTank et=ets.get(i);
1116     //如果不是自己
1117     if(et!=this)
1118     {
1119      //如果敌人的方向向上或者是向下
1120      if(et.direct==0||et.direct==2)
1121      {
1122       if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
1123       {
1124        return true; 
1125       }
1126       if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y+20>=et.y&&this.y+20<=et.y+30)
1127       {
1128        return true;
1129       }
1130       
1131      }
1132     
1133      if(et.direct==1||et.direct==3)
1134      {
1135       if(this.x+30>=et.x&&this.x+30<=et.x+30&&this.y>=et.y&&this.y<=et.y+20)
1136       {
1137        return true; 
1138       }
1139       if(this.x+30>=et.x && this.x+30<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
1140       {
1141        return true;
1142       }
1143      }
1144     }
1145  
1146    }
1147    
1148    
1149   case 2:
1150    //坦克向下
1151    //取出所有的敌人坦克
1152    for(int i=0;i<ets.size();i++)
1153    {
1154     //取出第一个坦克
1155     EnemyTank et=ets.get(i);
1156     //如果不是自己
1157     if(et!=this)
1158     {
1159      //如果敌人的方向向上或者是向下
1160      if(et.direct==0||et.direct==2)
1161      {
1162       if(this.x>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
1163       {
1164        return true; 
1165       }
1166       if(this.x+20>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
1167       {
1168        return true;
1169       }
1170       
1171      }
1172     
1173      if(et.direct==1||et.direct==3)
1174      {
1175       if(this.x+20>=et.x&&this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+20)
1176       {
1177        return true; 
1178       }
1179       if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+30)
1180       {
1181        return true;
1182       }
1183      }
1184     }
1185  
1186    }
1187    break; 
1188   case 3 :
1189    //坦克向左
1190    //取出所有的敌人坦克
1191    for(int i=0;i<ets.size();i++)
1192    {
1193     //取出第一个坦克
1194     EnemyTank et=ets.get(i);
1195     //如果不是自己
1196     if(et!=this)
1197     {
1198      //如果敌人的方向向上或者是向下
1199      if(et.direct==0||et.direct==2)
1200      {
1201       if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
1202       {
1203        return true; 
1204       }
1205       if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30)
1206       {
1207        return true;
1208       }
1209       
1210      }
1211     
1212      if(et.direct==1||et.direct==3)
1213      {
1214       if(this.x>=et.x&&this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
1215       {
1216        return true; 
1217       }
1218       if(this.x>=et.x && this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20)
1219       {
1220        return true;
1221       }
1222      }
1223     }
1224  
1225    }
1226   }
1227   
1228   return b;
1229  }
1230  
1231  public void run() {
1232   while(true)
1233   {  
1234    switch(this.direct)
1235    {
1236    case 0:
1237     for(int i=0;i<(int)(100*Math.random());i++)
1238     {
1239      try
1240      {
1241       Thread.sleep(50);  
1242      }
1243      catch (Exception e)
1244      {
1245       e.printStackTrace();
1246      }
1247      if(y>=speed && !this.isTouchOtherEnemy())
1248      {
1249       y-=speed;
1250      }
1251     }
1252     break;
1253    case 1:
1254     for(int i=0;i<(int)(100*Math.random());i++)
1255     {
1256      try
1257      {
1258       Thread.sleep(50);  
1259      }
1260      catch (Exception e)
1261      {
1262       e.printStackTrace();
1263      }
1264      if(x<=(400-(speed+30))&& !this.isTouchOtherEnemy())
1265      {
1266       x+=speed;
1267      }
1268     }
1269     break;
1270    case 2:
1271     for(int i=0;i<(int)(100*Math.random());i++)
1272     {
1273      try
1274      {
1275       Thread.sleep(50);  
1276      }
1277      catch (Exception e)
1278      {
1279       e.printStackTrace();
1280      }
1281      if(y<=(300-(speed+30))&& !this.isTouchOtherEnemy())
1282      {
1283       y+=speed;
1284      }
1285     }
1286     break;
1287    case 3:
1288     for(int i=0;i<(int)(100*Math.random());i++)
1289     {
1290      try
1291      {
1292       Thread.sleep(50);  
1293      }
1294      catch (Exception e)
1295      {
1296       e.printStackTrace();
1297      }
1298      if(x>=speed && !this.isTouchOtherEnemy())
1299      {
1300       x-=speed;
1301      }
1302     
1303     }
1304     break;
1305     
1306    }
1307    
1308    //让坦克随机产生一个新的方向
1309    this.direct=(int)(Math.random()*4);
1310    
1311    //判断敌人坦克是否死亡
1312    if(this.isLive==false)
1313    {
1314     //让坦克死亡后,退出线程
1315     break;
1316    }
1317    
1318   }
1319   
1320  }
1321 }
1322 
1323 
1324 //我的坦克
1325 class Hero extends Tank
1326 {
1327  //子弹
1328  //Shot s=null;
1329  Vector<Shot>  ss=new Vector<Shot>();
1330  Shot s=null;
1331  
1332  public Hero(int x, int y)
1333  {
1334   super(x,y);
1335  }
1336  //坦克向上移动
1337  
1338  //坦克的开火的能力和动作
1339  public void shotEnemy()
1340  {
1341   switch(this.direct)
1342   {
1343    case 0:
1344     s=new Shot(x+9,y-1,0);
1345     ss.add(s);
1346     break;
1347    case 1:
1348     s=new Shot(x+30,y+10,1);
1349     ss.add(s);
1350     break;
1351    case 2:
1352     s=new Shot(x+9,y+30,2);
1353     ss.add(s);
1354     break;
1355    case 3:
1356     s=new Shot(x-1,y+9,3);     ss.add(s);
1357     ss.add(s);
1358     break;
1359   }
1360  
1361   Thread t=new Thread(s);
1362   t.start();
1363   
1364  }
1365  
1366  
1367  public void moveUp()
1368  {
1369   this.y-=speed;  
1370  }
1371  public void moveRight()
1372  {
1373   this.x+=speed;  
1374  }
1375  
1376  public void moveDown()
1377  {
1378   this.y+=speed;  
1379  } 
1380  public void moveLeft()
1381  {
1382   this.x-=speed;  
1383  } 
1384 }
1385  
1386 class Shot implements Runnable
1387 {
1388  int x;
1389  int y;
1390  int direct;
1391  int speed=2;
1392  //是否活着
1393  
1394  boolean isLive=true;
1395  public  Shot(int x,int y,int direct)
1396  {
1397   this.x=x;
1398   this.y=y;
1399   this.direct=direct;
1400  }
1401  public void run()
1402  {
1403   while(true)
1404   {
1405    try {
1406     Thread.sleep(50);
1407    } catch (InterruptedException e) {
1408     e.printStackTrace();
1409    }
1410    
1411    switch(direct)
1412    {
1413    case 0:
1414    //向上
1415     y-=speed;break;
1416    case 1:
1417     x+=speed;break;
1418    case 2:
1419     y+=speed;break;
1420    case 3:
1421     x-=speed;break;    
1422    
1423    }
1424    
1425    //子弹何时死亡?
1426    //判断该子弹是否碰到边缘
1427    if(x<0||x>400||y<0||y>300)
1428    {
1429     this.isLive=false;
1430     break;
1431     
1432    }
1433    
1434   }
1435   
1436  }
1437 }

 

注:如果大家很多java基础内容不是很清楚,可以观看韩顺平的java学习视频,跟着教程做程序,效果很明显!(●ˇ∀ˇ●)

相关文章
|
6天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
6天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
24 3
|
7天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
9天前
|
Java 程序员
Java基础却常被忽略:全面讲解this的实战技巧!
小米,29岁程序员,分享Java中`this`关键字的用法。`this`代表当前对象引用,用于区分成员变量与局部变量、构造方法间调用、支持链式调用及作为参数传递。文章还探讨了`this`在静态方法和匿名内部类中的使用误区,并提供了练习题。
14 1
|
10天前
|
监控 Java 数据库连接
Java线程管理:守护线程与用户线程的区分与应用
在Java多线程编程中,线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。这两种线程在行为和用途上有着明显的区别,了解它们的差异对于编写高效、稳定的并发程序至关重要。
19 2
|
10天前
|
监控 Java 开发者
Java线程管理:守护线程与本地线程的深入剖析
在Java编程语言中,线程是程序执行的最小单元,它们可以并行执行以提高程序的效率和响应性。Java提供了两种特殊的线程类型:守护线程和本地线程。本文将深入探讨这两种线程的区别,并探讨它们在实际开发中的应用。
15 1
|
7月前
|
安全 Java
深入理解Java并发编程:线程安全与性能优化
【2月更文挑战第22天】在Java并发编程中,线程安全和性能优化是两个重要的主题。本文将深入探讨这两个主题,包括线程安全的基本概念,如何实现线程安全,以及如何在保证线程安全的同时进行性能优化。
62 0
|
7月前
|
存储 安全 Java
深入理解Java并发编程:线程安全与锁机制
【5月更文挑战第31天】在Java并发编程中,线程安全和锁机制是两个核心概念。本文将深入探讨这两个概念,包括它们的定义、实现方式以及在实际开发中的应用。通过对线程安全和锁机制的深入理解,可以帮助我们更好地解决并发编程中的问题,提高程序的性能和稳定性。
|
4月前
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
69 1
|
5月前
|
安全 Java 开发者
Java并发编程中的线程安全问题及解决方案探讨
在Java编程中,特别是在并发编程领域,线程安全问题是开发过程中常见且关键的挑战。本文将深入探讨Java中的线程安全性,分析常见的线程安全问题,并介绍相应的解决方案,帮助开发者更好地理解和应对并发环境下的挑战。【7月更文挑战第3天】
102 0