首页 > 编程语言 > java实现飞机大战游戏
2021
03-22

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();//创建开始界面
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学编程网。

编程技巧