java坦克大战练习。java基础项目。巩固java基础部分。

该项目是一个Java实现的坦克大战游戏,涉及多线程技术用于坦克的移动、子弹发射等,文件I/O用于保存游戏进度,数据库操作用Vector替代。游戏包含坦克及子弹的绘制,碰撞检测算法,以及继续上一局功能。难点在于防止敌方坦克重叠的逻辑判断。项目帮助巩固了Java基础并提升了问题解决能力。

项目演示视频

项目下载地址:Java坦克大战项目源码。-Java文档类资源-优快云文库

也可以关注我之后私信我留个邮箱留言要哪个源码,我会把源码

免费发送到你的邮箱。

用到的java技术

1.多线程

2.文件i/o操作

3.数据库

4.java面向对象编程


多线程技术应用到了坦克的子弹,移动,绘制,敌人坦克等等;

文件i/o操作作用到了保存坦克的数量以及坐标来实现继续上一局;

数据库当时是用Vector代替;


坦克及子弹的显示:显示是用的JPanel绘制实现的。

switch (direction) {
            case 0: //表示向上
                g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子
                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子
                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子
                g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒
                break;

部分实现代码

单独写的绘制坦克类,根据传进的方向参数而绘制出相应方向的坦克;


子弹碰撞检测:根据传进的子弹对象参数和坦克参数来进行相应的判定。

// 子弹碰撞检测方法
    public void BulletCollision(ShotBullet bulletBody, Tank TankBody) {
        switch (TankBody.getDirectionNum()) {
            case 0:
            case 2:
                if (bulletBody.x > TankBody.getX() &&
                        bulletBody.x < TankBody.getX() + 40 &&
                        bulletBody.y > TankBody.getY() &&
                        bulletBody.y < TankBody.getY() + 60) {
                    // 将子弹和敌人状态设为false,等同于杀死
                    bulletBody.bulletState = false;
                    TankBody.TankState = false;
                    // 子弹击中就把敌方坦克从vector里删除掉
                    enemyTankVector.remove(TankBody);
                    // 判断击中的坦克是不是enemytank类型如果是就把击毁坦克数加一
                    if (TankBody instanceof EnemyTank) {
                        Recorder.addWreckTankNum();
                    }
                    // 如果子弹碰到敌人则新建一个爆炸动画
                    Bomb bomb = new Bomb(TankBody.getX(), TankBody.getY());
                    bombVector.add(bomb);
                }
                break;

部分实现代码


// 判断己方子弹是否击中敌方坦克,依次遍历每个子弹依次判断
    public void hitEnemyTank() {
        for (int i = 0; i < ownHero.shotBulletVector.size(); i++) {
            ShotBullet shotBullet = ownHero.shotBulletVector.get(i);
            // shotBullet不能为空,同时shotBullet是活着的状态
            if (shotBullet != null && shotBullet.bulletState) {
                for (int j = 0; j < enemyTankVector.size(); j++) {
                    EnemyTank enemyTank = enemyTankVector.get(j);
                    BulletCollision(shotBullet, enemyTank);
                }
            }
        }
    }

这里是己方坦克是否击中敌方坦克


// 判断敌方子弹是否击中己方坦克,依次遍历每个子弹依次判断
    public void hitHeroTank() {
        // 先遍历敌方坦克数量
        for (int i = 0; i < enemyTankVector.size(); i++) {
            EnemyTank enemyTank = enemyTankVector.get(i);// 遍历取得敌方坦克
            // 遍历敌方坦克的子弹数量
            for (int j = 0; j < enemyTank.bulletsVector.size(); j++) {
                ShotBullet shotBullet = enemyTank.bulletsVector.get(j);// 取得敌方坦克子弹
                // 己方英雄和子弹必须是活的才会继续判断是否击中
                if (ownHero.TankState && shotBullet.bulletState) {
                    BulletCollision(shotBullet, ownHero);
                }
            }
        }
    }

判断敌方坦克是否击中自己


实现继续上一局:主要是把坦克的坐标写入到文件,需要的时候在读取。


    //写入txt文件的方法
    public static void infoWrite() {
        try {
            // 要存入的文件路径
            bw = new BufferedWriter(new FileWriter(filePath));

            bw.write(wreckTankNum + "\r\n");
            // 遍历坦克个数,把坐标写入到文件
            for (int i = 0; i < Recorder.enemyTankVector.size(); i++) {
                EnemyTank enemyTank = enemyTankVector.get(i);
                String tankInfo = enemyTank.getX() +
                        " " + enemyTank.getY() +
                        " " + enemyTank.getDirectionNum();
                bw.write(tankInfo + "\r\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

写入文件的方法


//用于读取filePath里的信息
    public static Vector<Nodes> getNodeAndEnemyTankInfo() {
        try {
            br = new BufferedReader(new FileReader(filePath));
            wreckTankNum = Integer.parseInt(br.readLine());
            String line = "";
            while ((line = br.readLine()) != null) {
                // 分割字符串,取得想要的部分
                String[] fileSplit = line.split(" ");
                Nodes nodes = new Nodes(Integer.parseInt(fileSplit[0]), Integer.parseInt(fileSplit[1])
                        , Integer.parseInt(fileSplit[2]));
                // 把nodes放到nodesVector里面
                nodesVector.add(nodes);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return nodesVector;
    }

读取文件方法

把读取的信息赋给一个集合里,到时候使用


如果用户选择的是继续上一局,用被赋值的集合初始化游戏坦克坐标

switch (userChoose) {
            case "1":// 表示开始新游戏
                // 把击毁坦克数量重置为零
                Recorder.setWreckTankNum(0);
                // 把敌方坦克遍历到enemyTanks里面
                for (int i = 0; i < enemyTankNumber; i++) {
                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);//创建敌人坦克
                    // 把enemyTankVector传到setEnemyTankVector方法中
                    enemyTank.setEnemyTankVector(enemyTankVector);

                    enemyTank.setDirectionNum(2);// 2表示下面方向
                    enemyTank.setSpeed(3);// 设置敌方坦克移动速度
                    new Thread(enemyTank).start();//启动敌方坦克移动线程
                    enemyTankVector.add(enemyTank);// 往vector里添加敌方坦克
                    ShotBullet enemyShotBullet = new ShotBullet(enemyTank.getX() + 20,
                            enemyTank.getY() + 60, enemyTank.getDirectionNum());
                    enemyTank.bulletsVector.add(enemyShotBullet);
                    new Thread(enemyShotBullet).start();// 启动敌方坦克子弹线程
                }
                // 表示用户输入正确
                judgeUserChoose = true;
                break;
            case "2":// 表示继续上次游戏
                // 把敌方坦克遍历到enemyTanks里面
                for (int i = 0; i < nodesVector.size(); i++) {
                    Nodes nodes = nodesVector.get(i);
                    EnemyTank enemyTank = new EnemyTank(nodes.getX(), nodes.getY());//创建敌人坦克
                    // 把enemyTankVector传到setEnemyTankVector方法中
                    enemyTank.setEnemyTankVector(enemyTankVector);

                    enemyTank.setDirectionNum(nodes.getDirection());// 表示方向
                    enemyTank.setSpeed(3);// 设置敌方坦克移动速度
                    new Thread(enemyTank).start();//启动敌方坦克移动线程
                    enemyTankVector.add(enemyTank);// 往vector里添加敌方坦克
                    ShotBullet enemyShotBullet = new ShotBullet(enemyTank.getX() + 20,
                            enemyTank.getY() + 60, enemyTank.getDirectionNum());
                    enemyTank.bulletsVector.add(enemyShotBullet);
                    new Thread(enemyShotBullet).start();// 启动敌方坦克子弹线程
                }
                // 表示用户输入正确
                judgeUserChoose = true;
                break;
        }

判断用户是否继续上一局


项目难点

这个项目的难点主要是设置敌方坦克不重叠的地方,其实用到的东西没那么难,主要是需要想到的地方很多。

//编写方法,判断当前的这个敌人坦克,是否和 enemyTanks 中的其他坦克发生的重叠或者碰撞
    public boolean judgeTankCollice() {
        // 判断当前敌人坦克(this)方向
        switch (this.getDirectionNum()) {
            case 0://上
                //让当前敌人坦克和其它所有的敌人坦克比较
                for (int i = 0; i < enemyTankVector.size(); i++) {
                    //从vector中取出一个敌人坦克
                    EnemyTank enemyTankGat = enemyTankVector.get(i);
                    //不和自己比较
                    if (enemyTankGat != this) {
                        //如果敌人坦克是上/下
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]
                        if (enemyTankGat.getDirectionNum() == 0 || enemyTankGat.getDirectionNum() == 2) {
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]
                            if (this.getX() >= enemyTankGat.getX()
                                    && this.getX() <= enemyTankGat.getX() + 40
                                    && this.getY() >= enemyTankGat.getY()
                                    && this.getY() <= enemyTankGat.getY() + 60) {
                                return true;
                            }
                            //3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]
                            if (this.getX() + 40 >= enemyTankGat.getX()
                                    && this.getX() + 40 <= enemyTankGat.getX() + 40
                                    && this.getY() >= enemyTankGat.getY()
                                    && this.getY() <= enemyTankGat.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人坦克是 右/左
                        //1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTankGat.getDirectionNum() == 1 || enemyTankGat.getDirectionNum() == 3) {
                            //2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]
                            if (this.getX() >= enemyTankGat.getX()
                                    && this.getX() <= enemyTankGat.getX() + 60
                                    && this.getY() >= enemyTankGat.getY()
                                    && this.getY() <= enemyTankGat.getY() + 40) {
                                return true;
                            }
                            //3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]
                            if (this.getX() + 40 >= enemyTankGat.getX()
                                    && this.getX() + 40 <= enemyTankGat.getX() + 60
                                    && this.getY() >= enemyTankGat.getY()
                                    && this.getY() <= enemyTankGat.getY() + 40) {
                                return true;
                            }
                        }
                    }

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

                        if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 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.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 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 < enemyTankVector.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTankVector.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上/下
                        //老韩分析
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 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.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 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 < enemyTankVector.size(); i++) {
                    //从vector 中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTankVector.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人坦克是上/下
                        //老韩分析
                        //1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]
                        //                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]

                        if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 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.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 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;
    }

判断重叠代码


结尾

通过这些项目让我学到了很多很多。让我巩固了java基础部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰忆往昔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值