news 2026/4/3 5:13:55

基于Java Swing的打砖块小游戏(2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Java Swing的打砖块小游戏(2)

1、演示视频

基于Java Swing的打砖块小游戏

2、项目截图

设计说明

3.1 整体架构设计

项目采用分层设计+面向对象封装的架构,主要分为以下几个部分:

  1. 界面层(UI层):由<代码开始>BreakoutGame<代码结束>类中的<代码开始>initUI()<代码结束>方法实现,负责创建游戏窗口、布局管理、组件初始化、事件绑定等。
  2. 游戏逻辑层:由<代码开始>updateGame()<代码结束>、<代码开始>checkCollisions()<代码结束>、<代码开始>checkGameStatus()<代码结束>等方法实现,负责处理游戏元素的运动、碰撞检测、状态判断等核心逻辑。
  3. 数据模型层:由<代码开始>Paddle<代码结束>(挡板)、<代码开始>Ball<代码结束>(小球)、<代码开始>Brick<代码结束>(砖块)三个内部类实现,封装了游戏元素的属性和行为。
  4. 渲染层:由<代码开始>GamePanel<代码结束>内部类的<代码开始>paintComponent()<代码结束>方法实现,负责绘制游戏元素和状态提示。

3.2 类结构设计

类名类型作用
BreakoutGame主类(继承JFrame)游戏入口,负责初始化界面、管理游戏状态、处理核心逻辑
GamePanel内部类(继承JPanel)游戏显示区的面板,负责绘制游戏元素和胜负提示
Paddle内部类封装挡板的属性(位置、尺寸、速度)和行为(移动)
Ball内部类封装小球的属性(位置、尺寸、速度)和行为(移动、反弹、加速)
Brick内部类封装砖块的属性(位置、尺寸)和状态(是否被消除)

3.3 布局设计

游戏窗口采用<代码开始>BorderLayout<代码结束>布局,分为两个区域:

  • CENTER区域:游戏显示区(<代码开始>GamePanel<代码结束>),尺寸为800×600像素,负责绘制游戏元素。
  • SOUTH区域:底部信息区(<代码开始>JPanel<代码结束>),高度为150像素,包含:
    • 提示文本域(<代码开始>JTextArea<代码结束>):支持自动换行,显示游戏规则、状态提示
    • 重新开始按钮(<代码开始>JButton<代码结束>):游戏胜利/失败时显示,点击后重置游戏

3.4 核心数据设计

项目中定义了大量常量来管理游戏的固定参数,便于统一修改和维护,主要常量分类如下:

  • 窗口常量:游戏显示区的宽度、高度,底部信息区的高度
  • 元素常量:挡板、小球、砖块的尺寸、速度、数量、间距
  • 游戏常量:刷新频率、小球最大速度、速度增量
  • 字体常量:统一管理界面中使用的字体样式和大小,解决中文乱码问题

四、算法说明

4.1 小球运动算法

小球的运动采用匀速直线运动模型,通过速度变量控制移动方向和距离,具体逻辑:

  1. 初始化:小球的初始速度由<代码开始>BALL_INIT_X_SPEED<代码结束>(X轴)和<代码开始>BALL_INIT_Y_SPEED<代码结束>(Y轴)定义,正数表示向右/向下,负数表示向左/向上。
  2. 移动:每次刷新时,小球的X坐标增加X轴速度,Y坐标增加Y轴速度(<代码开始>ball.move()<代码结束>方法)。
  3. 反弹:小球碰到边界、挡板、砖块后,反转对应轴的速度(如碰到左右边界反转X轴速度,碰到上下边界/挡板/砖块反转Y轴速度)。
  4. 加速:每消除1/3的砖块,小球的X轴和Y轴速度绝对值增加(<代码开始>increaseBallSpeed()<代码结束>方法),但不超过最大速度限制。

4.2 碰撞检测算法

项目采用矩形相交检测法(<代码开始>java.awt.Rectangle<代码结束>的<代码开始>intersects()<代码结束>方法)来检测碰撞,核心逻辑如下:

4.2.1 小球与边界的碰撞检测
// 小球与左右边界碰撞 if (ball.getX() <= 0 || ball.getX() + ball.getWidth() >= WIDTH) { ball.reverseXDirection(); // 反转X轴速度 ball.setX(Math.max(0, Math.min(ball.getX(), WIDTH - ball.getWidth()))); // 限制位置 } // 小球与上边界碰撞 if (ball.getY() <= 0) { ball.reverseYDirection(); // 反转Y轴速度 ball.setY(Math.max(0, ball.getY())); // 限制位置 } // 小球与下边界碰撞(游戏失败) if (ball.getY() + ball.getHeight() >= HEIGHT) { isGameOver = true; // 标记游戏失败 }
4.2.2 小球与挡板的碰撞检测

检测小球的边界矩形与挡板的边界矩形是否相交,若相交则处理反弹逻辑,并根据小球与挡板中心的偏移量调整小球的X轴速度,实现角度反弹效果:

if (ballBounds.intersects(paddleBounds)) { if (ball.getYSpeed() > 0 && ball.getY() + ball.getHeight() <= paddleBounds.getY() + paddleBounds.getHeight() / 2) { ball.reverseYDirection(); // 反转Y轴速度 // 计算偏移量,调整X轴速度 int ballCenter = ball.getX() + ball.getWidth() / 2; int paddleCenter = paddle.getX() + paddleBounds.getWidth() / 2; int offset = ballCenter - paddleCenter; int newXSpeed = Math.max(-BALL_MAX_SPEED, Math.min(offset / 5, BALL_MAX_SPEED)); ball.setxSpeed(newXSpeed != 0 ? newXSpeed : BALL_INIT_X_SPEED); } ball.setY(paddleBounds.getY() - ball.getHeight() - 1); // 防止小球陷入挡板 }
4.2.3 小球与砖块的碰撞检测

遍历砖块列表,检测小球与每个未被消除的砖块的边界矩形是否相交,若相交则标记砖块为已消除、移除砖块、反转小球Y轴速度,并触发小球加速逻辑:

Iterator brickIterator = bricks.iterator(); while (brickIterator.hasNext()) { Brick brick = brickIterator.next(); if (!brick.isBroken() && ballBounds.intersects(brick.getBounds())) { brick.setBroken(true); // 标记砖块已消除 brickIterator.remove(); // 移除砖块 ball.reverseYDirection(); // 反转Y轴速度 increaseBallSpeed(); // 小球加速 break; // 一次只处理一个砖块的碰撞 } }

4.3 游戏状态判断算法

游戏状态分为未开始、游戏中、胜利、失败四种,通过布尔变量标记,判断逻辑如下:

  • 未开始:isGameStart = false,初始状态,按下空格键后变为true。
  • 游戏中:isGameStart = trueisGameOver = falseisGameWin = false
  • 失败:isGameOver = true,小球碰到下边界时触发。
  • 胜利:isGameWin = true,砖块列表为空(所有砖块被消除)时触发。

五、测试说明

5.1 测试环境

  • 硬件环境:Intel Core i5及以上处理器,4GB及以上内存
  • 软件环境:Windows 10/11、Java 8/11/17、IntelliJ IDEA 2023

5.2 测试用例

测试用例ID测试内容测试步骤预期结果测试结果
TC001游戏启动运行主类,观察窗口是否正常显示窗口正常显示,底部信息区显示游戏规则和启动提示通过
TC002启动游戏按下空格键,观察小球是否开始运动小球开始按照初始速度运动,底部信息区显示“游戏中”提示通过
TC003挡板控制按下左/右方向键,观察挡板是否移动挡板随方向键左右移动,且不会超出窗口边界通过
TC004小球边界反弹观察小球碰到左右、上边界时的行为小球碰到边界后反弹,方向正确通过
TC005小球挡板碰撞控制挡板接住小球,观察碰撞后的行为小球反弹,且根据碰撞位置调整X轴速度通过
TC006砖块消除小球碰到砖块,观察砖块是否消失砖块被消除,从界面中消失通过
TC007小球加速消除1/3、2/3砖块时,观察小球速度小球速度依次增加,不超过最大速度通过
TC008游戏失败让小球碰到下边界,观察游戏状态游戏停止,显示失败提示,出现重新开始按钮通过
TC009游戏胜利消除所有砖块,观察游戏状态游戏停止,显示胜利提示,出现重新开始按钮通过
TC010重新开始游戏点击重新开始按钮或按空格键,观察游戏状态游戏重置为初始状态,可重新启动通过

5.3 测试总结

所有测试用例均通过,游戏的核心功能(界面展示、用户交互、碰撞检测、状态管理)均能正常工作,无明显bug。游戏运行流畅,界面响应及时,用户体验良好。

六、关键代码

6.1 游戏主类初始化代码

主类的构造方法,负责初始化界面、游戏元素和启动游戏循环:

/** * 构造方法:初始化游戏窗口和核心组件 * 执行流程:初始化界面 -> 初始化游戏元素 -> 启动游戏定时器 */ public BreakoutGame() { // 窗口尺寸校验(防止传入无效的尺寸值) if (WIDTH <= 0 || HEIGHT <= 0) { throw new IllegalArgumentException("窗口尺寸不能为负数或零"); } // 初始化游戏界面组件 initUI(); // 初始化游戏核心元素(挡板、小球、砖块) initGame(); // 启动游戏定时器(开始游戏循环) startGameLoop(); }

6.2 碰撞检测核心代码

处理小球与挡板、砖块的碰撞逻辑,是游戏的核心算法之一:

/** * 碰撞检测 * 功能:检测小球与挡板、砖块的碰撞,并处理碰撞后的逻辑(反弹、消除砖块、加速小球) */ private void checkCollisions() { // 获取小球的边界矩形(用于碰撞检测) Rectangle ballBounds = ball.getBounds(); // 获取挡板的边界矩形(用于碰撞检测) Rectangle paddleBounds = paddle.getBounds(); // ========== 小球与挡板碰撞检测与处理 ========== if (ballBounds.intersects(paddleBounds)) { // 仅处理小球向下运动时的碰撞(避免多次反弹) if (ball.getYSpeed() > 0 && ball.getY() + ball.getHeight() <= paddleBounds.getY() + paddleBounds.getHeight() / 2) { // 反转Y轴速度(小球向上反弹) ball.reverseYDirection(); // 计算小球与挡板中心的偏移量(用于调整小球X轴速度,实现角度反弹) int ballCenter = ball.getX() + ball.getWidth() / 2; int paddleCenter = paddle.getX() + paddleBounds.getWidth() / 2; int offset = ballCenter - paddleCenter; // 计算新的X轴速度(限制在最大速度范围内) int newXSpeed = Math.max(-BALL_MAX_SPEED, Math.min(offset / 5, BALL_MAX_SPEED)); // 设置小球X轴速度(如果速度为0,使用初始速度,避免小球垂直运动) ball.setxSpeed(newXSpeed != 0 ? newXSpeed : BALL_INIT_X_SPEED); } // 调整小球位置,防止小球陷入挡板内部 ball.setY(paddleBounds.getY() - ball.getHeight() - 1); } // ========== 小球与砖块碰撞检测与处理 ========== // 使用迭代器遍历砖块列表(支持遍历过程中删除元素) Iterator brickIterator = bricks.iterator(); while (brickIterator.hasNext()) { Brick brick = brickIterator.next(); // 仅检测未被消除的砖块与小球的碰撞 if (!brick.isBroken() && ballBounds.intersects(brick.getBounds())) { // 标记砖块为已消除 brick.setBroken(true); // 从列表中移除已消除的砖块 brickIterator.remove(); // 反转小球Y轴速度(反弹) ball.reverseYDirection(); // 增加小球速度(每消除1/3砖块时加速一次) increaseBallSpeed(); // 跳出循环(一次只处理一个砖块的碰撞,避免多次碰撞导致速度异常) break; } } }

6.3 游戏面板绘制代码

负责绘制游戏元素和胜负提示,是界面渲染的核心代码:

/** * 游戏面板内部类 * 功能:负责绘制游戏元素(挡板、小球、砖块)和胜负提示 */ private class GamePanel extends JPanel { /** * 重绘方法:绘制游戏界面 * @param g 绘图上下文对象(用于绘制图形) */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 调用父类方法,绘制背景 // 转换为2D绘图上下文(支持更丰富的绘图功能) Graphics2D g2d = (Graphics2D) g; // 开启抗锯齿(让绘制的图形更平滑) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // ========== 仅在游戏已开始时,绘制游戏元素 ========== if (isGameStart) { // 绘制挡板:蓝色矩形 g2d.setColor(Color.BLUE); g2d.fillRect(paddle.getX(), paddle.getY(), paddle.getWidth(), paddle.getHeight()); // 绘制小球:红色圆形(通过填充椭圆实现) g2d.setColor(Color.RED); g2d.fillOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight()); // 绘制砖块:遍历砖块列表,绘制未被消除的砖块(绿色矩形,黑色边框) for (Brick brick : bricks) { if (!brick.isBroken()) { g2d.setColor(Color.GREEN); g2d.fillRect(brick.getX(), brick.getY(), brick.getWidth(), brick.getHeight()); g2d.setColor(Color.BLACK); g2d.drawRect(brick.getX(), brick.getY(), brick.getWidth(), brick.getHeight()); } } // ========== 绘制胜负提示(视觉强化) ========== g2d.setFont(FONT_BOLD_LARGE); // 设置提示字体 if (isGameOver) { // 游戏失败:红色文字显示“游戏结束!”(水平居中) g2d.setColor(Color.RED); g2d.drawString("游戏结束!", WIDTH / 2 - 100, HEIGHT / 2); } else if (isGameWin) { // 游戏胜利:绿色文字显示“恭喜胜利!”(水平居中) g2d.setColor(Color.GREEN); g2d.drawString("恭喜胜利!", WIDTH / 2 - 100, HEIGHT / 2); } } // 游戏未开始时,游戏面板为空(所有提示在底部) } /** * 重写首选尺寸方法:确保游戏面板占满指定的游戏区域 * @return 游戏面板的首选尺寸(宽度WIDTH,高度HEIGHT) */ @Override public Dimension getPreferredSize() { return new Dimension(WIDTH, HEIGHT); } }

6.4 小球加速代码

实现小球的加速逻辑,提升游戏难度:

/** * 增加小球速度 * 功能:每消除1/3的砖块,小球速度增加一次(限制在最大速度范围内) */ private void increaseBallSpeed() { // 获取当前剩余砖块数量 int currentBrickCount = bricks.size(); // 计算已消除的砖块数量是否达到1/3的阈值(brickCount / 3为每次加速的阈值) if (brickCount / 3 > 0 && (brickCount - currentBrickCount) % (brickCount / 3) == 0 && ball.getSpeed() < BALL_MAX_SPEED) { // 增加小球速度(X轴和Y轴速度都增加) ball.increaseSpeed(BALL_SPEED_INCREMENT); } }

七、扩展建议

为了丰富游戏功能和提升用户体验,可对项目进行以下扩展:

  • 添加计分系统:记录玩家消除砖块的数量,显示得分
  • 添加关卡系统:设置不同的砖块布局和小球速度,实现多关卡游戏
  • 添加音效:碰撞、消除砖块、胜利/失败时播放音效
  • 添加皮肤系统:支持更换挡板、小球、砖块的颜色和样式
  • 添加暂停功能:支持暂停和继续游戏
  • 优化碰撞检测:采用更精确的像素碰撞检测,替代矩形相交检测
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/30 9:54:46

【30天从零学Python】重要补充四、检测有向环 - Kahn算法

30天从零学Python 通信工程专业科班生&#xff0c;用了几十年MATLAB&#xff0c;为了过大厂机考&#xff0c;不得不自学Python。 文章目录30天从零学Python重要补充四、检测有向环 - Kahn算法1. 有向环与拓扑排序1.1 Kahn 算法核心原理&#xff08;通俗版&#xff09;1.2 Kahn…

作者头像 李华
网站建设 2026/3/31 17:43:25

Flutter工程化实战:从单人开发到团队协作的规范与效率指南

Flutter工程化实战&#xff1a;从单人开发到团队协作的规范与效率指南 欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。 当Flutter项目从“单人小demo”升级为“多人协作的中大型项目”时&#xff0c;单纯依靠“编码能力”已无法保障项目质量—…

作者头像 李华
网站建设 2026/4/1 7:47:12

Flutter 与其他跨平台框架的核心差异分析

欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。### Flutter 框架对比分析&#xff1a;技术视角与代码案例 Flutter 与其他跨平台框架的核心差异分析 架构层面的根本区别 Flutter 采用独特的自渲染架构&#xff0c;其核心由以下组件构成&…

作者头像 李华
网站建设 2026/4/1 21:27:09

管理Linux的联网

1.NM&#xff08;管理网络的软件&#xff09;NM的特点NM能管理各种网络&#xff1a;有线网卡、无线网卡 动态ip、静态ip 以太网、非以太网 物理网卡、虚拟网卡工具齐全&#xff1a;命令行、文本界面、图形界面、web广纳天地&#xff1a;管理各种网络&#xff0c;有线、无线、物…

作者头像 李华