程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java__線程---基礎知識全面實戰---坦克大戰系列為例

Java__線程---基礎知識全面實戰---坦克大戰系列為例

編輯:JAVA編程入門知識

     今天想將自己去年自己編寫的坦克大戰的代碼與大家分享一下,主要面向學習過java但對java運用並不是很熟悉的同學,該編程代碼基本上涉及了java基礎知識的各個方面,大家可以通過練習該程序對自己的java進行一下實戰。

     每個程序版本代碼中,都附有相關注釋,看完注釋大家就可以對本程序設計有個很明顯的思路。真的很有趣,想對java重新溫習的同學完全不必再對厚厚的java基礎書籍進行閱讀了,在跟著本次代碼練習並分析後,大家一定會對java各方面基礎知識 尤其是線程的知識有更深一步的了解!!!

     本次坦克大戰系列的各個版本都是在一步步的升級改進,難度逐漸加大,功能愈加完善;話不多說,先給大家分享一下代碼(●ˇ∀ˇ●)

Tank大戰 version1.0

實現功能:
  1.繪制出我方Tank;

  2.可以通過鍵盤上下左右鍵 控制移動;

 package com.test;
 
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.event.*;
 
 import javax.swing.*;
 
 
 public class MyTankGame extends JFrame {
     Mypanel mp=null;
     public static void main(String[] args) {
         // TODO 自動生成的方法存根
        MyTankGame mtg=new MyTankGame();
     }
     //構造函數
     public MyTankGame()
     {
         mp=new Mypanel();
         this.add(mp);
         this.setSize(800,600);
         this.setVisible(true);
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
     }
 
 }
 
 //坦克類
 class Tank
 {
      //表示坦克橫坐標
     int x=0;
     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;
     }
 
     //表示坦克縱坐標
     int y=0;
     
     public Tank(int x,int y)
     {
         this.x=x;
         this.y=y;
     }
 }
 
 //我的Tank
 class Hero extends Tank
 {
 
     public Hero(int x, int y) {
         super(x, y);
         // TODO 自動生成的構造函數存根
     }
     
 }
 
 
 //我的面板
 class Mypanel extends JPanel
 {
     //定義一個我的坦克
     Hero hero=null;
     
     //構造函數
     public Mypanel()
     {
         hero=new Hero(100,100);
     }
     public void paint(Graphics g)
     {
         super.paint(g);
         //設置面板背景色,全部填充即可,默認為黑色
         g.fillRect(0, 0, 800, 600);
         //畫出我的tank,放到paint函數中
         this.DrawTank(hero.getX(), hero.getY(), g,0,0);//hero.getX(), hero.getY()就將x,y傳過去了
     }
     
     //畫出tank
     public void DrawTank(int x,int y,Graphics g,int direct,int type)
     {
         //判斷是什麼類型坦克
         switch(type)
         {
         case 0://我的tank
             g.setColor(Color.cyan);
             break;
         case 1://敵人的tank
             g.setColor(Color.orange);
             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.fillRect(x+9, y, 2, 10);
             break;
         }
     }
 }
 
 /*
                           畫出左邊矩形
             g.fill3DRect(hero.getX(), hero.getY(), 5, 30, false);
             //畫出右邊矩形
             g.fill3DRect(hero.getX()+15, hero.getY(), 5, 30, false);
             //畫出中間矩形
             g.fill3DRect(hero.getX()+5, hero.getY()+5, 10, 20, false);
             //畫出中間圓形
             g.fillOval(hero.getX()+5, hero.getY()+10, 10, 10);
             //畫出中間直線
             g.drawLine(hero.getX()+10, hero.getY()+15, 10, 20);
             break;
 
  */
  

 

Tank大戰 version2.0

java練習---->坦克大戰2.0------>引入多線程

