当前位置: 首页 > news >正文

Java Swing贪吃蛇游戏完整实现(MVC架构+MySQL排行榜+音效系统)

## 一、项目简介

这是一个基于 **Java Swing** 开发的经典贪吃蛇游戏,采用 **MVC架构** 设计,支持三种难度选择、MySQL排行榜存储、音效系统和多线程优化。该项目适合Java初学者学习GUI开发、设计模式和数据库操作。

## 二、功能特性

- 🎮 **完整游戏逻辑**:蛇的移动、吃食物、碰撞检测、游戏结束判定
- ⚡ **三种难度选择**:简单(250ms/帧)、中等(150ms/帧)、困难(80ms/帧)
- 🏆 **分数系统**:实时分数显示、本地文件存储最高分
- 📊 **MySQL排行榜**:支持全服排行榜和各难度排行榜
- 🔊 **音效系统**:开始游戏、吃食物、碰撞、游戏结束等音效
- 🎨 **现代化界面**:圆润的蛇设计、苹果食物、渐变背景、半透明遮罩
- ⏸️ **暂停/继续**:支持游戏暂停和继续功能

## 三、技术栈

- **语言**: Java SE 17
- **GUI框架**: Java Swing
- **设计模式**: MVC(Model-View-Controller)
- **数据库**: MySQL 8.0+
- **多线程**: SwingWorker
- **数据结构**: LinkedList

## 四、架构设计

### MVC模式

本项目采用经典的MVC架构模式,将游戏逻辑、界面渲染和用户交互分离:

```
┌─────────────────────────────────────────────────────────┐
│ View │
│ GameWindow + GamePanel │
│ (界面渲染、用户输入、音效播放) │
└───────────────────┬─────────────────────────────────────┘
│ 更新界面
│ 获取输入

┌─────────────────────────────────────────────────────────┐
│ Controller │
│ GameController │
│ (协调模型和视图、处理游戏逻辑) │
└───────────────────┬─────────────────────────────────────┘
│ 更新状态
│ 获取数据

┌─────────────────────────────────────────────────────────┐
│ Model │
│ Snake + food + GameState │
│ (数据模型、业务逻辑、状态管理) │
└─────────────────────────────────────────────────────────┘
```

### 核心类职责

| 类名 | 职责 | 所属层 |
|------|------|--------|
| GameController | 游戏核心逻辑,处理键盘事件 | Controller |
| GameWindow | 主窗口管理,界面切换 | View |
| GamePanel | 游戏画布,渲染蛇和食物 | View |
| Snake | 蛇的数据模型和移动逻辑 | Model |
| food | 食物生成和位置管理 | Model |
| GameState | 游戏状态封装 | Model |
| GameWorker | 后台线程,游戏循环 | Controller |

## 五、核心代码解析

### 1. 游戏主循环(SwingWorker优化)

使用 `SwingWorker` 进行多线程优化,游戏逻辑在后台线程执行,UI更新在事件调度线程执行:

```java
public class GameWorker extends SwingWorker<GameState, GameState> {
private final GameController controller;
private volatile boolean running = true;

@Override
protected GameState doInBackground() throws Exception {
while (running && !isCancelled()) {
if (controller.isGameRunning()) {
controller.update();
publish(new GameState(
controller.getSnake().getBody(),
controller.getFood().getPosition(),
controller.getScore(),
controller.isGameOver()
));
}
Thread.sleep(controller.getDifficulty().getDelay());
}
return null;
}

@Override
protected void process(List<GameState> chunks) {
for (GameState state : chunks) {
controller.getGamePanel().updateState(state);
}
}
}
```

**设计思路**:`doInBackground()` 在后台线程执行游戏逻辑,`process()` 在EDT线程更新UI,避免界面卡顿。

### 2. 蛇的移动逻辑

使用 `LinkedList` 实现蛇身的高效增删操作:

```java
public void move(Direction direction) {
Node head = snakeBody.getFirst();
Node newHead = new Node(
head.getX() + direction.getX(),
head.getY() + direction.getY()
);

snakeBody.addFirst(newHead);

if (isFoodEaten(newHead, food)) {
score += difficulty.getScorePerFood();
food.generateNewPosition(snakeBody);
} else {
snakeBody.removeLast();
}
}
```

**技术亮点**:
- `LinkedList.addFirst()` 和 `removeLast()` 时间复杂度均为 O(1)
- 蛇身增长时只添加头部,不删除尾部
- 正常移动时添加头部并删除尾部

### 3. 碰撞检测

实现蛇与墙壁、蛇与自身的碰撞检测:

```java
public boolean checkCollision() {
Node head = snakeBody.getFirst();

// 边界碰撞
if (head.getX() < 0 || head.getX() >= WIDTH ||
head.getY() < 0 || head.getY() >= HEIGHT) {
return true;
}

// 自身碰撞
for (int i = 1; i < snakeBody.size(); i++) {
Node bodyPart = snakeBody.get(i);
if (head.getX() == bodyPart.getX() &&
head.getY() == bodyPart.getY()) {
return true;
}
}

return false;
}
```

### 4. MySQL数据库操作

使用 `PreparedStatement` 防止SQL注入:

