Java小游戏之Swing框架实现飞机大战(附源码 超详细必看)

简介: Java小游戏之Swing框架实现飞机大战(附源码 超详细必看)

需要源码和图片集请点赞关注收藏后评论区留言~~~

1.项目主要工作

本次项目的题目——基于Java的飞机大战游戏的设计与实现,主要目的是实现飞机大战这个游戏。期望结果游戏无BUG现在人们将在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题统称为BUG——漏洞,简单易上手,老少皆宜,让玩家“玩不释手”。

从游戏的玩法来说,主要就是我方飞机(Hero airplane)和敌方飞机(Enemy airplane)的对决,首先是游戏的开始界面与结束界面,然后就是我方飞机(Hero airplane)的移动方式(鼠标移动或者键盘移动,我打算选择鼠标移动,因为鼠标移动可以转移到手机上,现在大多数手机都没有键盘,基本靠手指滑动操作),接下来就是我方飞机(Hero airplane)子弹的生成,然后是敌方飞机(Enemy airplane)的出现坐标的选择,然后飞机与子弹防碰撞,飞机与飞机的防碰撞,最后是我方飞机(Hero airplane)与敌方飞机(Enemy airplane)的对战结果。

该游戏要满足以下功能性需求:

(1)游戏状态控制功能

   游戏的状态控制包括运行、暂停、恢复及结束游戏,首先是游戏的开始页面,在游戏正在进行时,如果你有其他的事情又不想结束游戏你可以将鼠标移出游戏界面或者鼠标在游戏界面单击即可暂停游戏,当你的其他事情解决后你还可以选择恢复游戏,继续玩下去,当游戏结束时会显示游戏结束界面。

(2)游戏难度的调整

    玩家随着玩游戏的时间的增加,敌方飞机的数量会增加,出现的频率会有所提高,移动速度也会提高。

(3)游戏界面绘画功能

    在右上角显示游戏时间(游戏难度于时间成正比,即游戏时间越长难度越高),玩家游戏得分,与我方飞机生命值,游戏主屏用来显示玩家对我方飞机(Hero airplane)的控制与敌方飞机(Enemy airplane)的出现及移动的显示。

(4)玩家游戏控制功能

    玩家可以通过控制移动鼠标或者键盘来控制友机的移动。

项目分解结构(WBS)如下

 

效果图如下

部分源码

package main;
import java.util.Random;
//Airplane----�л����Ƿ����
public class Airplane extends FlyingObject implements Enemy {
  private int speed = 2;// �л��߲��IJ���
  public Airplane() {
    image = ShootGame.airplane;
    width = image.getWidth();
    height = image.getHeight();
    Random rand = new Random();
    x = rand.nextInt(ShootGame.WIDTH - this.width);
    y = -this.height; // y:���ĵл��ĸ�
  }
  // ��д getScore();
  public int getScore() {
    return 5;
  }
  public void step() {
    y += speed;
  }
  public boolean outOfBounds() {
    return this.y > ShootGame.HEIGHT; // �л���y������ڴ��ڵĸ�
  }
}
-------------
package main;
import java.util.Random;
//Be---С�۷�  ���Ƿ����Ҳ�ܻ�ȡ����
public class Bee extends FlyingObject implements Award{
  private int xSpeed = 1;     //x�����߲�����
  private int ySpeed = 2;     //y�����߲�����
  private int awardType;      //��������
  public Bee(){
    image = ShootGame.bee;
    width = image.getWidth();
    height = image.getHeight();
    Random rand = new Random();
    x = rand.nextInt(ShootGame.WIDTH - this.width);
      y = -this.height; 
    awardType = rand.nextInt(2);//������ɽ�������
  }
  public int getType(){
    return awardType;
  }
    public void step(){     
      if(x >= ShootGame.WIDTH - this.width){
        xSpeed = -1;
      }
      if(x <= 0){
        xSpeed = 1;
      }
      x += xSpeed;
      y += ySpeed;    
  }
    public boolean outOfBounds(){
      return this.y > ShootGame.HEIGHT;  
  }
}
-----------
package main;
//�ӵ�--ֻ�Ƿ����� 
public class Bullet extends FlyingObject{
  private int speed = 3;  //�ӵ��߲�������ֻ��y�����ڱ�
  public Bullet(int x,int y){//�ӵ�����������Ӣ�ۻ��ı仯���仯   
    image = ShootGame.bullet;
    width = image.getWidth();
    height = image.getHeight();
    this.x = x;
    this.y = y;
  }
    public void step(){
    y -= speed;
  }
    public boolean outOfBounds(){
    return this.y < -this.height;
  }
}
------------
package main;
import java.awt.image.BufferedImage;
public abstract class FlyingObject {
  protected BufferedImage image;//ͼƬ����--java�����е�
  protected int width;     //��
  protected int height;    //��
  protected int x;         //x����
  protected int y;         //y����
  //�������߲�
  public abstract void step();
  //Խ�緽��
  public abstract boolean outOfBounds();
  //���˱��ӵ�ײ 
  public boolean shootBy(Bullet bullet){
    //this:����       other���ӵ�
    int x1 = this.x;
    int x2 = this.x + this.width;
    int y1 = this.y;
    int y2 = this.y + this.height;
    int x = bullet.x;
    int y = bullet.y;
    return x > x1 && x < x2
        &&
        y > y1 && y < y2;
  }
}
-------------
package main;
import java.awt.image.BufferedImage;
//Ӣ�ۻ��Ƿ�����
public class Hero extends FlyingObject{
  private int life;                 //��
  private int doubleFire;           //����ֵ
  private BufferedImage[] images;   //ͼƬ����
  private int index;                //Э��ͼƬ�л�
  public Hero(){
    image = ShootGame.hero0;
    width = image.getWidth();
    height = image.getHeight();
    x = 150;
    y = 400;                
    life = 3;              //3����
    doubleFire = 0;        //��������
    images = new BufferedImage[]{ShootGame.hero0,ShootGame.hero1};
    index = 0;
  }
  public void step(){
    //ÿ100������һ��
    image = images[index++/10%images.length];   
    /*
    index++;
    int a = index / 10;
    int b = a % 2;
    image = images[b];
    */
  }
  public Bullet[] shoot(){
    int xStep = this.width/4;
    if(doubleFire > 0){           //˫��
      Bullet[] bullets = new Bullet[2];
      bullets[0] = new Bullet(this.x + 1 * xStep,this.y - 20);
      bullets[1] = new Bullet(this.x + 3 * xStep,this.y - 20);
      doubleFire -= 2;      //����˫��������ÿ�μ�2��ʵ�ʾ���2�������ij���ʱ��
      return bullets;
    }else{                        //����
      Bullet[] bullets = new Bullet[1];
      bullets[0] = new Bullet(this.x + 2 * xStep,this.y - 20);
      return bullets;
    }
  }
  public void moveTo(int x,int y){
    this.x = x - this.width/2;
    this.y = y - this.height/2;
  }
  public boolean outOfBounds(){
    return false;              //Ӣ�ۻ�����Խ��
  }
    //����
    public void addLife(){
      life++;
    }
    //��ȡ��
    public int getLife(){
      return life;
    }
    public void addDoubleFire(){
      doubleFire += 40;
    }
    //����ֵ����
    public void setDoubleFire(int doubleFire){
      this.doubleFire = doubleFire;
    }
    //Ӣ�ۻ�ײ����
    public boolean hit(FlyingObject other){
      int x1 = other.x - this.width/2;
      int x2 = other.x + other.width + this.width/2;
      int y1 = other.y - this.height/2;
      int y2 = other.y + other.height + this.height/2;
      int hx = this.x + this.width/2;
      int hy = this.y + this.height/2;
      return hx > x1 && hx < x2
          &&
           hy > y1 && hy < y2;
    }
    //����
    public void subtractLife(){
      life--;
    }    
}
-----------------package main;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
//�����������
public class ShootGame extends JPanel {
  /**
   * 
   */
  private static final long serialVersionUID = 9158805858745581422L;
  public static final int WIDTH = 400; // ���ڵĿ�
  public static final int HEIGHT = 654; // ���ڵĸ�
  // ��̬��Դ
  public static BufferedImage background; // ����ͼ
  public static BufferedImage start; // ��ʼͼ
  public static BufferedImage pause; // ��ͣͼ
  public static BufferedImage gameover; // ��Ϸ����ͼ
  public static BufferedImage airplane; // �л�ͼ
  public static BufferedImage bee; // �۷�ͼ
  public static BufferedImage bullet; // �ӵ�ͼ
  public static BufferedImage hero0; // Ӣ�ۻ�0ͼ
  public static BufferedImage hero1; // Ӣ�ۻ�1ͼ
  public static AudioClip music;
  public static final int START = 0;
  public static final int RUNNING = 1;
  public static final int PAUSE = 2;
  public static final int GAME_OVER = 3;
  private int state = 0; // ��ǰ״̬
  private Hero hero = new Hero(); // Ӣ�ۻ�
  private Bullet[] bullets = {}; // �ӵ�����
  private FlyingObject[] flyings = {}; // ��������
  private Timer timer;
  private int intervel = 10; // ���ʱ�䣺��λ--����
  // ��̬��
  static {
    try {
      background = ImageIO.read(ShootGame.class.getResource("background.png"));
      start = ImageIO.read(ShootGame.class.getResource("start.png"));
      pause = ImageIO.read(ShootGame.class.getResource("pause.png"));
      gameover = ImageIO.read(ShootGame.class.getResource("gameover.png"));
      airplane = ImageIO.read(ShootGame.class.getResource("airplane.png"));
      bee = ImageIO.read(ShootGame.class.getResource("bee.png"));
      bullet = ImageIO.read(ShootGame.class.getResource("bullet.png"));
      hero0 = ImageIO.read(ShootGame.class.getResource("hero0.png"));
      hero1 = ImageIO.read(ShootGame.class.getResource("hero1.png"));
      URL musicPath = ShootGame.class.getResource("game_music.wav");
      music = Applet.newAudioClip(musicPath);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  public static FlyingObject nextOne() {
    Random rand = new Random();
    int type = rand.nextInt(20); // ����0��19�������
    if (type == 0) { // �����Ϊ0������bee;���򷵻صл�
      return new Bee();
    } else {
      return new Airplane();
    }
  }
  int flyEnteredIndex = 0;
  // ���˵dz�
  public void enterAction() {// 10������һ��
    flyEnteredIndex++; // ÿ10������1
    if (flyEnteredIndex % 40 == 0) {
      FlyingObject obj = nextOne();
      flyings = Arrays.copyOf(flyings, flyings.length + 1);
      flyings[flyings.length - 1] = obj;// �����˸�ֵ��flyings��������һ��Ԫ��
    }
  }
  public void stepAction() { // 10������һ��
    hero.step(); // Ӣ�ۻ���һ��
    int num = time1 / 15;
    for (int i = 0; i < flyings.length; i++) {
      for(int j = 0; j <= num; j++) {
        flyings[i].step(); // ������һ��
      }
    }
    for (int i = 0; i < bullets.length; i++) {
      for(int j = 0; j <= num/2; j++) {
        bullets[i].step(); // �ӵ���һ��
      }
    }
  }
  int shootIndex = 0;
  public void shootAction() { // 10������һ��
    shootIndex++; // ÿ10������1
    if (shootIndex % 30 == 0) { // 300���뷢��һ���ӵ�
      Bullet[] bs = hero.shoot();// ��ȡ�ӵ�����
      bullets = Arrays.copyOf(bullets, bullets.length + bs.length);
      System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);
    }
  }
  // ɾ��Խ�������
  public void outOfBoundsAction() {
    int index = 0;
    FlyingObject[] flyingLives = new FlyingObject[flyings.length];
    for (int i = 0; i < flyings.length; i++) {
      FlyingObject f = flyings[i];
      if (!f.outOfBounds()) {
        flyingLives[index] = f;// ��Խ�磬����װ��flyingLives[]������
        index++;
      }
    }
    flyings = Arrays.copyOf(flyingLives, index);
    index = 0;
    Bullet[] bulletsLives = new Bullet[bullets.length];
    for (int i = 0; i < bullets.length; i++) {
      Bullet bs = bullets[i];
      if (!bs.outOfBounds()) {
        bulletsLives[index] = bs;// ��Խ�磬����װ��flyingLives[]������
        index++;
      }
    }
    bullets = Arrays.copyOf(bulletsLives, index);
  }
  int score = 0; // �÷�
  static double time = 0.00;//ʱ��
  static int time1 = 0;
  // �����ӵ������е���ײ
  public void bangAction() {
    for (int i = 0; i < bullets.length; i++) {
      bang(bullets[i]);
    }
  }
  // һ���ӵ������е���ײ
  public void bang(Bullet b) {
    int index = -1;// ��ײ���˵�����
    for (int i = 0; i < flyings.length; i++) {// �������еĵ���
      if (flyings[i].shootBy(b)) {// �ж��Ƿ�ײ��
        index = i; // ��¼��ײ���˵�����
        break;
      }
    }
    if (index != -1) {// ײ����
      FlyingObject one = flyings[index];
      if (one instanceof Enemy) {
        Enemy e = (Enemy) one;
        score += e.getScore();
      }
      if (one instanceof Award) {
        Award a = (Award) one;
        int type = a.getType();
        switch (type) {
        case Award.DOUBLE_FIRE: // ��������ֵ
          hero.addDoubleFire(); // Ӣ�ۻ����ӻ���
          break;
        case Award.LIFE: // ������
          hero.addLife(); // Ӣ�ۻ�����
          break;
        }
      }
      // ��ײ������flyings�����е����һ��Ԫ�ؽ���
      FlyingObject t = flyings[index];
      flyings[index] = flyings[flyings.length - 1];
      flyings[flyings.length - 1] = t;
      // ���ݣ�ɾ�����һ��Ԫ��---����ײ�Ķ���
      flyings = Arrays.copyOf(flyings, flyings.length - 1);
    }
  }
  public void checkGameOverAction() {
    if (isGameOver()) { // ������Ϸ
      state = GAME_OVER;
      time1 = 0;
      time = 0;
    }
  }
  public boolean isGameOver() {
    for (int i = 0; i < flyings.length; i++) { // ײ���ˣ�
      if (hero.hit(flyings[i])) {
        hero.subtractLife(); // ������1
        hero.setDoubleFire(0); // ����ֵ����
        // ��ײ֮�󣬽�������
        FlyingObject t = flyings[i];
        flyings[i] = flyings[flyings.length - 1];
        flyings[flyings.length - 1] = t;
        flyings = Arrays.copyOf(flyings, flyings.length - 1);
      }
    }
    return hero.getLife() <= 0; // Ӣ�ۻ�����<=0,��Ϸ����
  }
  // ����ִ�д���
  public void action() {
    MouseAdapter l = new MouseAdapter() {
      public void mouseMoved(MouseEvent e) {
        if (state == RUNNING) { // ����״̬��ִ��
          int x = e.getX(); // ���Y����
          int y = e.getY(); // ���X����
          hero.moveTo(x, y); // Ӣ�ۻ���������ƶ����ƶ�
        }
      }
      // ���ĵ���¼�
      public void mouseClicked(MouseEvent e) {
        switch (state) {
        case PAUSE:
          state = RUNNING;
          music.stop();
          music.loop();
          break;
        case RUNNING:
          state = PAUSE;
          music.stop();
          break;
        case START:
          state = RUNNING;
          music.stop();
          music.loop();
          break;
        case GAME_OVER:
          hero = new Hero();// �����ֳ�
          flyings = new FlyingObject[0];
          bullets = new Bullet[0];
          score = 0;
          state = START;
          music.stop();
          break;
        }
      }
      public void mouseEntered(MouseEvent e) {
        if (state == PAUSE) {
          state = RUNNING;
        }
      }
      public void mouseExited(MouseEvent e) {
        if (state == RUNNING) {
          state = PAUSE;
        }
      }
    };
    this.addMouseListener(l); // �����������¼�
    this.addMouseMotionListener(l);// ��������ƶ��¼�
    timer = new Timer(); // ������ʱ������
    timer.schedule(new TimerTask() {
      public void run() { // ��ʱ�ɵ��Ǹ���--10������һ��
        if (state == RUNNING) { // ����״̬��ִ��
          enterAction();
          stepAction();// ��������һ��
          shootAction();// �ӵ��볡
          outOfBoundsAction();// ɾ��Խ�������
          bangAction(); // �ӵ������ײ
          time = time +0.01;
          time1 = (int)time;
          checkGameOverAction();
        }
        repaint(); // �ػ�������paint()
      }
    }, intervel, intervel);
  }
  // ��дpaint()���� g����ʾ����
  public void paint(Graphics g) {
    g.drawImage(background, 0, 0, null); // ������ͼ
    paintHero(g);
    paintFlyingObjects(g);
    paintBullets(g);
    paintScore(g); // ���֣�����
    paintState(g);
  }
  // ��״̬
  public void paintState(Graphics g) {
    switch (state) {
    case START: // ����״̬������ͼ
      g.drawImage(start, 0, 0, null);
      break;
    case PAUSE: // ��ͣ״̬����ͣͼ
      g.drawImage(pause, 0, 0, null);
      break;
    case GAME_OVER: // ����״̬������ͼ
      g.drawImage(gameover, 0, 0, null);
      break;
    }
  }
  public void paintHero(Graphics g) {
    g.drawImage(hero.image, hero.x, hero.y, null); // ��Ӣ�ۻ�����
  }
  public void paintFlyingObjects(Graphics g) {
    for (int i = 0; i < flyings.length; i++) {
      FlyingObject f = flyings[i];
      g.drawImage(f.image, f.x, f.y, null);
    }
  }
  public void paintBullets(Graphics g) {
    for (int i = 0; i < bullets.length; i++) {
      Bullet b = bullets[i];
      g.drawImage(b.image, b.x, b.y, null);
    }
  }
  public void paintScore(Graphics g) { // ���֣�����
    g.setColor(new Color(0xFF0000));
    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));
    g.drawString("SCORE: " + score, 20, 25);
    g.drawString("LIFE: " + hero.getLife(), 20, 45);
    g.drawString("TIME:" +time1,20,65);
  }
  public static void main(String[] args) {
    JFrame frame = new JFrame("�ɻ���ս"); // ���ڶ���
    ShootGame game = new ShootGame(); // ���
    frame.add(game); // �������ӵ�������
      BufferedImage image;
    try {
      image = ImageIO.read(ShootGame.class.getResource("icon.jpg"));
      frame.setIconImage(image);
    } catch (FileNotFoundException e) {
    } catch (IOException e) {
    }  
    frame.setSize(WIDTH, HEIGHT); // ���ô��ڵĿ�͸�
    frame.setAlwaysOnTop(true); // ����һֱ��������
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // ����Ĭ�ϹرյIJ��������ڹر�ʱ�˳�����
    frame.setLocationRelativeTo(null); // ���ô��ڳ�ʼλ�ã�����)
    frame.setVisible(true); // ���ô���ɼ�
    game.action(); // ����ִ��
  }
}

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
2月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
53 3
|
7天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
32 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
4天前
|
JavaScript 安全 Java
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
33 12
|
8天前
|
人工智能 监控 安全
Java智慧工地(源码):数字化管理提升施工安全与质量
随着科技的发展,智慧工地已成为建筑行业转型升级的重要手段。依托智能感知设备和云物互联技术,智慧工地为工程管理带来了革命性的变革,实现了项目管理的简单化、远程化和智能化。
29 4
|
1月前
|
并行计算 算法 Java
Java中的Fork/Join框架详解
Fork/Join框架是Java并行计算的强大工具,尤其适用于需要将任务分解为子任务的场景。通过正确使用Fork/Join框架,可以显著提升应用程序的性能和响应速度。在实际应用中,应结合具体需求选择合适的任务拆分策略,以最大化并行计算的效率。
51 23
|
26天前
|
JavaScript Java 测试技术
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 6
|
27天前
|
前端开发 Java 程序员
菜鸟之路day02-04拼图小游戏开发一一JAVA基础综合项目
本项目基于黑马程序员教程,涵盖面向对象进阶、继承、多态等知识,历时约24小时完成。项目去除了登录和注册模块,专注于单机游戏体验。使用Git进行版本管理,代码托管于Gitee。项目包含窗体搭建、事件监听、图片加载与打乱、交互逻辑实现、菜单功能及美化界面等内容。通过此项目,巩固了Java基础并提升了实际开发能力。 仓库地址:[https://gitee.com/zhang-tenglan/puzzlegame.git](https://gitee.com/zhang-tenglan/puzzlegame.git)
42 6
|
1月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
SQL Java 数据库连接
Java面试题日积月累(SSM框架面试题22道)
Java面试题日积月累(SSM框架面试题22道)
126 0
|
7月前
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
86 1