java製作簡單的坦克大戰_java

來源:互聯網
上載者:User

詳情請參照注釋,這裡就不多廢話了,實現一下兒時的經典而已。

Blood.java

package com.hkm.TankWar;import java.awt.*;/** * 血塊類,我方坦克吃了可回血; * @author Hekangmin * */public class Blood {  private int x,y,w,h;//血塊的位置和寬度高度;     private TankWarClient tc;     private int step=0;//紀錄血塊移動的步數;     private boolean live=true;  public boolean isLive() {    return live;  }   public void setLive(boolean live) {    this.live = live;  }    /**     * 紀錄血塊的位置;     */  private int[][] pos={{400,300},{400,320},{420,320},{440,300},{440,330},{480,400},{520,400},{540,400}};          public Blood()  {    x=pos[0][0];    y=pos[0][1];    w=h=18;  }     public void draw(Graphics g)  {    if(!live) return;         Color c=g.getColor();    g.setColor(Color.CYAN);    g.fillOval(x, y, w, h);    g.setColor(c);         move();  }  /**   * 移動血塊   */  public void move()  {    step++;    if(step>=pos.length) step=0;    else{    x=pos[step][0];    y=pos[step][1];    }  }        public Rectangle getRect()  {    return new Rectangle(x,y,w,h);  }      }

Explode.java

package com.hkm.TankWar;import java.awt.*;/** * 爆炸類 * @author Hekangmin * */public class Explode {  private int x,y;//爆炸發生的位置     private boolean Live=true;     int dia[]={4,8,12,16,32,40,20,14,4};//用園類比,代表圓的直徑;     int step=0;//區別移到第幾個直徑     private TankWarClient tc;//持有引用     public Explode(int x,int y,TankWarClient tc)  {    this.x=x;    this.y=y;    this.tc=tc;  }  public void draw(Graphics g)  {    if(!Live)    {      tc.explodes.remove(this);      return;    }    if(step==dia.length)//如果到了最後一個直徑爆炸死亡;    {      Live=false;      step=0;      return;    }    Color c=g.getColor();    g.setColor(Color.YELLOW);    g.fillOval(x, y, dia[step], dia[step]);    g.setColor(c);    step++;  }   }

Missile.java

package com.hkm.TankWar;import java.awt.*;import java.awt.Event.*;import java.awt.event.KeyEvent;import java.util.List;/** * 子彈類 * @author Hekangmin * */ public class Missile {    private int x,y;//子彈的位置    private Tank.Direction dir;//坦克方向         private static final int XSPEED=10;//坦克x方向的移動速度,    private static final int YSPEED=10;//坦克y方向的移動速度,         public static final int WIDTH=10;    public static final int HEIGHT=10;         private boolean Live=true;//判斷子彈是否活著         private boolean good;//區分敵軍子彈和我軍子彈         private TankWarClient tc;       public Missile(int x, int y, Tank.Direction dir) {    this.x = x;    this.y = y;    this.dir = dir;  }     public Missile(int x,int y,boolean good,Tank.Direction dir,TankWarClient tc)  {    this(x,y,dir);    this.good=good;//將坦克好壞的屬性與子彈還壞屬性設定成相同;    this.tc=tc;  }     /**   * 畫出子彈   * @param g為畫筆   */  public void draw(Graphics g)  {    if(!Live)      {      tc.missiles.remove(this);      return;      }    Color c=g.getColor();    if(good)    {      g.setColor(Color.BLUE);    }    else g.setColor(Color.ORANGE);    g.fillOval(x, y, WIDTH, HEIGHT);    g.setColor(c);         move();  }     /**   * 根據坦克的方向讓子彈移動   */  private void move() {    switch(dir)    {    case L:      x-=XSPEED;      break;    case LU:      x-=XSPEED;      y-=YSPEED;      break;    case U:      y-=YSPEED;      break;    case RU:      x+=XSPEED;      y-=YSPEED;      break;    case R:      x+=XSPEED;      break;    case RD:      x+=XSPEED;      y+=YSPEED;      break;    case D:      y+=YSPEED;      break;    case LD:      x-=XSPEED;      y+=YSPEED;      break;    }         if(x<0||y<0||x>TankWarClient.GAME_WIDTH||y>TankWarClient.GAME_HEIGHT)//子彈越界則讓其死亡;    {      Live=false;    }  }        public boolean isLive()  {    return Live;  }   public Rectangle getRect()//擷取子彈的矩形地區;  {    return new Rectangle(this.x,this.y,this.WIDTH,this.HEIGHT);  }     /**   * 判斷子彈與坦克碰撞;   * @param t為坦克   * @return返回true則表示發生碰撞,否則沒有碰撞;   */  public boolean hitTank(Tank t)  {    if(this.Live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood())    {      if(t.isGood())      {        t.setLife(t.getLife()-10);        if(t.getLife()<=0) t.setLive(false);       }else{        t.setLive(false);      }      this.Live=false;///將子彈設為死亡;      Explode e=new Explode(x,y,tc);//發生爆炸;      tc.explodes.add(e);      return true;           }    return false;  }  /**   * 判斷子彈與敵軍坦克相撞;   * @param tanks敵軍坦克   * @returntrue表示相撞,false沒有相撞;   */  public boolean hitTanks(List<Tank> tanks)  {    for(int i=0;i<tanks.size();i++)    {      if(hitTank(tc.tanks.get(i)))      {        return true;      }    }         return false;  }     /**   * 判斷子彈是否撞牆   * @param w牆   * @returntrue,撞上,false,未撞上;   */  public boolean hitsWall(Wall w)  {    if(this.Live&&this.getRect().intersects(w.getRect()))    {      Live=false;      return true;    }    return false;  }      }

Tank.java

package com.hkm.TankWar;import java.awt.*;import java.awt.event.KeyEvent;import java.util.*;/** * 坦克類 * @author Hekangmin * */public class Tank {  public static final int XSPEED=5;//坦克x方向速度  public static final int YSPEED=5;     public static final int WIDTH=30;  public static final int HEIGHT=30;     private BloodBar bb=new BloodBar();//血條     private int life=100;     public int getLife() {    return life;  }   public void setLife(int life) {    this.life = life;  }    private static Random r=new Random();     private static int step=r.nextInt(12)+3;//定義一個數表示敵軍坦克隨機東的步數;     private boolean bL=false,bU=false,bR=false,bD=false;     enum Direction{L,LU,U,RU,R,RD,D,LD,STOP};//利用枚舉類型定義坦克方向;  private int x,y;     private int oldX,oldY;//紀錄上一步坦克的位置;     private boolean live=true;//判斷是否活著     public boolean isLive() {    return live;  }   public void setLive(boolean live) {    this.live = live;  }    private boolean good;//坦克是好是壞     public boolean isGood() {    return good;  }    private Direction ptDir=Direction.D;//新增炮筒的方向;     TankWarClient tc;//為了持有對方的引用以可以方便訪問其成員變數;     Direction dir=Direction.STOP;//一開始將坦克方向設為stop;           public Tank(int x,int y,boolean good,Direction dir,TankWarClient tc)  {    this.x=x;    this.y=y;    this.oldX=x;    this.oldY=y;    this.good=good;    this.dir=dir;    this.tc=tc;//持有對方的引用;  }        public void draw(Graphics g)  {    if(!live)//如果死亡則不再draw;    {        if(!good)      {        tc.tanks.remove(this);        if(tc.tanks.size()<5)//少於5輛坦克時添加坦克;        {          for(int i=0;i<10;i++)          {            int posX=r.nextInt(800);            int posY=r.nextInt(600);            tc.tanks.add(new Tank(posX,posY,false,Direction.D,tc));//使得坦克出現的位置隨機          }        }      }             return;    }         Color c=g.getColor();    if(good)     {      g.setColor(Color.RED);      bb.draw(g);    }    else g.setColor(Color.BLACK);    g.fillOval(x, y, WIDTH, HEIGHT);    g.setColor(c);         switch(ptDir)//畫出炮筒的方向;    {    case L:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-10, y+Tank.HEIGHT/2);//畫出炮筒,畫一條直線代替;      break;    case LU:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-7, y-7);      break;    case U:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y-10);      break;    case RU:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+7, y-7);      break;    case R:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+10, y+Tank.HEIGHT/2);      break;    case RD:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH+7, y+Tank.HEIGHT+7);      break;    case D:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x+Tank.WIDTH/2, y+Tank.HEIGHT+10);      break;    case LD:       g.drawLine(x+Tank.WIDTH/2, y+Tank.HEIGHT/2, x-7, y+HEIGHT+7);      break;    }    move();  }        public void move()  {    oldX=x;//紀錄坦克上一步的位置    oldY=y;         switch(dir)    {    case L:      x-=XSPEED;      break;    case LU:      x-=XSPEED;      y-=YSPEED;      break;    case U:      y-=YSPEED;      break;    case RU:      x+=XSPEED;      y-=YSPEED;      break;    case R:      x+=XSPEED;      break;    case RD:      x+=XSPEED;      y+=YSPEED;      break;    case D:      y+=YSPEED;      break;    case LD:      x-=XSPEED;      y+=YSPEED;      break;    case STOP:      break;    }    if(this.dir!=Direction.STOP)      this.ptDir=this.dir;         /**     * 防止坦克越界;     */    if(x<0) x=0;    if(y<25) y=25;    if(x+Tank.WIDTH>TankWarClient.GAME_WIDTH) x=TankWarClient.GAME_WIDTH-30;    if(y+Tank.HEIGHT>TankWarClient.GAME_HEIGHT) y=TankWarClient.GAME_HEIGHT-30;         if(!good)    {      Direction[] dirs=Direction.values();//將枚舉類型轉化成數組;             if(step==0)      {        step=r.nextInt(12)+3;        int rn=r.nextInt(dirs.length);//產生length以內隨機的整數;        dir=dirs[rn];      }      step--;      if(r.nextInt(40)>20) this.fire();//使敵軍坦克發射子彈;    }       }     /**   * 處理按鍵   * @param e鍵盤事件;   */  public void KeyPressed(KeyEvent e)  {    int key=e.getKeyCode();    switch(key)    {         case KeyEvent.VK_LEFT:      bL=true;      break;    case KeyEvent.VK_RIGHT:      bR=true;      break;    case KeyEvent.VK_UP:      bU=true;       break;    case KeyEvent.VK_DOWN:      bD=true;      break;    }    locationDir();  }        public void keyReleased(KeyEvent e) {    int key=e.getKeyCode();    switch(key)    {    case KeyEvent.VK_CONTROL:      fire();      break;    case KeyEvent.VK_LEFT:      bL=false;      break;    case KeyEvent.VK_RIGHT:      bR=false;      break;    case KeyEvent.VK_UP:      bU=false;       break;    case KeyEvent.VK_DOWN:      bD=false;      break;    case KeyEvent.VK_A:      superFire();      break;    case KeyEvent.VK_F2:      reBorn();      break;    }    locationDir();  }     /**   * 發射子彈   * @return返回子彈類型   */  public Missile fire() {    if(!live)      return null;    int mx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;//計運算元彈發射的位置;    int my=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;    Missile m=new Missile(mx,my,good,ptDir,this.tc);////根據炮筒方向發射子彈    tc.missiles.add(m);    return m;  }        public Missile fire(Direction dir)  {    if(!live)      return null;    int mx=this.x+Tank.WIDTH/2-Missile.WIDTH/2;    int my=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;    Missile m=new Missile(mx,my,good,dir,this.tc);//根據坦克的方向發射子彈;    tc.missiles.add(m);    return m;  }     public void superFire()  {    Direction[] dirs=Direction.values();    for(int i=0;i<8;i++)    {      fire(dirs[i]);    }  }        public void locationDir()  {    if(bL&&!bU&&!bR&&!bD)      dir=Direction.L;    else if(bL&&bU&&!bR&&!bD)      dir=Direction.LU;    else if(!bL&&bU&&!bR&&!bD)      dir=Direction.U;    else if(!bL&&bU&&bR&&!bD)      dir=Direction.RU;    else if(!bL&&!bU&&bR&&!bD)      dir=Direction.R;    else if(!bL&&!bU&&bR&&bD)      dir=Direction.RD;    else if(!bL&&!bU&&!bR&&bD)      dir=Direction.D;    else if(bL&&!bU&&!bR&&bD)      dir=Direction.LD;    else if(!bL&&!bU&&!bR&&!bD)      dir=Direction.STOP;  }         public Rectangle getRect()//擷取tank的矩形地區  {    return new Rectangle(this.x,this.y,this.WIDTH,this.HEIGHT);  }     /**   * 坦克撞牆   * @param w牆   * @returntrue撞上,false未撞上;   */  public boolean colliedsWithWall(Wall w)  {    if(this.live&&this.getRect().intersects(w.getRect()))    {      this.stay();      return true;    }    return false;  }     /**   * 處理坦克與坦克相撞,防止其互相穿越;   * @param tanks敵軍坦克;   * @return true撞上,false未撞上;   */  public boolean colliedsWithTanks(java.util.List<Tank> tanks)  {    for(int i=0;i<tanks.size();i++)    {      Tank t=tanks.get(i);      if(this!=t)      {        if(this.live&&this.isLive()&&this.getRect().intersects(t.getRect()))        {          this.stay();//返回上一步的位置;          t.stay();////返回上一步的位置          return true;        }               }      }    return false;  }      private void stay()  {    x=oldX;    y=oldY;  }     /**   * 為Tank的內部類;血條,顯示在我方坦克的頭頂上;   * @author Hekangmin   *   */  private class BloodBar  {    public void draw(Graphics g)    {      Color c=g.getColor();      g.setColor(Color.RED);      g.drawRect(x,y-10,WIDTH,10);      int w=WIDTH*life/100;      g.fillRect(x,y-10,w,10);    }  }     /**   * 吃到血塊加血;   * @param b血塊   * @returntrue吃到,false未吃到;   */  public boolean eat(Blood b)  {    if(this.live&&b.isLive()&&this.getRect().intersects(b.getRect()))    {      this.life=100;      b.setLive(false);      return true;    }    return false;  }     /**   * 我軍坦剋死後複活;   */  public void reBorn()  {    if(this.isGood()&&!this.isLive())    {      this.setLive(true);      this.setLife(100);    }  }}

TankWarClient.java

package com.hkm.TankWar;import java.awt.*;import java.awt.event.*;import java.util.List;import java.util.ArrayList; /** * 這個是遊戲的運行視窗; * @author Hekangmin * */public class TankWarClient extends Frame{/** * 遊戲視窗的寬度; */  public static final int GAME_WIDTH=800;     /**   * 遊戲視窗的高度;   */  public static final int GAME_HEIGHT=600;     Tank MyTank=new Tank(700,400,true,Tank.Direction.STOP,this);  List<Tank> tanks=new ArrayList<Tank>();  List<Explode> explodes=new ArrayList<Explode>();  List<Missile> missiles=new ArrayList<Missile>();  Wall w1=new Wall(300,200,20,200,this);  Wall w2=new Wall(600,300,30,150,this);  Blood b=new Blood();     /**   * 畫一張虛擬圖片;   */  Image OffScreenImage=null;     public TankWarClient(String name)//設定文字  {    super(name);  }     /**   * 運行視窗;   */     public void launchFrame()  {    for(int i=0;i<10;i++)//添加十輛敵軍坦克    {      tanks.add(new Tank(50+40*(i+1),50,false,Tank.Direction.D,this));    }         this.setBounds(200,100,GAME_WIDTH,GAME_HEIGHT);    this.setBackground(Color.GREEN);    this.addWindowListener(new WindowAdapter()//匿名類    {      public void windowClosing(WindowEvent e)      {        System.exit(0);      }    });    this.addKeyListener(new KeyMonitor());//加入鍵盤監聽器;    this.setResizable(false);//不可改變視窗的大小;         this.setVisible(true);         new Thread(new PaintThread()).start();//建立一個線程;  }     public void paint(Graphics g)  {    g.drawString("Missile count: "+missiles.size(), 10, 50);//顯示字串;    g.drawString("Explodes count: "+explodes.size(),10,70);    g.drawString("tanks count: "+tanks.size(),10,90);    g.drawString("Mytank life: "+MyTank.getLife(),10,110);    /**     * 畫出牆;     */    w1.draw(g);    w2.draw(g);         /**     * 檢測子彈與各類的事情;     */    for(int i=0;i<missiles.size();i++)    {      Missile m=missiles.get(i);      m.hitsWall(w1);      m.hitsWall(w2);      m.hitTanks(tanks);      m.hitTank(MyTank);      m.draw(g);             //if(!m.isLive())        //missiles.remove(m);      //else m.draw(g);    }    /**     * 畫出爆炸;     */    for(int i=0;i<explodes.size();i++)    {      Explode e=explodes.get(i);      e.draw(g);    }         for(int i=0;i<tanks.size();i++)    {      Tank t=tanks.get(i);      t.colliedsWithWall(w1);      t.colliedsWithWall(w2);      t.colliedsWithTanks(tanks);      t.draw(g);    }         b.draw(g);    MyTank.eat(b);    MyTank.draw(g);  }     /**   * 利用雙緩衝技術消除坦克閃爍的現象;   */  public void update(Graphics g) //g為畫在螢幕上的畫筆;  {    if(OffScreenImage==null)      OffScreenImage=this.createImage(GAME_WIDTH, GAME_HEIGHT);    Graphics gOffScreen=OffScreenImage.getGraphics();//gOffScreen是OffScreenImage的畫筆;    Color c=gOffScreen.getColor();    gOffScreen.setColor(Color.GREEN);    gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);    gOffScreen.setColor(c);    paint(gOffScreen);//畫在虛擬圖片上;    g.drawImage(OffScreenImage,0,0,null);//用g畫筆將虛擬圖片上的東西畫在螢幕上       }        private class PaintThread implements Runnable{     public void run() {      while(true)      {        repaint();//這裡的repaint方法是Frame類的        try{        Thread.sleep(100);        }catch(InterruptedException e){          e.printStackTrace();        }      }    }  }     private class KeyMonitor extends KeyAdapter  {    public void keyReleased(KeyEvent e) {      MyTank.keyReleased(e);    }     public void keyPressed(KeyEvent e) {      MyTank.KeyPressed(e);      }            }           public static void main(String[] args) {    new TankWarClient("My Tank World").launchFrame();  }            }

Wall.java

package com.hkm.TankWar;import java.awt.*;/** * 產生阻礙物牆這個類; * @author Hekangmin * */ public class Wall {  /**   * x,y為牆的位置,w,h為寬度高度;   */  int x,y,w,h;  /**   * 持有引用   */  TankWarClient tc;     public Wall(int x, int y, int w, int h, TankWarClient tc) {    this.x = x;    this.y = y;    this.w = w;    this.h = h;    this.tc = tc;  }     public void draw(Graphics g)  {    Color c=g.getColor();    g.setColor(Color.GRAY);    g.fillRect(x,y,w,h);    g.setColor(c);  }     /**   * 得到牆的矩形地區;   * @return   */  public Rectangle getRect()  {    return new Rectangle(x,y,w,h);  }   }

以上所述就是本文的全部內容了,希望大家能夠喜歡。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.