```java
public void saveScore(String playerName, int score, Difficulty difficulty) {
String insertSQL = "INSERT INTO high_scores " +
"(player_name, score, difficulty, date_time) VALUES (?, ?, ?, NOW())";

try (PreparedStatement pstmt = connection.prepareStatement(insertSQL)) {
pstmt.setString(1, playerName);
pstmt.setInt(2, score);
pstmt.setString(3, difficulty.name());
pstmt.executeUpdate();
} catch (SQLException e) {
System.err.println("保存分数失败: " + e.getMessage());
}
}
```

**安全措施**:
- 使用 `PreparedStatement` 预编译语句
- 配置文件读取数据库密码,不硬编码
- `.gitignore` 排除敏感配置文件

### 5. 音效系统

使用 Java Sound API 生成音效:

```java
public void playEatSound() {
try {
AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
SourceDataLine line = AudioSystem.getSourceDataLine(format);
line.open(format);
line.start();

byte[] sound = new byte[44100 / 50];
for (int i = 0; i < sound.length; i++) {
sound[i] = (byte) (Math.sin(i * 440 * 2 * Math.PI / 44100) * 127);
}
line.write(sound, 0, sound.length);
line.stop();
line.close();
} catch (Exception e) {
e.printStackTrace();
}
}
```

## 六、数据库设计

### 表结构

```sql
CREATE TABLE high_scores (
id INT AUTO_INCREMENT PRIMARY KEY,
player_name VARCHAR(50) NOT NULL,
score INT NOT NULL,
difficulty VARCHAR(20) NOT NULL,
date_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```

### 配置方式

创建 `db.properties` 文件:

```properties
db.password=your_mysql_password
```

> **注意**:`db.properties` 文件已加入 `.gitignore`,不会被提交到版本控制。

## 七、运行说明

### 环境要求

- JDK 17+
- MySQL 8.0+(可选,用于排行榜功能)

### 运行方式

**方式一:使用批处理脚本**

```bash
双击 run_game.bat
```

**方式二:手动编译运行**

```bash
javac -encoding UTF-8 -d out/production/snakeGrme src/com/zut/*.java
java -Dfile.encoding=UTF-8 -cp "out/production/snakeGrme;lib/mysql-connector-java-8.3.0.jar" com.zut.main
```

### 操作说明

| 按键 | 功能 |
|------|------|
| ↑ ↓ ← → | 控制蛇的移动方向 |
| P | 暂停 / 继续游戏 |
| R | 游戏结束后重新开始 |
| ← 返回按钮 | 返回主菜单 |

http://www.jsqmd.com/news/1131742/

相关文章:

  • 大模型:MessagesPlaceholder 是什么?
  • 3种CNN架构对比:从零搭建、VGG16迁移学习与ResNet50在猫狗识别上的性能实测
  • 如何用15分钟完成传统需要3小时的Hackintosh配置?OpCore-Simplify的智能革命
  • 【OpenHarmony/HarmonyOs 】单位换算引擎实战:长度、面积、体积、温度、速度的端侧计算方案
  • YOLOv3 与 RealSense D435i 协同:600张图像训练,实现多目标无序抓取位姿估计
  • Gensim 4.3.3 Word2Vec 参数调优实战:5个关键参数对藏文词向量质量的影响
  • 从Wafer到Chip:图解芯片制造5大核心工艺与10个关键测试节点
  • AIPCowork运维实战:从微信告警到中间件巡检,一句话就够了
  • 基于51单片机智能手势识别系统 PAG7620 9种手势成品21(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • APKMirror客户端开发实战:构建安全高效的安卓应用下载平台
  • Devicetree Specification v0.4 核心属性实战:5分钟掌握 reg、interrupts 与 ranges 配置
  • 2026最新8款AI编程工具学生党平替实测合集
  • 3 种朴素贝叶斯变体对比:高斯 vs 多项式 vs 伯努利,sklearn 实战 5 分钟
  • 2026年纸托包装如何选?看烘干房产能和模具设计避坑
  • 【OpenHarmony/HarmonyOs 】限时答题状态机实践:倒计时、暂停、自动提交与实况窗结束态设计
  • 基于multisim的RC有源滤波器的设计
  • 2026年电销机器人值不值得用?从成本、效果到选型的完整拆解
  • QGC V5.0 gstreamer视频流在安卓端画面卡顿、冻结,硬件解码失败的问题解决方案
  • ClaudeCode本地源码编译、调试、自定义接入大模型实操案例
  • LLaMA 2 / ChatGLM 等5款大模型位置编码对比:RoPE vs 绝对 vs 相对
  • 华为matepad pro运行jupyter
  • 【claude code实践】CLAUDE.md 应该写什么:命令、规范、架构与禁区
  • 2026最新7款AI编程工具学生党平替实测
  • 2026最新8款AI编程助手平替实测 覆盖全场景选型参考
  • 【claude code实践】CLAUDE.md 入门:给 AI 写一份项目说明书
  • 数据视图学习笔记
  • 支持Skill的国内最强AI视频生成工具是谁?Seedance 2.5 全球首发前完整拆解
  • 从零掌握Locust性能测试:Python代码化压测与分布式实战
  • 【OpenHarmony/HarmonyOs 】数学学习报告页:本地统计卡片、正确率与隐私友好学习画像
  • Snowflake OA亲测:两道题20分钟交卷,全靠提前刷过原题