用java手撸一个小游戏 --- 坦克大战

项目源码:阿里云盘分享https://www.aliyundrive.com/s/QfRtfSuY35w

工具:idea或其他

1.首先建一个包,我这里是com.test11。

2.在这个包里面建两个文件MyTankGame4.java和Members.java。MyTankGame4.java这个文件包含主要框架和带main的类。Members.java这个文件包含各种成员类,如Tank类,EnemyTank类,Hero类等等。

如图:

3.下面开始写代码,具体代码肯定没法一步一步讲,说说思路吧。

       先创建一个面板MyPanel,在面板里画出自己坦克。我们思路是用3个长方形和1条直线段来绘制坦克,这个坦克长为30像素,宽20像素。其中左右的长方形长为30,宽为5。中间的长方形长为20,宽为10。我们把画坦克这个过程封装一下成为drawTank。敌人坦克和自己的坦克就用颜色区别,每个坦克的方向为  上右下左  分别用  0123  来代表。

自己坦克的移动可以用监听机制来处理 wasd 来控制上下左右,j是攻击。敌人坦克的移动可以写个随机函数来让他随机变换方向

//随机产生一个新方向
            this.direct = (int)(Math.random()*4);

Math.random()函数会随机产生一个0<Math.random()<1之间的小数,那么Math.random()*4的范围就是0<Math.random()*4<4,再取整就是随机取0 1 2 3 了。 

      当然,无论是自己坦克的移动还是敌人坦克的移动都需要用到线程,在run()函数里不断的重绘MyPanel面板才能实现视觉上的移动效果。

      发射子弹需要先写一个子弹类,然后用监听机制加到坦克里面。发射后需要在run()函数里让他时时刻刻检测是否击中敌人或敌人是否击中了自己(这也是游戏占内存比较大的原因之一:你需要不断的判断子弹是否击中敌人/自己)。

      如果子弹击中敌人/自己,那么我们可以加入已经写好的炸弹类Bomb来实现爆炸特效。

      防止敌人坦克重叠也是时时刻刻检测和判断一个敌人和其余敌人的位置关系,自己画图来解决。

      做开始界面是JFrame的知识。

      做暂停和继续只需用监听机制,按下空格时让所有子弹的速度以及自己和敌人坦克的速度都为0,再按空格速度恢复。

      记录分数是在子弹击中敌人坦克的时候用变量做累加,最后显示出来。

      存档退出用到了文件流操作,每当进行存档退出时,我们可以把当前所有坦克的坐标以及方向记录下来保存到txt文件里,下次进入游戏时,如果点击继续上局游戏,就会读取txt文件里的内容,并把坦克按这个位置绘制。

      最后是坦克的爆炸音效,背景音乐也是文件流的操作。

********注意:如果是想复制我的代码试试效果的话,里面的路径要根据自己的位置来改变,爆炸图片在这里 ——> 传送门,至于音效的话网上找一下爆炸音效和背景音乐,然后把项目里面响应的路径改了就可以了。关于替换路径,可能有些人不太会,这里提供一种方法,你ctrl+f搜一下TankFire依次往下替换路径就可以,因为我所有用到路径的地方都用到了TankFire。

另外,由于文件流的处理,还要在

D:\java项目\TankFire路径(根据自己的路径)下先新建一个Rec.txt文件

这两个文件的内容如下: 

 (1)MyTankGame4类

/**
 * 功能:坦克大战 4.0
 * 1.画出坦克
 * 2.我的坦克可以移动
 * 3.坦克可以发射炮弹(炮弹可以连发,最多5发)
 * 4.炮弹击中敌人时敌人会死亡并有爆炸特效
 * 5.敌人坦克可以随机移动
 * 6.敌人坦克也可以发射子弹
 * 7.敌人坦克击中我的坦克时,我的坦克爆炸
 * 8.防止敌人坦克重叠
 * 9.可以分关(有开始界面和闪烁的效果)
 * 10.可以暂停和继续
 * 11.可以记录分数
 *    11.1可以记录玩家分数
 *    11.2可以记录敌人的坐标
 *    11.3可以存档退出和继续游戏
 * 12.可以处理声音文件
 */
package com.test11;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.util.Vector;

