Java實戰--飛機大戰

根據引導自己動手試試看

源碼具體詳情請點擊  https://download.csdn.net/download/qq_40803710/11011232  進行下載。

1.第一個任務:做6個子類

       Sky: y1;step   step();

       Hero: life;doubleFire   move(int x,int y){}

       Airplane: step      step();

       BigAirplane: step   step();

       Bee: xstep; ystep;   awardType//0表示帶命;1表示帶分    step();

       Bullet: step        step();

2.第二個任務:使用構造方法,初始化數據

       1)Sky:無參構造

              public Sky() {

              super(400,700,0,0);       

              y1=-700;

              step = 1;

       }

       2) Hero:無參構造

              public Hero() {

              super(97,124,400/2-97/2,400);

              life = 3;

              doubleFire = 0;//0表示單倍火力    >0表示雙倍火力

       }

       3)敵人對象(Airplane,BigAirplane,Bee)無參構造

              public Airplane() {

              super(49,36);

              step = 2;

       }

       public BigAirplane() {

              super(69,99);

              step = 2;

       }

       public Bee() {

              super(60,50);

              xstep = 1;

              ystep = 2;

              awardType = new Random().nextInt(2);  //0:火力值    1:命

       }

       4)Bullet

              public Bullet(int x,int y) {

              super(8,14,x,y);

              step = 3;

              state = LIFE;

       }

 

3. 第三個任務:定義FlyingObject(實現代碼重用)

1)定義FlyingObject,定義通用的變量和方法

2)設計兩個構造方法:

     對Airplane,Bee ,BigAirplane對象的初始化方法

     //給敵人對象初始化Airplane,BigAirplane,Bee

     public FlyingObject(int width,int height){

           this.width = width;

           this.height = height;

           x = new Random().nextInt(400-this.width);

          y = -height;

     },在子類中調用

     對Hero,Sky,Bullet對象的初始化方法

    //給Sky,Hero,Bullet三個類實例化的方法

    public FlyingObject(int width,int height,int x,int y){

           this.width = width;

           this.height = height;

           this.x = x;

           this.y = y;

    },在子類中調用

    3)調整成員變量的修飾符

    父類中可以被訪問的成員訪問修飾符:protected

    子類中的成員不被外界訪問修飾符:private

4.第四個任務:畫頁面

1)定義World類,繼承JPanel

2)定義窗口,顯示窗口

import javax.swing.JPanel;

import java.awt.Graphics;

import javax.swing.JFrame;

 

public class world extends JPanel{

    Sky sky = new Sky();

    public static void main(String args[]) {

           JFrame frame = new JFrame();

           world world = new world();

           frame.add(world);

          

           frame.setTitle("飛機大戰");  //設置窗口標題

           frame.setSize(400,700);   //設置窗口大小

           frame.setLocationRelativeTo(null);  //設置窗口居中顯示

           frame.setVisible(true);   //設置窗口可視化

    }

    //實現畫的功能

    public void paint(Graphics g) {

           sky.paintObject(g);

    }

}

3)把圖片拷貝到工程包下

4)加載圖片

4.1)天空

//存放圖片對象

    private static BufferedImage image;

    static{

           try {

                  //使用ImageIO讀取圖片

                  image = ImageIO.read(Sky.class.getResource("background.png"));

           } catch (IOException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

           }

    }

    4.2)小敵機

    //加載圖片到數組中

    private static BufferedImage[] images = new BufferedImage[5];

    static{

           for(int i = 0;i<images.length;i++){

                  try {

                         images[i]=ImageIO.read(Airplane.class.getResource("airplane"+i+".png"));

                  } catch (IOException e) {

                         // TODO Auto-generated catch block

                         e.printStackTrace();

                  }

           }

    }

    4.3)大敵機

    //加載圖片到數組中

    private static BufferedImage[] images = new BufferedImage[5];

    static{

           for(int i = 0;i<images.length;i++){

                  try {

                         images[i]=ImageIO.read(Airplane.class.getResource("bigplane"+i+".png"));

                  } catch (IOException e) {

                         // TODO Auto-generated catch block

                         e.printStackTrace();

                  }

           }

    }

5)獲取圖片

//類中有一個抽象方法時類不能定義爲對象 要想讓當前類創建對象

//要將父類抽象且方法抽象(父類中聲明)纔可以實現

public abstract BufferedImage getImage();

//子類中具體實現

5.1)天空@Override

    public BufferedImage getImage() {

           return image;

    }

       (1)小敵機

/*

        * 1、如果當前狀態爲活着,加載數組的第一張圖片

        * 2、如果當前狀態爲死亡,加載數組中剩餘的四張圖片,把state=REMOVE

        */

       int deadIndex = 1;

       @Override

       public BufferedImage getImage() {

              if(this.isLife()) {

                     return images[0];

              }else if(this.isDead()) {

                     //解決怎樣加載剩餘四張圖片  可以多次調用返回

                     BufferedImage image = images[deadIndex++];

                     if(deadIndex==images.length) {

                            state = REMOVE;

                     }

                     return image;

              }

              return null;

       }

(2)大敵機

/*

        * 1、如果當前狀態爲活着,加載數組的第一張圖片

        * 2、如果當前狀態爲死亡,加載數組中剩餘的四張圖片,把state=REMOVE

        */

       int deadIndex = 1;

       @Override

       public BufferedImage getImage() {

              if(this.isLife()) {

                     return images[0];

              }else if(this.isDead()) {

                     BufferedImage image = images[deadIndex++];

                     if(deadIndex==images.length) {

                            state = REMOVE;

                     }

                     return image;

              }

              return null;

       }

(3)蜜蜂

/*

        * 1、如果當前狀態爲活着,加載數組的第一張圖片

        * 2、如果當前狀態爲死亡,加載數組中剩餘的四張圖片,把state=REMOVE

        */

       int deadIndex = 1;

       @Override

       public BufferedImage getImage() {

              if(this.isLife()) {

                     return images[0];

              }else if(this.isDead()) {

                     //解決怎樣加載剩餘四張圖片  可以多次調用返回

                     BufferedImage image = images[deadIndex++];

                     if(deadIndex==images.length) {

                            state = REMOVE;

                     }

                     return image;

              }

              return null;

       }

(4)子彈

public Bullet[] getBullet() {

              if(doubleFire == 0) {

                     Bullet[] b = new Bullet[1];

                     int b_x = this.x + this.width/2;

                     int b_y = this.y - 20;

                     Bullet b1 = new Bullet(b_x,b_y);

                     b[0] = b1;

                     return b;

              }else {

                     Bullet[] b = new Bullet[2];    

                     int b_x = this.x + this.width/4;

                     int b_y = this.y - 20;

                     Bullet b1 = new Bullet(b_x,b_y);

                     b[0] = b1;

                    

                     int b_x2 = this.x + this.width/4*3;

                     Bullet b2 = new Bullet(b_x2,b_y);

                     b[0] = b1;

                     b[1] = b2;

                     return b;

              }

       }

 

/*

        * 1、如果當前狀態爲活着,加載數組的第一張圖片

        * 2、如果當前狀態爲死亡,把state=REMOVE

        */

       @Override

       public BufferedImage getImage() {

              if(this.isLife()) {

                     return image;

              }else if(this.isDead()) {

                            state = REMOVE;

                     }

              return null;

       }

6)畫圖片

public void paintObject(Graphics g) {

       g.drawImage(getImage(), x, y, null);

g.drawImage(getImage(), x, y, null);

}

在World類中畫圖片

    定義方法objectAction

    FlyingObject object [] = {};

    //敵人入場

    public void objectAction(){

           //小敵機的初始化

           object = new FlyingObject[6];

           object[0] = new Airplane();

           object[1] = new Airplane();

           object[2] = new Airplane();

           object[3] = new BigAirplane();

           object[4] = new BigAirplane();

           object[5] = new BigAirplane();

    }

    //實現畫的功能

    public void paint(Graphics g){

           sky.paintObject(g);

           //畫小敵機

           for(int i = 0;i<object.length;i++){

                  object[i].paintObject(g);

           }

    }

5.第五個任務:讓畫面動起來

(1)動起來

//天空向下移動

public void step() {

    y += step;

    y1 += step;

    if(y >= 700) {

           y = -700;

    }

    if(y1 >= 700) {

           y1 = -700;

    }

}

//敵人對象動起來

public void step() {

    y += step;

}

//小蜜蜂的step方法

public void step() {

           x += xstep;

           y += ystep;

           if(x>=400-this.width) {

                  xstep *= -1;

           }

    }

//子彈動起來

public void step() {

           y -= step;

}

(2)在world中定義方法

       //讓飛行物動起來

       public void stepAction() {

       //天空

       sky.step();

       //讓敵人(小敵機、大敵機、蜜蜂)動起來

       for(int i = 0;i<object.length;i++) {

              object[i].step();

       }

       //讓子彈動起來

       for(int i = 0;i<bullets.length;i++) {

              bullets[i].step();

       }

}

在run方法中調用

public void action() {

       //使用定時器

       Timer timer = new Timer();

       timer.schedule(new TimerTask() {

              public void run() {

                     objectAction();  //生成敵人對象

                     stepAction();    //讓畫面動起來

                     bulletAction();

                     //run()功能:調用paint()方法

                     repaint();

              }

       }, 10, 10);  //delay延遲  period

}

(3)隨機產生敵人對象

3.1)//隨機產生一個敵人對象

       public FlyingObject nextOne() {

              //20以內隨機數  分成三個範圍  定義其類型

              int Random = new Random().nextInt(20);

              if(Random<4) {

                     return new Bee();

              }else if(Random>=4 && Random<12) {

                     return new BigAirplane();

              }else {

                     return new Airplane();

              }

       }

       //控制生成敵人數量

       int flyIndex = 0;

       //敵人入場

       public void objectAction() {

              flyIndex++;

              if(flyIndex % 40 == 0) {

                     //敵人的初始化

                     FlyingObject obj = nextOne();

                     object = Arrays.copyOf(object, object.length+1);

                     object[object.length-1] = obj;

              }

       }

      

       //控制生成子彈數量

       int bulletIndex = 0;

       public void bulletAction() {

              bulletIndex++;

              if(bulletIndex % 40 == 0) {

                     //子彈的初始化

                     Bullet b1[] = hero.getBullet();

                     //數組擴容:原來數組回收,新建數組拷貝擴容,第二參數爲數組總大小

                     //Arrays.copyOf(original, newLength)

                     bullets = Arrays.copyOf(bullets, bullets.length + b1.length);

                     //對原數組數據拷貝第一個:從哪裏開始拷;第四個:從哪裏開始拷貝;第五個:拷貝多少個

                     System.arraycopy(b1, 0, bullets, bullets.length - b1.length, b1.length);

              }

             

       }

       3.2)把隨機對象放到數組中

       int index = 0;

       //敵人入場

       public void objectAction(){

              index++;

              if(index%40==0){

                     //小敵機的初始化

                     FlyingObject ob = nextOne();

                     object = Arrays.copyOf(object,object.length+1);

                     object[object.length-1]=ob;

              }

       }

 

       4)子彈的產生

       4.1)在Hero類中定義方法

       public Bullet[] getBullet(){

              if(doubleFire==0){

                     Bullet[] b = new Bullet[1];

                     int b_x = this.x + this.width/2;

                     int b_y = this.y - 20;

                     Bullet bl = new Bullet(b_x,b_y);

                     b[0] = bl;

                     return b;

              }else{

                     Bullet[] b = new Bullet[2];

                     int b_x = this.x + this.width/4;

                     int b_y = this.y - 20;

                     Bullet b1 = new Bullet(b_x,b_y);

                     int b_x2 = this.x + this.width/4*3;

                     Bullet b2 = new Bullet(b_x2,b_y);

                     b[0] = b1;

                     b[1] = b2;

                     return b;

              }

       }

 

       4.2)把子彈對象放到數組中

       int bulletIndex=0;

       //子彈入場

       public void bulletAction(){

              bulletIndex++;

              if(bulletIndex%30==0){

              Bullet bl[] = hero.getBullet();

      

              //數組擴容

              bullets = Arrays.copyOf(bullets, bullets.length+bl.length);

              //數組拷貝

              System.arraycopy(bl, 0, bullets, bullets.length-bl.length, bl.length);

             

              }

       }

             

       5)英雄機隨鼠標移動(Hero類中)

       5.1)//x,y表示鼠標的座標   (Hero類中)

       public void move(int x,int y){

              this.x = x - this.width/2;

              this.y = y - this.height/2;

       }

       5.2)添加事件監視器   (World類中)

       //定義鼠標的移動事件處理方法(內部類:(匿名類))

              MouseAdapter l = new MouseAdapter(){

                     public void mouseMoved(MouseEvent e){

                            //獲取鼠標點的座標

                            int x = e.getX();

                            int y = e.getY();

                            hero.move(x, y);

                     }

              };

              //給Jpanel添加事件監視器的對象

              this.addMouseMotionListener(l);

6.第六個任務:刪除越界的對象

  1. 在父類定義越界的方法,分別在子類中實現方法

public abstract boolean outOfBounds();

  1. 分別實現方法(敵人對象y>700,子彈y<0,天空和英雄機永不越界)
  1. 敵人

public boolean outOfBounds() {

   return this.y>700;

}

  1. 子彈

public boolean outOfBounds() {

   return this.y<0;

}

  1. 天空和英雄機

public boolean outOfBounds() {

   return false;

}

  1. 在world類中定義方法,回收越界對象,在action方法中調用

//回收越界的對象:(敵人,子彈)

  public void outOfBoundsAction() {

         //裝活着的敵人的對象的數組

         FlyingObject[] fo = new FlyingObject[object.length];

         //活着的敵人對象數目

         int lifeIndex = 0;

         //遍歷數組

         for(int i = 0;i<object.length;i++) {

                //從數組中獲取敵人的對象

                FlyingObject f = object[i];

                //找出沒有越界的敵人

                if(!f.outOfBounds()&&!f.isRemove()) {

                       fo[lifeIndex] = f;

                       lifeIndex++;

                }

         }

         //數組的拷貝

         object = Arrays.copyOf(fo, lifeIndex);

        

         //子彈的越界對象的刪除

         //定義數組,裝沒有越界的子彈

         Bullet[] bo = new Bullet[bullets.length];

         //活着的子彈對象數目

         int bulletsIndex = 0;

         //遍歷數組

         for(int i = 0;i<bullets.length;i++) {

                //從數組中獲取子彈的對象

                Bullet b = bullets[i];

                //找出沒有越界的子彈

                if(!b.outOfBounds()&&!b.isRemove()) {

                       bo[bulletsIndex] = b;

                       bulletsIndex++;

                }

         }

         //數組的拷貝

         bullets = Arrays.copyOf(bo, bulletsIndex);

  }

7.第七個任務:定義敵人和子彈(英雄機)發生碰撞的方法

  1. 定義方法,對敵人和子彈(英雄機)是否碰撞,other表示子彈(英雄機) this表示敵人對象

              public boolean hit(FlyingObject other) {

/*  x軸的範圍:this.x-other.width(左x)    this.x+this.width(右x)

y軸的範圍:this.y+this.height(上y)    this.y-other.height(下y)

  如果子彈的x,y座標在以上範圍內,說明撞上了,返回true,否則返回false        */

int x1 = this.x-other.width;

         int x2 = this.x + this.width;

         int y1 = this.y - other.height;

         int y2 = this.y + this.height;

         int x = other.x;

         int y = other.y;

 

         return x>=x1 && x<=x2 && y>=y1 && y<=y2;

  }

(2)定義接口,定義得分的方法

public interface Enemy { 

  public int getScore();

}

需要大敵機和小敵機實現接口,重寫方法

public int getScore() {

  return 1;

}

(3)定義接口,定義福利

public interface Award {//接口中都是公有靜態常量,不用寫屬性,只需類型名字

  int DOUBLEFIRE = 0;//帶火力值

  int LIFE = 1;//帶名

  int getType();

}

需要小蜜蜂實現接口

public int getType() {

  return awardType;

}

(4)定義功能方法

//讓敵人去死的方法(在FlyingObject類中實現)

public void goDead() {

  state = DEAD;

  }

//加命(在Hero類中實現)

  public void addLife(){

         life++;

  }

  //獲取命(在Hero類中實現)

  public int getLife(){

         return life;

  }

  //增加火力值(在Hero類中實現)

  public void addDoubleFire(){

         doubleFire+=40;

  }

8.第八個任務:當子彈和敵人碰撞之後的得分和福利的設置,並在頁面畫分和命

//子彈和敵人發生碰撞

int score = 0;

