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

  • 相关阅读:
    使用sublimehighlight 将文本 转化html
    iOS- 制作U盘安装Mac OS X 系统
    垃圾回收的常见算法
    jvm的三种参数类型
    HashMap遍历取值
    不要在 foreach 循环里进行元素的 remove/add 操作
    Arrays.asList()使用指南
    正确使用 equals 方法
    elasticsearch安装与配置(在Linux环境下配置)
    本地访问Linux里端口连接失败
  • 原文地址:https://www.cnblogs.com/X-knight/p/5348532.html
Copyright © 2020-2023  润新知