zoukankan      html  css  js  c++  java
  • 面向对象经典案例坦克大战


    package Tank;

    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.util.*;
    import javax.swing.*;

    /**
     * @author Administrator
     *包含主方法, MyPanel面板绘制我的坦克
     *2.画黄色坦克
     *lession3.画四个方向的坦克
     *4.坦克动起来+绘制3个敌人坦克
     *5.绘制子弹,子弹做成线程类
     *6.子弹连发,安排子弹只在画布中活动
     *7.限制子弹连发数在 KeyEvent.VK_J,子弹打中坦克方法 2层for循环
     *8.放入爆炸类图片 myPanel()新建图片对象,在原材料里新建爆炸类,在paint()里画爆炸效果,图片是和包同一级目录
     *9.敌人坦克动起来 做成线程类,难点自动调用重绘
     *10.敌人坦克围着屏幕转,敌人坦克发射子弹 在画坦克时 画敌人子弹
     *11.敌人坦克不能互相碰撞
     *12.制作开始游戏时的关卡显示面板
     *13.绘制新游戏菜单 开始我的面板    在原材料类新建Jilu类 定义静态方法敌人数量减少,然后在击中双方方法里调用
     *MyPanel里有tjsl()画出来 敌我坦克数量减少 显示在面板
     *14.每次开启游戏时,自动获得上次打死坦克数量  在右上面板显示
     *15.存盘退出 在记录类新建2个方法 MyPanel()里调用读取记录方法
     *16.新建存盘退出方法  新建位置类
     *17.Jilu类新建读盘方法  MyPanel()修改构造方法 增加if else判断
     *18.加上出场声音
     */
    public class Tank1 extends JFrame implements ActionListener{
        private MyPanel mp=null;
        private GuangkaPanel gkmp=null;
        private JMenuBar jmenuBar;
        private JMenu cd1;
        private JMenuItem cdx1,cdx2,cdx3,cdx4;
        public Tank1() {
            jmenuBar=new JMenuBar();
            cd1=new JMenu("游戏(G)");
            cd1.setMnemonic('G');
            cdx1=new JMenuItem("新游戏(N)");
            cdx2=new JMenuItem("退出游戏(E)");
            cdx3=new JMenuItem("存盘退出(C)");
            cdx4=new JMenuItem("继续游戏(S)");
            cdx1.addActionListener(this);cdx2.addActionListener(this);
            cdx3.addActionListener(this);cdx4.addActionListener(this);
            cdx1.setActionCommand("newGame");cdx2.setActionCommand("exit");
            cdx3.setActionCommand("saveExit");cdx4.setActionCommand("goonGame");
            cd1.add(cdx1);cd1.add(cdx2);cd1.add(cdx3);cd1.add(cdx4);
            jmenuBar.add(cd1);
            this.setJMenuBar(jmenuBar);
            this.setIconImage((new ImageIcon("tank.jpg")).getImage());
            
            gkmp=new GuangkaPanel();    
            Thread t=new Thread(gkmp);
            t.start();
            this.add(gkmp);        
            
            this.setSize(600, 500);
            this.setLocation(300, 280);
            this.setResizable(false);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
            this.setTitle("坦克大战");
        }
        public static void main(String[] args) {
            Tank1 t1=new Tank1();
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getActionCommand().equals("newGame"))//新游戏事件
            {
                mp=new MyPanel("newGame");
                this.remove(gkmp);
                this.add(mp);
                this.addKeyListener(mp);
                Thread t=new Thread(mp);
                t.start();
                this.setVisible(true);
            }
            else if(e.getActionCommand().equals("goonGame"))//继续游戏
            {
                //封装
                mp=new MyPanel("goonGame");        
                Thread t=new Thread(mp);
                t.start();
                this.remove(gkmp);
                this.add(mp);        
                this.addKeyListener(mp);
                this.setVisible(true);
            }
            else if(e.getActionCommand().equals("saveExit"))//保存退出
            {
                Jilu jl=new Jilu();
                jl.setDtk(mp.dtk);//设置下敌人坦克的面板
                jl.cunpan();
                System.exit(0);
            }
            else if(e.getActionCommand().equals("exit"))//直接退出游戏
            {
                Jilu.bcjl();
                System.exit(0);
            }
        }
    }
    class GuangkaPanel extends JPanel implements Runnable{
        int times=0;
    public void paint(Graphics g) {        
            super.paint(g);
            g.fillRect(0, 0, 400, 300);
            if(times%2==0) {//画关卡面板,时间出现闪烁的效果
                g.setColor(Color.yellow);
                Font myFont=new Font("华文行楷",Font.BOLD,38);
                g.setFont(myFont);
                g.drawString("第1关", 140, 140);
            }
    }
        @Override
        public void run() {
            while(true) {
                try {
                    Thread.sleep(600);//间隔多少出现闪烁
                } catch (Exception e) {e.printStackTrace();}
                times++;
                this.repaint();
            }
        }    
    }
    /**
     * @author Administrator
     *面板绘制坦克
     */
    class MyPanel extends JPanel implements KeyListener, Runnable{

         MyTank mt=null;
         DiTank dt=null;
        //敌人坦克多线程 使用vector集合  坦克组 向量
        Vector<DiTank> dtk=new Vector<DiTank>();
        Vector<Baozha> bzjh=new Vector<Baozha>();    
        static Vector<Weizhi> wzjh=new Vector<Weizhi>();

        int tksl=3;
        //爆炸也需要做向量,有3张图片
        Image tp1=null;
        Image tp2=null;
        Image tp3=null;
        
        public MyPanel(String ss) {
            //第一个读取硬盘数据
            Jilu.dqjl();
            mt=new MyTank(140,232);
            if(ss=="newGame") {            
                for(int i=0;i<tksl;i++) {
                     dt=new DiTank((i)*180+5, 0);
                    dt.setFangxiang(2);
                    Thread t2=new Thread(dt);
                    t2.start();//敌人坦克启动线程
                    Zidan zd=new Zidan(dt.x+10,dt.y+30,2);
                    dt.dzd.add(zd);
                    Thread t3=new Thread(zd);//敌人发射子弹线程
                    t3.start();
                    dtk.add(dt);
                    dt.dtkxl(dtk);//?
                }
            }else if(ss.equals("goonGame")) {
                wzjh=Jilu.dupan();
                for(int i=0;i<wzjh.size();i++) {
                    Weizhi wz=wzjh.get(i);
                    DiTank dt=new DiTank(wz.x,wz.y);
                    dt.setFangxiang(wz.fangxiang);
                    dt.dtkxl(dtk);
                    Thread t2=new Thread(dt);
                    t2.start();//敌人坦克启动线程
                    Zidan zd=new Zidan(dt.x+10,dt.y+30,2);
                    dt.dzd.add(zd);
                    Thread t3=new Thread(zd);//敌人发射子弹线程
                    t3.start();
                    dtk.add(dt);            
                }
            }
            Shengyin sy=new Shengyin("./tank.wav");
            sy.start();
            tp1=Toolkit.getDefaultToolkit().getImage(("src/bzxg1.gif"));
            tp2=Toolkit.getDefaultToolkit().getImage(("src/bzxg2.gif"));
            tp3=Toolkit.getDefaultToolkit().getImage(("src/bzxg3.gif"));

        }
        //画敌我坦克数量减少方法
        public void tjsl(Graphics g) {
            this.drawTank(80, 330, g, 0, 0);
            g.setColor(Color.black);
            g.drawString(Jilu.getMtsl()+"", 116, 350);
            this.drawTank(150, 330, g, 0, 1);
            g.setColor(Color.black);
            g.drawString(Jilu.getDtsl()+"", 186, 350);
            
            this.drawTank(450, 86, g, 0, 1);
            g.setColor(Color.black);
            g.drawString(Jilu.getSdtj()+"", 486, 107);
            g.setColor(Color.BLACK);
            Font f=new Font("华文彩云",Font.BOLD,20);
            g.setFont(f);
            g.drawString("你消灭的坦克总数", 410, 40);
        }
        public void paint(Graphics g) {
            
            super.paint(g);
            g.fillRect(0, 0, 400, 300);
            this.tjsl(g);
            //画我的坦克
            if(mt.shengming) {
                this.drawTank(mt.getX(),mt.getY(),g,mt.fangxiang,0);
            }
            //画敌人的坦克 3辆
            for(int i=0;i<dtk.size();i++) {
                DiTank dt=dtk.get(i);
                if(dt.shengming) {
                    this.drawTank(dtk.get(i).getX(),dtk.get(i).getY(),g,dt.fangxiang,1);
                    for(int j=0;j<dt.dzd.size();j++) {        
                        
                        Zidan dtzd=dt.dzd.get(j);//每次往里装一颗子弹
                        if(dtzd!=null && dtzd.shengming==true) {
                            g.setColor(Color.white);
                            g.fill3DRect(dtzd.x, dtzd.y, 3, 3, false);
                        }
                        if(dtzd.shengming==false) {//子弹碰墙 后进行删除
                            dt.dzd.remove(dtzd);    
                        }
                    }
                }
            }
            //画我的坦克子弹
            for(int i=0;i<mt.aa.size();i++) {
                Zidan zd=mt.aa.get(i);//每次往里装一颗子弹
                if(mt.zd!=null && mt.zd.shengming==true) {
                    g.setColor(Color.white);
                    g.fill3DRect(zd.x, zd.y, 3, 3, false);
                }
                if(zd.shengming==false) {//子弹碰墙 后进行删除
                    mt.aa.remove(zd);    
                }
            }
    /*        //画敌人坦克子弹  已经放到画敌人坦克循环里了
            for(int i=0;i<dt.dzd.size();i++) {        
                //DiTank dt=dtk.get(i);
                Zidan dtzd=dt.dzd.get(i);//每次往里装一颗子弹
                if(dtzd!=null && dtzd.shengming==true) {
                    g.setColor(Color.white);
                    g.fill3DRect(dtzd.x, dtzd.y, 3, 3, false);
                }
                if(dtzd.shengming==false) {//子弹碰墙 后进行删除
                    dt.dzd.remove(dtzd);    
                }
            }*/
            //画爆炸类
        for(int i=0;i<bzjh.size();i++) {
            
            Baozha bz=bzjh.get(i);
            if(bz.shengcunqi>6) {
                g.drawImage(tp1, bz.x, bz.y, 30, 30, this);            
            }else if(bz.shengcunqi>3) {
                g.drawImage(tp2, bz.x, bz.y, 30, 30, this);
            }else {
                g.drawImage(tp3, bz.x, bz.y, 30, 30, this);
            }
            bz.suqsd();
            if(bz.shengcunqi==0) {
                bzjh.remove(bz);
            }
        }
        
    }
        //击中我方坦克的方法
        public void jzwf() {
            for(int i=0;i<this.dtk.size();i++) {//将敌人坦克一个个取出来
                DiTank dt=dtk.get(i);
                for(int j=0;j<dt.dzd.size();j++) {//将敌人子弹一个个取出来,2者进行比较
                    Zidan zd=dt.dzd.get(j);
                    if(mt.shengming) {
                        this.jzdf(zd, mt);
                    }
                }
                this.repaint();
            }
        }
        //击中敌人坦克方法
        public void jzdf1() {
            for(int i=0;i<mt.aa.size();i++) {//每取出一颗子弹
                Zidan zd=mt.aa.get(i);
                if(zd.shengming) {
                    for(int j=0;j<dtk.size();j++) {//每取出一个敌人坦克
                        DiTank dt=dtk.get(i);
                        if(dt.shengming) {
                            if(this.jzdf(zd, dt)) {//b2值为真
                                Jilu.dtjs();
                                Jilu.sdsl();
                            }
                        }                    
                    }    
                }
                this.repaint();
            }
        }
        //子弹击中敌人坦克方 法 升级为击中双方坦克的方法
            public boolean jzdf(Zidan zd,Tank dt) {//多态 父类引用指向子类对象
                //子弹不分敌我的 这里
                DiTank dt1;
                boolean b2=false;
                switch(dt.fangxiang) {
                case 0:
                case 2:
                    if(zd.x>dt.x && zd.x<dt.x+20 && zd.y>dt.y && zd.y<dt.y+30)
                    {
                        Baozha bz=new Baozha(dt.x,dt.y);//需要给爆炸图传入x,y坐标值
                        bzjh.add(bz);
                        zd.shengming=false;
                        dt.shengming=false;
                        b2=true;
                    /*if(dt instanceof DiTank) {//判断当前传入的对象是属于哪个类的,然后执行操作
                        Jilu.dtjs();
                        Jilu.sdsl();
                        }*/                    
                    }
                    break;
                case 1:
                case 3:
                    if(zd.x>dt.x && zd.x<dt.x+30 && zd.y>dt.y && zd.y<dt.y+20)
                    {
                        Baozha bz=new Baozha(dt.x,dt.y);
                        bzjh.add(bz);
                        zd.shengming=false;
                        dt.shengming=false;    
                        b2=true;
                        //if(dt instanceof DiTank) {Jilu.dtjs();Jilu.sdsl();}
                    }            
                }
                return b2;
            }
        

        public void drawTank(int x, int y, Graphics g, int fangxiang, int leixing) {
            switch(leixing) {
            case 0://我的坦克 黄色
                g.setColor(Color.yellow);
                break;
            case 1://敌人的坦克 绿色
                g.setColor(Color.green);
            }
            switch(fangxiang) {
            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-3);
                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-3, 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+33);
                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+33, y+10);
                break;
            }
        }
        @Override
        public void keyTyped(KeyEvent e) {}
        public void keyReleased(KeyEvent e) {}
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode()==KeyEvent.VK_W) {
                this.mt.setFangxiang(0);
                mt.xiangshang();
            }else if(e.getKeyCode()==KeyEvent.VK_A){
                this.mt.setFangxiang(1);
                mt.xiangzuo();
            }else if(e.getKeyCode()==KeyEvent.VK_S){
                this.mt.setFangxiang(2);
                mt.xiangxia();
            }else if(e.getKeyCode()==KeyEvent.VK_D){
                this.mt.setFangxiang(3);
                mt.xiangyou();
            }
            if(e.getKeyCode()==KeyEvent.VK_J) {
                if(mt.aa.size()<3) {//限制子弹数为8个
                    this.mt.fszd();
                }            
            }
            this.repaint();
        }
        
        @Override
    /*    public void run() {
            while(true) {
                try {
                    Thread.sleep(100);//合理利用资源 隔100ms重绘制
                } catch (Exception e) {}
                //子弹和坦克在面板碰撞
                for(int i=0;i<mt.aa.size();i++) {
                    //二层循环的目的每发子弹和每量敌人坦克碰撞
                    Zidan zd=mt.aa.get(i);
                    if(zd.shengming) {
                        for(int j=0;j<dtk.size();j++) {
                            DiTank dt=dtk.get(j);
                            if(dt.shengming) {                            
                                this.jzdf(zd,dt);                                
                            }
                        }
                    }
                    this.repaint();
                }
        // 因为敌方坦克没有线程来自动调用重绘,
    //你可以在Mypanel的run方法判断子弹和坦克的那个线程this.repaint()再外面一个循环再加一个this.repaint()
                this.repaint();
            }
        
        }//run()
    */
        public void run() {//第10课后直接在MyPanel线程类调用方法
            while(true) {
                try {
                    Thread.sleep(100);//合理利用资源 隔100ms重绘制
                } catch (Exception e) {}
                this.jzdf1();
                this.jzwf();
                this.repaint();
            }
        }
    }

  • 相关阅读:
    windows 系列机器查看tcp 配置
    test windows live writer
    win7 mysql 启动 问题
    用enum枚举量做下标初始化数组
    二层VXLAN静态配置
    pip install scrapy报错原文
    python练习2
    pycharm字体大小设置快捷键的方法
    python练习1
    centos 7下修改IP地址为静态
  • 原文地址:https://www.cnblogs.com/smartwen666/p/7859693.html
Copyright © 2011-2022 走看看