news 2026/2/11 6:10:32

基于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/2/1 18:43:13

电科金仓数据库如何支持Oracle风格的PL/SQL操作

引言 在数据库国产化替代的浪潮中,企业面临的最大挑战之一就是如何平滑迁移现有的Oracle应用系统。KingbaseES(简称KES)作为国产数据库的代表产品,通过深度的Oracle兼容性设计,特别是在PL/SQL操作层面的全面支持,为企业提供了一条低成本、低风险的迁移路径。本文将详细介绍Kin…

作者头像 李华
网站建设 2026/2/6 20:42:37

全员 RTO5 政策,TikTok 开卷?

TikTok 开卷&#xff1f; TikTok 虽然和抖音性质类似&#xff0c;母公司也都是字节跳动。 但两者的工作节奏&#xff0c;其实差异挺大&#xff0c;毕竟 TikTok 的主要办公地点&#xff0c;是在美国洛杉矶或新加坡。 一些海外 IT 公司常见的福利待遇&#xff0c;TikTok 还是享受…

作者头像 李华
网站建设 2026/2/10 20:02:54

JSP如何结合AES加密实现大文件上传存储?

文件管理系统毕业设计&#xff1a;从零到崩溃的全过程 1. 我的毕业设计困境 "卧槽&#xff0c;这毕业设计是要我命啊&#xff01;"当我看到老师给出的文件管理系统需求时&#xff0c;差点把刚买的珍珠奶茶喷出来。 10G大文件上传&#xff1f;断点续传&#xff1f;…

作者头像 李华
网站建设 2026/2/10 9:55:16

毕业设计项目 基于机器视觉的目标跟踪算法

文章目录 0 前言2 目标跟踪效果3 目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 今天学长向大家分享一个毕业设计项目 为了大家能够顺利以及最少的精力通过毕设&…

作者头像 李华
网站建设 2026/2/7 17:38:31

【大模型预训练】15-分布式训练概述:解决单机算力瓶颈的核心技术路径

引言分布式训练是现代深度学习中解决单机算力瓶颈的核心技术路径之一。随着深度学习模型的复杂性和数据量的急剧增加&#xff0c;传统的单机训练方式已难以满足高效计算的需求。分布式训练通过将计算任务分配到多个计算节点上&#xff0c;协同完成模型的训练过程&#xff0c;从…

作者头像 李华
网站建设 2026/2/9 18:46:23

重构智慧书-第10条:名声与好运

一、原文呈现名声与好运一个经久不衰&#xff0c;一个流转不定。前者常跚跚来迟&#xff0c;后者可助人乐生。好运须防他人嫉妒;名声须防湮没无闻。你可以诚心求好运有时亦可努力促成之;然一切名声无不以持之以恒的苦干为本。求名的愿望植根于力量与旺盛的精力。从古到今&#…

作者头像 李华