[Java] 游戏--坦克大战 →→→→→进入此内容的聊天室

来自 , 2020-08-14, 写在 Java, 查看 116 次.
URL http://www.code666.cn/view/fe51510c
  1. 1.主类
  2. package s1230坦克大战;
  3. import java.awt.Color;
  4. import java.awt.Graphics;
  5. import java.awt.event.KeyEvent;
  6. import java.awt.event.KeyListener;
  7. import java.util.Vector;
  8. import javax.swing.ImageIcon;
  9. import javax.swing.JFrame;
  10. import javax.swing.JPanel;
  11.  
  12. import 工具类.ThreadSleep;
  13.  
  14. public class Tank1 extends JFrame {
  15. static int panelXLength=700;
  16. static int panelYlength=700;
  17. static int gameXLength=500;
  18. static int gameYLength=500;
  19. static int zidanNum=0;
  20.  
  21.  
  22.         MyPanel mp=null;
  23.        
  24.         public static void main(String[] args)
  25.         {
  26.                 Tank1 t1=new Tank1();
  27.         }
  28.  
  29.         public  Tank1()
  30.         {       mp=new MyPanel();
  31.             this.add(mp);
  32.                 this.setTitle("坦克大战");                                                                                                          //设置窗体的标题        
  33.         this.setLocationRelativeTo(null);                                                                                               //设置窗体出现位置居中
  34.         this.setDefaultCloseOperation(3);                                                                                                       //设置窗体的关闭操作
  35.         this.setResizable(true);                                                                        //设置禁止调整窗体的大小
  36.         this.setIconImage((new ImageIcon("E:/Michael/javaImage/扫雷图片/bomb.png").getImage()));            //设置标题栏图标      
  37.         this.setSize(panelXLength,panelYlength);                                                                                        //设置窗体的大小                        
  38.         this.setLocationRelativeTo(null);                                                               //设置窗体出现在屏幕中间  
  39.         this.addKeyListener(mp);
  40.         this.setVisible(true);           
  41.        
  42.         Thread o=new Thread(mp);                                                                    //添加线程很重要 不然子弹不会动
  43.         o.start();                                                                                  //这个线程的作用是不断执行MyPanel
  44.         }
  45.              
  46.     class MyPanel extends JPanel implements KeyListener,Runnable
  47.     {
  48.         MyTank mt=null;      //有什么作用?
  49.         Vector<EnemyTank> dtk=new Vector<EnemyTank>();             //new 出一个新的vector对象,vector多线程
  50.         int tankNum=3;
  51.        
  52.        public MyPanel()
  53.        {
  54.           mt=new MyTank(250,400);                                     //创建我方坦克    
  55.           for(int i=0;i<tankNum;i++)                                  //批量创建敌方坦克,要用到vector
  56.           { EnemyTank dt=new EnemyTank((i)*180+5,10);                
  57.             dtk.add(dt);
  58.             Thread r=new Thread(dt);                                  //让坦克动起来的线程                      
  59.              r.start();
  60.           }
  61.        }
  62.  
  63.     public void paint(Graphics g)
  64.     {
  65.      super.paint(g);
  66.       g.fillRect(0,0,gameXLength,gameYLength);                                      
  67.       this.drawTank(mt.getX(),mt.getY(),g,mt.leixing,mt.fangxiang);     //在界面上绘制我方坦克,x(坐标),y(坐标),画笔g,类型,方向
  68.      
  69.       for(int i=0;i<tankNum;i++)                                        //在界面上批量绘制敌方坦克
  70.       {   if(dtk.get(i).life==true)
  71.           {this.drawTank(dtk.get(i).getX(),dtk.get(i).getY(),g,0,dtk.get(i).fangxiang);       //x(坐标),y(坐标),画笔g,类型,方向
  72.            
  73.            for(int j=0;j<dtk.get(i).dzd.size();j++)
  74.              {  
  75.                    Zidan zd=dtk.get(i).dzd.get(j);
  76.                 dtk.get(i).shoot();
  77.                
  78.                if(zd!=null&&zd.life==true)    //mt.zd.life==true 控制子弹的范围
  79.                {  
  80.                     g.setColor(Color.RED);                                      //设置子弹颜色
  81.                     g.fill3DRect(zd.x, zd.y, 3,3, false);                   //绘制子弹,如何让子弹动起来            
  82.                }  
  83.                  if(zd.life==false)            //除去Vector中的zd对象,目的是为了实现子弹数量限制
  84.                          dtk.get(i).dzd.remove(zd);
  85.              }
  86.           }
  87.       }
  88.      
  89.      
  90.       for(int i=0;i<mt.aa.size();i++)            //绘制我方坦克子弹
  91.       {  Zidan zd=mt.aa.get(i);
  92.        
  93.          if(zd!=null&&mt.zd.life==true)    //mt.zd.life==true 控制子弹的范围
  94.          {  
  95.           g.setColor(Color.RED);                                      //设置子弹颜色
  96.           g.fill3DRect(zd.x, zd.y, 3, 3, false);                   //绘制子弹,如何让子弹动起来             
  97.          }  
  98.          if(zd.life==false)            //除去Vector中的zd对象,目的是为了实现子弹数量限制
  99.                  mt.aa.remove(zd);
  100.       }
  101.      
  102.     }
  103.  
  104.      //子弹是否击中tank的判断方法*************************************
  105.        public void jizhong(Zidan zd,EnemyTank dt)
  106.        {   switch(dt.fangxiang)
  107.            {
  108.             case 0:
  109.             case 1:
  110.                 if(zd.x>dt.x&&zd.x<dt.x+20&&zd.y>dt.y&&zd.y<dt.y+30)
  111.                 { zd.life=false; dt.life=false;}
  112.             break;
  113.            
  114.             case 2:
  115.             case 3:
  116.                 if(zd.x>dt.x&&zd.x<dt.x+30&&zd.y>dt.y&&zd.y<dt.y+20)
  117.                 { zd.life=false; dt.life=false;}
  118.             break;
  119.            }  
  120.        }
  121.      //子弹是否击中tank的判断方法*************************************  
  122.  
  123.    
  124.                 private void drawTank(int x, int y, Graphics g, int leixing, int fangxiang) //绘制坦克的方法
  125.         {
  126.        
  127.                   switch(leixing)                                             //设置坦克颜色,0为黄色,1为绿色
  128.           {
  129.           case 0:  g.setColor(Color.YELLOW);break;
  130.           case 1:  g.setColor(Color.GREEN);break;
  131.           }
  132.          
  133.           switch(fangxiang)    //坦克方向,case0表示面朝上方的坦克,1表示面朝右方,2表示面朝下方,3表示面朝左方
  134.           {  
  135.           case 0:         g.fill3DRect(x, y, 5, 30, false);                   //履带
  136.                       g.fill3DRect(x+15, y, 5, 30, false);                //履带
  137.                       g.fill3DRect(x+5, y+5, 10, 20, false);              //中间正方形车体
  138.                       g.fillOval(x+5, y+10, 10, 10);                      //椭圆炮台
  139.                       g.drawLine(x+10, y+15, x+10, y-3);                  //炮管:绝对长度为18
  140.                       break;
  141.                      
  142.           case 1:     g.fill3DRect(x, y, 30, 5, false);                                   //履带
  143.                           g.fill3DRect(x, y+15, 30, 5, false);                            //履带
  144.                           g.fill3DRect(x+5, y+5, 20, 10, false);                          //中间正方形车体
  145.                           g.fillOval(x+10, y+5, 10, 10);                                          //椭圆炮台
  146.                           g.drawLine(x+15, y+10, x-3, y+10);                              //炮管:绝对长度为18
  147.                       break;
  148.                      
  149.           case 2:     g.fill3DRect(x, y, 5, 30, false);                                   //履带
  150.                                           g.fill3DRect(x+15, y, 5, 30, false);                            //履带
  151.                                           g.fill3DRect(x+5, y+5, 10, 20, false);                          //中间正方形车体
  152.                                           g.fillOval(x+5, y+10, 10, 10);                                          //椭圆炮台
  153.                                           g.drawLine(x+10, y+15, x+10, y+33);                             //炮管:绝对长度为18
  154.                                           break;
  155.                                          
  156.           case 3:     g.fill3DRect(x, y, 30, 5, false);                                   //履带
  157.                                   g.fill3DRect(x, y+15, 30, 5, false);                            //履带
  158.                                   g.fill3DRect(x+5, y+5, 20, 10, false);                          //中间正方形车体
  159.                                   g.fillOval(x+5, y+5, 10, 10);                                           //椭圆炮台
  160.                                   g.drawLine(x+10, y+10, x+28, y+10);                             //炮管:绝对长度为18
  161.                                   break;
  162.           }
  163.         }      
  164.             public void keyTyped(KeyEvent e) {}                          
  165.             public void keyReleased(KeyEvent e) {}
  166.                 public void keyPressed(KeyEvent e)
  167.                 {   //坦克的方向控制,依次是上下左右,对应按键是w s a d。
  168.                          if(e.getKeyCode()==KeyEvent.VK_W)
  169.                          {                         
  170.                            this.mt.setFangxiang(0);
  171.                            this.mt.upMove();
  172.                            
  173.                          }
  174.                        
  175.                          if(e.getKeyCode()==KeyEvent.VK_S)
  176.                          { this.mt.setFangxiang(2);
  177.                            this.mt.downMove();
  178.                          }
  179.                          if(e.getKeyCode()==KeyEvent.VK_A)
  180.                          { this.mt.setFangxiang(1);
  181.                            this.mt.leftMove();
  182.                          }
  183.                          if(e.getKeyCode()==KeyEvent.VK_D)
  184.                          { this.mt.setFangxiang(3);
  185.                            this.mt.rightMove();
  186.                          }
  187.                          
  188.                          if(e.getKeyCode()==KeyEvent.VK_J)               //监听发射子弹的按钮
  189.                          {   if(mt.aa.size()<8)                          //限制子弹发射的数量为8颗
  190.                                  this.mt.shoot();
  191.                          }       
  192.                          
  193.                          this.repaint();                                //还没搞懂这个是干嘛的?
  194.                 }
  195.                          
  196.                 public void run()
  197.                          {  
  198.                                  while(true)
  199.                                  {
  200.                                          ThreadSleep.threadSleep(100);
  201.                  
  202.                                    for(int i=0;i<mt.aa.size();i++)            //2层循环的作用是,让每一颗子弹和每一辆坦克的坐标对比,来确定被打中的坦克
  203.                                    {  Zidan zd=mt.aa.get(i);                  //取出子弹
  204.                                         if(zd.life)                             //如果子弹有效
  205.                                       {  
  206.                                         for(int j=0;j<dtk.size();j++)    
  207.                                         {EnemyTank dt=dtk.get(j);     //取出坦克对象
  208.                                          if(dt.life)  this.jizhong(zd,dt);//判断子弹是否击中tank                                                                               
  209.                                         }
  210.                                       }
  211.                                    }  
  212.                             this.repaint();                         //还没搞懂这个是干嘛的?
  213.                              }                   
  214.                          }
  215.     }
  216. }
  217.  
  218.  
  219.  
  220. 2.sucai
  221. package s1230坦克大战;
  222.  
  223. import java.util.Random;
  224. import java.util.Vector;
  225.        
  226. class Tank {
  227.     int x=0,y=0; //横纵坐标
  228.     int speed=9;
  229.     int fangxiang=0;
  230.     int leixing=1;
  231.     int time=0;
  232.     boolean life=true;
  233.    
  234.         public Tank(int x,int y)           //构造方法
  235.         {this.x=x;
  236.          this.y=y;
  237.         }
  238.  
  239.         public int  getSpeed()                                  {return speed;}
  240.         public void setSpeed(int speed)                     {this.speed = speed;}
  241.         public int  getX()                                                      {return x;}
  242.         public void setX(int x)                                         {this.x = x;}
  243.         public int  getY()                                                      {return y;}
  244.         public void setY(int y)                                         {this.y = y;}
  245.         public void upMove()                                            {if(y>5)  y-=speed;}                            //向上移动
  246.         public void downMove()                                          {if(y<460)y+=speed;}                                    //向下移动
  247.         public void leftMove()                                          {if(x>5)  x-=speed;}                                            //向左移动
  248.         public void rightMove()                                         {if(x<460)x+=speed;}                                            //向右移动
  249.         public int  getFangxiang()                              {return fangxiang;}
  250.         public void setFangxiang(int fangxiang)         {this.fangxiang = fangxiang;}
  251.         public int getLeixing()                     {return leixing;}
  252.         public void setLeixing(int leixing)         {this.leixing = leixing;}
  253.                
  254.  
  255. }
  256.  
  257.  class MyTank extends Tank
  258.  {   Vector<Zidan> aa=new Vector<Zidan>();      //专门存放子弹,来解决一按发射键子弹消失的问题
  259.          Zidan zd=null;
  260.        
  261.         public MyTank(int x,int y)
  262.                 {super(x,y);}                          //调用父类的构造方法
  263.  
  264.         public void shoot()
  265.         {  switch(this.fangxiang)
  266.                 {       case 0: zd=new Zidan(x+10,y,0);         aa.add(zd);break;                //每发射一颗子弹都加入到容器Vector中
  267.                         case 1: zd=new Zidan(x,y+10,1);         aa.add(zd);break;                      
  268.                         case 2: zd=new Zidan(x+10,y+30,2);      aa.add(zd);break;              
  269.                         case 3: zd=new Zidan(x+30,y+10,3);      aa.add(zd);break;
  270.                 }
  271.                 Thread t=new Thread(zd);                                        //这个线程是为了让子弹动起来
  272.                 t.start();             
  273.         }
  274.  }
  275.  
  276.  
  277.  class EnemyTank extends Tank implements Runnable
  278.  {   int speed=1;                      //每次线程调用,坦克前进一次的距离
  279.      Zidan zd=null;
  280.    
  281.      Vector<Zidan> dzd=new Vector<Zidan>();      //专门存放子弹,来解决一按发射键子弹消失的问题
  282.          public EnemyTank(int x,int y)
  283.                 {super(x,y);}                          //调用父类的构造方法
  284.          
  285.          
  286.          public void shoot()
  287.                 {  switch(this.fangxiang)
  288.                         {       case 0: zd=new Zidan(x+10,y,0);         dzd.add(zd);break;               //每发射一颗子弹都加入到容器Vector中
  289.                                 case 1: zd=new Zidan(x,y+10,1);         dzd.add(zd);break;                     
  290.                                 case 2: zd=new Zidan(x+10,y+30,2);      dzd.add(zd);break;             
  291.                                 case 3: zd=new Zidan(x+30,y+10,3);      dzd.add(zd);break;
  292.                         }
  293.                         Thread t=new Thread(zd);                                        //这个线程是为了让子弹动起来
  294.                         t.start();             
  295.                 }
  296.          
  297.          public void run()
  298.          {
  299.                  while(true)
  300.                  {  
  301.                     int length;
  302.                     Random a=new Random();
  303.                         this.fangxiang=(int)(Math.random()*4);           //随机产生方向
  304.                         switch(this.fangxiang)
  305.                             { case 0:                            
  306.                                            length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的距离为 次数*speed,就是每次随机方向前进的总距离                            
  307.                                            for(int i=0;i<length;i++)
  308.                                        {
  309.                                            if(y>5)y-=speed;
  310.                                            else break;
  311.                                            try {Thread.sleep(50);}                                    //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
  312.                                            catch (Exception e) {}
  313.                                        }
  314.                                        break;          
  315.                            
  316.                               case 1:                            
  317.                                        length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
  318.                                            for(int i=0;i<length;i++)
  319.                                            {
  320.                                                    if(x>5)x-=speed;
  321.                                                    else break;
  322.                                                    try {Thread.sleep(50);}                                    //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
  323.                                                    catch (Exception e) {}
  324.                                            }
  325.                                            break;      
  326.                                      
  327.                               case 2:                            
  328.                                           length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
  329.                                           for(int i=0;i<length;i++)
  330.                                           {
  331.                                                   if(y<480)y+=speed;
  332.                                                   else break;
  333.                                                   try {Thread.sleep(50);}                                     //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
  334.                                                   catch (Exception e) {}
  335.                                           }
  336.                                           break;
  337.                                          
  338.                               case 3:                          
  339.                                       length=a.nextInt(59)+13;                     //每次随机方向,坦克前进的次数 次数*speed,就是每次随机方向前进的总距离
  340.                                       for(int i=0;i<length;i++)
  341.                                       {
  342.                                           if(x<470)x+=speed;
  343.                                           else break;
  344.                                           try {Thread.sleep(50);}                                     //通过线程挂起的时间,控制地方坦克移动的频率,0.2秒前进一次
  345.                                           catch (Exception e) {}
  346.                                       }
  347.                                       break;                             
  348.                             }
  349.          
  350.                          if(this.life==false)    break;      //如果坦克被子弹击中,那么就退出循环
  351.                          Vector<Zidan> dzd=new Vector<Zidan>();
  352.                          //坦克发子弹的代码
  353.                          time++;
  354.                          if(time%2==0)
  355.                          {    if(life)
  356.                              {
  357.                                      if(dzd.size()<5)
  358.                                      {  Zidan zd=null;
  359.                                         switch(fangxiang)
  360.                                         {
  361.                                          case 0: zd=new Zidan(x+10,y,0);
  362.                                                          dzd.add(zd);
  363.                                                          break;
  364.                                                          
  365.                                          case 1: zd=new Zidan(x+10,y,1);
  366.                                                      dzd.add(zd);
  367.                                                      break;
  368.                                          
  369.                                          case 2: zd=new Zidan(x+10,y,2);
  370.                                                          dzd.add(zd);
  371.                                                          break;
  372.                                          
  373.                                          case 3: zd=new Zidan(x+10,y,3);
  374.                                                          dzd.add(zd);
  375.                                                          break;
  376.                                         }
  377.                                        
  378.                                         Thread t5=new Thread(zd);
  379.                                         t5.start();            
  380.                               }
  381.                              }
  382.                                  
  383.                          }
  384.                  }
  385.                  
  386.                  
  387.          }
  388.  
  389.  }
  390.  
  391.  class Zidan implements Runnable
  392.  { int x,y;
  393.    int fangxiang;
  394.    int speed=9;
  395.    boolean life=true;
  396.  
  397.    public Zidan(int x,int y,int fangxiang)
  398.    {this.x=x;
  399.     this.y=y;
  400.     this.fangxiang=fangxiang;
  401.    }
  402.    
  403.    public void run()
  404.    {
  405.            while(true)                 //线程下面有死循环都要有休眠时间
  406.            {
  407.                     try {Thread.sleep(50);}                            
  408.                         catch (Exception e) {}
  409.                        
  410.                         switch(fangxiang)
  411.                         {       case 0: y-=speed;break;
  412.                         case 1: x-=speed;break;
  413.                         case 2: y+=speed;break;                
  414.                         case 3: x+=speed;break;
  415.                         }
  416.                
  417.                         if(x<0||x>500||y<0||y>500)  //子弹出了游戏边界就自动就将生命值设为false
  418.                         {this.life=false;  break;}
  419.                
  420.            }
  421.    }
  422.  
  423.  }
  424.  

回复 "游戏--坦克大战"

这儿你可以回复上面这条便签

captcha