【JavaSE】坦克大战,代码含超详细注释(核心类每行都有),看了就懂。包含:面向对象 OOP IO编程 文件编程 算法 GUI 多线程 线程知识


实现功能

  1. 绘制我方与敌方坦克
  2. 键盘控制我方坦克移动与发射
  3. 敌方发射子弹
  4. 子弹打到坦克,坦克会消失并且爆炸
  5. 敌方坦克自由移动且自由发射
  6. 我方坦克发射多颗子弹,并且设置同时存在的子弹数量上限
  7. 防止敌方坦克重叠并且设置移动范围
  8. 记录成绩,并且按照记录的信息继续上一局游戏

本次项目使用了:面向对象 OOP IO编程 文件编程 算法 GUI 多线程 线程知识

一、编写各种类

Tank类

  • 坦克类是我放坦克和敌方坦克的父类,包含了坦克的横坐标,纵坐标,方向与速度,还定义了坦克上下左右移动的方法
package Tank2.Tank;

import javax.swing.*;

public class Tank extends JFrame {
   
   
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int diret;//坦克的方向
    private int speed = 1;//控制速度
    boolean islive = true;

    public Tank(int x, int y )  {
   
   
        this.x = x;
        this.y = y;

    }

    public int getSpeed() {
   
   
        return speed;
    }

    public void setSpeed(int speed) {
   
   
        this.speed = speed;
    }

    //上右下左移动方法
    public void moveUp() {
   
   
        if (y > 0){
   
   
            y -= speed;
        }
    }
    public void moveRight() {
   
   
        if (x + 60 < 1000){
   
   
            x += speed;
        }
    }
    public void moveDown() {
   
   
        if (y + 60 < 750){
   
   
            y += speed;
        }
    }
    public void moveLeft() {
   
   
        if (x > 0){
   
   
            x -= speed;
        }
    }

    public int getDiret() {
   
   
        return diret;
    }

    public void setDiret(int diret) {
   
   
        this.diret = diret;
    }

    @Override
    public int getX() {
   
   
        return x;
    }

    public void setX(int x) {
   
   
        this.x = x;
    }

    @Override
    public int getY() {
   
   
        return y;
    }

    public void setY(int y) {
   
   
        this.y = y;
    }
}

Shot类

  • 子弹类,同样定义了横纵坐标还有方向与速度,但也加入了判断子弹是否还存活的布尔型,为后面子弹打中坦克会消亡做功能铺垫
  • 同时定义了移动的线程,因为子弹要一直动,所以要用到线程
  • 同时还加入了什么时候将子弹生命置为false的判断语句
package Tank2.Tank;

public class Shot implements Runnable{
   
   
    int x; //子弹x坐标
    int y; //子弹y坐标
    int direct = 0; //子弹方向
    int speed = 3; //子弹的速度
    boolean isLive = true; //子弹是否还存活

    //构造器
    public Shot(int x, int y, int direct) {
   
   
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

    //子弹要一直动,而且不能一下子就到边界,所以用了线程然后还加入了休眠代码
    @Override
    public void run() {
   
   //射击
        while (true) {
   
   

            //休眠 50毫秒
            try {
   
   
                Thread.sleep(50);
            } catch (InterruptedException e) {
   
   
                e.printStackTrace();
            }
            //根据方向来改变x,y坐标
            switch (direct) {
   
   
                case 0://上
                    y -= speed;
                    break;
                case 1://右
                    x += speed;
                    break;
                case 2://下
                    y += speed;
                    break;
                case 3://左
                    x -= speed;
                    break;
            }
            //当子弹移动到面板的边界时,就应该销毁(把启动的子弹的线程销毁),
            //判断子弹是否存活,当子弹打到坦克时会被置为flase,线程随之退出
            if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750 && isLive) ) {
   
   
                isLive = false;
                break;
            }

        }
    }
}

enemyTank类

  • 敌方坦克的类,继承了Tank父类,因为要一直动所以同样加入了线程
  • 本类多加了Shot集合,用来存放敌方坦克发射的子弹,也加入了判断是否死亡的布尔型
  • 这里提供一个方法,可以将MyPanel 的成员 Vector enemyTanks = new Vector<>();
    //设置到 enemyTank 的成员 enemyTanks
  • 提供了判断敌方坦克重叠的方法
  • 提供了坦克发射子弹的方法可以设置子弹上限,还有坦克自己随机移动的方法
package Tank2.Tank;

import java.util.Vector;

public class enemyTank extends Tank implements Runnable{
   
   
    //类里创建Shot集合
    Vector<Shot> shots = new Vector<>();
    //判断敌方坦克是否存在
    boolean islive = true;

    //增加成员,enemyTank 可以得到敌人坦克的Vector
    Vector<enemyTank> enemyTanks = new Vector<>();

    public enemyTank(int x, int y) {
   
   
        super(x, y);
    }


    //这里提供一个方法,可以将MyPanel 的成员 Vector<enemyTank> enemyTanks = new Vector<>();
    //设置到 enemyTank 的成员 enemyTanks
    public  void setEnemyTanks(Vector<enemyTank> enemyTanks) {
   
   
        this.enemyTanks = enemyTanks;
    }
    //编写方法,判断当前的这个敌人坦克,是否和 enemyTanks 中的其他坦克发生的重叠或者碰撞
    public boolean isTouchEnemyTank(){
   
   
        //判断当前敌人坦克(this) 方向
        switch (this.getDiret()) {
   
   
            case 0: //上
                //让当前敌人坦克和其它所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
   
   
                    //从vector 中取出一个敌人坦克
                    enemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
   
   
                        //如果敌人坦克是上/下
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDiret() == 0 || enemyTank.getDiret() == 2) {
   
   
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                        }
                        //如果敌人坦克是 右/左
                        //1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDiret() == 1 || enemyTank.getDiret() == 3) {
   
   
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                        }
                    }

                }
                break;
            case 1: //右
                //让当前敌人坦克和其它所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
   
   
                    //从vector 中取出一个敌人坦克
                    enemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
   
   
                        //如果敌人坦克是上/下
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDiret() == 0 || enemyTank.getDiret() == 2) {
   
   
                            //2. 当前坦克 右上角的坐标 [this.getX() + 60, this.getY()]
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                        }
                        //如果敌人坦克是 右/左
                        //1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDiret() == 1 || enemyTank.getDiret() == 3) {
   
   
                            //2. 当前坦克 右上角的坐标 [this.getX() + 60, this.getY()]
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                        }
                    }
                }
                break;
            case 2: //下
                //让当前敌人坦克和其它所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
   
   
                    //从vector 中取出一个敌人坦克
                    enemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
   
   
                        //如果敌人坦克是上/下
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDiret() == 0 || enemyTank.getDiret() == 2) {
   
   
                            //2. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 60]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                        }
                        //如果敌人坦克是 右/左
                        //1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDiret() == 1 || enemyTank.getDiret() == 3) {
   
   
                            //2. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 60]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                            //3. 当前坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                        }
                    }
                }
                break;
            case 3: //左
                //让当前敌人坦克和其它所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
   
   
                    //从vector 中取出一个敌人坦克
                    enemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
   
   
                        //如果敌人坦克是上/下
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDiret() == 0 || enemyTank.getDiret() == 2) {
   
   
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY() ]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                            //3. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 40]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
   
   
                                return true;
                            }
                        }
                        //如果敌人坦克是 右/左
                        //1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDiret() == 1 || enemyTank.getDiret() == 3) {
   
   
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY() ]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                            //3. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 40]
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
   
   
                                return true;
                            }
                        }
                    }
                }
                break;
        }
        return  false;
    }
    @Override
    public void run() {
   
   
        while (true){
   
   

            //这里我们判断如果shots size() < 15, 创建一颗子弹,放入到
            //shots集合,并启动
            if (islive && shots.size() < 15) {
   
   //一部坦克可以同时存在15颗子弹
                Shot s = null;
                //判断坦克的方向,创建对应的子弹
                switch (getDiret()) {
   
   
                    case 0:
                        s = new Shot(getX() + 20, getY(), 0);
                        break;
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值