还存在bug的坦克大战

//存在缺陷:敌军偶尔会隐身,有些地方要改进下,如加入墙的方式

 

 

package com.liuqinlin.TankWar图片版;

 

import java.awt.*;

import java.awt.event.*;

import java.util.List;

import java.util.ArrayList;

import java.util.Random;

 

 

/**

 * 这个类是游戏的主窗口

 * 它控制着子弹、坦克、墙、爆炸和血块的引用

 */

 

public class TankWarClient extends Frame{

 

/**

* 显示游戏窗口的大小

*/

public static final int Game_WIDTH=820;

public static final int Game_HEIGTH=660;

Image OffScreenImage=null;

Image image=null ;

Image GameOver=null ;

    Tank MyTank=new Tank(290, 622, this, true ,direction.STOP);

    Boold bd=new Boold();

 

    /**

     * 对我军坦克超级炮弹数量的控制

     */

    int multiCounts=5 ;

    int superCounts=8 ;

 

    //为打不烂的墙专门设置对象

    /**

     * 设置两堵墙的大小和方位 

     */

 

    Tank EnemyTank;

    Missile myTank;

 

    /**

     * 设置容器来装子弹、爆炸、和敌军坦克

     */

    List<Missile> Missiles=new ArrayList<Missile>();

    List<Explode> Explodes=new ArrayList<Explode>();

    List<Tank> EnemyTanks=new ArrayList<Tank>();

    List<Wall>walls=new ArrayList<Wall>();

    List<Image>images=new ArrayList<Image>() ;

    List<Wall>nonWalls=new ArrayList<Wall>() ;

 

    /**

     * 画出血条和显示子弹、坦克、生命值等

     * 并获取对坦克类 、子弹类等的引用

     */

public void paint(Graphics g) {

//显示炮弹数量

Color c=g.getColor();

g.setColor(Color.red);

g.drawString("multiMissiles Count: "+multiCounts , 20, 40);

g.drawString("EnemyTanks Count:"+EnemyTanks.size(), 20, 60);

g.drawString("Missiles Count:"+Missiles.size(), 20, 80);

   g.setColor(c);

   

   GameOver=Toolkit.getDefaultToolkit().getImage(Tank.class.getClassLoader().getResource("Images/GameOver.jpg") );

   

   /**

    * 敌军坦克被消灭光后自动加入8辆敌军坦克

    */

   if(EnemyTanks.size()<=0){

    for(int i=0; i<8; i++){

EnemyTanks.add(new Tank(50+60*(i+1), 0 , this, false ,direction.D));

}

   }

   //需要改进

   for(int i=0 ; i<images.size(); i++){

    image=images.get(i);

    g.drawImage(image, 371 , 577 , null);

   }

   if(images.size()==0){

    g.drawImage(GameOver, 3, 25 ,null);

    return ;

   }

   

   for(int i=0 ; i<walls.size(); i++){

    Wall wallt=walls.get(i) ;

    wallt.draw(g);

   }

   

   for(int i=0 ; i<nonWalls.size(); i++){

       Wall nonWall=nonWalls.get(i); 

       nonWall.draw(g);

   }

   

   

   /**

    * 从容器中取出子弹并打击敌军坦克和敌军坦克打击我军坦克

    * 对子弹撞墙进行控制处理

    */

        for(int i=0;i<Missiles.size();i++){

            myTank=Missiles.get(i);

 

         myTank.isHitTanks(EnemyTanks);

            myTank.isHitTank(MyTank);

            myTank.isHitImage(images);

            myTank.isHitWall(walls);

            myTank.isHitNonWalls(nonWalls);

 

            myTank.draw(g);

        }

 

        /**

         * 从爆炸容器中获取爆炸并画出效果

         */

        for(int i=0;i<Explodes.size();i++){

         Explode e=Explodes.get(i);

            e.draw(g);

        }

   

        /**

         * 从敌军坦克容器中画出坦克

         * 

         */

        for(int i=0; i<EnemyTanks.size() ;i++){

            EnemyTank= EnemyTanks.get(i);

 

            /**

             * 敌军坦克撞墙处理引用

             */

            EnemyTank.isCollidesWithWall(walls);

            EnemyTank.isCollidesWithNonWall(nonWalls);

            /**

             * 敌军坦克间的碰撞处理引用

             * 敌军坦克和我军坦克间的碰撞处理引用

             */

            EnemyTank.isCollidesWithTanks(EnemyTanks);

            EnemyTank.isCollidesWithTank(MyTank);

 

         EnemyTank.draw(g);

        }

 

        /**

         * 对画出血块的引用

         * 画出我军坦克并对其吃血块处理的引用

         * 画出两堵墙的引用

         */

 

        MyTank.isCollidesWithWall(walls);

        MyTank.isCollidesWithNonWall(nonWalls);

 

        bd.draw(g);

MyTank.draw(g);

MyTank.eatBoold(bd);

    }

 

/**

* 本方法使用双缓冲消除闪烁现象

* 将所有东西画在虚拟图片上,一次性显示出来

*/

 

  public void update(Graphics g) {

 

/**

* 画出虚拟画布

*/

          if(OffScreenImage==null){

               OffScreenImage=this.createImage(Game_WIDTH,Game_HEIGTH);

          }

          Graphics gOffScreenImage=OffScreenImage.getGraphics();

          Color c=gOffScreenImage.getColor();

          gOffScreenImage.setColor(Color.BLACK);

          gOffScreenImage.fillRect(0, 0, Game_WIDTH , Game_HEIGTH);

          gOffScreenImage.setColor(c);

 

          /**

           * 把虚拟画布的画笔传给paint()方法

           * 并用真实画笔g把画布一次性显示出来

           */

          paint(gOffScreenImage);  

          g.drawImage(OffScreenImage, 0, 0, null);

         }

 

public static void main(String[] args) {

         new TankWarClient().launchFrame();

}

 

/**

* 本方法显示游戏主窗口

*/

public void launchFrame(){

Random r=new Random();

images.add(Toolkit.getDefaultToolkit().getImage(Tank.class.getClassLoader().getResource("Images/tou.jpg") )) ;

/**

* 开始游戏时画出10辆敌军坦克

*/

direction []dir=direction.values();

for(int i=0; i<8; i++){

int rn=r.nextInt(dir.length);

EnemyTanks.add(new Tank(50+70*(i+2), 0 , this, false ,dir[rn]));

}

int w=100 ;

int h=80 ;

for(int i=0 ; i<7 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=130 ;

   h=90 ;

for(int i=0 ; i<7; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=160 ;

   h=120 ;

for(int i=0 ; i<2; i++){

walls.add(new Wall(w,h, 40, 30, this) ) ;

h+=30 ;

}

 

w=200 ;

h=90 ;

for(int i=0 ; i<7; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=230 ;

h=180 ;

for(int i=0 ; i<2  ; i++){

walls.add(new Wall(w,h, 80, 30, this) ) ;

h+=30 ;

}

w=310 ;

   h=100 ;

for(int i=0 ; i<7; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=340 ;

   h=130 ;

for(int i=0 ; i<5 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=370 ;

   h=160 ;

for(int i=0 ; i<2 ; i++){

walls.add(new Wall(w,h, 45, 30, this) ) ;

h+=30 ;

}

w=415 ;

   h=160 ;

for(int i=0 ; i<2 ; i++){

walls.add(new Wall(w,h, 45 , 30, this) ) ;

h+=30 ;

}

w=460 ;

   h=130 ;

for(int i=0 ; i<5 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=490 ;

   h=100 ;

for(int i=0 ; i<7 ; i++){

walls.add(new Wall(w,h, 30, 30 ,this) ) ;

h+=30 ;

}

w=520 ;

   h=180 ;

for(int i=0 ; i<2 ; i++){

walls.add(new Wall(w,h, 80, 30, this) ) ;

h+=30 ;

}

w=600 ;

   h=90 ;

for(int i=0 ; i<7 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=630 ;

   h=120 ;

for(int i=0 ; i<2 ; i++){

walls.add(new Wall(w,h, 40, 30, this) ) ;

h+=30 ;

}

w=670 ;

   h=100 ;

for(int i=0 ; i<7 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

w=700 ;

   h=80 ;

for(int i=0 ; i<7 ; i++){

walls.add(new Wall(w,h, 30, 30, this) ) ;

h+=30 ;

}

//下层建筑

w=330 ;

   h=546 ;

for(int i=0 ; i<4 ; i++){

walls.add(new Wall(w,h, 20, 30 ,this) ) ;

h+=27 ;

}

w=350 ;

   h=577 ;

for(int i=0 ; i<3 ; i++){

walls.add(new Wall(w,h, 20, 30 ,this) ) ;

h+=25 ;

}

w=350 ;

   h=546 ;

for(int i=0 ; i<6 ; i++){

walls.add(new Wall(w,h, 20, 30 ,this) ) ;

w+=20 ;

}

w=450 ;

   h=576 ;

for(int i=0 ; i<3 ; i++){

walls.add(new Wall(w,h, 20, 30,this ) ) ;

h+=26 ;

}

w=470 ;

   h=546 ;

for(int i=0 ; i<4 ; i++){

walls.add(new Wall(w,h, 20, 30,this) ) ;

h+=30 ;

}

w=310 ;

   h=515 ;

for(int i=0 ; i<10 ; i++){

walls.add(new Wall(w,h, 20, 30, this) ) ;

w+=20 ;

}

w=360 ;

   h=484 ;

for(int i=0 ; i<5 ; i++){

walls.add(new Wall(w,h, 20, 30 , this) ) ;

w+=20 ;

}

w=40 ;

   h=330 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=90 ;

   h=350 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=140 ;

   h=370 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=190 ;

   h=390 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=240 ;

   h=410 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

 

w=560 ;

   h=410 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=610 ;

   h=390 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=660 ;

   h=370 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=710 ;

   h=350 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

w=760 ;

   h=330 ;

for(int i=0 ; i<11 ; i++){

walls.add(new Wall(w,h, 20, 20, this) ) ;

h+=19 ;

}

//打不烂的墙

 int w0=348 ;

 int h0=400 ;

 for(int i=0 ; i<6 ; i++){

 nonWalls.add(new Wall(w0 ,h0 , 25, 25, this) ) ;

 w0+=20 ;

}

/**

* 对游戏窗口的关闭监听处理

*/

addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);

}

});

/**

*设置游戏窗口不可改变

*设置窗口背景、大小、起始位置和标题 

*/

        this.setResizable(false);

this.setTitle("TankWar");

this.setBackground(Color.BLACK);

this.setSize(Game_WIDTH ,Game_HEIGTH);

setLocation(50,50);

this.addKeyListener(new KeyMonitor());

setVisible(true);

//启动线程

   new Thread(new PaintThread()).start();

}

/**

* 调用线程设置刷新频率为50ms

* 并对画面以刷新频率为间隔进行重画

* @author liuqinglin

*

*/

private class PaintThread implements Runnable{

 

public void run() {

    while(true){

    repaint();             

     

    try {

Thread.sleep(50);

} catch (InterruptedException e) {

e.printStackTrace();

}

    }

}

}

 

private class KeyMonitor extends KeyAdapter{

     /**

     * 对按键释放的监听处理

     */

public void keyReleased(KeyEvent e) {

           MyTank.keyreleased( e);

}

        /**

         * 对我军坦克按键进行监听处理

         */

public void keyPressed(KeyEvent e) {

           MyTank.keypressed(e);

}

        

}

}

 

 

//tank

 

package com.liuqinlin.TankWar图片版;

 

import java.awt.*;

import java.awt.event.*;

import java.util.*;

 

/**

 * 本类为制造坦克的类

 * 并根据当前myTank的炮筒方向调用子弹进行打击

 * @author liuqinglin

 *

 */

public class Tank {

private int x, y;

//记录坦克原先的位置,为撞墙处理准备

private int oldx, oldy ;

/**

* 超级炮弹的起始数量设置

*/

    public int superCounts=0 ;

public int multiCounts=0 ;

    private int life=100 ;

 

//给敌军坦克改变方向前的移动距离

private int step=rn.nextInt(15)+4 ;

private boolean live=true ;

private boolean good;

 

/**

      * 控制坦克速度和坦克大小

     */

    private static Random rn=new Random();

 

    /**

     * 对按键方向的Boolean判断

     */

boolean BL=false,BU=false,BR=false,BD=false;

/**

* 新建一个方向的枚举类,控制9个方向

* @author liuqinglin

*

*/

    //dir为坦克的起始方向

    direction dir=direction.STOP;

    //ptDir为炮筒的起始方向

direction ptDir=direction.U;

//ptd:记录坦克的方向

    direction ptd;

    Missile m ;

    TankWarClient tc;

    Tank t ;

 

    private static Toolkit tk=Toolkit.getDefaultToolkit();

    private static Map<String , Image> imgs=new HashMap<String , Image >();

 

    static Image[] enemyTankImages=null ;

static{//静态区域里可以写代码

      enemyTankImages=new Image[] {

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankL.gif") ) ,

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankLU.gif") ) ,

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankU.gif") ) ,

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankRU.gif") ) ,

                      tk.getImage(Tank.class.getClassLoader().getResource("images/tankR.gif") ) , 

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankRD.gif") ) ,

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankD.gif") ) ,

                  tk.getImage(Tank.class.getClassLoader().getResource("images/tankLD.gif") ) 

      } ;

      imgs.put("L", enemyTankImages[0]);

      imgs.put("LU", enemyTankImages[1]);

      imgs.put("U", enemyTankImages[2]);

      imgs.put("RU", enemyTankImages[3]);

      imgs.put("R", enemyTankImages[4]);

      imgs.put("RD", enemyTankImages[5]);

      imgs.put("D", enemyTankImages[6]);

      imgs.put("LD", enemyTankImages[7]);

}

public static final int XSPEED=4 , YSPEED=4 ;

public static final int WIDTH=35 ;

public static final int HEIGHT=35 ;

 

public Tank(int x, int y, boolean good) {

this.x = x;

this.y = y;

this.good=good;

}

/**

* 判断敌我,画出坦克

* @param x 坦克方位x顶坐标

* @param y 坦克方位y顶坐标

* @param tc 主窗口的控制引用

* @param good 敌我识别

* @param dir 坦克的初始方向状态

*/

public Tank(int x, int y, TankWarClient tc, boolean good, direction dir) {

this(x, y,good );//调用上面那个构造函数

this.dir=dir ;

        this.tc=tc;

        /**

         * 记录坦克的方位,为碰撞处理准备

         */

        oldx=x; 

        oldy=y ;

}

 

/**

* @param g 画坦克和炮筒的画笔

*/

public void draw(Graphics g){    

/**

* 如果坦克被击中 则不再重画

* 如为敌军坦克,还从敌军坦克容器中移除

*/

 if(! live){

 if(! good){

 tc.EnemyTanks.remove(this);

    return ;

 }

 return ;

 }

 

//画出血条

 if(good){

 Color cs=g.getColor();

         g.setColor(Color.red);

 g.draw3DRect(x+1 , y-6 , 100/3 , 5, true);

 g.fill3DRect(x+1 , y-6 , getLife()/3 ,5, true);

 g.setColor(cs);

 }

 

       /**

         * 获取坦克stop前的方向,为坦克stop时确定炮筒的方向

         */

         ptd=ptDir ;

 

         /**

          * 根据炮筒方向画出炮筒

          */

         switch(ptDir){

         case L :

         g.drawImage(imgs.get("L"),x ,y, null);

         break;  

     case U :

     g.drawImage(imgs.get("U"),x ,y, null);

     break;

     case R :

     g.drawImage(imgs.get("R"),x ,y, null);

     break;    

     case D :

     g.drawImage(imgs.get("D"),x ,y, null);

     break;

     case STOP :

     break;

     }

 

         move();

    }

 

/**

* 坦克移动前先记录下方位

*/

public void move(){

oldx=x; oldy=y ;

switch(dir){

     case L :

         x-=XSPEED ; 

         break;  

     case U :

         y-=YSPEED ;

         break;

     case R :

         x+=XSPEED ;

         break;    

     case D :

         y+=YSPEED ;

         break;

     case STOP :

     break;

     }

 

/**

 * 若坦克越界则置为相应边缘位置

 */

     if(x<0)x=0;

     if(y<20)y=20 ;

     if(x+ WIDTH >=TankWarClient.Game_WIDTH) { x=TankWarClient.Game_WIDTH - WIDTH ;}

     if(y +HEIGHT>=TankWarClient.Game_HEIGTH){ y=TankWarClient.Game_HEIGTH - HEIGHT ;}

 

     /**

     * 一次运动完后判断是否为敌军

     * 若为敌军,则进行step判断,若step已经走完为0

     * 则重新为step随机置一个值,重新赋予一个随机运动方向

     */

     if(! good){

     /**

          * 不能对枚举类直接进行下标访问

          * 对其建立数组装好9个方向

          */

     direction []dirs=direction.values();

     if(step==0){

     step=rn.nextInt(30)+10 ;

     /**

      * r 为在9个方向的数组长度进行随机产生 0 到 8的下标

      */

     int r=rn.nextInt(dirs.length);

         /**

          * 由随机产生的下标数生成坦克方向

          * 并赋予炮筒方向

          */

     dir=dirs[r];

         ptDir=dir ;

     }

      

     /**

      * 由随机数产生 39 时敌军坦克发射子弹

              *解决了子弹发射频率过快的 问题

      */

     if(rn.nextInt(40)>38){

     this.fire();

     }

     step-- ;

     }

     }

 

/**

 * 本方法控制碰撞发生时stay

 * 回到原来的位置

 */

public void stay(){

         x=oldx; 

         y=oldy;

}

/**

 * 控制按键,产生方向

 * @param e KeyEvent事件

 */

public void keypressed(KeyEvent e){

    int key=e.getKeyCode();

    switch(key){

    case KeyEvent.VK_A :

      BL=true; break;

       case KeyEvent.VK_W:

      BU=true; break;

       case KeyEvent.VK_D :

      BR=true; break;

       case KeyEvent.VK_S :

      BD=true; break;

    

        case KeyEvent.VK_LEFT :

          BL=true; break;

        case KeyEvent.VK_UP :

          BU=true; break;

        case KeyEvent.VK_RIGHT :

            BR=true; break;

        case KeyEvent.VK_DOWN :

            BD=true; break;

    }

        currentDirection();

 }

 

/**

* 为解决按键fire子弹太密集的问题

* keyreleased后才发射子弹即fire 

* @param e  KeyEvent 事件

*/

public void keyreleased(KeyEvent e){

      int key=e.getKeyCode();

          switch(key){

          case KeyEvent.VK_A :

          BL=false; break;

          case KeyEvent.VK_W:

          BU=false; break;

          case KeyEvent.VK_D :

          BR=false; break;

          case KeyEvent.VK_S :

          BD=false; break;

          

          case KeyEvent.VK_LEFT :

          BL=false; break;

          case KeyEvent.VK_UP :

          BU=false; break;

          case KeyEvent.VK_RIGHT :

              BR=false; break;

          case KeyEvent.VK_DOWN :

              BD=false; break;

          case KeyEvent.VK_SPACE :

              fire(); break;

          case KeyEvent.VK_F :

          fires(); break ;

          case KeyEvent.VK_F2 :

          

          /**

           * 若myTank死亡可按F2重新开始游戏

           * 一切重置;myTank没死则不能重新开始

           */

          if(! this.live){

                  live=true ;

                  this.setLife(100);

                  tc.multiCounts=5 ;

                  multiCounts=0 ;

          break ;

          }else break ;

          }

          currentDirection();

    }

/**

* 各类子弹或者炮弹的发射的统一发射

* @return 返回子弹

*/

public Missile  fire() {

/**

* 坦克已死就不能再发射子弹了

*/

if(! live){

return null ;

}

/**

* 各类子弹先得装入容器中才能发射

* 调整子弹绘制的位置

*/

int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2 ;

int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/3 ;

        m=new Missile(x, y, ptDir  ,tc, good);

        tc.Missiles.add(m);

        return m ;

  }

 

/**

* 散弹的发射控制最终也得调用fire()

*/

private void fires(){

 /**

     * 控制8个方向散弹的发射次数

     */

   if(multiCounts<5){

       multiCounts++ ;

       tc.multiCounts-- ;

   }else return ;

    /**

     * 通过数组获取8个方向的发射方向

     * 进行for循环朝8个方向开火

     */

direction [] dirs=direction.values();

for(int i=0; i<dirs.length ; i++){

ptDir=dirs[i];

fire();

}

}

/**

* 由按键获得的4个方向的Boolean值更进一步的细分方向为8个方向

* 并简单的设置炮筒方向与坦克方向一致

*/

    public  void currentDirection(){

    if(!BL&&!BU&&!BR&&!BD){

    ptDir=ptd ;

    dir=direction.STOP ;   

    }else if(BL&&!BU&&!BR&&!BD){

    ptDir=direction.L ;

    dir=direction.L ;    

    }else if(BL&&BU&&!BR&&!BD){

    ptDir=direction.U ;

    dir=direction.U ;   

    }else if(!BL&&BU&&!BR&&!BD){

    ptDir=direction.U ;

    dir=direction.U ;   

    }else if(!BL&&BU&&BR&&!BD){

    ptDir=direction.U ;

    dir=direction.U ;   

    }else if(!BL&&!BU&&BR&&!BD){

    ptDir=direction.R ;

    dir=direction.R ;

    }else if(!BL&&!BU&&BR&&BD){

    ptDir=direction.D ;

    dir=direction.D ;   

    }else if(!BL&&!BU&&!BR&&BD){

    ptDir=direction.D ;

    dir=direction.D ;   

    }else if(BL&&!BU&&!BR&&BD){

    ptDir=direction.D ;

    dir=direction.D ;   

    }

   }

 

    public boolean eatBoold(Boold bd){

     if(this.live&& bd.isLive() && this.getRect().intersects(bd.getRect())){

    

     if(this.getLife()<=50){

       this.setLife(this.getLife()+50);

     }else this.setLife(100);

     bd.setLive(false);

     return true ;

     }return false ;

    }

 

public boolean isGood() {

return good;

}

 

    public boolean isLive() {

return live;

}

 

public void setLive(boolean live) {

this.live = live;

}

public Rectangle getRect(){

return new Rectangle(x, y, WIDTH , HEIGHT);

}

public boolean isCollidesWithImage(Image image){

  if(this.live&&this.getRect().intersects(370, 541 ,60, 60)){

               stay();

      return true ;

    }

 

    return false ;

   }                      

 public boolean isCollidesWithWall(java.util.List<Wall> walls){

 for(int i=0 ; i<tc.walls.size(); i++){

      Wall wall=tc.walls.get(i);

  if(this.live&&this.getRect().intersects(wall.getRect())){

                   this.stay();

  return true ;

    }

 }

    return false ;

   }                                                   

 //碰撞打不烂的墙

 public boolean isCollidesWithNonWall(java.util.List<Wall> nonWalls){

 for(int i=0 ; i<nonWalls.size(); i++){

      Wall nonWall=nonWalls.get(i);

  if(this.live&&this.getRect().intersects(nonWall.getRect())){

                   this.stay();

  return true ;

    }

 }

    return false ;

   }                             

 

 /**

  * 处理敌军之间的碰撞

  * @param EnemyTanks 敌军一群坦克

  * @return 撞上则返回 true ,否则false

  */

 public  boolean isCollidesWithTanks(java.util.List<Tank>EnemyTanks){

 for(int i=0; i<EnemyTanks.size();i++){

 t=EnemyTanks.get(i);

           //判断不能是同一辆坦克

 if(this !=t){  

        if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){

                   this.stay();

                   t.stay();

       return true ;

        }

    }

 }

 return false ;

     }

 

 /**

  * 

  * @param t 单个坦克

  * @return 撞上墙就返回 true ,否则false

  */

 public boolean isCollidesWithTank(Tank t){

 if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){

 this.stay();

 t.stay();

 return true ;

 }

 return false ;

 

 }

 

 /**

  * 

  * @return 获取我军坦克生命值

  */

public int getLife() {

return life;

}

/**

* @param life 设置我军坦克生命值

*/

public void  setLife(int life){

this.life=life ;

}

}

 

//Missile子弹

 

package com.liuqinlin.TankWar图片版;

 

//让坦克动起来

//解决坦克移动方向变化过快的问题。用了记录步数的方法

 

import java.awt.*;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

 

/**

 * 本类为子弹类,对各种类型子弹进行统一绘制

 * 并对碰撞进行处理

 * @author liuqinglin

 *

 */

public class Missile {

private int x, y;

    private boolean live=true;

    private boolean good;

 

private TankWarClient tc;

    static direction dr;

    direction ptDir;

 

    /**

     * 控制子弹速度

     */

    public  int XSPEED=10,YSPEED=10;

    public  static final int WIDTH=10;

    public  static final int HEIGHT=10;

 

    private static Toolkit tk=Toolkit.getDefaultToolkit();

    private static Map<String , Image> imgs=new HashMap<String , Image >();

 

    static Image[] missileImages=null ;

static{//静态区域里可以写代码

       missileImages=new Image[] {

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileL.gif") ) ,

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileLU.gif") ) ,

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileU.gif") ) ,

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileRU.gif") ) ,

                      tk.getImage(Missile.class.getClassLoader().getResource("images/missileR.gif") ) , 

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileRD.gif") ) ,

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileD.gif") ) ,

                  tk.getImage(Missile.class.getClassLoader().getResource("images/missileLD.gif") ) 

      } ;

      imgs.put("L", missileImages[0]);

      imgs.put("LU", missileImages[1]);

      imgs.put("U", missileImages[2]);

      imgs.put("RU", missileImages[3]);

      imgs.put("R", missileImages[4]);

      imgs.put("RD", missileImages[5]);

      imgs.put("D", missileImages[6]);

      imgs.put("LD", missileImages[7]);

}

 

    /**

     * 

     * @param x 

     * @param y子弹绘制的位置

     * @param WIDTH  

     * @param HEIGTH  

     * @param ptDir 

     */

public Missile(int x, int y,direction ptDir) {

this.x = x  ;

this.y = y ;

this.ptDir=ptDir;

}

/**

 * 根据接收到的子弹信息绘制子弹

 * @param x 子弹绘制的位置

 * @param y 子弹绘制的位置

 * @param ptDir myTank的炮筒方向

 * @param tc 主窗口的控制引用

 * @param good 敌我识别,以判断画出敌军坦克还是我军坦克

 */

public Missile(int x, int y, direction ptDir,TankWarClient tc,boolean good){

this(x, y, ptDir);

this.tc=tc;

this.good=good ;

}

    public  void draw(Graphics g){

     /**

     * 如果子弹死亡就从容器中移除

     * 就不在重画

     */

     if(! live){

     tc.Missiles.remove(this);

     return ;

     }

 

      /**

       * 随传递过来的炮筒方向画出炮弹

       */

     switch(ptDir){

     case L :

      g.drawImage(imgs.get("L"), x, y, null);

      break ;

     case U :

      g.drawImage(imgs.get("U"),x, y, null);

     break ;

     case R :

      g.drawImage(imgs.get("R"),x, y, null);

      break ;

     case D :

      g.drawImage(imgs.get("D"),x, y, null);

      break ;

     }

    

       move();

    }

 

    /**

     * 根据炮筒方向使相应x 、y方位变化以实现

     * 子弹的运动

     */

    private void move() {

        switch(ptDir){

       case L:

          x-=XSPEED; 

          break;  

       case U:

           y-=YSPEED;

           break;

       case R:

          x+=XSPEED;

          break;    

       case D:

          y+=YSPEED;

          break;

        }

 

        /**

         * 如果子弹出界就判定死亡

         */

        if(x<0 || y<0 || x>TankWarClient.Game_WIDTH || y>TankWarClient.Game_HEIGTH ){

         live=false;

        }

}

    /**

     * 由子弹的大小方框进行简单的子弹碰撞处理

     * @return 子弹的大小方框

     */

    public Rectangle getRect(){

return new Rectangle(x, y, missileImages[4].getWidth(null), missileImages[4].getHeight(null));

}

 

    public boolean isHitImage(List<Image> images){

     for(int i=0; i<images.size(); i++){

     Image image=images.get(i);

        if(this.live&&this.getRect().intersects(371, 577 , 80, 80)){

        this.live=false ;

        tc.images.remove(image);

            return true ;

        }

        }

     return false ;

    } 

 

    /**

     * 对子弹撞墙处理

     * @param wall 被子弹撞的墙

     * @return 子弹撞上墙则返回true,否则false

     */

    public boolean isHitWall(List <Wall> walls){

     for(int i=0; i<tc.walls.size(); i++){

     Wall wall=tc.walls.get(i);

        if(this.live&& wall.isLive()&& this.getRect().intersects(wall.getRect())){  

         this.live=false ;

        wall.setLive(false);

    

     Explode e=new Explode(x, y, tc);

     tc.Explodes.add(e);

     return true ;

     }

     }

     return false ;

    }

    //碰撞打不烂的墙

    public boolean isHitNonWalls(List <Wall> nonWalls){

     for(int i=0; i<nonWalls.size(); i++){

     Wall nonWall=nonWalls.get(i);

        if(this.live&&this.getRect().intersects(nonWall.getRect())){  

         this.live=false ;

 

         Explode e=new Explode(x, y, tc);

       tc.Explodes.add(e);

       return true ;

        }

       }

     return false ;

    }

    /**

     * 

     * @param t 被子弹打击的坦克

     * @return 打中则返回true,否则false

     */

    public boolean isHitTank(Tank t){

     /**

     * 首先确定子弹活着并且要打击的坦克也活着

     * 如果子弹小方框和坦克的的方框是否相交

     * 若不是同一方的坦克,并且方框相交则子弹和

     * 坦克都死亡

     */

     if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good !=t.isGood()){

     /**

     * 如果被打中的坦克为我方坦克则进行血条管理

     * 被打中一次减少20滴血,总共100滴

     * 若为敌军坦克则直接死亡

     */

     if(t.isGood()){

     t.setLife(t.getLife()-20) ;

     if(t.getLife()<=0) { t.setLive(false); }

     }else { t.setLive(false); }

    

     this.live=false ;

     /**

     * 根据子弹的方位画出爆炸并添加入爆炸容器中

     */

     Explode e=new Explode(x, y, tc);

     tc.Explodes.add(e);

     return true ;

     }else

     return false ;

    }

 

    /**

     * myTank要打击每一辆敌军坦克,需要加入装有一批敌军坦克的容器为参数

     * @param EnemyTanks 给我军坦克打击的一群敌军坦克

     * @return 打中敌军坦克则返回true,否则false

     */

    public boolean isHitTanks(List<Tank> EnemyTanks){

     for(int i=0 ; i<tc.EnemyTanks.size(); i++){//每次打击循环一遍,查看哪个被打中了

     if(isHitTank(tc.EnemyTanks.get(i))){

       return true ;

     }

     }

     return false ;

    }

 

}

 

 

//explode爆炸

 

 

package com.liuqinlin.TankWar图片版;

 

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Toolkit;

 

 

/**

 * 本类为游戏添加爆炸效果

 * @author liuqinglin

 *

 */

public class Explode {

int x, y;

private boolean live=true ;

private static boolean init=false ;

int step=0;

private TankWarClient tc ;

//获取当前平台系统的工具包以调用当前系统的东西

private static Toolkit tk=Toolkit.getDefaultToolkit();

    //若定义的变量不是静态的,每new一个Explode就重新load一个变量

private static Image[] imgs={

 tk.getImage(Explode.class.getClassLoader().getResource("images/0.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/8.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/9.gif") ) ,

 tk.getImage(Explode.class.getClassLoader().getResource("images/10.gif") ) ,

 

} ;

/**

* 由Missile类传递来的击中敌军坦克的子弹方位画出爆炸

* @param x 爆炸的x顶坐标

* @param y 爆炸的y顶坐标

* @param tc 主窗口传递过来的控制引用

*/

public Explode(int x, int y, TankWarClient tc){

this.x=x;

this.y=y;

this.tc=tc;

}

public void draw(Graphics g){

//防止第一发打中没爆炸效果出现

//因为系统可能采用了异步IO方法

//现在采用虚代理方法即先把图片读到内存

//在看不见的方位画出来

if(! init){

for (int j = 0; j < imgs.length; j++) {

g.drawImage(imgs[j], -100 , -100 , null);

}

}

if(! live){

tc.Explodes.remove(this);

   return ;

}

if(step==imgs.length){

live=false ;

step=0 ;

}

g.drawImage(imgs[step], x, y, null);

 

step++ ;

}

 

}

 

//wall墙

 

 

package com.liuqinlin.TankWar图片版;

 

 

 

import java.awt.*;

/**

 * 本类对墙的控制和画出

 * @author liuqinglin

 *

 */

public class Wall {

private int x , y,w, h ;

private boolean live=true ;

TankWarClient tc ;

public boolean isLive() {

return live;

}

public void setLive(boolean live) {

this.live = live;

}

public Wall(int x, int y, int w, int h, TankWarClient tc) {

this.x = x;

this.y = y;

this.w=w; 

this.h=h ;

this.tc=tc ;

}

  /**

   * 按主窗口传递的方位大小画出墙

   * @param g 画笔

   */

public void draw(Graphics g){

if(! live ){

tc.walls.remove(this);

return ;

}

//设置打不烂和打得烂的墙的颜色

Color c=g.getColor();

if(x>=348 && x<=473 &&y >=400&&y<=425){

Color co=new Color(225, 216 ,226);

g.setColor(co);

}else {

  Color cs=new Color(200, 100 ,50);

           g.setColor(cs);

}

g.draw3DRect(x, y, w, h, true);

g.fill3DRect(x, y, w, h, true);

g.setColor(c);

}

 

/**

* 获取墙的方框以便进行碰撞处理

* @return 当前墙壁的外形(墙外头的正方形)

*/

public Rectangle getRect() {

return new Rectangle(x, y, w,h);

}

}

 

//direction方向

 

package com.liuqinlin.TankWar图片版;

 

public enum direction {

L,  U , R,  D, STOP

}

 

//boold加血的血块

 

package com.liuqinlin.TankWar图片版;

 

 

import java.awt.*;

import java.util.*;

/**

 * 本类为游戏添加给我军坦克加血的血块

 * @author liuqinglin

 *

 */

public class Boold {

private int x, y ;

    private int w, h ;

    private boolean live=true ;

 

int step=0 ;

    Random rd=new Random();

    /**

     * 根据pos数组给血块重画的方位定位

     */

int [][]pos={

{200, 200}, {300, 300}, {400, 400}, {500, 500}, {600, 500}, {450, 300}, {300, 150}, 

{200, 300}, {400, 250}, {150, 100}, {88, 200}, {150, 300},{80, 80}, {400, 100}, {400, 500}

};

 

public Boold() {

this.x = 200 ;

this.y = 200 ;

this.w = 15 ;

this.h = 15 ;

}

 

/**

* 画出血块,被吃后消失

* @param g  进行血块的绘制的画笔

*/

public  void draw(Graphics g ){

if(! live)return ;

Color c=g.getColor();

g.setColor(Color.MAGENTA);

g.fill3DRect(x, y, w, h, true);

move();

}

/**

* 按血块方位对血块进行自动绘制

* 并利用随机数控制血块的运动频率

*/

public void move(){

int bu=rd.nextInt(88);

if(bu>86){

   step++ ;

   if(step<pos.length){

  x=pos[step][0];

  y=pos[step][1];

   }else step=0 ;

}

}

 

    public boolean isLive() {

return live;

}

 

public void setLive(boolean live) {

this.live = live;

}

 

public Rectangle getRect() {

return new Rectangle(x, y, w, h);

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值