《飞机大战游戏》实训项目(Java GUI实现)(操持模式)(浅易)

[复制链接]
发表于 2026-1-20 00:56:56 | 显示全部楼层 |阅读模式
目次
  一、终极实现后,结果如下。
  (1)简单先容本游戏项目(待美满)
  (2)运行结果图(详细各人自己可以试)
  初始运行情况。
  手动更换配景图。
  通过子弹攻击敌机,累计游戏分数。由变量"score"控制。
  二、各个类的代码如下
  (1)启动类(主类)
  (2)自界说的"窗口"类(Frame)extends"JFrame"
  (3)自界说"内容面板"类(Panel)extends"JPanel"
  (4)"敌机"类(EnemyPlane)
  (5)"本人飞机"类(Plane)
  (6)"子弹"类(Fire)
  

  一、终极实现后,结果如下。

   (1)简单先容本游戏项目(待美满)

  

  • 只是学校的简单的实训项目,内里还可以举行许多内容可以增补大概美满。
  • 内里有一个功能,博主实现的时间,"大"的敌机左右移动时,存在"摇摇摆晃"的情况。以是这里博主把这一部门的代码解释了,只让其"y的坐标值"变革。
  • "小"敌机移动速率快,"大"敌机移动速率慢。
  • 游戏界面的配景图,不会随着时间而举行改变(各人可以美满)。
  • "自己飞机"的键盘移动操纵不是很流畅,须要美满。
  • "敌机"没有血量,自己操控的飞机没有血量,没有游戏竣事"game over"的触发。
  • 只有子弹击中敌机的判断。当子弹的坐标与敌机坐标满足条件,就触发方法,将敌机remove()。
  • 子弹与敌机的创建都用到了线程的知识。而且通过"W"(上)、"S"(下)、"A"(左)、"D"(右)大概鼠标举行操控自己的飞机,举行攻击"x坐标指定范围内"、"y坐标为0"天生的敌机。
  • 根本的技能用到了Java GUI(可视化)提供的类"anel"、"JFrame",以及其下的方法实现。
  • 当运行到肯定的时间,该实训项目会出现报错地方(敌机天生线程、子弹天生线程)。
(2)运行结果图(详细各人自己可以试)

  

  • 初始运行情况。

  

  • 手动更换配景图。

  

  • 通过子弹攻击敌机,累计游戏分数。由变量"score"控制。

  二、各个类的代码如下

   (1)启动类(主类)

  1. package ui;
  2. /**
  3. * @Title: Main
  4. * @Author HeYouLong
  5. * @Package ui
  6. * @Date 2024/9/12 上午8:33
  7. * @description:
  8. */
  9. public class Main {
  10.     public static void main(String[] args) {
  11.         Frame frame = new Frame();
  12.         Panel panel = new Panel(frame);
  13.         frame.add(panel);
  14.         panel.begin();
  15.         panel.fireBegin();
  16.         frame.setVisible(true);
  17.     }
  18. }
复制代码
(2)自界说的"窗口"类(Frame)extends"JFrame"

  

  • "JFrame"类是 Java Swing 图形用户界面工具包中的一个非常告急的类,它代表了一个窗口,是顶级容器之一。在 Swing 应用步伐中,险些全部的 GUI 组件都直接或间接地包罗在一个"JFrame"窗口中。
  • JFrame 提供了窗口的根本功能,如标题栏、最小化/最大化按钮、关闭按钮以及可调解巨细的边框。但是,JFrame 自己不包罗任何可视化组件(如按钮、文本框等);这些组件必须被添加到 JFrame 的内容面板(ContentPane)中,而内容面板默认是一个 "JPanel"。
  1. package ui;
  2. import javax.swing.*;
  3. /**
  4. * @Title: Frame
  5. * @Author HeYouLong
  6. * @Package ui
  7. * @Date 2024/9/12 上午8:32
  8. * @description:
  9. */
  10. public class Frame extends JFrame {
  11.     public Frame(){
  12.         setTitle("设计模式课程飞机大战");
  13.         setSize(512,768);
  14.         setLocationRelativeTo(null);//居中
  15.         setResizable(false);//不准随便改变窗口大小
  16.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口——>退出进程
  17.     }
  18. }
复制代码
(3)自界说"内容面板"类(Panel)extends"JPanel"

  

  • "JPanel" 类是 Java Swing 图形用户界面工具包中的一个非常告急的类,它继续自 JComponent 并实现了 Container 接口。JPanel 是一种轻量级的容器,可以用来构造和管理其他 GUI 组件(如按钮、文本框、标签等)。与 JFrame 差别的是,JPanel 自己不是一个顶级容器,它必须被添加到某个顶级容器(如 JFrame、JDialog 或 JApplet)中才华表现。
  • 这个类的内容比力多,由于是"内容面板"嘛。
  1. package ui;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.KeyAdapter;
  5. import java.awt.event.KeyEvent;
  6. import java.awt.event.MouseAdapter;
  7. import java.awt.event.MouseEvent;
  8. import java.awt.image.BufferedImage;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. /**
  12. * @Title: Panel
  13. * @Author HeYouLong
  14. * @Package ui
  15. * @Date 2024/9/12 上午8:38
  16. * @description:
  17. */
  18. public class Panel extends JPanel {
  19.     private BufferedImage bg = GetImg.getImg("bg5.jpg");
  20.     private Plane plane;
  21.     private List<EnemyPlane> enemyPlaneList = new ArrayList<>();
  22.     private List<Fire> fires = new ArrayList<>();
  23.     //敌机
  24.     public void begin() {
  25.         new Thread() {
  26.             public void run() {
  27.                 while (true) {
  28.                     CreateEp(); //创建敌机 todo
  29.                     MoveEp(); //敌机移动 todo
  30.                     hit(); //子弹碰撞
  31.                     try {
  32.                         Thread.sleep(20);
  33.                     } catch (InterruptedException e) {
  34.                         throw new RuntimeException(e);
  35.                     }
  36.                     repaint();//画敌机
  37.                 }
  38.             }
  39.         }.start();
  40.     }
  41.     private static int score=0;
  42.     //判断子弹与敌机是否碰撞
  43.     private void hit() {
  44.         for (int i = 0; i < enemyPlaneList.size(); i++) {
  45.             EnemyPlane enemyPlane = enemyPlaneList.get(i);
  46.             for (int j = 0; j < fires.size(); j++) {
  47.                 Fire fire = fires.get(j);
  48.                 if(fire.x+fire.image.getWidth()/2>enemyPlane.getX() && fire.x<enemyPlane.getX()+enemyPlane.getImg().getWidth() && fire.y+fire.image.getHeight()/2>enemyPlane.getY() && fire.y<enemyPlane.getY()+enemyPlane.getImg().getHeight()){
  49.                     enemyPlaneList.remove(i);
  50.                     fires.remove(j);
  51.                     score++;
  52.                 }
  53.             }
  54.         }
  55.     }
  56.     //子弹的线程
  57.     public void fireBegin() {
  58.         new Thread() {
  59.             public void run() {
  60.                 while (true) {
  61.                     //创建子弹
  62.                     fireCreate();
  63.                     //子弹移动
  64.                     fireMove();
  65.                     //休息线程
  66.                     try {
  67.                         Thread.sleep(10);
  68.                     } catch (InterruptedException e) {
  69.                         throw new RuntimeException(e);
  70.                     }
  71.                     //画子弹
  72.                     repaint();
  73.                 }
  74.             }
  75.         }.start();
  76.     }
  77.     private void fireMove() {
  78.         for (int i = 0; i < fires.size(); i++) {
  79.             Fire fire = fires.get(i);
  80.             fire.y=fire.y-10;
  81.         }
  82.     }
  83.     private static int index = 0;
  84.     private void fireCreate() {
  85.         index++;
  86.         if (index >= 12) {
  87.             Fire fire = new Fire(plane);
  88.             fires.add(fire);
  89.             index = 0;
  90.         }
  91.     }
  92.     private void MoveEp() {
  93.         for (int i = 0; i < enemyPlaneList.size(); i++) {
  94.             EnemyPlane enemyPlane = enemyPlaneList.get(i);
  95.             enemyPlane.move();
  96.         }
  97.     }
  98.     private static int count = 0;
  99.     private void CreateEp() {
  100.         count++;
  101.         if (count >= 12) {
  102.             EnemyPlane enemyPlane = new EnemyPlane();
  103.             enemyPlaneList.add(enemyPlane);
  104.             count = 0;
  105.         }
  106.     }
  107.     public Panel(Frame frame) {
  108.         plane = new Plane();
  109.         //鼠标操作
  110.         mouse();
  111.         //键盘操作 todo
  112.         key(frame);
  113.     }
  114.     private void key(Frame frame) {
  115.         KeyAdapter keyAdapter = new KeyAdapter() {
  116.             @Override
  117.             public void keyPressed(KeyEvent e) {
  118.                 super.keyPressed(e);
  119.                 int i = e.getKeyCode();//获得按的键
  120.                 if (i == KeyEvent.VK_A || i == KeyEvent.VK_LEFT) {
  121.                     plane.setX(plane.getX() - 30);
  122.                     if (plane.getX() <= 0) {
  123.                         plane.setX(0);
  124.                     }
  125.                 } else if (i == KeyEvent.VK_D || i == KeyEvent.VK_RIGHT) {
  126.                     plane.setX(plane.getX() + 30);
  127.                     if (plane.getX() >= 395) {
  128.                         plane.setX(395);
  129.                     }
  130.                 } else if (i == KeyEvent.VK_W || i == KeyEvent.VK_UP) {
  131.                     plane.setY(plane.getY() - 30);
  132.                     if (plane.getY() <= 0) {
  133.                         plane.setY(0);
  134.                     }
  135.                 } else if (i == KeyEvent.VK_S || i == KeyEvent.VK_DOWN) {
  136.                     plane.setY(plane.getY() + 30);
  137.                     if (plane.getY() >= 635) {
  138.                         plane.setY(635);
  139.                     }
  140.                 }
  141.                 repaint();
  142.             }
  143.         };
  144.         frame.addKeyListener(keyAdapter);
  145.     }
  146.     private void mouse() {
  147.         MouseAdapter mouseAdapter = new MouseAdapter() {
  148.             @Override
  149.             public void mouseMoved(MouseEvent e) {
  150.                 super.mouseMoved(e);
  151.                 plane.setX(e.getX() - plane.getImage().getWidth() / 2);
  152.                 plane.setY(e.getY() - plane.getImage().getHeight() / 2);
  153.                 //重新画
  154.                 repaint();
  155.             }
  156.         };
  157.         addMouseListener(mouseAdapter);
  158.         addMouseMotionListener(mouseAdapter);
  159.     }
  160.     @Override
  161.     public void paint(Graphics g) {
  162.         super.paint(g);
  163.         g.drawImage(bg, 0, 0, null);
  164. //本人飞机初始位置
  165.         g.drawImage(plane.getImage(), plane.getX(), plane.getY(), null);
  166. //画敌机
  167.         for (int i = 0; i < enemyPlaneList.size(); i++) {
  168.             EnemyPlane enemyPlane = enemyPlaneList.get(i);
  169.             g.drawImage(enemyPlane.getImg(), enemyPlane.getX(), enemyPlane.getY(), null);
  170.         }
  171.         //画子弹
  172.         for (int i = 0; i < fires.size(); i++) {
  173.             Fire fire = fires.get(i);
  174.             g.drawImage(fire.image,fire.x, fire.y,fire.image.getWidth()/2,fire.image.getHeight()/2, null);
  175.         }
  176.         //画分数
  177.         g.setColor(Color.white);
  178.         Font font = new Font("黑体", Font.PLAIN, 22);
  179.         g.setFont(font);
  180.         g.drawString("当前游戏分数:"+score, 10, 20);
  181.     }
  182. }
复制代码
(4)"敌机"类(EnemyPlane)

  (控制初始敌机天生的初始x、y坐标位置,控制出现边界,差别范例飞机移动速率等等)
  1. package ui;
  2. import java.awt.image.BufferedImage;
  3. import java.util.Random;
  4. /**
  5. * @Title: EnemyPlane
  6. * @Author HeYouLong
  7. * @Package ui
  8. * @Date 2024/9/13 上午10:26
  9. * @description:
  10. */
  11. public class EnemyPlane {
  12.     private int x;
  13.     private int y;
  14.     private int z;
  15.     private BufferedImage img;
  16.     public void move(){
  17.         final int MOVE_SPEED = 10; // 固定的移动速度
  18.         final int ENEMY_WIDTH = this.img.getWidth(); // 敌机图像的宽度
  19.         if(z<10){
  20.             y=y+14;
  21.             return;
  22.         }else{
  23.             /*Random random = new Random();
  24.             int i = random.nextInt(2);
  25.             if(i==0){
  26.                 x -= MOVE_SPEED; // 假设z也影响移动速度,这里简单地使用z的模和加数来调整
  27.                 if (x <= 0) {
  28.                     x = 512-ENEMY_WIDTH; // 防止敌机移出屏幕左侧
  29.                 }
  30.             }else {
  31.                 // 向右移动
  32.                 x += MOVE_SPEED; // 同上,调整移动速度
  33.                 if (x >= 512-this.img.getWidth()) {
  34.                     x = 0;
  35.                 }
  36.             }*/
  37.             y=y+8;
  38.         }
  39.     }
  40.     public EnemyPlane() {
  41.         Random random = new Random();
  42.         int i = random.nextInt(15)+1;
  43.         String j = i<10?"0"+i:i+"";//文件名
  44.         String imgName = "ep"+j+".png";
  45.         this.img=GetImg.getImg(imgName);//随机图片
  46.         this.y=0;
  47.         this.z=i;
  48.         this.x=random.nextInt(512-this.img.getWidth());
  49.     }
  50.     public int getX() {
  51.         return x;
  52.     }
  53.     public void setX(int x) {
  54.         this.x = x;
  55.     }
  56.     public int getY() {
  57.         return y;
  58.     }
  59.     public void setY(int y) {
  60.         this.y = y;
  61.     }
  62.     public BufferedImage getImg() {
  63.         return img;
  64.     }
  65.     public void setImg(BufferedImage img) {
  66.         this.img = img;
  67.     }
  68.     public int getZ() {
  69.         return z;
  70.     }
  71.     public void setZ(int z) {
  72.         this.z = z;
  73.     }
  74. }
复制代码
(5)"本人飞机"类(Plane)

  (设置初始位置、选定飞机图片、getter()、setter())
  1. package ui;
  2. import java.awt.image.BufferedImage;
  3. /**
  4. * @Title: Plane
  5. * @Author HeYouLong
  6. * @Package ui
  7. * @Date 2024/9/12 上午9:05
  8. * @description:
  9. */
  10. public class Plane {
  11.     private int x;
  12.     private int y;
  13.     private BufferedImage image;
  14.     public Plane() {
  15.         x=200;
  16.         y=500;
  17.         image = GetImg.getImg("hero.png");
  18.     }
  19.     public int getX() {
  20.         return x;
  21.     }
  22.     public void setX(int x) {
  23.         this.x = x;
  24.     }
  25.     public int getY() {
  26.         return y;
  27.     }
  28.     public void setY(int y) {
  29.         this.y = y;
  30.     }
  31.     public BufferedImage getImage() {
  32.         return image;
  33.     }
  34.     public void setImage(BufferedImage image) {
  35.         this.image = image;
  36.     }
  37. }
复制代码
(6)"子弹"类(Fire)

  (子弹的初始坐标与飞机的坐标要举行适配,也就是有接洽。选定子弹图片)
  1. package ui;
  2. import java.awt.image.BufferedImage;
  3. /**
  4. * @Title: Fire
  5. * @Author HeYouLong
  6. * @Package ui
  7. * @Date 2024/9/20 上午10:34
  8. * @description:
  9. */
  10. //子弹类
  11. public class Fire {
  12.     BufferedImage image;
  13.     int x;
  14.     int y;
  15.     public Fire(Plane plane) {
  16.         image = GetImg.getImg("fire.png");
  17.         //子弹的坐标
  18.         x=plane.getX()+plane.getImage().getWidth()/2-image.getWidth()/2/2;
  19.         y=plane.getY()-image.getHeight()/2/2;
  20.     }
  21. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表