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学习视频,跟着教程做程序,效果很明显!(●ˇ∀ˇ●)

时间: 2024-10-14 09:21:47

Java__线程---基础知识全面实战---坦克大战系列为例的相关文章

线程基础知识系列(三)线程的同步

本文是系列的第三篇,前面2篇,主要是针对单个线程如何管理,启动等,没有过多涉及多个线程是如何协同工作的. 线程基础知识系列(二)线程的管理 :线程的状态,控制,休眠,Interrupt,yield等 线程基础知识系列(一)线程的创建和启动  :线程的创建和启动,join(),daemon线程,Callable任务. 本文的主要内容 何谓线程安全? 何谓共享可变变量? 认识synchronized关键字 认识Lock synchronized vs Lock 1.何谓线程安全 多线程是把双刃剑,带

线程基础知识系列(四)线程的同步2 线程通信和Condition变量

本文是系列的第四篇. 线程基础知识系列(三)线程的同步  :同步控制,锁及synchronized 线程基础知识系列(二)线程的管理 :线程的状态,控制,休眠,Interrupt,yield等 线程基础知识系列(一)线程的创建和启动  :线程的创建和启动,join(),daemon线程,Callable任务. 第三篇文章,重点阐述了如何使用锁和同步块对线程间共享可变变量保护,保证只有一个线程可以进入临界区.其实,没有过多的涉及另一个重要的同步概念:线程协作.第三篇中涉及的线程间并没有有效的协调.

线程基础知识

什么是线程: 在一个程序里的一个执行路线就叫做线程(thread).更准确的定义是:线程是"一个进程内部的控制序列" 一切进程至少都有一个执行线程 进程与线程 进程是资源竞争的基本单位 线程是程序执行的最小单位 线程共享进程数据,但也拥有自己的一部分数据 线程ID 一组寄存器 栈 errno 信号状态 优先级 fork和创建新线程的区别 当一个进程执行一个fork调用的时候,会创建出进程的一个新拷贝,新进程将拥有它自己的变量和它自己的PID.这个新进程的运行时间是独立的,它在执行时几乎

C#反射基础知识和实战应用

首先来说一下什么是反射? 反射提供了封装程序集.模块和类型的对象(Type类型) 可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后,可以调用类型的方法或访问其字段和属性 . 总之,有了反射,以前很多实现不了的功能都可以实现. 下面先来写一个小例子,体验一下反射是怎么一回事: 打开VS2010,新建一个控制台应用程序,在program.cs里面写代码 首先引入命名空间: using System.Reflection; 下如下代码: PropertyInfo l

线程基础知识系列(二)线程的管理

本篇是线程基础知识系列的第二篇,主要简单江夏线程管理相关知识点. 线程基础知识系列(一)线程的创建和启动:说明了线程的2种创建和启动,join(),daemon线程,Callable 任务. 本文的主要内容 线程的状态 线程的优先级 sleep vs wait 线程的流程控制 Interrupt yield让出你的CPU 1.线程的状态 以<线程基础知识系列(一)线程的创建和启动>这张图,是程序的运行时线程信息截图.有main线程,user Threads,daemon Threads.现在咱

线程基础知识系列(五)认识volatile

线程基础知识系列(四)线程的同步2  :线程的notify-wait通信机制,以及Condition条件变量 线程基础知识系列(三)线程的同步  :同步控制,锁及synchronized 线程基础知识系列(二)线程的管理 :线程的状态,控制,休眠,Interrupt,yield等 线程基础知识系列(一)线程的创建和启动  :线程的创建和启动,join(),daemon线程,Callable任务. 本篇文章主要讨论的关键字是volatile. volatile使用场景 volatile介绍 vol

Python3分布式爬虫(scrap+redis)基础知识和实战详解

背景 随着业务需求的变化,大规模爬虫遇到各种问题.python爬虫具有先天优势,社区资源比较齐全,各种框架也完美支持.爬虫性能也得到极大提升.本次分享从基础知识入手,涉及python 的两大爬虫框架pyspider.scrapy,并基于scrapy.scrapy-redis 做了分布式爬虫的介绍(直接粘贴的ppt截图)会涉及 redis.mongodb等相关知识. 一.前沿 1.1 爬虫是什么? 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本.

Java线程基础知识(状态、共享与协作)

1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源 线程:CPU调度的最小单位,必须依赖进程而存在. 澄清并行和并发 并行:同一时刻,可以同时处理事情的能力 并发:与单位时间相关,在单位时间内可以处理事情的能力 高并发编程的意义.好处和注意事项 好处:充分利用cpu的资源.加快用户响应的时间,程序模

IOS 多线程-线程基础知识

大部分现代操作系统,包括IOS,都支持执行线程的概念.每个进程可以包含多个线程,他们可以同时运行.如果只有一个处理器核心,操作系统将在所有执行线程之间切换,非常类似于在所有执行线程之间切换.如果拥有多个核心(核心),线程将像进程一样,分散到多个核心上去执行. 一个进程中的所有线程共享可执行程序代码和全局数据.每个线程也可以拥有一些独有的数据.线程可以使用一种成为互斥量或锁的特殊结构,这种结构可以确保特定的代码块无法一次没多个线程执行.在多个线程同时访问相同数据时,这有助于保证正确的结果,在一个线