public class MyTankGame4 extends JFrame implements ActionListener {
    MyPanel mp = null;
    MyStartPanel msp = null;
    JMenuBar jmb = null;
    JMenu jm1 = null;
    JMenu jm2 = null;
    JMenu jm3 = null;
    JMenuItem jmi1 = null;
    JMenuItem jmi2 = null;
    JMenuItem jmi3 = null;
    JMenuItem jmi4 = null;
    public static int jud = 0;

    public static void main(String[] args) throws IOException {
        MyTankGame4 mtg = new MyTankGame4();
    }

    public MyTankGame4() throws IOException {
        jmb = new JMenuBar();
        jm1 = new JMenu("游戏(G)");
        jm2 = new JMenu("暂停(空格)");
        jm3 = new JMenu("开始(空格)");
        jmi1 = new JMenuItem("开始新游戏(N)");
        jmi2 = new JMenuItem("退出游戏(E)");
        jmi3 = new JMenuItem("存档退出");
        jmi4 = new JMenuItem("继续上局游戏");
        //注册监听
        jmi1.addActionListener(this);
        jmi1.setActionCommand("new game");
        jmi2.addActionListener(this);
        jmi2.setActionCommand("exit");
        jmi3.addActionListener(this);
        jmi3.setActionCommand("save and exit");
        jmi4.addActionListener(this);
        jmi4.setActionCommand("continue");

        //设置快捷方式
        jm1.setMnemonic('G');
        jmi1.setMnemonic('N');
        jmi2.setMnemonic('E');
        jm1.add(jmi1);
        jm1.add(jmi2);
        jm1.add(jmi3);
        jm1.add(jmi4);
        jmb.add(jm1);
        jmb.add(jm2);
        jmb.add(jm3);
        this.setJMenuBar(jmb);

        msp = new MyStartPanel();
        this.add(msp);
        Thread t = new Thread(msp);
        t.start();

        this.setSize(600,500);
        this.setLocation(500,220);
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getActionCommand().equals("new game")){
            jud = 1;
            this.remove(msp);
            try {
                mp = new MyPanel(0);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            this.add(mp);
            Thread t = new Thread(mp);
            t.start();
            this.addKeyListener(mp);
            this.setVisible(true);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        }else if(e.getActionCommand().equals("exit")){
            Recorder.Rec();
            System.exit(0);
        }else if(e.getActionCommand().equals("save and exit")){
            Recorder rd = new Recorder();
            rd.setEts(mp.ets);
            rd.RecAndEnemyRec();
            System.exit(0);
        }else if(e.getActionCommand().equals("continue")){
            this.remove(msp);
            try {
                mp = new MyPanel(1);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            this.add(mp);
            Thread t = new Thread(mp);
            t.start();
            this.addKeyListener(mp);
            this.setVisible(true);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        }
    }
}

//我的开始面板
class MyStartPanel extends JPanel implements Runnable{
    int times = 0;

    public MyStartPanel() throws IOException {
        MyPanel mp= new MyPanel(0);
        mp.palyAudio();
        MyPanel.playtime = 2;
    }

    public void paint(Graphics g){
        super.paint(g);
        g.fillRect(0,0,600,500);
        if(times%2==0) {
            g.setColor(Color.yellow);
            Font myFont = new Font("华文新魏", Font.BOLD, 30);
            g.setFont(myFont);
            g.drawString("Stage 1!", 220, 180);
        }
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            times++;
            this.repaint();
        }
    }
}

//我的面板
class MyPanel extends JPanel implements KeyListener,Runnable {
    //定义一个我的坦克
    Hero hero = null;

    //定义敌人坦克集合
    Vector<EnemyTank> ets = new Vector<EnemyTank>();

    //定义一个炸弹集合
    Vector<Bomb> bombs = new Vector<Bomb>();