public void bulletHitAction(){

       //遍歷子彈集合,

       for(int i = 0;i<bullets.length;i++){

              //拿到一個子彈對象

              Bullet b = bullets[i];

              for(int j = 0;j<object.length;j++){//遍歷敵人集合

                     FlyingObject f = object[j];//獲取一個敵人對象

                            if(b.isLife()&&f.isLife()&&f.hit(b)){//子彈對象和所有的敵人碰撞的匹配

                            f.goDead();//敵人去死

                            b.goDead();//子彈去死

                            if(f instanceof Enemy){//如果是(大敵機或者是小敵機)

                                   score += ((Enemy) f).getScore();//得分

                            }

                            if(f instanceof Award){//如果是小蜜蜂

                                   switch(((Award) f).getType()){

                                   case  Award.DOUBLEFIRE://帶火力值得小蜜蜂

                                          hero.addDoubleFire();//火力值增加

                                   case Award.LIFE://帶命的小蜜蜂

                                          hero.addLife();//命增加

                                   }

                            }

                     }

              }

       }

       }

  g.drawString("Scoure:"+score, 10, 40);

  g.drawString("Life:"+hero.getLife(), 10, 60);

 

9.第九個任務:英雄機和敵人發生碰撞:如果碰到的是大(小)敵機,命-1;

                 如果碰到的是小蜜蜂:火力清0

(1)在Hero類中定義方法:subLife();    clearFire();

//減命

       public void subLife(){

              life--;

       }

       //清空火力值

       public void clearFire(){

              doubleFire = 0;

       }

(2)heroHitAction();

//英雄機和敵人碰撞

       public void heroHitAction() {

              for(int i = 0;i<object.length;i++) //遍歷敵人集合

              {

                     FlyingObject f = object[i]; //獲取一個敵人對象

                     if(f.isLife()&&f.hit(hero)) {

                            f.goDead(); //敵人去死

                            if(f instanceof Enemy) {

                                   hero.subLife();

                            }

                            if(f instanceof Award) {

                                   hero.clearFire();

                            }

                     }

              }

       }

10.第10個任務:畫窗口的狀態

  1. 在World類中定義4個常量,表示窗口的狀態:開始,運行,暫停,結束

public static final int START = 0;

public static final int RUNNING = 1;

public static final int PAUSE = 2;

public static final int GAMEOVER = 3;

     private int state = START;

  1. 設計程序結束的方法,checkGameOverAction();

  public void checkGameOverAction() {

         if(hero.getLife()==0&&hero.isRemove()) {

                state = GAMEOVER;

         }

         if(hero.getLife()==0)

         {

                hero.goDead();

         }

         }

  1. 在World類中定義3個靜態變量,加載圖片(啓動,暫停,結束)

//存放圖片對象

  private static BufferedImage startImage;

  private static BufferedImage pauseImage;

  private static BufferedImage gameOverImage;

  static {

         try {

                //以讀取流的方式加載圖片

                startImage = ImageIO.read(Sky.class.getResource("start.png"));

                pauseImage = ImageIO.read(Sky.class.getResource("pause.png"));

                gameOverImage = ImageIO.read(Sky.class.getResource("gameover.png"));

         }

         catch(IOException e) {

                e.printStackTrace();

         }

  }

  1. 在World類中的paint()方法中根據不同的狀態畫不同的的圖片

switch(state) {

         case START:

                g.drawImage(startImage, 0, 0, null);

                break;

         case PAUSE:

                g.drawImage(pauseImage, 0, 0, null);

                break;

         case GAMEOVER:

                g.drawImage(gameOverImage, 0, 0, null);

                break;

         }

  1. 在不同狀態下,顯示不同的運行情況

MouseAdapter l = new MouseAdapter() {

                public void mouseMoved(MouseEvent e) {

                       if(state == RUNNING) {

                              int x = e.getX();

                              int y = e.getY();

                              hero.move(x, y);

                       }

                }

                public void mouseEntered(MouseEvent e) {

                       if(state == PAUSE) {

                              state = RUNNING;

                       }

                }

                public void mouseExited(MouseEvent e) {

                       if(state == RUNNING) {

                              state = PAUSE;

                       }

                }

                public void mouseClicked(MouseEvent e) {

                       if(state == START) {

                              state = RUNNING;

                       }

                       if(state == GAMEOVER) {

                              //初始化操作

                              object = new FlyingObject[0];

                              bullets = new Bullet[0];

                              score = 0;

                              hero = new Hero();

                              state = START;

                       }

                }

         };

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章