作者:Mars酱
声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。
转载:欢迎转载,转载前先请联系我!
介绍
清明节的时候写了个 Java 版贪吃蛇游戏 JSnake ------ 基于 Java Swing 开发的经典贪吃蛇游戏,采用观察者模式实现游戏逻辑与 UI 层的解耦,具有现代化的 UI 设计和流畅的游戏体验。
其实已经很多人写过了,不过没事就再写,先看游戏画面
游戏中:

游戏结束:

项目信息
| 项目属性 | 信息 |
|---|---|
| 项目名称 | JSnake 贪吃蛇游戏 |
| 版本 | 1.0-SNAPSHOT |
| 开发语言 | Java 21 |
| 构建工具 | Maven |
| GUI 框架 | Java Swing |
| 作者 | Mars.z |
架构设计
设计理念
本项目采用观察者模式实现游戏逻辑与 UI 层的解耦,核心设计原则:
- 逻辑与渲染分离 :
GameEngine作为纯游戏逻辑层,不依赖任何 UI 组件 - 事件驱动架构 :通过
GameEvent和GameEventListener实现层间通信 - 单一职责原则:每个类专注于单一功能,便于维护和扩展
架构图
scss
┌─────────────────────────────────────────────────────────────────┐
│ UI 层 (Swing) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ GameWindow │ │ TitleBar │ │ ScorePanel │ │
│ │ (主窗口) │ │ (标题栏) │ │ (分数面板) │ │
│ └──────┬───────┘ └──────────────┘ └──────────────────────┘ │
│ │ implements GameEventListener │
│ ▼ │
├─────────────────────────────────────────────────────────────────┤
│ 事件层 (Event Layer) │
│ ┌──────────────────────┐ ┌─────────────────────────────┐ │
│ │ GameEvent (枚举) │ │ GameEventListener (接口) │ │
│ │ - SCORE_UPDATED │ │ - onGameEvent() │ │
│ │ - GAME_OVER │ │ │ │
│ │ - FOOD_EATEN │ │ │ │
│ │ - SNAKE_MOVED │ │ │ │
│ └──────────────────────┘ └─────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 逻辑层 (Logic Layer) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ GameEngine (游戏引擎) │ │
│ │ - 蛇的移动逻辑 │ │
│ │ - 碰撞检测 │ │
│ │ - 食物生成 │ │
│ │ - 游戏状态管理 │ │
│ │ - 事件通知 │ │
│ └──────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 控制层 (Control Layer) │
│ ┌────────────────────────┐ ┌─────────────────────────────┐ │
│ │ ThreadsController │ │ KeyboardListener │ │
│ │ (游戏线程控制器) │ │ (键盘监听器) │ │
│ └────────────────────────┘ └─────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 数据层 (Data Layer) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Tuple │ │ DataOfSquare│ │ ScoreManager │ │
│ │ (坐标元组) │ │ (方块数据) │ │ (分数管理) │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
类关系图
markdown
┌─────────────────┐
│ JSnakeGame │ (主入口)
└────────┬────────┘
│ creates
▼
┌─────────────────┐ implements ┌──────────────────┐
│ GameWindow │─────────────►│ GameEventListener │
└────────┬────────┘ └──────────────────┘
│ ▲
│ creates │ notifies
▼ │
┌─────────────────┐ uses ┌──────────────────┐
│ThreadsController │───────►│ GameEngine │
└─────────────────┘ └────────┬─────────┘
│ creates
▼
┌──────────────────┐
│ GameEvent │
└──────────────────┘
工程项目结构
bash
jsnake/
├── pom.xml # Maven 配置文件
├── README.md # 项目说明文档
├── DESIGN.md # 详细设计文档
├── src/
│ ├── main/java/com/mz/jsnake/
│ │ ├── JSnakeGame.java # 主入口类
│ │ └── core/ # 核心逻辑包
│ │ ├── GameEngine.java # 游戏引擎(纯逻辑层)
│ │ ├── GameEvent.java # 游戏事件枚举
│ │ ├── GameEventListener.java # 游戏事件监听接口
│ │ ├── GameWindow.java # 游戏主窗口
│ │ ├── ThreadsController.java # 游戏线程控制器
│ │ ├── KeyboardListener.java # 键盘监听器
│ │ ├── DataOfSquare.java # 方块数据类
│ │ ├── SquarePanel.java # 方块面板类
│ │ ├── ScoreManager.java # 分数管理器
│ │ ├── ScorePanel.java # 分数面板
│ │ ├── GameOverDialog.java # 游戏结束对话框
│ │ ├── TitleBar.java # 标题栏组件
│ │ ├── ButtonStyleHelper.java # 按钮样式辅助类
│ │ └── Tuple.java # 坐标元组类
│ └── test/java/com/mz/jsnake/ # 测试目录
├── target/ # 构建输出目录
│ ├── classes/ # 编译后的 class 文件
│ └── snake_high_score.dat # 最高分存储文件
└── .idea/ # IntelliJ IDEA 配置
核心模块说明
| 模块 | 文件 | 职责 |
|---|---|---|
| 入口模块 | JSnakeGame | 程序入口,初始化游戏窗口 |
| 游戏引擎 | GameEngine | 纯游戏逻辑处理,包含移动、碰撞检测、食物生成 |
| 事件系统 | GameEvent / GameEventListener | 定义游戏事件,实现层间解耦 |
| 主窗口 | GameWindow | 组装 UI 组件,监听游戏事件 |
| 线程控制 | ThreadsController | 控制游戏循环和渲染更新 |
| 输入处理 | KeyboardListener | 监听键盘输入,传递方向指令 |
| 数据管理 | ScoreManager / Tuple / DataOfSquare | 分数持久化、坐标表示、方块数据 |
| UI 组件 | TitleBar / ScorePanel / GameOverDialog | 标题栏、分数面板、结束对话框 |
功能特性
- 经典玩法:使用方向键控制蛇的移动,吃食物增长
- 边界穿越:蛇到达边界后从对面出现
- 分数系统:实时显示当前分数和历史最高分
- 最高分持久化:游戏关闭后保留历史最高分
- 现代化 UI:无边框窗口设计、深色主题、按钮悬停效果
- 可拖动窗口:点击标题栏区域可拖动窗口
快速开始
环境要求
- JDK 21 或更高版本
- Maven 3.x
技术要点
1. 观察者模式
通过 GameEventListener 接口和 GameEvent 枚举实现事件驱动:
java
// 游戏引擎通知事件
notifyListeners(GameEvent.SCORE_UPDATED, score);
// UI 层响应事件
@Override
public void onGameEvent(GameEvent event, int data) {
switch (event) {
case SCORE_UPDATED:
// 更新分数显示
break;
case GAME_OVER:
// 显示游戏结束对话框
break;
}
}
2. 线程安全
- UI 更新通过
SwingUtilities.invokeLater()在 EDT 中执行 - 游戏逻辑在独立线程中运行
- 使用
volatile关键字保证线程间可见性
3. 数据持久化
使用 Java 序列化将最高分保存到文件:
java
// 保存
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
oos.writeInt(highScore);
}
扩展建议
- 难度级别:添加不同速度设置
- 障碍物系统:在网格中添加障碍物
- 特殊食物:不同颜色食物给予不同分数
- 音效系统:添加吃食物和游戏结束音效
- 皮肤系统:支持更换蛇和食物的颜色/样式
依赖项
本项目仅依赖 Java 标准库,无第三方依赖:
- Java 21+
- Swing (JDK 自带)
- AWT (JDK 自带)
一分钟结束了,下载代码帮我修复bug吧,哈哈哈哈
gitee: