JAVA写的坦克大战(单机图片版)

Posted 帅东

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA写的坦克大战(单机图片版)相关的知识,希望对你有一定的参考价值。

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


package _25增加配置文件;

import java.awt.*;
import java.awt.event.*;
import java.util.List;

import java.util.ArrayList;
/**
 * 这是这款游戏的主窗口,各个类都有他的引用
 * @author ☆东★
 *
 */
public class TankClient extends Frame{
    private Image offScreamImage = null;
    public static int WIDTH,HEIGHT;
    public int times = 0;//用来表示发了几发炮弹
    public List<Bullets> myBullets = new ArrayList<Bullets>();//代表还有几发炮弹
    public List<Explode> explodes = new ArrayList<Explode>();
    public List<Tank> enemyTank = new ArrayList<Tank>();
    public Tank myTank = new Tank(50,500,true,Direction.STOP,this);//把TankClient对象传进去,使Tank可以操作TankClient里面的部分数据

    public int width = Toolkit.getDefaultToolkit().getScreenSize().width;
    public int height = Toolkit.getDefaultToolkit().getScreenSize().height;

    public Wall wall1 = new Wall(100,100,20,200,this);
    public Wall wall2 = new Wall(300,450,70,70,this);
    public Blood b = new Blood(this);
    private boolean GAME_OVER = false;

    /**
     * 这个方法时画出图形的主要方法,其他类实现的图形,最终都要放到这个方法中
     */
    public void paint(Graphics g) {
        wall1.draw(g);
        wall2.draw(g);
        b.draw(g);
        myTank.drawTank(g);
        myTank.eat(b);

        /**
         * 当敌人没有了,就再生成一些敌人
         */
        if(enemyTank.size()==0){
            int reinitTank = Integer.parseInt(GetProp.getProp("reTankCount"));
            for(int i = 0;i<reinitTank;i++){
                Tank t = new Tank(50+80*i,50,false,Direction.STOP,this);
                t.GAME_LEVEL -= 3 ;
                enemyTank.add(t);
            }
        }
        /**
         * 每隔25毫秒就重画地方所有坦克
         */
        for(int i=0 ;i<enemyTank.size();i++){//画出敌人坦克
            Tank t = enemyTank.get(i);
            t.hitWall(wall1);
            t.hitWall(wall2);
            t.hitTank(enemyTank);//敌方坦克不能互相碰撞
//          myTank.hitTank(enemyTank);//使我方坦克也不能喝敌方坦克相碰(这个还有点问题  以后研究)
            t.drawTank(g);
        }
        /**
         * 画出爆炸
         */
        for(int i = 0;i<explodes.size();i++){
            Explode e = explodes.get(i);
            e.draw(g);
        }
        /**
         *  给用户的提示信息
         */
        g.setFont(new Font("", Font.BOLD, 15));//设置字体
        if(times>=30){
            g.drawString("还有多少发炮弹:"+0, 10, 50);
            g.setColor(Color.red);
            g.drawString("没炮弹了(充钱)", 20, 75);
        }
        else{
            g.drawString("还有多少发炮弹:"+(30-times), 10, 50);
            g.drawString("敌方坦克:"+enemyTank.size(), 10, 70);
        }
        /**
         * 画子弹,当子弹没有了,就不能画子弹了
         */
        if(myBullets.size()!=0)
        for(int i=0;i<myBullets.size();i++){
            Bullets b = myBullets.get(i);//创建这一发炮弹  这一发子弹里面有坐标有方向
            b.hitTanks(enemyTank);//判断是否击中坦克(击中了就设置live标志为false)
            b.hitTank(myTank);
            b.hitWall(wall1);//设置子弹撞墙时的动作
            b.hitWall(wall2);//设置子弹撞墙时的动作
            b.draw(g);//当击中坦克,子弹自己就不再画自己了(通过坦克自己内部的live标志)
        }
    }

    /**
     * 添加双缓冲消除闪烁现象
     */
    public void update(Graphics g) {
        if(offScreamImage == null){
            offScreamImage = this.createImage(WIDTH,HEIGHT);//把所有东西都画在这张图片上
        }

        Graphics gOffScream = offScreamImage.getGraphics();//获取这张图片的画笔
        //下面是重画屏幕,使他恢复原来的颜色
        Color c = g.getColor();
        gOffScream.setColor(Color.gray);
        gOffScream.fillRect(0, 0, WIDTH, HEIGHT);
        gOffScream.setColor(c);

        paint(gOffScream);//调用paint方法。使这张图片也画上   paint方法里面的图片

        g.drawImage(offScreamImage, 0, 0, null);
    }

    /**
     * 程序开始的主方法
     */
    public void lauchFrame(){
        //获取屏幕信息
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension size = kit.getScreenSize();
        WIDTH = size.width/2+size.width/4;
        HEIGHT = size.height/2+size.height/4;
        this.setBounds(size.width/8,size.height/8,WIDTH,HEIGHT);

        Image image = kit.getImage("1.jpg");
        setIconImage(image);

//      this.setResizable(false);//设置不可以调整大小
        this.setBackground(Color.gray);
//      setUndecorated(true);//把标题栏去掉
//      setUndecorated(true);//全屏
//      getGraphicsConfiguration().getDevice().setFullScreenWindow(this);


        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                GAME_OVER = true;
                System.exit(0);
            }
        });
        this.addKeyListener(myTank.new MyKeyEvent());

        //使用配置文件
        int initTankCount = Integer.parseInt(GetProp.getProp("initTankCount"));
        for(int i = 1;i<initTankCount;i++){
            enemyTank.add(new Tank(50+50*i,50,false,Direction.STOP,this));
        }

        setVisible(true);

        new Thread(new PaintThread()).start();//创建一个线程,重画
    }

    public static void main(String[] args) {
        new TankClient().lauchFrame();
    }

    /**
     * 重画的一个线程
     * @author ☆东★
     *
     */
    private class PaintThread implements Runnable{
        public void run() {
            while(!GAME_OVER){
                repaint();
                try {
                    Thread.sleep(25);//每80毫秒重画一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/*//获取屏幕信息
   Toolkit kit = Toolkit.getDefaultToolkit();
   Dimension size = kit.getScreenSize();
   int screenWidth = size.width;
   int screenHeight = size.height;
   //设置窗口宽高
   jf.setSize(screenWidth/4, screenHeight/4);
   jf.setLocation(screenWidth/4, screenHeight/4);
   //设置图标
   Image image = kit.getImage("smile.gif");
   jf.setIconImage(image);


    void setResizable(boolean resizable) 
          设置此窗体是否可由用户调整大小。 

    public abstract Color getColor()获取此图形上下文的当前颜色。

    public abstract void setColor(Color c)将此图形上下文的当前颜色设置为指定颜色。使用此图形上下文的所有后续图形操作均使用这个指定的颜色。 

    public void repaint()重绘此组件。 
    如果此组件是轻量级组件,则此方法会尽快调用此组件的 paint 方法。否则此方法会尽快调用此组件的 update 方法。

    abstract  boolean drawImage(Image img, int x, int y, ImageObserver observer) 
          绘制指定图像中当前可用的图像。 
 */
package _25增加配置文件;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
 * 画坦克的主要类
 * @author ☆东★
 *
 */
public class Tank {
    private int x,y;// x  y  代表了tank现在的位置
    private int oldX,oldY;//记录坦克上一步的位置
//  private static final int WIDTH = 30,HEIGHT = 30;//坦克大小
    private static final int WIDTH = 50,HEIGHT = 50;//坦克大小
    private static final int XSPEED = 5,YSPEED = 5;//坦克xy方向运动速度 
    public int GAME_LEVEL = 14;//默认游戏难度为12  越高越简单,最高17  最低3
    //想让Tank向8个方向走
    private boolean bL = false ,bU = false ,bR = false ,bD = false;//用于记录  键盘按下的  上下左右  (按下之后就设置为True)
    private Direction dir = Direction.STOP;//坦克的最开始的方向
    private Direction ptDir = Direction.D;//炮筒最开始的方向
    private TankClient tc = null;
    private boolean good ;
    private boolean live = true;
    private static Random rand = new Random();
    private int step = rand.nextInt(15)+3;//设置随机朝一个方向移动的步数,不然老是在同一个地方乱动
    private int life = 100;//给我方坦克设置血量
    private BloodBar bb  = new BloodBar();

    /**
     * 增加图片
     */
    private static Toolkit tk = Toolkit.getDefaultToolkit();
    private static Map<String,Image> imags = new HashMap<String,Image>();
    private static Image[] tankImage = null;
    static {
        tankImage = new Image[]{
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankL.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankLU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankRD.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankR.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankRU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankD.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/tankLD.gif"))
        };
        imags.put("L", tankImage[0]);
        imags.put("LU", tankImage[1]);
        imags.put("U", tankImage[2]);
        imags.put("RD", tankImage[3]);
        imags.put("R", tankImage[4]);
        imags.put("RU", tankImage[5]);
        imags.put("D", tankImage[6]);
        imags.put("LD", tankImage[7]);
    }

    public int getLife() {
        return life;
    }
    public void setLife(int life) {
        this.life = life;
    }
    public void setGood(boolean good) {
        this.good = good;
    }
    public boolean isGood() {
        return good;
    }
    public boolean isLive() {
        return live;
    }
    public void setLive(boolean live) {
        this.live = live;
    }

    public Tank(int x,int y,boolean good,Direction dir,TankClient tc){//获取TankClient的引用,让Tank可以调用TankClient里面的数据,因为子弹的方向是由Tank决定的,而TankClient要获取Bullets方向
        this.x = x;
        this.y = y;
        this.good = good;
        this.dir = dir;
        this.tc = tc;
    }

    public void drawTank(Graphics g){//坦克自己画自己
        if(!live){
            tc.enemyTank.remove(this);
            return;
        }

        if(good){
            bb.draw(g);
        }

        ptDraw(g);//画炮筒

        move();
    }
    /**
     * 用于判断  tank 往哪个方向走        用枚举里面的数   来判断是往哪个方向走的    从此 x y 的改变就从move这个方法里面改变(原来是从KeyAdapter 里面改变的)
     */
    private void move(){
        oldX = x;//记录上一步的位置
        oldY = y;

        switch(dir){//dir决定最终坦克的方向
        case L : 
            x-=XSPEED; break;
        case LU :
            x-=XSPEED; y-=YSPEED; break;
        case U :
            y-=XSPEED; break;
        case RD :
            x+=XSPEED; y+=YSPEED; break;
        case R :
            x+=XSPEED; break;
        case RU :
            x+=XSPEED; y-=YSPEED; break;
        case D :
            y+=YSPEED; break;
        case LD :
            x-=XSPEED; y+=YSPEED; break;
        case STOP : break;
        }
        /**
         * 判断是否出界
         */
        if(x<=5)
            x = 5;
        if(y<=30)
            y = 30;
        if(x>=TankClient.WIDTH-Tank.WIDTH-5)
            x = TankClient.WIDTH-Tank.WIDTH-5;
        if(y>=TankClient.HEIGHT-Tank.HEIGHT-5)
            y=TankClient.HEIGHT-Tank.HEIGHT-5;

        /**
         * 给炮筒一个方向
         */
        if(this.dir != Direction.STOP)//如果地方坦克   坦克方向不为Stop,,那么改变炮筒方向(与坦克方向一样)
            ptDir = dir;
        /**
         * 让炮筒发射子弹
         */
        if(!good){//如果是敌方坦克
            if(step == 0){
                Direction[] arr = Direction.values();// 把enum转化为数组
                int r = rand.nextInt(arr.length);//从0到arr的最大长度
                dir = arr[r];
                step = rand.nextInt(15)+3;//生成0---14之间的数

                //给敌方tank增加炮弹。。不能太密集
                if(step>=GAME_LEVEL) fire();
            }
            step--;
        }
    }
    /**
     * 画出炮筒
     * @param g
     */
    private void ptDraw(Graphics g){
        switch(ptDir){
        case L : 
            g.drawImage(imags.get("L"),x, y, null); break;
        case LU :
            g.drawImage(imags.get("LU"),x, y, null); break;
        case U :
            g.drawImage(imags.get("U"),x, y, null); break;
        case RD :
            g.drawImage(imags.get("RD"),x, y, null); break;
        case R :
            g.drawImage(imags.get("R"),x, y, null); break;
        case RU :
            g.drawImage(imags.get("RU"),x, y, null); break;
        case D :
            g.drawImage(imags.get("D"),x, y, null); break;
        case LD :
            g.drawImage(imags.get("LD"),x, y, null); break;
        case STOP :
            g.drawImage(imags.get("STOP"),x, y, null); break;
        }
    }
    /**
     * Tank真正走的方向  L, LU, U, RD, R, RU, D, LD, STOP   取决于dir的值
     */
    private void realDirection(){
        if(bL && !bU && !bR && !bD)
            dir = Direction.L;
        else if(bL && bU && !bR && !bD)
            dir = Direction.LU;
        else if(!bL && bU && !bR && !bD)
            dir = Direction.U;
        else if(!bL && !bU && bR && bD)
            dir = Direction.RD;
        else if(!bL && !bU && bR && !bD)
            dir = Direction.R;
        else if(!bL && bU && bR && !bD)
            dir = Direction.RU;
        else if(!bL && !bU && !bR && bD)
            dir = Direction.D;
        else if(bL && !bU && !bR && bD)
            dir = Direction.LD;
        else if(!bL && !bU && !bR && !bD)
            dir = Direction.STOP;
    }
    /**
     * Tank发射子弹   给子弹一个信号,,让子弹往自己指定的方向发子弹
     */
    private void fire(){
        if(good)
            tc.times++;//每次 发子弹的时候,设置一个计数器

        int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
        int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
        Bullets b = new Bullets(x,y,ptDir,good,tc);

        if(!good)//地方塔克可以一直创建子弹
            tc.myBullets.add(b);
        else if(tc.times<30 && live){//如果是我方坦克,发子弹次数少于20次,而且坦克活着,那么就装一发炮弹
            tc.myBullets.add(b);
        }//这样做保证了,当自己的子弹用完了,敌方还可以发炮弹
    }
    /**
     * 超级炮筒
     */
    private void superFire(){
        Direction[] arr = dir.values();//转化为数组
        for(int i = 0;i<8;i++){
            fire(arr[i]);
        }
        tc.times += 4;//相当于给散弹多一点子弹  发一发相当于以前发4发
    }
    /**
     * 发射超级炮弹
     * @param dir 不受炮筒方向控制的炮弹
     */
    private void fire(Direction dir){
        int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
        int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
        Bullets b = new Bullets(x,y,dir,good,tc);

        if(tc.times<30 && live){//如果是我方坦克,发子弹次数少于80次
            tc.myBullets.add(b);
        }
    }
    /**
     * 判断两个矩形是否相碰的方法
     * @return 返回值在判断是否相碰会用到
     */
    public Rectangle getRect(){
        return new Rectangle(x,y,WIDTH,HEIGHT);
    }
    /**
     * 判断是否撞墙
     * @param w 墙
     */
    public void hitWall(Wall w){
        if(live && this.getRect().intersects(w.getRect())){
            x = oldX;
            y = oldY;
        }
    }
    public void hitTank(java.util.List<Tank> tanks){
        for(int i = 0;i<tanks.size();i++){
            Tank t = tanks.get(i);
            if(this != t)//这一个判断非常重要,不然自己肯定和自己是相碰的,全都不动了
            if(live && this.getRect().intersects(tanks.get(i).getRect())){
                x = oldX;
                y = oldY;
            }
        }
    }
    /**
     * 吃血块方法
     * @param b 血块
     */
    public void eat(Blood b){
        if(this.live && this.getRect().intersects(b.getRect())){
            this.life = 100;
            b.setLive(false);
        }
    }
    /**
     * 画血量
     * @author ☆东★
     *
     */
    private class BloodBar{
        public void draw(Graphics g){
            Color c = g.getColor();
            g.setColor(Color.red);
            g.drawRect(x, y-15, WIDTH, HEIGHT/4);
            int width = WIDTH * life/100;
            g.fillRect(x, y-15, width, HEIGHT/4);
            g.setColor(c);
        }
    }

    /**
     * 添加按键事件
     * @author ☆东★
     *
     */
    class MyKeyEvent extends KeyAdapter{
        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();
            switch(key){
            case KeyEvent.VK_UP    : bU = true; break;//注意这里不能用e.VK_UP  e是变量了,不能出现变量
            case KeyEvent.VK_DOWN  : bD = true; break;
            case KeyEvent.VK_RIGHT : bR = true; break;
            case KeyEvent.VK_LEFT  : bL = true; break;

            case KeyEvent.VK_Q     : fire(); break;//按下Q键就可以获取子弹  的位置和  坦克现在的方向(子弹的方向)然后调用paint函数重画子弹
            case KeyEvent.VK_W     : superFire(); break;
            case KeyEvent.VK_SPACE : tc.times = 0; break;
            case KeyEvent.VK_F2    : if(!live) { live = true; life = 100;}//获得重生
            }
            realDirection();//上面只是判断是那几个按键被按下,,最终tank的走向是看dir的值
        }
        public void keyReleased(KeyEvent e) {
            int key = e.getKeyCode();
            switch(key){
            case KeyEvent.VK_UP    : bU = false; break;//注意这里不能用e.VK_UP  e是变量了,不能出现变量
            case KeyEvent.VK_DOWN  : bD = false; break;
            case KeyEvent.VK_RIGHT : bR = false; break;
            case KeyEvent.VK_LEFT  : bL = false; break;
            }
            realDirection();//上面只是判断是那几个按键被释放
        }
    }
}
package _25增加配置文件;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
/**
 * 爆炸类
 * @author ☆东★
 *
 */
public class Explode {//爆炸
    private int x , y;
    private boolean live = true;
    private int step = 0;//画到第几步了
    private TankClient tc;
    private static boolean init;
    private static Toolkit tk = Toolkit.getDefaultToolkit();
    private static Image[] image = {
            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/2.gif")),
            tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")),
            tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")),
            tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif")),
            tk.getImage(Explode.class.getClassLoader().getResource("images/6.gif")),
            tk.getImage(Explode.class.getClassLoader().getResource("images/7.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"))
    };

    Explode(int x,int y,TankClient tc){
        this.x = x;
        this.y = y;
        this.tc = tc;
    }

    public void draw(Graphics g){
        if(!init){
            for (int i = 0; i< image.length; i++) {//会发现第一次打敌人,不会出现爆炸。可能是系统第一次 加载图片的时候不会放到内存中
                g.drawImage(image[i], 100, 100, null);
            }
            init = true;
        }

        if(!live){
            tc.explodes.remove(this);//当爆炸不存在了,就从TankClient的爆炸集合中移除当前爆炸
            return ;
        }
        if(step==11){
            this.live = false;
            this.step = 0;
            return ;
        }
        g.drawImage(image[step++], x, y, null);
    }
}
package _25增加配置文件;
/**
 * 方向的枚举
 * @author ☆东★
 *
 */
public enum Direction {
    L, LU, U, RD, R, RU, D, LD, STOP//用来表示Tank是朝 哪个方法走的   以后这个枚举就来代表坦克的走向
}
package _25增加配置文件;

import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 子弹类
 * @author ☆东★
 *
 */
public class Bullets {//子弹类
    private int x,y;//坦克的位置,也是子弹的位置
    private boolean live = true;
    public static final int WIDTH = 10, HEIGHT = 10;//子弹大小
    private static final int XSPEED = 10,YSPEED = 10;//子弹速度
    private TankClient tc;
    private boolean good;//用于标识子弹是哪一方的子弹
    Direction dir;

    private static Toolkit tk = Toolkit.getDefaultToolkit();
    private static Map<String,Image> imags = new HashMap<String,Image>();
    private static Image[] tankImage = null;
    static {
        tankImage = new Image[]{//L, LU, U, RD, R, RU, D, LD, STOP
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileL.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileLU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileRD.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileR.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileRU.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileD.gif")),
                tk.getImage(Explode.class.getClassLoader().getResource("images/missileLD.gif"))
        };
        imags.put("L", tankImage[0]);
        imags.put("LU", tankImage[1]);
        imags.put("U", tankImage[2]);
        imags.put("RD", tankImage[3]);
        imags.put("R", tankImage[4]);
        imags.put("RU", tankImage[5]);
        imags.put("D", tankImage[6]);
        imags.put("LD", tankImage[7]);
    }

    public Bullets(int x,int y,Direction dir,boolean good,TankClient tc){
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.good = good;
        this.tc = tc;
    }

    public void draw(Graphics g){
        if(!live){
            tc.myBullets.remove(this);//用于删除子弹。不然这一发子弹打中敌人,另一个敌人来到这个地方也会死
            return;
        }
        if(good){
            Color c = g.getColor();
            g.setColor(Color.black);
            g.fillOval( x, y, WIDTH, HEIGHT);
            g.setColor(c);
        }

            switch(dir){
            case L : 
                g.drawImage(imags.get("L"),x, y, null); break;
            case LU :
                g.drawImage(imags.get("LU"),x, y, null); break;
            case U :
                g.drawImage(imags.get("U"),x, y, null); break;
            case RD :
                g.drawImage(imags.get("RD"),x, y, null); break;
            case R :
                g.drawImage(imags.get("R"),x, y, null); break;
            case RU :
                g.drawImage(imags.get("RU"),x, y, null); break;
            case D :
                g.drawImage(imags.get("D"),x, y, null); break;
            case LD :
                g.drawImage(imags.get("LD"),x, y, null); break;
            case STOP :
                g.drawImage(imags.get("STOP"),x, y, null); break;
            }

        move();
    }

    //子弹自己的移动方向速度
    private void move() {
        switch(dir){
        case L : 
            x-=XSPEED; break;
        case LU :
            x-=XSPEED; y-=YSPEED; break;
        case U :
            y-=XSPEED; break;
        case RD :
            x+=XSPEED; y+=YSPEED; break;
        case R :
            x+=XSPEED; break;
        case RU :
            x+=XSPEED; y-=YSPEED; break;
        case D :
            y+=YSPEED; break;
        case LD :
            x-=XSPEED; y+=YSPEED; break;
        }

        if(x<0 || y<0 || x>TankClient.WIDTH || y>TankClient.HEIGHT){//子弹超出边界  就让他在子弹集合中删除
            live = false;
        }
    }

    public Rectangle getRect(){
        return new Rectangle(x,y,WIDTH,HEIGHT);
    }


    //下面就是判断  坦克是否被击中,一级击中后会发生的事,一个函数可以解决,第一个函数里面就是循环,可以把它放在第二个函数里(只是不容易看而已)
    public void hitTanks(List<Tank> tanks){
        for(int i=0;i<tanks.size();i++)
            hitTank(tanks.get(i));//每次,挨个挨个的判断每一辆坦克是否被击中
    }
    public void hitTank(Tank t){
        //判断是否这辆坦克的面积,是否和子弹相碰,,,,坦克必须活着,不然死了以后,子弹打到相同位置,子弹也会消失
        if(this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()){//boolean intersects(Rectangle r) 确定此 Rectangle 是否与指定的 Rectangle 相交。 
            if(t.isGood()){
                t.setLife(t.getLife()-20);//每当我们被击中就减少20滴血
                if(t.getLife()<=0)
                    t.setLive(false);
            } else//如果是敌方坦克就直接死
            t.setLive(false);//把塔克也弄死,,,把标志live设置为false(死)

            this.live = false;//把子弹也弄消失
            Explode e = new Explode(x,y,tc);//每次击中再增加一个爆炸类
            tc.explodes.add(e);//给TankClient的爆炸集合,增加一个爆炸
        }
    }

    public void hitWall(Wall w){//判断是否撞到墙了
        if(this.live && this.getRect().intersects(w.getRect())){
            this.live = false;
        }
    }

}
package _25增加配置文件;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
/**
 * 血量类
 * @author ☆东★
 *
 */
public class Blood {
    private int x ,y , w ,h;
    private TankClient tc;
    private boolean live = true;
    private Random rand = new Random();


    Blood(TankClient tc){
        this.tc = tc;
    }

    public boolean isLive() {
        return live;
    }
    public void setLive(boolean live) {
        this.live = live;
    }

    public void draw(Graphics g){
        if(!live) return ;
        x = rand.nextInt(tc.WIDTH/50)+600;
        y = rand.nextInt(tc.HEIGHT/50)+150;
        Color c = g.getColor();
        g.setColor(Color.green);
        g.fillRect(x, y, 20, 20);
        g.setColor(c);
    }

    public Rectangle getRect(){
        return new Rectangle(x, y, 20, 20);
    }

}
package _25增加配置文件;

import java.awt.Graphics;
import java.awt.Rectangle;
/**
 * 墙类
 * @author ☆东★
 *
 */
public class Wall {
    private int x,y,w,h;
    private TankClient tc;

    public Wall(int x, int y, int w, int h, TankClient tc) {
        super();
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.tc = tc;
    }

    public void draw(Graphics g){
        g.fillRect(x, y, w, h);
    }

    public Rectangle getRect(){
        return new Rectangle(x,y,w,h);
    }

}
package _25增加配置文件;

import java.io.IOException;
import java.util.Properties;

/**
 * 使用配置文件,,采用了单例设计模式
 * @author ☆东★
 *
 */
public class GetProp {
    private static Properties prop = new Properties();

    static{
        try {
            prop.load(GetProp.class.getClassLoader().getResourceAsStream(Java坦克大战

我所知道坦克大战(单机版)之 建造目录

Java坦克大战 跟学韩顺平老师视频开发

《游戏学习》JAVA版坦克大战课程设计及源码

《游戏学习》JAVA版坦克大战课程设计及源码

java学习之坦克大战游戏