java實現飛機大戰遊戲

java實現飛機大戰

用Java寫個飛機大戰遊戲練習一下,實現可播放遊戲背景音樂和遊戲的基本功能

設計

1、準備好相應的圖片和背景音樂(.wav文件);
2、直接看源碼;
3、還有部分功能未實現。

源碼

package forGame

加載遊戲圖片類

package forGame;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

//遊戲圖片包裝
public class ImageUtil {

  //圖片大小
  public static int WIDTH_BACK;
  public static int HEIGHT_BACK;
  public static int WIDTH_PLANE;
  public static int HEIGHT_PLANE;

  //圖片
  public static BufferedImage START;
  public static ImageIcon BUTTON;
  public static BufferedImage PLANE_1;
  public static BufferedImage PLANE_2;
  public static BufferedImage Bullet_1;
  public static BufferedImage Bullet_2;
  public static BufferedImage XIAO_PLANE;
  public static BufferedImage BOMB_PLANE1;
  public static BufferedImage BOMB_PLANE2;

  static {
    try {
      START = ImageIO.read(new File("src\\image\\背景2.png"));
      BUTTON = new ImageIcon("src\\image\\開始.png");
      PLANE_1 = ImageIO.read(new File("src\\image\\飛機1.png"));
      PLANE_2 = ImageIO.read(new File("src\\image\\飛機2.png"));
      Bullet_1 = ImageIO.read(new File("src\\image\\導彈1.png"));
      Bullet_2 = ImageIO.read(new File("src\\image\\導彈2.png"));
      XIAO_PLANE = ImageIO.read(new File("src\\image\\小飛機.png"));
      BOMB_PLANE1 = ImageIO.read(new File("src\\image\\飛機爆炸1.png"));
      BOMB_PLANE2 = ImageIO.read(new File("src\\image\\飛機爆炸2.png"));
    } catch (IOException e) {
      e.printStackTrace();
    }
    WIDTH_BACK = START.getWidth();
    HEIGHT_BACK = START.getHeight();
    WIDTH_PLANE = PLANE_1.getWidth();
    HEIGHT_PLANE = PLANE_1.getHeight();
  }
}

播放遊戲背景音樂類

package forGame;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.io.File;

//播放背景音樂(.wav文件)
public class PlayMusic {
  private Clip clip;
  //需要傳入要播放的文件位置的字符串
  public void start(File file)
  {
    try
    {
      //創建相當於音樂播放器的對象
      clip = AudioSystem.getClip();
      //轉成可播放的文件
      AudioInputStream audioInput = AudioSystem.getAudioInputStream(file);
      //播放器打開這個文件
      clip.open(audioInput);
      //clip.start();//隻播放一次
      //循環播放
      clip.loop(Clip.LOOP_CONTINUOUSLY);
    } catch(Exception ex){
      ex.printStackTrace();
    }
    //死循環不讓主程序結束(swing可不用)
    /*
      while(true){
      }
    */
  }

  //關閉音樂播放
  public void exit(){
    clip.close();//停止音樂播放,下次播放重新開始
  }

  //停止音樂播放
  public void stop(){
    clip.stop();//停止音樂播放,下次播放繼續播放
  }
}

package planeGame

接口

package planeGame;

import java.awt.*;

//繪制接口
public interface DrawMe {
  void drawMe(Graphics g);
}
package planeGame;

//分數接口
public interface Grade {
  int getGrade();
}

窗口父類

package planeGame;

import forGame.ImageUtil;
import forGame.PlayMusic;

import javax.swing.*;
import java.io.File;

//窗口父類
public class MyJFrameFather extends JFrame{
  protected int y1 = 0;
  protected int y2 = -830;
  protected PlayMusic playMusic = new PlayMusic();
  public MyJFrameFather(String name){
    super(name);
    setSize(ImageUtil.WIDTH_BACK, ImageUtil.HEIGHT_BACK);
    setLocationRelativeTo(null);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    playMusic.start(new File("src\\music\\bgm.wav"));
  }
}

開始界面

package planeGame;

import forGame.ImageUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

//遊戲開始界面
public class StartJFrame extends MyJFrameFather{
  public StartJFrame(){
    super("開始界面");
    ImageIcon imageIcon = ImageUtil.BUTTON;
    JButton jButton = new JButton(imageIcon);
    //設置按鈕沒有邊框
    jButton.setBorder(null);
    jButton.setBounds(200,350,imageIcon.getIconWidth(),imageIcon.getIconHeight());
    jButton.setBackground(Color.lightGray);
    setLayout(null);
    add(jButton);
    setVisible(true);
    jButton.addActionListener(actionListener);
  }

  @Override
  public void paint(Graphics g) {
    g.drawImage(ImageUtil.START,0,0 ,null );
  }

  private ActionListener actionListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
      playMusic.exit();
      new GameJFrame();
      dispose();
    }
  };
}

飛機父類(抽象類)

package planeGame;

import java.awt.*;

//飛機父類
public abstract class Plane implements DrawMe{
  //飛機坐標
  protected Point p = new Point();
  //飛機是否活著
  protected boolean isLive = true;
  //飛機移動速度
  protected int speed;
  public Plane(int x,int y){
    p.x = x;
    p.y = y;
  }
  //修改飛機坐標以重復使用
  public abstract void setP(int x);
  //畫自己
  public abstract void drawMe(Graphics g);
  //移動
  public abstract void move();
  //獲取飛機坐標
  protected Point getP(){
    return p;
  }

  //飛機發射子彈
  public void playBullet(Bullet bullet){
   //子彈狀態為true
    bullet.setLive();
  }

  //改變飛機狀態
  public void setLive(boolean aboolean){
    isLive = aboolean;
  }

  //返回飛機狀態
  public boolean getIsLive(){
    return isLive;
  }
}

主飛機類

package planeGame;

import forGame.ImageUtil;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

//主飛機
public class MainPlane extends Plane{
  //移動方向 1;上 -1:下 2:右 -2:左
  private int direction = 1;
  public MainPlane(int x, int y) {
    super(x, y);
  }

  @Override
  public void setP(int x) {}

  private boolean aBoolean = true;//繪制動態主飛機
  @Override
  public void drawMe(Graphics g) {
    if(isLive){
      if(aBoolean) {
        g.drawImage(ImageUtil.PLANE_1, p.x, p.y, null);
        aBoolean = false;
      }
      else {
        g.drawImage(ImageUtil.PLANE_2, p.x, p.y, null);
        aBoolean = true;
      }
    }
    else{
      g.drawImage(ImageUtil.BOMB_PLANE1, p.x, p.y, null);//未繪制動態爆炸效果
    }
  }

  @Override
  public void move() {
    if(direction == 1 && p.y > 30)
      p.move(p.x,p.y + speed);
    else if(direction == -1 && p.y < ImageUtil.HEIGHT_BACK - ImageUtil.HEIGHT_PLANE)
      p.move(p.x,p.y + speed);
    else if(direction == 2 && p.x < ImageUtil.WIDTH_BACK - ImageUtil.HEIGHT_PLANE)
      p.move(p.x + speed,p.y);
    if(direction == -2 && p.x > 0)
      p.move(p.x + speed,p.y);
  }

  //監聽飛機移動
  private KeyListener keyListener = new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
      int keyCode = e.getKeyCode();
      //移動方向 1;上 -1:下 2:右 -2:左
      //上
      if(keyCode == KeyEvent.VK_UP){
        direction = 1;
        speed = -20;
        move();
      }
      //下
      if(keyCode == KeyEvent.VK_DOWN){
        direction = -1;
        speed = 20;
        move();
      }
      //左
      if(keyCode == KeyEvent.VK_LEFT){
        direction = -2;
        speed = -32;
        move();
      }
      //右
      if(keyCode == KeyEvent.VK_RIGHT){
        direction = 2;
        speed = 32;
        move();
      }
    }
  };
  //返回鍵盤監聽器
  public KeyListener getKeyListener(){
    return keyListener;
  }
  //主飛機是否與敵機相撞
  public void isBomb(Plane[] planes){
    for(int i = 0;i < planes.length; i++) {
      if (planes[i].getIsLive()) {
        if(planes[i].getP().x > p.x && planes[i].getP().x < p.x + 128 && (p.y - planes[i].getP().y < 64)) {
          isLive = false;
          planes[i].setLive(false);
        }
      }
    }
  }
}

敵機類

package planeGame;

import forGame.ImageUtil;

import java.awt.*;

//敵機,未設置發射子彈功能
public class GamePlane extends Plane implements Grade{
  public GamePlane(int x, int y) {
    super(x, y);
  }

  @Override
  public void setP(int x) {
    p.x = x;
    p.y = 0;
  }

  @Override
  public void drawMe(Graphics g) {
    g.drawImage(ImageUtil.XIAO_PLANE,p.x,p.y,null);
    move();
  }

  @Override
  public void move() {
    if(p.y < 900)
      p.y = p.y +20;
    else
      isLive = false;
  }

 //未實現
  @Override
  public int getGrade() {
    return 0;
  }
}

子彈類

package planeGame;

import forGame.ImageUtil;

import java.awt.*;

//子彈類
public class Bullet implements DrawMe {
  private boolean isLive = false;//是否繪制子彈
  private int x;//子彈初始橫坐標
  private int y;//子彈初始縱坐標
  private int color;//繪制什麼子彈的標志
  public Bullet(int number,int x,int y){
    this.color = number;
    this.x =x;
    this.y =y;
  }

  //修改子彈坐標
  public void setXY(int x,int y){
    this.x =x;
    this.y =y;
  }

  //修改子彈狀態
  public void setLive(){
    isLive = true;
  }
  public boolean getLive(){
    return isLive;
  }
  //繪制子彈
  @Override
  public void drawMe(Graphics g) {
    if(color == 1){
      g.drawImage(ImageUtil.Bullet_1, x, y,null);
    } else {
      g.drawImage(ImageUtil.Bullet_2, x, y, null);
    }
    move();
  }

  //子彈移動
  private void move(){
    if(color == 1){
      if(y > 30)
        y = y - 50;
      else
        isLive = false;
    }else{
      if(y < 900)
        y = y + 100;
      else
        isLive = false;
    }
  }

  //子彈是否擊中敵機
  public boolean isBom(Plane[] planes){
    boolean is = false;
    for(int i = 0;i < planes.length;i ++){
      if(planes[i].getIsLive()){
        if(x > planes[i].getP().x && x < planes[i].getP().x + 64){
          if(y - planes[i].getP().y <= 64) {
            isLive = false;
            planes[i].setLive(false);
            is = true;
          }
        }
      }
    }
    return is;
  }

  //子彈是否與主機相撞
  private void isBom(Plane plane){

  }

}

創建主飛機、敵機、子彈類

package planeGame;

import java.util.Random;

//生產飛機、子彈
public class Production{
  Random random = new Random();
  private GamePlane[] gamePlanes = new GamePlane[16];
  private Bullet[] bullets = new Bullet[50];

  //背景圖:596 x 854
  //飛機圖:128 x 128
  //子彈圖:9 x 21
  private MainPlane mainPlane = new MainPlane(random.nextInt(400),random.nextInt(160) + 400);
  public MainPlane getMainPlane() {
    return mainPlane;
  }

  //生產敵機

  public GamePlane[] getGamePlanes() {
    for(int i = 0;i < 16;i ++){
      gamePlanes[i] = new GamePlane(0,0);
      gamePlanes[i].setLive(false);
    }
    return gamePlanes;
  }

 //修改一個敵機狀態為true
  public void setGamePlanes(){
    for(int i = 0;i < 16;i ++){
      if(!gamePlanes[i].isLive){
        gamePlanes[i].setP(random.nextInt(12) * 45 + 32);
        gamePlanes[i].setLive(true);
        break;
      }
    }
  }
 //隨機產生一個boolean值
  public boolean getBoolean(){
    return random.nextBoolean();
  }

  //生產子彈
  public Bullet[] getBullets() {
    for(int i = 0;i < 50;i ++){
      if(i < 20)
        bullets[i] = new Bullet(1,0,0);
      else
        bullets[i] = new Bullet(2,0,0);
    }
    return bullets;
  }
}

遊戲界面

package planeGame;

import forGame.ImageUtil;
import forGame.PlayMusic;

import java.awt.*;

//遊戲界面,繪制並顯示
public class GameJFrame extends MyJFrameFather{
  private boolean isRepaint = true;
  private PlayMusic playMusicB = new PlayMusic();
  private Production production = new Production();
  private GamePlane[] gamePlanes;
  private Bullet[] bullets;
  private MainPlane mainPlane = production.getMainPlane();
  private int grade = 0;
  public GameJFrame(){
    super("遊戲界面");
    setVisible(true);
    addKeyListener(mainPlane.getKeyListener());
    MyRunning myRunning = new MyRunning();
    myRunning.start();
    gamePlanes = production.getGamePlanes();
    bullets = production.getBullets();
  }

  @Override
  public void paint(Graphics g) {
    Image image = this.createImage(getWidth(),getHeight());
    Graphics gImage = image.getGraphics();
    gImage.setColor(gImage.getColor());
    gImage.fillRect(0,0,getWidth(),getHeight());
    super.paint(gImage);

    //596 x 854
    //繪制動態背景
    if(y2 == 0){
      y1 = 0;
      y2 = -830;
    }
    gImage.drawImage(ImageUtil.START,0 ,y1 ,null );
    gImage.drawImage(ImageUtil.START,0 ,y2 ,null );
    y1 = y1 + 10;
    y2 = y2 + 10;
    //繪制飛機子彈
    if(mainPlane.isLive){//主飛機活著
      for(int i = 0;i < 20;i ++){
       //找子彈狀態為false,重新設置坐標並修改狀態
        if(!bullets[i].getLive()){
          bullets[i].setXY(mainPlane.getP().x + 60,mainPlane.getP().y - 21);
          mainPlane.playBullet(bullets[i]);
          break;
        }
      }
      //繪制活著的敵機
      for(int i =0;i < 10;i ++){
        if(gamePlanes[i].isLive){
          gamePlanes[i].drawMe(gImage);
        }
      }
      //控制什麼時候讓敵機活
      if(production.getBoolean() && production.getBoolean())
        production.setGamePlanes();
      //判斷主飛機是否爆炸
      mainPlane.isBomb(gamePlanes);
      //繪制主飛機
      mainPlane.drawMe(gImage);
      //首先判斷子彈是否擊中敵機,沒有擊中則繪制子彈
      for(int i = 0;i < bullets.length;i ++){
        if(bullets[i].getLive()) {
          if (bullets[i].isBom(gamePlanes))
            grade = grade + 10;
          else
            bullets[i].drawMe(gImage);
        }
      }
    }else{
      isRepaint = false;
      mainPlane.drawMe(gImage);
      gImage.setFont(new Font("宋體",Font.ITALIC ,50));
      gImage.drawString("GameOver",200,350);
    }
    gImage.drawString("得分:" + grade,10,100);
    //最後繪制緩沖後的圖片
    g.drawImage(image,0 ,0 , null);
  }
 
 //多線程去控制重新繪制的時間
  private class MyRunning extends Thread{
    @Override
    public void run() {
      while (isRepaint){
        try {
          sleep(100);
          repaint();
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

測試類

package planeGame;

//測試類
public class Demo {
  public static void main(String[] args) {
    new StartJFrame();//創建開始界面
  }
}

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: