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

来自 , 2020-06-05, 写在 Java, 查看 117 次.
URL http://www.code666.cn/view/9c19a2aa
  1. package mzxmzx;
  2.  
  3.  
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.util.Random;
  7.  
  8.  
  9. public class Tank {
  10.         /**
  11.          * 坦克的移动速度
  12.          */
  13.         public static final int XSPEED = 5;
  14.         public static final int YSPEED = 5;
  15.        
  16.         public static final int WIDTH = 30;//坦克的宽度定义为常量
  17.         public static final int HEIGHT = 30;//坦克的高度定义为常量
  18.        
  19.         private boolean live = true;//返回布尔类型,判断坦克的生死
  20.         private int life = 100;
  21.         private BloodBar bb = new BloodBar();//BloodBar一个bb出来
  22.         public int getLife() {
  23.                 return life;
  24.         }
  25.  
  26.         public void setLife(int life) {
  27.                 this.life = life;
  28.         }
  29.  
  30.         TankClient tc;
  31.        
  32.         private boolean good;//定义一个布尔变量,判断敌我坦克
  33.        
  34.         public boolean isGood() {
  35.                 return good;
  36.         }
  37.  
  38.         private int x, y;
  39.         private int oldX,oldY;
  40.         private void stay(){//坦克撞到墙之后定义为stay
  41.                 x = oldX;
  42.                 y = oldY;
  43.         }
  44.        
  45.         private static Random r = new Random();
  46.        
  47.         private boolean bL=false, bU=false, bR=false, bD = false;//用4个布尔类型的值代表是不是按下了4个键,当按下某个键时由FALSE变成true
  48.         enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};//枚举
  49.        
  50.         private int step = r.nextInt(12) + 3; //最小值至少移动3步,最大值移动到14步
  51.         private Direction dir = Direction.STOP;//给默认值为STOP
  52.         private Direction ptDir = Direction.D;//炮筒的方向(向下的方向)
  53.  
  54.         public Tank(int x, int y, boolean good) {
  55.                 this.x = x;
  56.                 this.y = y;
  57.                 this.oldX = x;
  58.                 this.oldY = y;
  59.                 this.good = good;
  60.         }
  61.        
  62.         public Tank(int x, int y, boolean good,Direction dir, TankClient tc) {
  63.                 this(x, y, good);
  64.                 this.dir = dir;
  65.                 this.tc = tc;
  66.         }
  67.        
  68.         public void draw(Graphics g) {
  69.                 if(!live){
  70.                         if(!good){
  71.                                 tc.tanks.remove(this);
  72.                         }return;
  73.                 }
  74.                
  75.                 Color c = g.getColor();//设置前景色
  76.                 if(good) g.setColor(Color.RED);//我们的坦克颜色设置
  77.                 else g.setColor(Color.BLUE);//敌方坦克设置
  78.                 g.fillOval(x, y, WIDTH, HEIGHT);//画一个实心圆(50,50为坐标,30,,30是圆的高度和宽度)
  79.                 g.setColor(c);;//把原来颜色设置回来
  80.                 if(good)bb.draw(g); //把我的坦克的血条画出来
  81.                 switch(ptDir) {
  82.                 case L:
  83.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2);
  84.                         break;
  85.                 case LU:
  86.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y);
  87.                         break;
  88.                 case U:
  89.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y);
  90.                         break;
  91.                 case RU:
  92.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y);
  93.                         break;
  94.                 case R:
  95.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2);
  96.                         break;
  97.                 case RD:
  98.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT);
  99.                         break;
  100.                 case D:
  101.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT);
  102.                         break;
  103.                 case LD:
  104.                         g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT);
  105.                         break;
  106.                 }
  107.                
  108.                 move();
  109.         }
  110.        
  111.         void move() {
  112.                 this.oldX=x;
  113.                 this.oldY=y;//move之前记录上一步坦克x,y的值
  114.                 switch(dir) {
  115.                 case L:
  116.                         x -= XSPEED;
  117.                         break;
  118.                 case LU:
  119.                         x -= XSPEED;
  120.                         y -= YSPEED;
  121.                         break;
  122.                 case U:
  123.                         y -= YSPEED;
  124.                         break;
  125.                 case RU:
  126.                         x += XSPEED;
  127.                         y -= YSPEED;
  128.                         break;
  129.                 case R:
  130.                         x += XSPEED;
  131.                         break;
  132.                 case RD:
  133.                         x += XSPEED;
  134.                         y += YSPEED;
  135.                         break;
  136.                 case D:
  137.                         y += YSPEED;
  138.                         break;
  139.                 case LD:
  140.                         x -= XSPEED;
  141.                         y += YSPEED;
  142.                         break;
  143.                 case STOP:
  144.                         break;
  145.                 }
  146.                
  147.                 if(this.dir != Direction.STOP) {
  148.                         this.ptDir = this.dir;
  149.                 }
  150.                
  151.                 if(x < 0) x = 0;//解决坦克出界的问题
  152.                 if(y < 30) y = 30;//注意标题栏
  153.                 if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
  154.                 if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
  155.             if(!good){
  156.                  Direction[] dirs = Direction.values();   //将方向转化为数组
  157.                  if(step == 0){      //只有STEP等于0时,才转方向
  158.                          step = r.nextInt(12)  + 3;
  159.                          int rn = r.nextInt(dirs.length);//move完成后,如果是敌军坦克的,随机产生一个数,来设定坦克下一个方向
  160.                      dir = dirs[rn];    
  161.                  }
  162.                 step --;
  163.                 if(r.nextInt(50)>48)this.fire();//防止敌军炮火太猛烈,生成大于48的随机数时才开火
  164.             }
  165.            
  166.         }
  167.        
  168.         public void keyPressed(KeyEvent e) {
  169.                 int key = e.getKeyCode();//定义一个key,(获得按键的虚拟码)
  170.                 switch(key) {
  171.                  /* case KeyEvent.VK_CONTROL:
  172.                // tc.missiles.add(fire());//一种调用方法:调用fire方法,返回值是一发炮弹
  173.                         fire();
  174.                  break;*/       // 在KeyPressed中子弹太密集,将其设置为抬起发炮弹(released)
  175.                 case KeyEvent.VK_LEFT :
  176.                         bL = true;
  177.                         break;
  178.                 case KeyEvent.VK_UP :
  179.                         bU = true;
  180.                         break;
  181.                 case KeyEvent.VK_RIGHT :
  182.                         bR = true;
  183.                         break;
  184.                 case KeyEvent.VK_DOWN :
  185.                         bD = true;
  186.                         break;
  187.                 case KeyEvent.VK_F2:
  188.                         if(!this.live){
  189.                                 this.live = true;//复活
  190.                                 this.life = 100;//100血
  191.                         }break;
  192.                 }
  193.                 locateDirection();
  194.         }
  195.        
  196.         void locateDirection() {
  197.                 if(bL && !bU && !bR && !bD) dir = Direction.L;
  198.                 else if(bL && bU && !bR && !bD) dir = Direction.LU;
  199.                 else if(!bL && bU && !bR && !bD) dir = Direction.U;
  200.                 else if(!bL && bU && bR && !bD) dir = Direction.RU;
  201.                 else if(!bL && !bU && bR && !bD) dir = Direction.R;
  202.                 else if(!bL && !bU && bR && bD) dir = Direction.RD;
  203.                 else if(!bL && !bU && !bR && bD) dir = Direction.D;
  204.                 else if(bL && !bU && !bR && bD) dir = Direction.LD;
  205.                 else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;
  206.         }
  207.  
  208.         public void keyReleased(KeyEvent e) {
  209.                 int key = e.getKeyCode();//定义一个key,(获得按键的虚拟码)
  210.                 switch(key) {
  211.                 case KeyEvent.VK_CONTROL:
  212.                         fire();
  213.                         break;
  214.                 case KeyEvent.VK_LEFT :
  215.                         bL = false;
  216.                         break;
  217.                 case KeyEvent.VK_UP :
  218.                         bU = false;
  219.                         break;
  220.                 case KeyEvent.VK_RIGHT :
  221.                         bR = false;
  222.                         break;
  223.                 case KeyEvent.VK_DOWN :
  224.                         bD = false;
  225.                         break;
  226.                 case KeyEvent.VK_A:
  227.                         superFire();
  228.                         break;
  229.                 }
  230.                 locateDirection();             
  231.         }
  232.        
  233.         public Missile fire() {//fire方法返回值Missile
  234.                 if(!live) return null;//解决自己坦克被击杀后,仍然可以操作的问题
  235.                 int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;//计算x,y的位置
  236.                 int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
  237.                 Missile m = new Missile(x, y,good, ptDir, this.tc);//坦克的x,y
  238.                 tc.missiles.add(m);
  239.                 return m;
  240.         }
  241.         public Missile fire(Direction dir){//超级炮弹的fire方法
  242.                 if(!live) return null;//解决自己坦克被击杀后,仍然可以操作的问题
  243.                 int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2;//计算x,y的位置
  244.                 int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2;
  245.                 Missile m = new Missile(x, y,good, dir, this.tc);//坦克的x,y
  246.                 tc.missiles.add(m);
  247.                 return m;
  248.                
  249.         }
  250.         private void superFire() {//超级炮弹!!
  251.                 Direction[] dirs = Direction.values();
  252.                 for(int i=0; i<8; i++) {
  253.                         fire(dirs[i]);
  254.                 }
  255.         }
  256.        
  257.         public Rectangle getRect() {//矩形,子弹左上角位置,宽度高度
  258.                 return new Rectangle(x, y, WIDTH, HEIGHT);
  259.         }
  260.  
  261.         public boolean isLive() {
  262.                 return live;
  263.         }
  264.  
  265.         public void setLive(boolean live) {
  266.                 this.live = live;
  267.         }
  268.         /**
  269.          *  为了解决坦克穿过墙这一问题
  270.          * @param w  坦克撞击的墙
  271.          * @return   坦克一旦撞上了枪,返回true,否则返回false
  272.          */
  273.         public boolean collidesWithWall(Wall w) {//解决坦克穿过墙这一问题
  274.                 if(this.live && this.getRect().intersects(w.getRect())) {
  275.                         this.stay();
  276.                         return true;
  277.                 }
  278.                 return false;
  279.         }
  280.         public boolean collidesWithTanks(java.util.List<Tank> tanks) {
  281.                 for(int i=0; i<tanks.size(); i++) {
  282.                         Tank t = tanks.get(i);//两辆坦克不是一辆坦克才相撞
  283.                         if(this != t) {
  284.                                 if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) {
  285.                                         this.stay();//两辆坦克都停止
  286.                                         t.stay();
  287.                                         return true;
  288.                                 }
  289.                         }
  290.                 }
  291.                 return false;
  292.         }
  293.         private class BloodBar {//坦克的血条
  294.                 public void draw(Graphics g) {
  295.                         Color c = g.getColor();
  296.                         g.setColor(Color.RED);
  297.                         g.drawRect(x, y-10, WIDTH, 10);//外面的框
  298.                         int w = WIDTH * life/100 ;//计算宽度
  299.                         g.fillRect(x, y-10, w, 10);
  300.                         g.setColor(c);
  301.                 }
  302.         }
  303.         public boolean eat(Blood b) {//吃掉血块
  304.                 if(this.live && b.isLive() && this.getRect().intersects(b.getRect())) {
  305.                         this.life = 100;//吃掉血块血量恢复至100
  306.                         b.setLive(false);//
  307.                         return true;
  308.                 }
  309.                 return false;
  310.         }
  311. }
  312.  

回复 "坦克大战"

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

captcha