實現功能:
  1.有敵方tank與我方tank;

  2.我方tank可以控制移動;

  3.我方tank可以發射炮彈;

  4.敵方tank未作處理;

 package TankGame2;
 
 import java.awt.*;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.util.*;
 import javax.swing.*;
 public class MyTankGame2  extends JFrame
 {
  MyPanel mp=null;
  public static void main(String[] args)
  {
   MyTankGame2 mytankgame1=new MyTankGame2();  
  }
  
  public MyTankGame2()
  {
   mp=new MyPanel();
   //啟動mp線程
   
   Thread t=new Thread(mp);
   t.start();
   
   this.add(mp);
   this.addKeyListener(mp);
   
   this.setSize(400,300);
   this.setVisible(true);
   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
  }
 }
 
 
 class MyPanel extends JPanel implements KeyListener,Runnable
 {
  //定義我的坦克,成員變量
  Hero hero=null;
  
  //定義敵人的坦克組
  
  Vector<EnemyTank> ets=new Vector<EnemyTank>();
  int enSize=3;
  
  public void paint (Graphics g)
  {
    super.paint(g);
    g.fillRect(0,0,400,300);
   
    //畫出自己的坦克
    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
   
    //畫出子彈
    if (hero.s!=null&&hero.s.isLive==true)
    {
     g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false);
    
    }
   
   
    //畫出敵人的坦克
    for(int i=0;i<ets.size();i++)
    {
    
     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
    
    }
  
  }
  
  //畫出坦克函數(擴展)
  public void drawTank(int x,int y,Graphics g,int direct,int type)
  {
   //判斷類型
   switch (type)
   {
   case 0:
    g.setColor(Color.cyan);break;
   case 1:
    g.setColor(Color.yellow);break;  
   }
   //判斷方向
   
   switch(direct)
   {
   //向上
   case 0:
     //畫出我的坦克(到時候再封裝成一個函數)
     //1.畫出左面的矩形
     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
     g.fill3DRect(x,y,5,30,false);
    
     //2.畫出右邊的矩形
     g.fill3DRect(x+15,y,5,30,false);
    
     //3.畫出坦克的中間矩形
     g.fill3DRect(x+5, y+5, 10, 20,false);
     //畫出中間的圓
     g.fillOval(x+4, y+10,10,10);
     //畫出線
     g.drawLine(x+9, y+15, x+9, 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+4, 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;   
   } 
   
  }
  
  
  public MyPanel()
  {
   hero=new Hero(100,100);
   
   //初始化敵人的坦克
   for(int i=0;i<enSize;i++)
   {
    //創建敵人的坦克對象   
    EnemyTank et=new EnemyTank((i+1)*50,0);
    et.setColor(0);
    et.setDirect(2);
    ets.add(et);   
   }
   
  }
  
  //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右
  public void keyPressed(KeyEvent e)
  {
   if(e.getKeyCode()==KeyEvent.VK_UP)
   {
    // 設置我的坦克的方向
    this.hero.setDirect(0); 
    this.hero.moveUp();
   }
  
   else if (e.getKeyCode()==KeyEvent.VK_DOWN)
   {
    this.hero.setDirect(2);   
    this.hero.moveDown();   
   }
  
   else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
   {
    this.hero.setDirect(1);   
    this.hero.moveRight();
    
   }  
   else if (e.getKeyCode()==KeyEvent.VK_LEFT)
   {
    this.hero.setDirect(3);   
    this.hero.moveLeft();   
   }
   
   if (e.getKeyCode()==KeyEvent.VK_SPACE)
   {
    this.hero.shotEnemy();
    
   }
   
  
   //必須重新繪制Panel
   this.repaint(); 
  }
  
  public void keyReleased(KeyEvent e)                      //有什麼用?!!!!!!!!!!!
  {
   
  }
  public void keyTyped(KeyEvent e)
  {
   
  }
  public void run()
  {
  //每個一百毫秒去重畫子彈
   while(true)
   {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    this.repaint();
    
   }
  }
   
 }
 

 class Tank
 {
  
  //設置坦克的速度
  int speed=1;
  public int getSpeed()
  {
   return speed;
  }
  public void setSpeed(int speed)
  {
   this.speed = speed;
  }
  //表示坦克的橫坐標
  int x=0;
  //坦克的縱坐標
  int y=0;
  int direct=0;
  int color;
  
  //坦克方向,0表示上,1表示右,2表示下,3表示左
  public int getColor() {
   return color;
  }
  public void setColor(int color) {
   this.color = color;
  }
  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 EnemyTank extends Tank
 {
  public EnemyTank(int x,int y)
  {
   super(x,y);                                                            //super的用法???
   
  }
 }
  
 
 //我的坦克
 class Hero extends Tank
 {
  //子彈
  Shot s=null;
  public Hero(int x, int y)
  {
   super(x,y);
  }
  //坦克向上移動
  
  //坦克的開火的能力和動作
  public void shotEnemy()
  {
   switch(this.direct)
   {
    case 0:
     s=new Shot(x+9,y-1,0);
     break;
    case 1:
     s=new Shot(x+30,y+10,1);
     break;
    case 2:
     s=new Shot(x+9,y+30,2);
     break;
    case 3:
     s=new Shot(x-1,y+9,3);
     break;
   }
  
   Thread t=new Thread(s);
   t.start();
   
  }
  
  
  public void moveUp()
  {
   this.y-=speed;  
  }
  public void moveRight()
  {
   this.x+=speed;  
  }
  
  public void moveDown()
  {
   this.y+=speed;  
  } 
  public void moveLeft()
  {
   this.x-=speed;  
  } 
 }
 
 
 class Shot implements Runnable                                        //runnable的用法????
 {
  int x;
  int y;
  int direct;
  int speed=1;
  //是否活著
  
  boolean isLive=true;
  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>400||y<0||y>300)
    {
     this.isLive=false;
     break;
     
    }
    
   }
   
  }
 }

 

Tank大戰 version3.0

java練習---->坦克大戰3.0

實現功能:
  1.有敵方tank與我方tank;

  2.我方tank可以控制移動,可以發射炮彈;

  3.寫一個函數專門判斷子彈是否擊中敵人坦克;

  4.判斷tank是否活著;