    int enSize = 10;
    public static int playtime = 1;
    public static int pressReflect = 1;

    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    //构造函数
    public MyPanel(int flag) throws IOException {
        Vector<Node> nodes = new Vector<Node>();
        if(MyTankGame4.jud==1) {
            System.out.println("asfodafes");

            File f = new File("D:\\java项目\\TankFire\\Rec.txt");
            FileWriter fw = new FileWriter("D:\\java项目\\TankFire\\Rec.txt");
            BufferedWriter bw = new BufferedWriter(fw);
            f.delete();
            try {
                f.createNewFile();
                bw.write(0+"");
            } catch (Exception e1) {
                e1.printStackTrace();
            }finally {
                try {
                    bw.close();
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        nodes = Recorder.getRecAndEnemy();
        Recorder.getRec();
        hero = new Hero(100,100);

        if(flag==0) {
            //初始化敌人坦克
            for (int i = 0; i < enSize; i++) {
                EnemyTank et = new EnemyTank((i + 1) * 50, 0);
                et.setColor(1);
                et.setDirect(2);
                //启动坦克
                Thread t = new Thread(et);
                t.start();
                //添加敌人子弹
                Shot s = new Shot(et.x + 10, et.y + 30, 2);
                et.ss.add(s);
                //启动子弹线程
                Thread t1 = new Thread(s);
                t1.start();
                ets.add(et);
                //将其他敌人坦克交给该敌人坦克
                et.getTanks(ets);
            }
        }else{
            //初始化敌人坦克
            for (int i = 0; i < nodes.size(); i++) {
                Node node = nodes.get(i);
                EnemyTank et = new EnemyTank(node.x, node.y);
                et.setColor(1);
                et.setDirect(2);
                //启动坦克
                Thread t = new Thread(et);
                t.start();
                //添加敌人子弹
                Shot s = new Shot(et.x + 10, et.y + 30, 2);
                et.ss.add(s);
                //启动子弹线程
                Thread t1 = new Thread(s);
                t1.start();
                ets.add(et);
                //将其他敌人坦克交给该敌人坦克
                et.getTanks(ets);
            }
        }

        //播放音乐
        palyAudio();

        //初始化图片
//        image1 = Toolkit.getDefaultToolkit().getImage("bomb1.png");
//        image2 = Toolkit.getDefaultToolkit().getImage("bomb2.png");
//        image3 = Toolkit.getDefaultToolkit().getImage("bomb3.png");

        try {
            image1 = ImageIO.read(new File("bomb1.png"));
            image2 = ImageIO.read(new File("bomb2.png"));
            image3 = ImageIO.read(new File("bomb3.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void palyAudio(){
        //播放音乐
        AePlayWave apw = null;
        AePlayWave apw2 = null;
        AePlayWave apw3 = null;
        AePlayWave apw4 = null;
        AePlayWave shot = null;
        apw = new AePlayWave("D:\\java项目\\TankFire\\Source\\Sound\\start.wav");
        apw2 = new AePlayWave("D:\\java项目\\TankFire\\Source\\Sound\\background2.wav");
        apw3 = new AePlayWave("D:\\java项目\\TankFire\\Source\\Sound\\explosion.wav");
        apw4 = new AePlayWave("D:\\java项目\\TankFire\\Source\\Sound\\explosion2.wav");
        shot = new AePlayWave("D:\\java项目\\TankFire\\Source\\Sound\\shot.wav");

        if(playtime==1){
            apw.start();
        }else if(playtime==2){
            apw2.start();
        }if(playtime==3){
            apw3.start();
        }if(playtime==4){
            apw4.start();
        }if(playtime==5){
            shot.start();
        }
    }

    //画出提示信息
    public void showInfo(Graphics g){
        //画出提示信息坦克(该坦克不参与战斗)
        this.drawTank(100,405,g,1,0);
        g.setColor(Color.black);
        g.drawString(Recorder.getEnNum()+"",130,425);
        this.drawTank(500,405,g,0,0);
        g.setColor(Color.black);
        g.drawString(Recorder.getMyLife()+"",530,425);
        Font myFont = new Font("宋体",Font.BOLD,15);
        g.setFont(myFont);
        g.drawString("你的总成绩:",200,425);
        this.drawTank(290,405,g,1,0);
        g.setColor(Color.black);
        g.drawString(Recorder.getKillEnemy()+"",320,425);
    }

    //重新paint
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0,0,600,400);
        //画出提示信息
        showInfo(g);

        //画出自己的坦克和子弹
        if(hero.isLive) {
            //画坦克
            this.drawTank(hero.getX(), hero.getY(), g, 0, this.hero.direct);
        }
        //画子弹
        for(int i=0;i<hero.ss.size();i++) {
            Shot myShot = hero.ss.get(i);//遍历向量中的每颗子弹

            //画出每颗子弹
            if (myShot != null && myShot.isAlive == true) {
                g.draw3DRect(myShot.getX(), myShot.getY(), 1, 1, false);
            }
            //从向量中去掉死亡的子弹
            if(myShot.isAlive == false){
                hero.ss.remove(myShot);
            }
        }
        //画出敌人的坦克和子弹
        for (int i = 0; i < ets.size(); i++) {
            EnemyTank et = ets.get(i);
            if(et.isLive==true) {
                //画坦克
                this.drawTank(et.getX(), et.getY(), g, 1, et.getDirect());
            }
            //画子弹
            for(int j=0;j<et.ss.size();j++){
                Shot enemyShot = et.ss.get(j);
                if(enemyShot.isAlive == true){
                    g.draw3DRect(enemyShot.getX(), enemyShot.getY(), 1, 1, false);
                }else {
                    et.ss.remove(enemyShot);
                }
            }

        }

        //画出炸弹
        for(int i=0;i<bombs.size();i++){
            Bomb b = bombs.get(i);

            if(b.life>6){
                g.drawImage(image1,b.x,b.y,30,30,this);
//                System.out.println("第1张图已画出");
            } else if(b.life>3){
                g.drawImage(image2,b.x,b.y,30,30,this);
//                System.out.println("第2张图已画出");
            } else{
                g.drawImage(image3,b.x,b.y,30,30,this);
//                System.out.println("第3张图已画出");
            }
            //生命值减小
            b.lifeDown();
            //如果炸弹的生命值为0,将该炸弹从向量中剔除
            if(b.life==0){
                bombs.remove(b);
            }
        }
    }
    //判断敌人坦克是否击中我
    public void hitMe(){
        for(int i=0;i<ets.size();i++){
            EnemyTank et = ets.get(i);
            for(int j=0;j<et.ss.size();j++){
                Shot s = et.ss.get(j);
                if(hero.isLive) {
                    hitTank(s,hero);
                }
            }
        }
    }

    //判断我的子弹是否击中敌人
    public void hitEnemyTank(){
        //判断是否子弹是否打中坦克
        for(int i=0;i<hero.ss.size();i++){
            //取出每颗子弹
            Shot myShot = hero.ss.get(i);
            if(myShot.isAlive){
                for(int j=0;j<ets.size();j++){
                    //遍历每个敌人坦克
                    EnemyTank et = ets.get(j);
                    if(et.isLive==true) {
                        hitTank(myShot, et);
                    }
                }
            }
        }
    }

    //判断坦克是否击中敌人坦克
    public void hitTank(Shot s, Tank et){
        switch (et.direct){
            case 0:
            case 2:
                if(s.getX()<et.getX()+20&&s.getX()>et.getX()&&s.getY()>et.getY()&&s.getY()<et.getY()+30){//击中敌军,子弹死亡,敌人坦克死亡
                    s.isAlive = false;
                    et.isLive = false;
                    if(et.color==1) {
                        playtime = 3;
                        palyAudio();
                        Recorder.reduceEnemy();
                        Recorder.addkillEnemy();
                    }
                    if(et.color==0){
                        playtime = 4;
                        palyAudio();
                        Recorder.reduceMe();
                    }
                    Bomb b = new Bomb(et.getX(),et.getY());
                    bombs.add(b);
                }
                break;
            case 1:
            case 3:
                if(s.getX()<et.getX()+30&&s.getX()>et.getX()&&s.getY()>et.getY()&&s.getY()<et.getY()+20){//击中敌军,子弹死亡,敌人坦克死亡
                    s.isAlive = false;
                    et.isLive = false;
                    if(et.color==1) {
                        playtime = 3;
                        Recorder.reduceEnemy();
                        Recorder.addkillEnemy();
                        palyAudio();
                    }
                    if(et.color==0){
                        playtime = 4;
                        Recorder.reduceMe();
                        palyAudio();
                    }
                    Bomb b = new Bomb(et.getX(),et.getY());
                    bombs.add(b);
                }
                break;
        }
    }

    //画出坦克
    public void drawTank(int x,int y,Graphics g,int type,int direct) {
        //判断坦克类型
        switch (type) {
            case 0:
                g.setColor(Color.cyan);
                break;
            case 1:

                g.setColor(Color.yellow);
                break;
            default:
                break;
        }

        //判断方向
        switch (direct) {
            //向上
            case 0:
                g.fill3DRect(x,y,5,30,false);
                g.fill3DRect(x+15,y,5,30,false);
                g.fill3DRect(x+5,y+5,10,20,false);
                g.fillOval(x+5,y+10,10,10);
                g.drawLine(x+10,y+15,x+10,y);
                break;
            //向右
            case 1:
                g.fill3DRect(x,y,30,5,false);
                g.fill3DRect(x,y+15,30,5,false);
                g.fill3DRect(x+5,y+5,20,10,false);
                g.fillOval(x+10,y+5,10,10);
                g.drawLine(x+15,y+10,x+30,y+10);
                break;
            //向下
            case 2:
                g.fill3DRect(x,y,5,30,false);
                g.fill3DRect(x+15,y,5,30,false);
                g.fill3DRect(x+5,y+5,10,20,false);
                g.fillOval(x+5,y+10,10,10);
                g.drawLine(x+10,y+15,x+10,y+30);
                break;
            //向左
            case 3:
                g.fill3DRect(x,y,30,5,false);
                g.fill3DRect(x,y+15,30,5,false);
                g.fill3DRect(x+5,y+5,20,10,false);
                g.fillOval(x+10,y+5,10,10);
                g.drawLine(x+15,y+10,x,y+10);
                break;
            default:
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //wasd控制方向上下左右
    @Override
    public void keyPressed(KeyEvent e) {
        //设置我的坦克方向
        if(e.getKeyCode() == KeyEvent.VK_W) {
            this.hero.setDirect(0);
            this.hero.moveUp();
        }if(e.getKeyCode() == KeyEvent.VK_A){
            this.hero.setDirect(3);
            this.hero.moveLeft();
        }if(e.getKeyCode() == KeyEvent.VK_S){
            this.hero.setDirect(2);
            this.hero.moveDown();
        }if(e.getKeyCode() == KeyEvent.VK_D){
            this.hero.setDirect(1);
            this.hero.moveRight();
        }
        if(e.getKeyCode() == KeyEvent.VK_J){
            if(hero.ss.size()<=4) {
                this.hero.shotEnemy();
                playtime = 5;
                palyAudio();
            }
        }
        if(e.getKeyCode() == KeyEvent.VK_SPACE){
                pressReflect++;
                if(pressReflect%2==0) {
                    speedTozero();
                }else{
                    speedRefresh();
                }
        }

        this.repaint();
    }

    public void speedTozero(){
        for(int i=0;i<ets.size();i++){
            EnemyTank et = ets.get(i);
            et.speed = 0;
            for(int j=0;j<et.ss.size();j++){
                Shot s = et.ss.get(j);
                s.speed = 0;
            }
        }
        hero.speed = 0;
    }

    public void speedRefresh(){
        for(int i=0;i<ets.size();i++){
            EnemyTank et = ets.get(i);
            et.speed = 3;
            for(int j=0;j<et.ss.size();j++){
                Shot s = et.ss.get(j);
                s.speed = 3;
            }
        }
        hero.speed = 3;
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    public void run(){
        while (true){
            try {
                Thread.sleep(50);
                playtime++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断我是否击中敌人坦克
            this.hitEnemyTank();
            //判断敌人坦克是否击中我
            this.hitMe();
            if(pressReflect%2==1) {
                this.repaint();
            }
        }
    }
}

(2)Members类 

package com.test11;

import javax.sound.sampled.*;
import java.io.*;
import java.util.Vector;

class Node{
    int x;
    int y;
    int direct;
    public Node(int x,int y,int direct){
        this.x = x;
        this.y = y;
        this.direct = direct;
    }
}

//声音类
class AePlayWave extends Thread{
    private String filename;

    public AePlayWave(String wavefile){
        filename = wavefile;
    }

    public void run(){
        File SoundFile = new File(filename);

        AudioInputStream audioInputStream = null;

        try {
            audioInputStream = AudioSystem.getAudioInputStream(SoundFile);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        AudioFormat Format = audioInputStream.getFormat();
        SourceDataLine sdl = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class,Format);

        try {
            sdl = (SourceDataLine)AudioSystem.getLine(info);
            sdl.open(Format);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        sdl.start();
        int nBytesRead = 0;
        //缓冲
        byte[] abData = new byte [1024];
        try {
            while(nBytesRead!=-1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) {
                    sdl.write(abData, 0, nBytesRead);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        } finally {
            sdl.drain();
            sdl.close();
        }
    }
}


//记录类
class Recorder{
    //记录敌人坦克的数量
    private static int EnNum = 10;
    //记录自己的坦克数量
    private static int myLife = 3;
    //记录总成绩
    private static int killEnemy = 0;
    //定义输入输出流
    private static FileWriter fw = null;
    private static BufferedWriter bw = null;
    private static FileReader fr = null;
    private static BufferedReader br = null;
    private Vector<EnemyTank> ets = new Vector<EnemyTank>();
    static Vector<Node> nodes = new Vector<Node>();

    public static Vector<Node> getRecAndEnemy(){
        try {
            fr = new FileReader("D:\\java项目\\TankFire\\Rec.txt");
            br = new BufferedReader(fr);
            String n = "";
            n = br.readLine();
            killEnemy = Integer.parseInt(n);

            while((n=br.readLine())!=null){
                String []xyz = n.split(" ");
                Node node = new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]));
                nodes.add(node);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return nodes;
    }

    public static void Rec(){
        File f = new File("D:\\java项目\\TankFire\\Rec.txt");
        f.delete();
        try {
            f.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void getRec(){
        try {
            fr = new FileReader("D:\\java项目\\TankFire\\Rec.txt");
            br = new BufferedReader(fr);
            String n = br.readLine();
            killEnemy = Integer.parseInt(n);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void RecAndEnemyRec(){
        try {
            fw = new FileWriter("D:\\java项目\\TankFire\\Rec.txt");
            bw = new BufferedWriter(fw);
            bw.write(killEnemy+"\r\n");

            for(int i=0;i<ets.size();i++){
                EnemyTank em = ets.get(i);
                if(em.isLive){
                    String x = em.x+" "+em.y+" "+em.direct;
                    bw.write(x+"\r\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bw.close();
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static int getKillEnemy() {
        return killEnemy;
    }

    public static void setKillEnemy(int killEnemy) {
        Recorder.killEnemy = killEnemy;
    }

    public static int getEnNum() {
        return EnNum;
    }

    public static void setEnNum(int enNum) {
        EnNum = enNum;
    }

    public static int getMyLife() {
        return myLife;
    }

    public static void setMyLife(int myLife) {
        Recorder.myLife = myLife;
    }

    public Vector<EnemyTank> getEts() {
        return ets;
    }

    public void setEts(Vector<EnemyTank> ets) {
        this.ets = ets;
    }

    public static void reduceEnemy(){
        EnNum--;
    }

    public static void reduceMe(){
        myLife--;
    }

    public static void addkillEnemy(){
        killEnemy++;
    }

}

//子弹类
class Shot implements Runnable{
    int x;
    int y;
    int direct;
    int speed = 2;
    boolean isAlive = true;

    public int getX() {
        return x;
    }

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

    public int getY() {
        return y;
    }

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

    public Shot(int x, int y,int direct) {
        this.x = x;
        this.y = y;
        this.direct = direct;
    }

    public void run(){
        while(true){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            switch (direct){
                case 0:
                    y -= speed;
                    break;
                case 1:
                    x += speed;
                    break;
                case 2:
                    y += speed;
                    break;
                case 3:
                    x -= speed;
                    break;
            }
            if(x<=0||x>=600||y>=400||y<=0){
                isAlive = false;
                break;
            }
//            System.out.println("x = "+x+" y = "+y);
        }
    }
}

//坦克类
class Tank {
    int x = 0;
    int y = 0;
    boolean isLive = true;

    //坦克颜色
    int color ;

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    //坦克的速度
    int speed = 2;
    public int getSpeed() {
        return speed;
    }

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

    //0表示上  1表示右  2表示下  3表示左
    int direct = 0;

    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }

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

    public int getX() {
        return x;
    }

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

    public int getY() {
        return y;
    }

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

//我的坦克
class Hero extends Tank {
    Vector<Shot> ss = new Vector<Shot>();
    Shot s = null;

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

    //向上移动
    public void moveUp(){
        if(y>0) {
            y -= speed;
        }
    }

    //向下移动
    public void moveDown(){
        if(y<370) {
            y += speed;
        }
    }

    //向左移动
    public void moveLeft(){
        if(x>0) {
            x -= speed;
        }
    }

    //向右移动
    public void moveRight(){
        if(x<570) {
            x += speed;
        }
    }

    public void shotEnemy(){
        switch (this.direct){
            case 0:
                //创建一颗子弹
                s = new Shot(x+10,y,0);
                //讲子弹加入到向量中
                ss.add(s);
                break;
            case 1:
                s = new Shot(x+30,y+10,1);
                ss.add(s);
                break;
            case 2:
                s = new Shot(x+10,y+30,2);
                ss.add(s);
                break;
            case 3:
                s = new Shot(x,y+10,3);
                ss.add(s);
                break;
        }
        Thread t = new Thread(s);
        t.start();
    }
}

//敌人坦克类
class EnemyTank extends Tank implements Runnable{
    //创建敌人坦克集合用于得到其他所有坦克的集合
    Vector<EnemyTank> ets = new Vector<EnemyTank>();
    //创建敌人的子弹集合,敌人添加子弹应当在刚创建坦克和子弹死亡后
    Vector<Shot> ss = new Vector<Shot>();
    //敌人坦克的速度
    int speed = 2;
    int times = 0;

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

    public void getTanks(Vector<EnemyTank> em){
        this.ets = em;
    }

    //判断该敌人坦克是否与其他敌人坦克重叠
    public boolean isTouchOtherEnemyTank(){
        boolean b = false;

        switch (this.direct) {
            //该敌人坦克向上
            case 0:
                for (int i = 0; i < ets.size(); i++) {
                    //取出所有敌人坦克
                    EnemyTank et = ets.get(i);
                    if (et != this) {
                        //如果其他敌人坦克向上或向下
                        if (et.direct == 0 || et.direct == 2) {
                            if (this.x > et.x && this.x < et.x + 20 && this.y > et.y && this.y < et.y + 30) {
                                return true;
                            }
                            if (this.x + 20 > et.x && this.x + 20 < et.x + 20 && this.y > et.y && this.y < et.y + 30) {
                                return true;
                            }
                        }
                        //如果其他敌人坦克向左或向右
                        if (et.direct == 1 || et.direct == 3) {
                            if (this.x > et.x && this.x < et.x + 30 && this.y > et.y && this.y < et.y + 20) {
                                return true;
                            }
                            if (this.x + 20 > et.x && this.x + 20 < et.x + 30 && this.y > et.y && this.y < et.y + 20) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 1:
                for (int i = 0; i < ets.size(); i++) {
                    //取出所有敌人坦克
                    EnemyTank et = ets.get(i);
                    if (et != this) {
                        //如果其他敌人坦克向上或向下
                        if (et.direct == 0 || et.direct == 2) {
                            if (this.x + 30 > et.x && this.x + 30 < et.x + 20 && this.y > et.y && this.y < et.y + 30) {
                                return true;
                            }
                            if (this.x + 30 > et.x && this.x + 30 < et.x + 20 && this.y + 20 > et.y && this.y + 20 < et.y + 30) {
                                return true;
                            }
                        }
                        //如果其他敌人坦克向左或向右
                        if (et.direct == 1 || et.direct == 3) {
                            if (this.x + 30 > et.x && this.x + 30 < et.x + 30 && this.y > et.y && this.y < et.y + 20) {
                                return true;
                            }
                            if (this.x + 30 > et.x && this.x + 30 < et.x + 30 && this.y + 20 > et.y && this.y + 20 < et.y + 20) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 2:
                for (int i = 0; i < ets.size(); i++) {
                    //取出所有敌人坦克
                    EnemyTank et = ets.get(i);
                    if (et != this) {
                        //如果其他敌人坦克向上或向下
                        if (et.direct == 0 || et.direct == 2) {
                            if (this.x > et.x && this.x < et.x + 20 && this.y + 30 > et.y && this.y + 30 < et.y + 30) {
                                return true;
                            }
                            if (this.x + 20 > et.x && this.x + 20 < et.x + 20 && this.y > et.y && this.y < et.y + 30) {
                                return true;
                            }
                        }
                        //如果其他敌人坦克向左或向右
                        if (et.direct == 1 || et.direct == 3) {
                            if (this.x > et.x && this.x < et.x + 30 && this.y + 30 > et.y && this.y + 30 < et.y + 20) {
                                return true;
                            }
                            if (this.x + 20 > et.x && this.x + 20 < et.x + 30 && this.y + 30 > et.y && this.y + 30 < et.y + 20) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case 3:
                for (int i = 0; i < ets.size(); i++) {
                    //取出所有敌人坦克
                    EnemyTank et = ets.get(i);
                    if (et != this) {
                        //如果其他敌人坦克向上或向下
                        if (et.direct == 0 || et.direct == 2) {
                            if (this.x > et.x && this.x < et.x + 20 && this.y > et.y && this.y < et.y + 30) {
                                return true;
                            }
                            if (this.x > et.x && this.x < et.x + 20 && this.y + 20 > et.y && this.y + 20 < et.y + 30) {
                                return true;
                            }
                        }
                        //如果其他敌人坦克向左或向右
                        if (et.direct == 1 || et.direct == 3) {
                            if (this.x > et.x && this.x < et.x + 30 && this.y > et.y && this.y < et.y + 20) {
                                return true;
                            }
                            if (this.x > et.x && this.x < et.x + 30 && this.y + 20 > et.y && this.y + 20 < et.y + 20) {
                                return true;
                            }
                        }
                    }
                }
                break;
        }
        return b;
    }

    public void run(){
        //让敌人坦克随机移动
        while (true){
            switch (this.direct){
                case 0:
                    for(int i=0;i<30;i++){
                        if(y>0&&!this.isTouchOtherEnemyTank()) {
                            y -= speed;
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1:
                    for(int i=0;i<30;i++){
                        if(x<570&&!this.isTouchOtherEnemyTank()) {
                            x += speed;
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2:
                    for(int i=0;i<30;i++){
                        if(y<370&&!this.isTouchOtherEnemyTank()) {
                            y += speed;
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3:
                    for(int i=0;i<30;i++){
                        if(x>0&&!this.isTouchOtherEnemyTank()) {
                            x -= speed;
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
            //随机产生一个新方向
            this.direct = (int)(Math.random()*4);

            if(this.isLive == false){
                break;
            }
            times++;
            //判断是否要给敌人坦克加入子弹
            if(times%2==0) {
                if (isLive == true) {
                    if (ss.size() < 5) {
                        Shot s = null;
                        //没有子弹,添加子弹
                        switch (direct) {
                            case 0:
                                //创建一颗子弹
                                s = new Shot(x + 10, y, 0);
                                //将子弹加入到向量中
                                ss.add(s);
                                break;
                            case 1:
                                s = new Shot(x + 30, y + 10, 1);
                                ss.add(s);
                                break;
                            case 2:
                                s = new Shot(x + 10, y + 30, 2);
                                ss.add(s);
                                break;
                            case 3:
                                s = new Shot(x, y + 10, 3);
                                ss.add(s);
                                break;
                        }
                        //启动线程
                        Thread t = new Thread(s);
                        t.start();
                    }
                }
            }
        }
    }
}

//炸弹类
class Bomb{
    int x;
    int y;
    //炸弹的生命
    int life = 9;
    boolean isLive = true;

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

    //减少生命值
    public void lifeDown(){
        if(life>0){
            life--;
        }else{
            this.isLive = false;
        }
    }
}

最终效果图

里面有背景音乐和爆炸音效,有爆炸特效,有开始和暂停功能,有开始新游戏,存档退出,直接退出和继续上局游戏的功能。

这个小案例仅供参考,我是没继续往下做了,做这个真的很耗时,如果遇到bug真的很烧脑,我终于知道为什么计算机容易秃顶了。但是总之挺开心的, 自己的第一个项目,知道到了什么叫真正的项目! 有问题欢迎留言提出。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小的香辛料

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

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

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

打赏作者

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

抵扣说明:

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

余额充值