(注:本版本中,Tank是不可以發射炮彈的······)

 package TankGame3;
 
 import java.awt.*;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.util.*;
 import javax.swing.*;
 import java.util.Vector;
 public class MyTankGame4  extends JFrame
 {
  MyPanel mp=null;
  public static void main(String[] args)
  {
   MyTankGame4 mytankgame1=new MyTankGame4();  
  }
  
  public MyTankGame4()
  {
   mp=new MyPanel();
   //啟動mp線程
   
   Thread t=new Thread(mp);
   t.start();
   
   this.add(mp);
   this.addKeyListener(mp);
   
   this.setSize(400,300);
   this.setVisible(true);
   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
  }
 }
 class MyPanel extends JPanel implements KeyListener,Runnable
 {
  //定義我的坦克,成員變量
  Hero hero=null;
  
  //定義敵人的坦克組
  
  Vector<EnemyTank> ets=new Vector<EnemyTank>();
  int enSize=3;
  
  public void paint (Graphics g)
  {
    super.paint(g);
    g.fillRect(0,0,400,300);
   
    //畫出自己的坦克
    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
   
    //從Vector ss中取出每一顆子彈,並畫出
    for(int i=0;i<this.hero.ss.size();i++)
    {
     Shot myShot=hero.ss.get(i);   
   
   
     //畫出子彈,只畫一顆子彈
     if (myShot!=null&&myShot.isLive==true)
     {
      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
     
     }
     if (myShot.isLive==false)
     {
      //從ss中刪除該子彈
      hero.ss.remove(myShot);
     
     }
    }
   
    //畫出敵人的坦克
    for(int i=0;i<ets.size();i++)
    {
     EnemyTank et=ets.get(i);
     if(et.isLive) 
     {
     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
     }
    }
  
  }
  
  //寫一個函數專門判斷子彈是否擊中敵人坦克
  public void hitTank(Shot s,EnemyTank et)
  {
   //判斷該坦克的方向
   switch(et.direct)
   {
   //如果敵人的方向是上或者是下
   case 0:
   case 2:
    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
    }
   case 1:
   case 3:
    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
     
    }
   
   }
   
  }
  
  //畫出坦克函數(擴展)
  public void drawTank(int x,int y,Graphics g,int direct,int type)
  {
   //判斷類型
   switch (type)
   {
   case 0:
    g.setColor(Color.cyan);break;
   case 1:
    g.setColor(Color.yellow);break;  
   }
   //判斷方向
   
   switch(direct)
   {
   //向上
   case 0:
     //畫出我的坦克(到時候再封裝成一個函數)
     //1.畫出左面的矩形
     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
     g.fill3DRect(x,y,5,30,false);
    
     //2.畫出右邊的矩形
     g.fill3DRect(x+15,y,5,30,false);
    
     //3.畫出坦克的中間矩形
     g.fill3DRect(x+5, y+5, 10, 20,false);
     //畫出中間的圓
     g.fillOval(x+4, y+10,10,10);
     //畫出線
     g.drawLine(x+9, y+15, x+9, 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+4, 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;   
   } 
   
  }
  
  
  public MyPanel()
  {
   hero=new Hero(100,100);
   
   //初始化敵人的坦克
   for(int i=0;i<enSize;i++)
   {
    //創建敵人的坦克對象   
    EnemyTank et=new EnemyTank((i+1)*50,0);
    et.setColor(0);
    et.setDirect(2);
    ets.add(et);   
   }
   
  }
  
  //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右
  public void keyPressed(KeyEvent e)
  {
   if(e.getKeyCode()==KeyEvent.VK_W)
   {
    // 設置我的坦克的方向
    this.hero.setDirect(0); 
    this.hero.moveUp();
   }
  
   else if (e.getKeyCode()==KeyEvent.VK_S)
   {
    this.hero.setDirect(2);   
    this.hero.moveDown();   
   }
  
   else if (e.getKeyCode()==KeyEvent.VK_D)
   {
    this.hero.setDirect(1);   
    this.hero.moveRight();
    
   }  
   else if (e.getKeyCode()==KeyEvent.VK_A)
   {
    this.hero.setDirect(3);   
    this.hero.moveLeft();   
   }
   
   if (e.getKeyCode()==KeyEvent.VK_J)
   {   
    this.hero.shotEnemy();   
   }  
  
   //必須重新繪制Panel
   this.repaint(); 
  }
  public void keyReleased(KeyEvent e)
  {
   
  }
  public void keyTyped(KeyEvent e)
  {
   
  }
  public void run()
  {
  //每個一百毫秒去重畫子彈
   while(true)
   {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    
    for(int i=0;i<hero.ss.size();i++)
    {
     Shot myShot=hero.ss.get(i);
     //判斷子彈是否有效
     if(myShot.isLive)
     {
      //取出每個坦克,與它判斷
      for(int j=0;j<ets.size();j++)
      {
       //取出坦克
       EnemyTank et=ets.get(j);
       if(et.isLive)
       {
        this.hitTank(myShot,et);
        
       }
       
      }
      
     }
    }
    
    this.repaint();
    
   }
  }
   
 }
 
 //package MyTankGame4;
 //import java.util.Vector;
 //import MyTankGame4.Shot;
 //import MyTankGame4.Tank;
 class Tank
 {
  
  //設置坦克的速度
  int speed=1;
  public int getSpeed()
  {
   return speed;
  }
  public void setSpeed(int speed)
  {
   this.speed = speed;
  }
  //表示坦克的橫坐標
  int x=0;
  //坦克的縱坐標
  int y=0;
  int direct=0;
  int color;
  
  //坦克方向,0表示上,1表示右,2表示下,3表示左
  public int getColor() {
   return color;
  }
  public void setColor(int color) {
   this.color = color;
  }
  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 EnemyTank extends Tank
 {
  boolean isLive=true;
  public EnemyTank(int x,int y)
  {
   super(x,y);
   
  }
 }
  
 
 //我的坦克
 class Hero extends Tank
 {
  //子彈
  //Shot s=null;
  Vector<Shot>  ss=new Vector<Shot>();
  Shot s=null;
  
  public Hero(int x, int y)
  {
   super(x,y);
  }
  //坦克向上移動
  
  //坦克的開火的能力和動作
  public void shotEnemy()
  {
   switch(this.direct)
   {
    case 0:
     s=new Shot(x+9,y-1,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+9,y+30,2);
     ss.add(s);
     break;
    case 3:
     s=new Shot(x-1,y+9,3);     ss.add(s);
     ss.add(s);
     break;
   }
  
   Thread t=new Thread(s);
   t.start();
   
  }
  
  
  public void moveUp()
  {
   this.y-=speed;  
  }
  public void moveRight()
  {
   this.x+=speed;  
  }
  
  public void moveDown()
  {
   this.y+=speed;  
  } 
  public void moveLeft()
  {
   this.x-=speed;  
  } 
 }
 class Shot implements Runnable
 {
  int x;
  int y;
  int direct;
  int speed=1;
  //是否活著
  
  boolean isLive=true;
  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>400||y<0||y>300)
    {
     this.isLive=false;
     break;
     
    }
    
   }
   
  }
 }

 

Tank大戰 version4.0

java練習---->坦克大戰4.0

實現功能:
  1.有敵方tank與我方tank;

  2.雙方都可以控制移動,可以發射炮彈;

  3.敵方坦克可以被擊中消失

  4.有爆炸效果;

  5.可以計算生命值和炸彈生命;

 package TankGame4;
 //package MyTankGame4;
 import java.util.Vector;
 import java.awt.*;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.util.*;
 import javax.swing.*;
 public class MyTankGame4  extends JFrame
 {
  MyPanel mp=null;
  public static void main(String[] args)
  {
   MyTankGame4 mytankgame1=new MyTankGame4();  
  }
  
  public MyTankGame4()
  {
   mp=new MyPanel();
   //啟動mp線程
   
   Thread t=new Thread(mp);
   
   t.start();
   
   this.add(mp);
   this.addKeyListener(mp);
   
   this.setSize(400,300);
   this.setVisible(true);
   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
  }
 }
 class MyPanel extends JPanel implements KeyListener,Runnable
 {
  //定義我的坦克,成員變量
  Hero hero=null;
  
  //定義敵人的坦克組
  
  Vector<EnemyTank> ets=new Vector<EnemyTank>();
  int enSize=5;
  
  //定義炸彈集合
  Vector<Bomb> bombs=new Vector<Bomb>();
  
  public void run()
  {
  //每個一百毫秒去重畫子彈
   while(true)
   {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    
    for(int i=0;i<hero.ss.size();i++)
    {
     Shot myShot=hero.ss.get(i);
     //判斷子彈是否有效
     if(myShot.isLive)
     {
      //取出每個坦克,與它判斷
      for(int j=0;j<ets.size();j++)
      {
       //取出坦克
       EnemyTank et=ets.get(j);
       if(et.isLive)
       {
        this.hitTank(myShot,et);
        
       }      
      }
      
     }
    }
    
    this.repaint();
    //判斷是否需要給坦克加入新的子彈
    for(int i=0;i<ets.size();i++)
    {
     EnemyTank et=ets.get(i);
     if(et.isLive)
     {
      if (et.ss.size()<5&&(int)(100*Math.random())>75)
      {
       //每輛坦克的子彈少於5發的話
       //添加
       Shot s=null;
       switch(et.direct)
       {
       case 0:
        s=new Shot(et.x+9,et.y-1,0);
        et.ss.add(s);
        break;
       case 1:
        s=new Shot(et.x+30,et.y+10,1);
        et.ss.add(s);
        break;
       case 2:
        s=new Shot(et.x+9,et.y+30,2);
        et.ss.add(s);
        break;
       case 3:
        s=new Shot(et.x-1,et.y+9,3);    
        et.ss.add(s);
        break;            
       }
       
       //啟動子彈線程
       Thread t=new Thread(s);
       t.start();
       
      }
   
     }
    }
    
   }
  
  }
  
  public void paint (Graphics g)
  {
    super.paint(g);
    g.fillRect(0,0,400,300);
   
    //畫出自己的坦克
    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
   
    //從Vector ss中取出每一顆子彈,並畫出
    for(int i=0;i<this.hero.ss.size();i++)
    {
     Shot myShot=hero.ss.get(i);   
   
   
     //畫出子彈,只畫一顆子彈
     if (myShot!=null&&myShot.isLive==true)
     {
      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
     
     }
     if (myShot.isLive==false)
     {
      //從ss中刪除該子彈
      hero.ss.remove(myShot);
     
     }
    }
   
    //畫出炸彈
    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);
    }
    else if(b.life>3)
    {
     g.drawImage(image2, b.x, b.y, 30,30,this);
    }
    else
    {
     g.drawImage(image3, b.x, b.y, 30,30,this);
    }
    //讓b的生命值減小
    b.lifeDown();
    //如果炸彈的生命值為0,我們就剔除
    if(b.life==0) bombs.remove(b);
    
    
    }
   
   
    //畫出敵人的坦克
    for(int i=0;i<ets.size();i++)
    {
     EnemyTank et=ets.get(i);
     if(et.isLive) 
     {
     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
     //畫出敵人的子彈
    
     for(int j=0;j<et.ss.size();j++)
     {
      //取出子彈
      Shot enemyShot=et.ss.get(j);
      if(enemyShot.isLive)
      {
       g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
      }
      else
      {
      //如果敵人的坦克死亡就從Vector去掉
       et.ss.remove(enemyShot);
      
      }
      
     }
     }
    }
  
  }
  
  //寫一個函數專門判斷子彈是否擊中敵人坦克
  public void hitTank(Shot s,EnemyTank et)
  {
   //判斷該坦克的方向
   switch(et.direct)
   {
   //如果敵人的方向是上或者是下
   case 0:
   case 2:
    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
     //創建一個炸彈,放入Vector
     Bomb b=new Bomb(et.x,et.y);
     //放入Vector
     bombs.add(b);
    }
   case 1:
   case 3:
    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
     //創建一個炸彈,放入Vector
     Bomb b=new Bomb(et.x,et.y);
     //放入Vector
     bombs.add(b);    
    }
   
   }
   
  }
  
  //畫出坦克函數(擴展)
  public void drawTank(int x,int y,Graphics g,int direct,int type)
  {
   //判斷類型
   switch (type)
   {
   case 0:
    g.setColor(Color.cyan);break;
   case 1:
    g.setColor(Color.yellow);break;  
   }
   //判斷方向
   
   switch(direct)
   {
   //向上
   case 0:
     //畫出我的坦克(到時候再封裝成一個函數)
     //1.畫出左面的矩形
     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
     g.fill3DRect(x,y,5,30,false);
    
     //2.畫出右邊的矩形
     g.fill3DRect(x+15,y,5,30,false);
    
     //3.畫出坦克的中間矩形
     g.fill3DRect(x+5, y+5, 10, 20,false);
     //畫出中間的圓
     g.fillOval(x+4, y+10,10,10);
     //畫出線
     g.drawLine(x+9, y+15, x+9, 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+4, 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;   
   } 
   
  }
  
  //定義三張圖片,三張圖片切換組成一顆炸彈
  Image image1=null;
  Image image2=null;
  Image image3=null;
  
  //構造函數
  public MyPanel()
  {
   hero=new Hero(100,100);
   
   //初始化敵人的坦克
   for(int i=0;i<enSize;i++)
   {
    //創建敵人的坦克對象   
    EnemyTank et=new EnemyTank((i+1)*50,0);
    et.setColor(0);
    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 t2=new Thread(s);
    t2.start();
    //加入
    
    ets.add(et);   
   }
   
   image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));
   image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
   image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg"));
   
  }
  
 //鍵按下處理向左,向下,向上,向右
 public void keyPressed(KeyEvent e)
 {
  if(e.getKeyCode()==KeyEvent.VK_UP)
  {
   // 設置我的坦克的方向
   this.hero.setDirect(0); 
   this.hero.moveUp();
  }
 
  else if (e.getKeyCode()==KeyEvent.VK_DOWN)
  {
   this.hero.setDirect(2);   
   this.hero.moveDown();   
  }
 
  else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
  {
   this.hero.setDirect(1);   
   this.hero.moveRight();
   
  }  
  else if (e.getKeyCode()==KeyEvent.VK_LEFT)
  {
   this.hero.setDirect(3);   
   this.hero.moveLeft();   
  }
  
  if (e.getKeyCode()==KeyEvent.VK_J)
  {
   this.hero.shotEnemy();
   
  }
   //必須重新繪制Panel
   this.repaint(); 
  }
  public void keyReleased(KeyEvent e)
  {
   
  }
  public void keyTyped(KeyEvent e)
  {
   
  }
   
 }
  
 
 class Tank
 {
  
  //設置坦克的速度
  int speed=3;
  public int getSpeed()
  {
   return speed;
  }
  public void setSpeed(int speed)
  {
   this.speed = speed;
  }
  //表示坦克的橫坐標
  int x=0;
  //坦克的縱坐標
  int y=0;
  int direct=0;
  int color;
  
  //坦克方向,0表示上,1表示右,2表示下,3表示左
  public int getColor() {
   return color;
  }
  public void setColor(int color) {
   this.color = color;
  }
  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 EnemyTank extends Tank implements Runnable
 {
  boolean isLive=true;
  
  //定義一個向量,可以存放敵人的子彈
  
  Vector<Shot> ss=new Vector<Shot>();
  //敵人添加子彈應該在剛剛創建坦克和坦克子彈死亡之後
  
  
  
  public EnemyTank(int x,int y)
  {
   super(x,y);
   
  }
  public void run() {
   while(true)
   {  //移動前進
    switch(this.direct)
    {
    case 0:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(y>=speed)
      {
       y-=speed;
      }
     }
     break;
    case 1:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(x<=400-(speed+30))
      {
       x+=speed;
      }
     }
     break;
    case 2:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(y<=300-(speed+30))
      {
       y+=speed;
      }
     }
     break;
    case 3:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(x>=speed)
      {
       x-=speed;
      }
     
     }
     break;
     
    }
    
    //讓坦克隨機產生一個新的方向
    if(Math.random()>0.50)
    this.direct=(int)(Math.random()*4);
    
    //判斷敵人坦克是否死亡
    if(this.isLive==false)
    {
     //讓坦克死亡後,退出線程
     break;
    }
    
   }
   
  }
 }
  
 
 //我的坦克
 class Hero extends Tank
 {
  //子彈
  //Shot s=null;
  Vector<Shot>  ss=new Vector<Shot>();
  Shot s=null;
  
  public Hero(int x, int y)
  {
   super(x,y);
  }
  //坦克向上移動
  
  //坦克的開火的能力和動作
  public void shotEnemy()
  {
   switch(this.direct)
   {
    case 0:
     s=new Shot(x+9,y-1,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+9,y+30,2);
     ss.add(s);
     break;
    case 3:
     s=new Shot(x-1,y+9,3);     ss.add(s);
     ss.add(s);
     break;
   }
  
   Thread t=new Thread(s);
   t.start();
   
  }
  
  
  public void moveUp()
  {
   this.y-=speed;  
  }
  public void moveRight()
  {
   this.x+=speed;  
  }
  
  public void moveDown()
  {
   this.y+=speed;  
  } 
  public void moveLeft()
  {
   this.x-=speed;  
  } 
 }
  
 class Shot implements Runnable
 {
  int x;
  int y;
  int direct;
  int speed=1;
  //是否活著
  
  boolean isLive=true;
  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>400||y<0||y>300)
    {
     this.isLive=false;
     break;
     
    }
    
   }
   
  }
 }
 class Bomb
 {
  //定義炸彈的坐標
  int x,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;}
   
  }
  
 }

 

Tank大戰 version5.0

java練習---->坦克大戰5.0

實現功能:
  1.在原有基礎啊上進行優化和功能完善;

  2.增加闖關功能等;

  3.完結版!!!!!

 package TankGame5;
 
 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.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.*;
 import java.io.*;
 import java.util.Vector;
 import javax.imageio.ImageIO;
 import javax.swing.*;
 
 
 public class MyTankGame5  extends JFrame implements ActionListener
 {
     //聲明一個標志
  int  flag=0;
 // 聲明一個運行面板
  MyPanel mp=null;
  //定義一個開始的面板
  MyStartPanel msp=null;
  
  //做出我需要的菜單
  JMenuBar jmb=null;
  //開始游戲
  JMenu jm1=null;
  JMenuItem jmi1=null;
     //退出系統
  JMenuItem jmi2=null;
  JMenuItem jmi3=null;
  JMenuItem jmi4=null;
  
  public static void main(String[] args)
  {
   MyTankGame5 mytankgame1=new MyTankGame5(); 
   mytankgame1.setLocationRelativeTo(null);//將JFrame設置在中間
 //  mytankgame1.setLocation(210,140);//設置JFrame的位置
  }
  
  public MyTankGame5() //構造
  {//初始化菜單欄
   jmb=new JMenuBar();
   jm1=new JMenu("游戲(G)");
   
   //設置快捷方式
   jm1.setMnemonic('G');
   jmi1=new JMenuItem("開始新游戲(N)");
   jmi2=new JMenuItem("退出游戲(E)");
   jmi3=new JMenuItem("存盤退出(C)");
   jmi4=new JMenuItem("繼續上次游戲(L)");
 
   jmi1.setMnemonic('N');
   jmi2.setMnemonic('E');
   jmi3.setMnemonic('C');
   jmi4.setMnemonic('L');
 
   //對jmi1響應,注冊監聽,標記消息源
   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 game");
   
   jm1.add(jmi1);
   jm1.add(jmi2);
   jm1.add(jmi3);
   jm1.add(jmi4);
   jmb.add(jm1);
   
 //  聲明初始化面板
     
   msp=new MyStartPanel();
   
   Thread t=new Thread(msp);
   t.start();
 //  初始化窗口,構造函數的重點
   this.setJMenuBar(jmb);//千萬注意啊!!!!
   
   this.add(msp);
   this.setSize(400,300);
   this.setVisible(true);
   this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
  }
  public void actionPerformed(ActionEvent e)
  {
   //對用戶不同的點擊做出不同的處理
 //     首先得到command字符串,判斷消息源
   if(e.getActionCommand().equals("new game"))
   {
    this.setSize(600,500);
    mp=new MyPanel(flag);
    //啟動mp線程
    
    Thread t1=new Thread(mp);
   
    t1.start();
    //先刪除舊的面板
    this.remove(msp);
    
    this.add(mp);
    //注冊監聽
    this.addKeyListener(mp);
    //顯示
    this.setVisible(true);
   }
   else if(e.getActionCommand().equals("exit"))
   {
    //用戶退出   
    //保存擊毀敵人數量
    Recorder.keepRecording();
    System.exit(0);   
   }
   
   else if(e.getActionCommand().equals("save and exit"))
   {
    Recorder.keepRecAndEnemyTank(mp.ets);
    if(this.mp.hero.isLive==true)
    {
     Recorder.keepRecAndMyTank(this.mp.hero);
     
    }
    System.exit(0);   
   }
   else if(e.getActionCommand().equals("continue game"))
   {
    this.setSize(600,500);
    flag=1;
    mp=new MyPanel(flag);
    //啟動mp線程
    
    Thread t1=new Thread(mp);
   
    t1.start();
    //先刪除舊的面板
    this.remove(msp);
    
    this.add(mp);
    //注冊監聽
    this.addKeyListener(mp);
    //顯示
    this.setVisible(true);
   }
  }
 }
 
 
 //開始面板起一個提示的作用
 class MyStartPanel 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);
    //開關信息的字體
    try{
    Font myFont=new Font("華文新魏",Font.BOLD,30);
    g.setFont(myFont);
    }   catch(Exception e){e.printStackTrace();}
    
    g.drawString("stage:1", 150, 150);
   }
  }
  public void run()
  {  
   while(true)
   {
    try {
     Thread.sleep(500);
    } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    this.repaint();
    times++;
    if(times==1000) times=0;
   }
  }
   
 }
 
 
 class MyPanel extends JPanel implements KeyListener,Runnable
 {
  //定義我的坦克,成員變量
  Hero hero=null;
  
  //判斷是續上局還是新的游戲
  String flag="newGame";
   
  //定義敵人的坦克組
  
  Vector<EnemyTank> ets=new Vector<EnemyTank>();
 // 全局變量,聲明,敵人坦克數量 
  static int enSize=5;
  public static int getEnSize() {
   return enSize;
  }
  //定義炸彈集合
  Vector<Bomb> bombs=new Vector<Bomb>();
 // paint 方法被面板適時自動調用
  public void paint (Graphics g)
  {
    super.paint(g);
    g.fillRect(0,0,400,300);
   
    //畫出提示信息
    this.showInfo(g);
   
    //畫出自己的坦克
    if(hero.isLive==true)
    {
    this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
    }
    //從Vector ss中取出每一顆子彈,並畫出,如果有子彈
    for(int i=0;i<this.hero.ss.size();i++)
    {
     Shot myShot=hero.ss.get(i);     
   
     //畫出子彈,只畫一顆子彈
     if (myShot!=null&&myShot.isLive==true)
     {
      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
     
     }
     if (myShot.isLive==false)
     {
      //從ss中刪除該子彈
      hero.ss.remove(myShot);
     
     }
    }
   
    //畫出炸彈
    for(int i=0;i<bombs.size();i++)
    {
    // 取出炸彈
    Bomb b=bombs.get(i);
    
    if(b.life>6)
    {
     g.drawOval(b.x, b.y, 30, 30);
 //       g.drawImage(image1, b.x, b.y, 30,30,this);
    }
    else if(b.life>3)
    {
        g.drawOval(b.x, b.y, 20, 20);
 //    g.drawImage(image2, b.x, b.y, 30,30,this);
  
    }
    else
    {
        g.drawOval(b.x, b.y, 10, 10);
 //    g.drawImage(image3, b.x, b.y, 30,30,this);
    }
    //讓b的生命值減小
    b.lifeDown();
    //如果炸彈的生命值為0,我們就剔除
    if(b.life==0) bombs.remove(b);
       
    }
   
   
    //畫出敵人的坦克
    for(int i=0;i<ets.size();i++)
    {
     EnemyTank et=ets.get(i);
     if(et.isLive) 
     {
     this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0);
     //畫出敵人的子彈
    
     for(int j=0;j<et.ss.size();j++)
     {
      //取出子彈
      Shot enemyShot=et.ss.get(j);
      if(enemyShot.isLive)
      {
       g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
      }
      else
      {
      //如果敵人的坦克死亡就從Vector去掉
       et.ss.remove(enemyShot);
      
      }
      
     }
     }
    }
  
  }
  //判斷我是否被擊中了
  public void hitMe()
  {
   //取出敵人的每一顆子彈
   
   for(int i=0;i<this.ets.size();i++)
   {
    //取出坦克
    EnemyTank et=ets.get(i);
    
    //取出每一顆子彈
    for (int j=0;j<et.ss.size();j++)
    {
     //取出子彈
     Shot enemyShot=et.ss.get(j);
     if(hero.isLive)//&&Recorder.getMyLife()>=1
     {
      this.hitTank(enemyShot, hero);  
      //Recorder.setMyLife(Recorder.getMyLife()-1);
     }
     
    }
    
   }
   
  }
  
  
  //判斷我的子彈是否擊中敵人的坦克
  public void hitEnemyTank()
  {
   for(int i=0;i<hero.ss.size();i++)
   {
    Shot myShot=hero.ss.get(i);
    //判斷子彈是否有效
    if(myShot.isLive)
    {
     //取出每個坦克,與它判斷
     for(int j=0;j<ets.size();j++)
     {
      //取出坦克
      EnemyTank et=ets.get(j);
      if(et.isLive)
      {
       this.hitTank(myShot,et);
       
      }      
     }
     
    }
   }
   
  }
 
  //寫一個函數專門判斷子彈是否擊中敵人坦克
  public void hitTank(Shot s,Tank et)
  {
   //判斷該坦克的方向
   switch(et.direct)
   {
   //如果敵人的方向是上或者是下
   case 0:
   case 2:
    if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
     //減少敵人數量
     if (et.getClass()==EnemyTank.class)//反射機制
     {
      Recorder.reduceEnNum();
      //增加我的記錄
      Recorder.addEnNumRec();
     }
     
     if (et.getClass()==Hero.class)//反射機制
     {
      
     }
     //創建一個炸彈,放入Vector
     Bomb b=new Bomb(et.x,et.y);
     //放入Vector
     bombs.add(b);
    }
   case 1:
   case 3:
    if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20))
    {
     //擊中了
     //子彈死亡
     s.isLive=false;
      //敵人坦克也要死亡
     et.isLive=false;
     //減少敵人數量
     if (et.getClass()==EnemyTank.class)//反射機制
     {
      Recorder.reduceEnNum();
      //增加我的記錄
      Recorder.addEnNumRec();
     }
     
     if (et.getClass()==Hero.class)//反射機制
     {
      Recorder.setMyLife(Recorder.getMyLife() - 1);
     }
     //創建一個炸彈,放入Vector
     Bomb b=new Bomb(et.x,et.y);
     //放入Vector
     bombs.add(b);    
    }
   
   }
   
  }
  
  //畫出坦克函數(擴展)
  public void drawTank(int x,int y,Graphics g,int direct,int type)
  {
   //判斷類型
   switch (type)
   {
   case 0:
    g.setColor(Color.cyan);break;
   case 1:
    g.setColor(Color.yellow);break;  
   }
   //判斷方向
   
   switch(direct)
   {
   //向上
   case 0:
     //畫出我的坦克(到時候再封裝成一個函數)
     //1.畫出左面的矩形
     //g.drawRect(hero.getX(), hero.getY(), 5, 30);
     g.fill3DRect(x,y,5,30,false);
    
     //2.畫出右邊的矩形
     g.fill3DRect(x+15,y,5,30,false);
    
     //3.畫出坦克的中間矩形
     g.fill3DRect(x+5, y+5, 10, 20,false);
     //畫出中間的圓
     g.fillOval(x+4, y+10,10,10);
     //畫出線
     g.drawLine(x+9, y+15, x+9, 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+4, 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;   
   } 
   
  }
  
  
  public void run()
  {
  //每個一百毫秒去重畫子彈
   while(true)
   {
    try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    
   
    this.hitEnemyTank();
    
    //函數,判斷敵人的子彈是否擊中我了
    this.hitMe();
    
    this.repaint();
    //判斷是否需要給坦克加入新的子彈
    for(int i=0;i<ets.size();i++)
    {
     EnemyTank et=ets.get(i);
     if(et.isLive)
     {
      if (et.ss.size()<3)
      {
       //沒有子彈了
       //添加
       Shot s=null;
       switch(et.direct)
       {
       case 0:
        s=new Shot(et.x+9,et.y-1,0);
        et.ss.add(s);
        break;
       case 1:
        s=new Shot(et.x+30,et.y+10,1);
        et.ss.add(s);
        break;
       case 2:
        s=new Shot(et.x+9,et.y+30,2);
        et.ss.add(s);
        break;
       case 3:
        s=new Shot(et.x-1,et.y+9,3);    
        et.ss.add(s);
        break;            
       }
       
       //啟動子彈線程
       Thread t=new Thread(s);
       t.start();      
      }  
     }
    }   
   } 
  }
  //定義三張圖片,三張圖片切換組成一顆炸彈
  Image image1=null;
  Image image2=null;
  Image image3=null;
  int flagOfContinue;
  //構造函數
  public MyPanel(int flag)
  {  
   
   this.flagOfContinue=flag;
   //恢復記錄
   Recorder.getRecording();
   
   
   if(this.flagOfContinue==0)
   {
    //如果不是繼續上次就直接建一個
    hero=new Hero(100,100);
    //初始化敵人的坦克
    for(int i=0;i<enSize;i++)
    {
     //創建敵人的坦克對象   
     EnemyTank et=new EnemyTank((i+1)*60,0);
     et.setColor(0);
     et.setDirect(2);
     //將MyPanel的敵人坦克向量交給該敵人坦克
     et.setEts(ets);
     
     
     //啟動敵人的坦克
     
     Thread t=new Thread(et);
     t.start();
     //給敵人坦克添加一顆子彈
     Shot s=new Shot(et.x+10,et.y+30,2);
     et.ss.add(s);
     Thread t2=new Thread(s);
     t2.start();
     //加入
     
     ets.add(et);   
    }
   }
   else if(this.flagOfContinue==1)
   {
    //如果是繼續上次的就讀取坐標
    Vector<Node> nodes1=new Vector<Node>();
    nodes1=Recorder.getNodes();
  
     //初始化敵人的坦克
     for(int i=0;i<nodes1.size();i++)
     {
      if(nodes1.get(i).type==0)
      { 
       //創建敵人的坦克對象   
       EnemyTank et=new EnemyTank(nodes1.get(i).x,nodes1.get(i).y);
       et.setColor(0);
       et.setDirect(nodes1.get(i).direct);
       //將MyPanel的敵人坦克向量交給該敵人坦克
       et.setEts(ets);
       
       
       //啟動敵人的坦克
       
       Thread t=new Thread(et);
       t.start();
       //給敵人坦克添加一顆子彈
       Shot s=new Shot(et.x+10,et.y+30,2);
       et.ss.add(s);
       Thread t2=new Thread(s);
       t2.start();
       //加入
       
       ets.add(et);   
      }
      else if(nodes1.get(i).type==1)
      {
       //如果保存有我上次的坦克的信息,就按照信息保存
       hero=new Hero(nodes1.get(i).x,nodes1.get(i).y);
       hero.setDirect(nodes1.get(i).direct);
      }
     }
     
   }
  
 //  image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));//文件應該放在src文件夾裡面
 //  image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg"));
 //  image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg"));
   //關於圖像我們使用好一點的方法,引入java.io.File;和java.io.IOException;
   try
   {
    image1=ImageIO.read(new File("33.jpg"));//此時文件應該放在工程的根目錄裡面
    image2=ImageIO.read(new File("22.jpg"));
    image3=ImageIO.read(new File("11.jpg"));
   }
   catch (IOException e)
   {
    e.printStackTrace();
   }
   
  }
  //畫出提示信息
  public void showInfo(Graphics g)
  {
    //畫出提示信息的坦克 ,該坦克不參加戰斗
    this.drawTank(80,330,g,0,0);  
    g.setColor(Color.black);  
    g.drawString(Recorder.getEnNum()+"",110,350);
   
    this.drawTank(150,330,g,0,1);
    g.setColor(Color.black);  
    g.drawString(Recorder.getMyLife()+"",180,350);
    //畫出玩家的總成績
   
    g.setColor(Color.black);
 try{
    Font f=new Font("宋體",Font.BOLD,20);
    g.setFont(f);
 }catch(Exception e){    e.printStackTrace();}
    g.drawString("您的總成績:",420,40);
   
    this.drawTank(420, 60, g, 0, 0);
   
    g.setColor(Color.BLACK);
    g.drawString(Recorder.getAllEnemy()+"",460,80);
   
  }
  
  //鍵按下處理a表示左,s表示向下,w表示向上,d表示向右
  public void keyPressed(KeyEvent e)
  {
   if(hero.isLive)
   {
    if(e.getKeyCode()==KeyEvent.VK_UP&&hero.getY()>0)
    {
     // 設置我的坦克的方向
     this.hero.setDirect(0); 
     this.hero.moveUp();
    }
   
    else if (e.getKeyCode()==KeyEvent.VK_DOWN&&hero.getY()<270)
    {
     this.hero.setDirect(2);   
     this.hero.moveDown();   
    }
   
    else if (e.getKeyCode()==KeyEvent.VK_RIGHT&&hero.getX()<370)
    {
     this.hero.setDirect(1);   
     this.hero.moveRight();
     
    }  
    else if (e.getKeyCode()==KeyEvent.VK_LEFT&&hero.getX()>0)
    {
     this.hero.setDirect(3);   
     this.hero.moveLeft();   
    }
    
    if (e.getKeyCode()==KeyEvent.VK_SPACE)
    {   
     this.hero.shotEnemy();   
    }  
   
    //必須重新繪制Panel
    this.repaint(); 
   }
  }
  public void keyReleased(KeyEvent e)
  {
   
  }
  public void keyTyped(KeyEvent e)
  {
   
  }
   
 }
 
 
 //----------------------------------------------------
 
 class Node
 {
  int x;
  int y;
  int direct;
  int type;
  public Node(int x,int y,int direct,int type)
  {
   this.x=x;
   this.y=y;
   this.direct=direct; 
   this.type=type;
  } 
  
 }
 
 
 
 //記錄類
 class Recorder
 {
  public static int getEnNum() {
   return enNum;
  }
  public static void setEnNum(int enNum) {
   Recorder.enNum = enNum;
  }
  public static int getMyLife() {
   return myLife;
  }
  public static void setMyLife(int myLife) {
   Recorder.myLife = myLife;
  }
  //記錄每關多少敵人
  private static int enNum=MyPanel.getEnSize();
  //設置我有多少可以用的人
  public static int myLife=3;
  //記錄總共消滅了多少敵人
  private static  int  allEnNum=0;
  //從文件中恢復記錄點
  static Vector<Node> nodes=new Vector<Node>();
  private static FileWriter fw=null;
  private static BufferedWriter bw=null;
  private static FileReader fr=null;
  private static BufferedReader br=null;
  
  public static Vector<Node> getNodes()
  {
   try {
    fr=new FileReader("d:\\myRecording.txt");  
    br=new BufferedReader(fr);
    String n="";
   
    n=br.readLine();//讀第一行
    allEnNum=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]),Integer.parseInt(xyz[3]));
     nodes.add(node);
    } 
   }
   
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {   
    try {
     br.close();
     fr.close();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
   return nodes;
  }
  public static void keepRecAndEnemyTank(Vector<EnemyTank> ets)
  {
   try
   {
    //創建
    fw=new FileWriter("d:\\myRecording.txt");
    bw=new BufferedWriter(fw);
    
    bw.write(allEnNum+"\r\n");
    
    //保存當前還活著的敵人坐標和方向
    for(int i=0;i<ets.size();i++)
    {
     //取出第一個坦克
     EnemyTank et=ets.get(i);
     if(et.isLive)
     {
      //活著的保存
      String record=et.x+" "+et.y+" "+et.direct+" "+0;    
      //寫入
      bw.write(record+"\r\n");    
     }   
    }
    
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {
    //關閉流
    try {
     //誰先開誰後關
     bw.close();
     fw.close();
    } catch (Exception e2) {
    }   
   }
   
  }
  
  public static void keepRecAndMyTank(Hero hero)
  {
   try
   {
    //創建
    fw=new FileWriter("d:\\myRecording.txt",true);//追加
    bw=new BufferedWriter(fw);
       
    //保存當前我的坐標和方向
    String record=hero.x+" "+hero.y+" "+hero.direct+" "+1;    
    //寫入
    bw.write(record+"\r\n");    
   
   }
    
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {
     //關閉流
    try
    {
     //誰先開誰後關
     bw.close();
     fw.close();
    }
    catch (Exception e2)
    {
     e2.printStackTrace();
    }   
   }
   
  }
   
  //從文件中讀取記錄
  public static void getRecording()
  {
   try {
    fr=new FileReader("d:\\myRecording.txt");  
    br=new BufferedReader(fr);
    String n=br.readLine();
    allEnNum=Integer.parseInt(n);
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {   
    try {
     br.close();
     fr.close();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
   
  }
  //把玩家擊毀敵人的坦克數量保存到文件中
  public static void keepRecording()
  {
   try
   {
    //創建
    fw=new FileWriter("d:\\myRecording.txt");
    bw=new BufferedWriter(fw);
    
    bw.write(allEnNum+"\r\n");
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {
    //關閉流
    try {
     //誰先開誰後關
     bw.close();
     fw.close();
    } catch (Exception e2) {
    }   
   }  
  }
  
  public static int getAllEnemy() {
   return allEnNum;
  }
  public static void reduceEnNum()
  {
   enNum--;  
  }
  
  //消滅敵人
  public static void addEnNumRec()
  {
   allEnNum++;
  }
  
 }
 
 
 class Bomb
 {
  //定義炸彈的坐標
  int x,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;}
   
  }
 }
 
 
 class Tank
 {
  
  //設置坦克的速度
  int speed=3;
  public int getSpeed()
  {
   return speed;
  }
  public void setSpeed(int speed)
  {
   this.speed = speed;
  }
  //表示坦克的橫坐標
  int x=0;
  //坦克的縱坐標
  int y=0;
  int direct=0;
  int color;
  boolean isLive=true;
  
  //坦克方向,0表示上,1表示右,2表示下,3表示左
  public int getColor() {
   return color;
  }
  public void setColor(int color) {
   this.color = color;
  }
  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 EnemyTank extends Tank implements Runnable
 {
  //定義一個向量,可以訪問到MyPanel上所有敵人的坦克
  Vector<EnemyTank> ets=new Vector<EnemyTank>();
  
  //定義一個向量,可以存放敵人的子彈
  
  Vector<Shot> ss=new Vector<Shot>();
  //敵人添加子彈應該在剛剛創建坦克和坦克子彈死亡之後
  public EnemyTank(int x,int y)
  {
   super(x,y);  
  }
  
  //得到MyPanel的敵人坦克向量
  public void setEts(Vector<EnemyTank> vv)
  {
   this.ets=vv;
   
  }
  
  
  //判斷是否碰到了別人的坦克
  public boolean isTouchOtherEnemy()
  {
   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<=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+30)
       {
        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;
       }
      }
     }
  
    }
    
    
   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<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30)
       {
        return true;
       }
       
      }
     
      if(et.direct==1||et.direct==3)
      {
       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; 
       }
       if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+30)
       {
        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>=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+20>=et.y&&this.y+20<=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;
       }
      }
     }
  
    }
   }
   
   return b;
  }
  
  public void run() {
   while(true)
   {  
    switch(this.direct)
    {
    case 0:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(y>=speed && !this.isTouchOtherEnemy())
      {
       y-=speed;
      }
     }
     break;
    case 1:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(x<=(400-(speed+30))&& !this.isTouchOtherEnemy())
      {
       x+=speed;
      }
     }
     break;
    case 2:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(y<=(300-(speed+30))&& !this.isTouchOtherEnemy())
      {
       y+=speed;
      }
     }
     break;
    case 3:
     for(int i=0;i<(int)(100*Math.random());i++)
     {
      try
      {
       Thread.sleep(50);  
      }
      catch (Exception e)
      {
       e.printStackTrace();
      }
      if(x>=speed && !this.isTouchOtherEnemy())
      {
       x-=speed;
      }
     
     }
     break;
     
    }
    
    //讓坦克隨機產生一個新的方向
    this.direct=(int)(Math.random()*4);
    
    //判斷敵人坦克是否死亡
    if(this.isLive==false)
    {
     //讓坦克死亡後,退出線程
     break;
    }
    
   }
   
  }
 }
 
 
 //我的坦克
 class Hero extends Tank
 {
  //子彈
  //Shot s=null;
  Vector<Shot>  ss=new Vector<Shot>();
  Shot s=null;
  
  public Hero(int x, int y)
  {
   super(x,y);
  }
  //坦克向上移動
  
  //坦克的開火的能力和動作
  public void shotEnemy()
  {
   switch(this.direct)
   {
    case 0:
     s=new Shot(x+9,y-1,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+9,y+30,2);
     ss.add(s);
     break;
    case 3:
     s=new Shot(x-1,y+9,3);     ss.add(s);
     ss.add(s);
     break;
   }
  
   Thread t=new Thread(s);
   t.start();
   
  }
  
  
  public void moveUp()
  {
   this.y-=speed;  
  }
  public void moveRight()
  {
   this.x+=speed;  
  }
  
  public void moveDown()
  {
   this.y+=speed;  
  } 
  public void moveLeft()
  {
   this.x-=speed;  
  } 
 }
  
 class Shot implements Runnable
 {
  int x;
  int y;
  int direct;
  int speed=2;
  //是否活著
  
  boolean isLive=true;
  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>400||y<0||y>300)
    {
     this.isLive=false;
     break;
     
    }
    
   }
   
  }
 }

 

注:如果大家很多java基礎內容不是很清楚,可以觀看韓順平的java學習視頻,跟著教程做程序,效果很明顯!(●ˇ∀ˇ●)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved