Add 经典贪吃蛇游戏 - Pygame 实现的精美贪吃蛇小游戏
This commit is contained in:
+225
@@ -0,0 +1,225 @@
|
|||||||
|
# 🐍 Python 经典贪吃蛇游戏
|
||||||
|
|
||||||
|
一个使用 Python 和 Pygame 开发的经典贪吃蛇游戏,画面精美,操作简单有趣!
|
||||||
|
|
||||||
|
## ✨ 游戏特性
|
||||||
|
|
||||||
|
### 🎮 核心玩法
|
||||||
|
- **经典规则** - 控制蛇移动,吃到食物变长
|
||||||
|
- **渐进难度** - 每吃 5 个食物速度加快
|
||||||
|
- **精美画面** - 现代化 UI 设计,蛇有眼睛动画
|
||||||
|
- **流畅操作** - 支持方向键和 WASD 双控制方案
|
||||||
|
|
||||||
|
### 🎨 视觉效果
|
||||||
|
- 深蓝色背景 + 网格线
|
||||||
|
- 绿色蛇身,带眼睛动画
|
||||||
|
- 红色圆形食物,带高光和阴影
|
||||||
|
- 半透明游戏结束/暂停界面
|
||||||
|
- 实时分数和速度显示
|
||||||
|
|
||||||
|
### 🎯 游戏功能
|
||||||
|
- 暂停/继续功能(P 键)
|
||||||
|
- 游戏结束后快速重开(空格键)
|
||||||
|
- 优雅退出(ESC 键)
|
||||||
|
- 碰撞检测(墙壁和自己)
|
||||||
|
- 速度系统(10-25 FPS)
|
||||||
|
|
||||||
|
## 📦 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r game_requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
或者单独安装:
|
||||||
|
```bash
|
||||||
|
pip install pygame>=2.5.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 方法 1:运行启动文件
|
||||||
|
```bash
|
||||||
|
python play_game.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方法 2:直接运行游戏
|
||||||
|
```bash
|
||||||
|
python snake_game.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎮 游戏操作
|
||||||
|
|
||||||
|
| 按键 | 功能 |
|
||||||
|
|------|------|
|
||||||
|
| ↑ / W | 向上移动 |
|
||||||
|
| ↓ / S | 向下移动 |
|
||||||
|
| ← / A | 向左移动 |
|
||||||
|
| → / D | 向右移动 |
|
||||||
|
| P | 暂停/继续游戏 |
|
||||||
|
| 空格 | 游戏结束后重新开始 |
|
||||||
|
| ESC | 退出游戏 |
|
||||||
|
|
||||||
|
## 📖 游戏规则
|
||||||
|
|
||||||
|
1. **目标** - 控制蛇吃到尽可能多的食物
|
||||||
|
2. **得分** - 每个食物 = 10 分
|
||||||
|
3. **加速** - 每吃 5 个食物(50 分),速度提升 2 档
|
||||||
|
4. **失败条件**:
|
||||||
|
- 蛇头撞到墙壁
|
||||||
|
- 蛇头撞到自己的身体
|
||||||
|
5. **最大速度** - 25 FPS(初始速度 10 FPS)
|
||||||
|
|
||||||
|
## 🏆 技巧提示
|
||||||
|
|
||||||
|
### 新手技巧
|
||||||
|
- 开始时速度较慢,熟悉操作
|
||||||
|
- 提前规划路线,不要急转弯
|
||||||
|
- 尽量保持在屏幕中央活动
|
||||||
|
|
||||||
|
### 进阶技巧
|
||||||
|
- 利用墙壁反弹改变方向
|
||||||
|
- 预留足够的转弯空间
|
||||||
|
- 高速时小幅调整方向
|
||||||
|
- 观察蛇头眼睛判断方向
|
||||||
|
|
||||||
|
### 高分策略
|
||||||
|
- 采用"之"字形路线清理食物
|
||||||
|
- 避免把自己逼入死角
|
||||||
|
- 保持蛇身紧凑,留出空间
|
||||||
|
- 后期以生存为主,不要贪心
|
||||||
|
|
||||||
|
## 🎨 游戏画面
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────┐
|
||||||
|
│ Score: 120 Speed: 14 │
|
||||||
|
├────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ●●●●● (蛇) │
|
||||||
|
│ ● │
|
||||||
|
│ ● │
|
||||||
|
│ ●●●● │
|
||||||
|
│ ● │
|
||||||
|
│ ● 🍎 (食物) │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 自定义配置
|
||||||
|
|
||||||
|
### 修改窗口大小
|
||||||
|
编辑 `snake_game.py` 中的初始化参数:
|
||||||
|
```python
|
||||||
|
game = SnakeGame(width=1000, height=800, cell_size=25)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 修改颜色
|
||||||
|
编辑 `snake_game.py` 中的颜色字典:
|
||||||
|
```python
|
||||||
|
self.colors = {
|
||||||
|
'background': (15, 23, 42), # 背景色
|
||||||
|
'snake_head': (34, 197, 94), # 蛇头颜色
|
||||||
|
'snake_body': (22, 163, 74), # 蛇身颜色
|
||||||
|
'food': (239, 68, 68), # 食物颜色
|
||||||
|
# ... 更多颜色
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 修改初始速度
|
||||||
|
```python
|
||||||
|
self.speed = 15 # 改为 15 FPS
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 常见问题
|
||||||
|
|
||||||
|
### Q: 游戏窗口打不开?
|
||||||
|
A: 确保已安装 Pygame:`pip install pygame`
|
||||||
|
|
||||||
|
### Q: 按键没反应?
|
||||||
|
A: 确保游戏窗口处于焦点状态,点击窗口后再操作
|
||||||
|
|
||||||
|
### Q: 游戏太慢/太快?
|
||||||
|
A: 修改 `self.speed = 10` 调整初始速度
|
||||||
|
|
||||||
|
### Q: 想要更大/更小的蛇?
|
||||||
|
A: 修改 `cell_size = 20` 调整格子大小
|
||||||
|
|
||||||
|
## 🎯 扩展计划
|
||||||
|
|
||||||
|
- [ ] 添加音效和背景音乐
|
||||||
|
- [ ] 多种难度选择
|
||||||
|
- [ ] 排行榜系统
|
||||||
|
- [ ] 多种蛇皮肤
|
||||||
|
- [ ] 双人模式
|
||||||
|
- [ ] 特殊道具(加速、减速、穿墙)
|
||||||
|
- [ ] 地图编辑器
|
||||||
|
- [ ] 录像回放功能
|
||||||
|
|
||||||
|
## 💻 技术实现
|
||||||
|
|
||||||
|
### 核心技术
|
||||||
|
- **Pygame** - 游戏引擎和渲染
|
||||||
|
- **网格系统** - 基于网格的移动和碰撞检测
|
||||||
|
- **队列数据结构** - 蛇身管理
|
||||||
|
- **事件驱动** - 键盘输入处理
|
||||||
|
|
||||||
|
### 性能优化
|
||||||
|
- 只重绘变化的部分
|
||||||
|
- 使用矩形碰撞检测
|
||||||
|
- 帧率控制保证流畅性
|
||||||
|
|
||||||
|
### 代码结构
|
||||||
|
```
|
||||||
|
SnakeGame
|
||||||
|
├── __init__() # 初始化
|
||||||
|
├── reset_game() # 重置游戏
|
||||||
|
├── _generate_food() # 生成食物
|
||||||
|
├── _handle_events() # 处理事件
|
||||||
|
├── _update() # 更新状态
|
||||||
|
├── _check_collision() # 碰撞检测
|
||||||
|
├── _draw_grid() # 绘制网格
|
||||||
|
├── _draw_snake() # 绘制蛇
|
||||||
|
├── _draw_food() # 绘制食物
|
||||||
|
├── _draw_score() # 绘制分数
|
||||||
|
├── _draw_game_over() # 游戏结束画面
|
||||||
|
├── _draw_paused() # 暂停画面
|
||||||
|
├── draw() # 总绘制
|
||||||
|
└── run() # 主循环
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 版本历史
|
||||||
|
|
||||||
|
### v1.0.0
|
||||||
|
- ✅ 基础游戏功能
|
||||||
|
- ✅ 精美 UI 界面
|
||||||
|
- ✅ 蛇眼睛动画
|
||||||
|
- ✅ 暂停/继续功能
|
||||||
|
- ✅ 速度系统
|
||||||
|
- ✅ 碰撞检测
|
||||||
|
|
||||||
|
## 🎓 学习价值
|
||||||
|
|
||||||
|
通过这个游戏可以学习:
|
||||||
|
- Pygame 基础使用
|
||||||
|
- 游戏循环设计
|
||||||
|
- 碰撞检测算法
|
||||||
|
- 事件处理机制
|
||||||
|
- 面向对象编程
|
||||||
|
- 动画原理
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## 🎉 开始游戏
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装依赖
|
||||||
|
pip install -r game_requirements.txt
|
||||||
|
|
||||||
|
# 运行游戏
|
||||||
|
python play_game.py
|
||||||
|
```
|
||||||
|
|
||||||
|
祝你玩得开心!🐍🎮
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pygame>=2.5.0
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
"""
|
||||||
|
Python 小游戏合集
|
||||||
|
贪吃蛇游戏启动文件
|
||||||
|
"""
|
||||||
|
|
||||||
|
from snake_game import main
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+382
@@ -0,0 +1,382 @@
|
|||||||
|
"""
|
||||||
|
经典贪吃蛇游戏
|
||||||
|
使用方向键控制蛇的移动,吃到食物后蛇会变长
|
||||||
|
撞墙或撞到自己则游戏结束
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Tuple, List
|
||||||
|
|
||||||
|
|
||||||
|
class Direction(Enum):
|
||||||
|
"""方向枚举"""
|
||||||
|
UP = (0, -1)
|
||||||
|
DOWN = (0, 1)
|
||||||
|
LEFT = (-1, 0)
|
||||||
|
RIGHT = (1, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class SnakeGame:
|
||||||
|
"""贪吃蛇游戏类"""
|
||||||
|
|
||||||
|
def __init__(self, width: int = 800, height: int = 600, cell_size: int = 20):
|
||||||
|
"""
|
||||||
|
初始化游戏
|
||||||
|
|
||||||
|
Args:
|
||||||
|
width: 游戏窗口宽度
|
||||||
|
height: 游戏窗口高度
|
||||||
|
cell_size: 每个格子的大小
|
||||||
|
"""
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.cell_size = cell_size
|
||||||
|
|
||||||
|
# 计算网格数量
|
||||||
|
self.grid_width = width // cell_size
|
||||||
|
self.grid_height = height // cell_size
|
||||||
|
|
||||||
|
# 初始化 Pygame
|
||||||
|
pygame.init()
|
||||||
|
self.screen = pygame.display.set_mode((width, height))
|
||||||
|
pygame.display.set_caption("🐍 经典贪吃蛇")
|
||||||
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
# 字体
|
||||||
|
self.font_large = pygame.font.Font(None, 74)
|
||||||
|
self.font_medium = pygame.font.Font(None, 48)
|
||||||
|
self.font_small = pygame.font.Font(None, 36)
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
self.colors = {
|
||||||
|
'background': (15, 23, 42), # 深蓝色背景
|
||||||
|
'snake_head': (34, 197, 94), # 绿色蛇头
|
||||||
|
'snake_body': (22, 163, 74), # 深绿色蛇身
|
||||||
|
'food': (239, 68, 68), # 红色食物
|
||||||
|
'grid': (30, 41, 59), # 网格线
|
||||||
|
'text': (255, 255, 255), # 白色文字
|
||||||
|
'score_bg': (51, 65, 85) # 分数背景
|
||||||
|
}
|
||||||
|
|
||||||
|
# 游戏状态
|
||||||
|
self.reset_game()
|
||||||
|
|
||||||
|
def reset_game(self):
|
||||||
|
"""重置游戏状态"""
|
||||||
|
# 蛇的初始位置(中心)
|
||||||
|
start_x = self.grid_width // 2
|
||||||
|
start_y = self.grid_height // 2
|
||||||
|
|
||||||
|
self.snake: List[Tuple[int, int]] = [
|
||||||
|
(start_x, start_y),
|
||||||
|
(start_x - 1, start_y),
|
||||||
|
(start_x - 2, start_y)
|
||||||
|
]
|
||||||
|
|
||||||
|
# 初始方向(向右)
|
||||||
|
self.direction = Direction.RIGHT
|
||||||
|
self.next_direction = Direction.RIGHT
|
||||||
|
|
||||||
|
# 生成第一个食物
|
||||||
|
self.food = self._generate_food()
|
||||||
|
|
||||||
|
# 游戏状态
|
||||||
|
self.score = 0
|
||||||
|
self.game_over = False
|
||||||
|
self.paused = False
|
||||||
|
self.speed = 10 # 初始速度(FPS)
|
||||||
|
|
||||||
|
def _generate_food(self) -> Tuple[int, int]:
|
||||||
|
"""
|
||||||
|
生成食物位置
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
食物的坐标 (x, y)
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
food_pos = (
|
||||||
|
random.randint(0, self.grid_width - 1),
|
||||||
|
random.randint(0, self.grid_height - 1)
|
||||||
|
)
|
||||||
|
# 确保食物不会生成在蛇身上
|
||||||
|
if food_pos not in self.snake:
|
||||||
|
return food_pos
|
||||||
|
|
||||||
|
def _handle_events(self):
|
||||||
|
"""处理事件"""
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if event.type == pygame.KEYDOWN:
|
||||||
|
if self.game_over:
|
||||||
|
if event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
|
||||||
|
self.reset_game()
|
||||||
|
elif event.key == pygame.K_ESCAPE:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# 暂停功能
|
||||||
|
if event.key == pygame.K_p:
|
||||||
|
self.paused = not self.paused
|
||||||
|
|
||||||
|
# 方向控制
|
||||||
|
if event.key in [pygame.K_UP, pygame.K_w]:
|
||||||
|
if self.direction != Direction.DOWN:
|
||||||
|
self.next_direction = Direction.UP
|
||||||
|
elif event.key in [pygame.K_DOWN, pygame.K_s]:
|
||||||
|
if self.direction != Direction.UP:
|
||||||
|
self.next_direction = Direction.DOWN
|
||||||
|
elif event.key in [pygame.K_LEFT, pygame.K_a]:
|
||||||
|
if self.direction != Direction.RIGHT:
|
||||||
|
self.next_direction = Direction.LEFT
|
||||||
|
elif event.key in [pygame.K_RIGHT, pygame.K_d]:
|
||||||
|
if self.direction != Direction.LEFT:
|
||||||
|
self.next_direction = Direction.RIGHT
|
||||||
|
elif event.key == pygame.K_ESCAPE:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
|
"""更新游戏状态"""
|
||||||
|
if self.game_over or self.paused:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 更新方向
|
||||||
|
self.direction = self.next_direction
|
||||||
|
|
||||||
|
# 计算新的头部位置
|
||||||
|
head_x, head_y = self.snake[0]
|
||||||
|
dx, dy = self.direction.value
|
||||||
|
new_head = (head_x + dx, head_y + dy)
|
||||||
|
|
||||||
|
# 检查碰撞
|
||||||
|
if self._check_collision(new_head):
|
||||||
|
self.game_over = True
|
||||||
|
return
|
||||||
|
|
||||||
|
# 移动蛇
|
||||||
|
self.snake.insert(0, new_head)
|
||||||
|
|
||||||
|
# 检查是否吃到食物
|
||||||
|
if new_head == self.food:
|
||||||
|
self.score += 10
|
||||||
|
self.food = self._generate_food()
|
||||||
|
|
||||||
|
# 每吃 5 个食物加速一次
|
||||||
|
if self.score % 50 == 0:
|
||||||
|
self.speed = min(self.speed + 2, 25) # 最大速度 25
|
||||||
|
else:
|
||||||
|
# 没吃到食物,移除尾部
|
||||||
|
self.snake.pop()
|
||||||
|
|
||||||
|
def _check_collision(self, position: Tuple[int, int]) -> bool:
|
||||||
|
"""
|
||||||
|
检查碰撞
|
||||||
|
|
||||||
|
Args:
|
||||||
|
position: 要检查的位置
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
是否发生碰撞
|
||||||
|
"""
|
||||||
|
x, y = position
|
||||||
|
|
||||||
|
# 撞墙
|
||||||
|
if x < 0 or x >= self.grid_width or y < 0 or y >= self.grid_height:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 撞到自己
|
||||||
|
if position in self.snake:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _draw_grid(self):
|
||||||
|
"""绘制网格背景"""
|
||||||
|
for x in range(0, self.width, self.cell_size):
|
||||||
|
pygame.draw.line(self.screen, self.colors['grid'],
|
||||||
|
(x, 0), (x, self.height))
|
||||||
|
for y in range(0, self.height, self.cell_size):
|
||||||
|
pygame.draw.line(self.screen, self.colors['grid'],
|
||||||
|
(0, y), (self.width, y))
|
||||||
|
|
||||||
|
def _draw_snake(self):
|
||||||
|
"""绘制蛇"""
|
||||||
|
for i, (x, y) in enumerate(self.snake):
|
||||||
|
rect = pygame.Rect(
|
||||||
|
x * self.cell_size,
|
||||||
|
y * self.cell_size,
|
||||||
|
self.cell_size - 2,
|
||||||
|
self.cell_size - 2
|
||||||
|
)
|
||||||
|
|
||||||
|
# 蛇头颜色不同
|
||||||
|
color = self.colors['snake_head'] if i == 0 else self.colors['snake_body']
|
||||||
|
pygame.draw.rect(self.screen, color, rect, border_radius=5)
|
||||||
|
|
||||||
|
# 画蛇眼睛
|
||||||
|
if i == 0:
|
||||||
|
eye_size = 4
|
||||||
|
if self.direction == Direction.UP:
|
||||||
|
eye1_pos = (x * self.cell_size + 5, y * self.cell_size + 5)
|
||||||
|
eye2_pos = (x * self.cell_size + self.cell_size - 9, y * self.cell_size + 5)
|
||||||
|
elif self.direction == Direction.DOWN:
|
||||||
|
eye1_pos = (x * self.cell_size + 5, y * self.cell_size + self.cell_size - 9)
|
||||||
|
eye2_pos = (x * self.cell_size + self.cell_size - 9, y * self.cell_size + self.cell_size - 9)
|
||||||
|
elif self.direction == Direction.LEFT:
|
||||||
|
eye1_pos = (x * self.cell_size + 5, y * self.cell_size + 5)
|
||||||
|
eye2_pos = (x * self.cell_size + 5, y * self.cell_size + self.cell_size - 9)
|
||||||
|
else: # RIGHT
|
||||||
|
eye1_pos = (x * self.cell_size + self.cell_size - 9, y * self.cell_size + 5)
|
||||||
|
eye2_pos = (x * self.cell_size + self.cell_size - 9, y * self.cell_size + self.cell_size - 9)
|
||||||
|
|
||||||
|
pygame.draw.circle(self.screen, (255, 255, 255), eye1_pos, eye_size)
|
||||||
|
pygame.draw.circle(self.screen, (255, 255, 255), eye2_pos, eye_size)
|
||||||
|
|
||||||
|
def _draw_food(self):
|
||||||
|
"""绘制食物"""
|
||||||
|
x, y = self.food
|
||||||
|
center_x = x * self.cell_size + self.cell_size // 2
|
||||||
|
center_y = y * self.cell_size + self.cell_size // 2
|
||||||
|
|
||||||
|
# 画圆形食物
|
||||||
|
pygame.draw.circle(self.screen, self.colors['food'],
|
||||||
|
(center_x, center_y), self.cell_size // 2 - 2)
|
||||||
|
|
||||||
|
# 画高光
|
||||||
|
highlight_pos = (center_x - 3, center_y - 3)
|
||||||
|
pygame.draw.circle(self.screen, (255, 100, 100), highlight_pos, 3)
|
||||||
|
|
||||||
|
def _draw_score(self):
|
||||||
|
"""绘制分数"""
|
||||||
|
# 分数背景
|
||||||
|
score_rect = pygame.Rect(10, 10, 200, 50)
|
||||||
|
pygame.draw.rect(self.screen, self.colors['score_bg'], score_rect, border_radius=10)
|
||||||
|
|
||||||
|
# 分数文字
|
||||||
|
score_text = self.font_small.render(f"Score: {self.score}", True, self.colors['text'])
|
||||||
|
self.screen.blit(score_text, (20, 25))
|
||||||
|
|
||||||
|
# 速度显示
|
||||||
|
speed_text = self.font_small.render(f"Speed: {self.speed}", True, self.colors['text'])
|
||||||
|
self.screen.blit(speed_text, (120, 25))
|
||||||
|
|
||||||
|
def _draw_game_over(self):
|
||||||
|
"""绘制游戏结束画面"""
|
||||||
|
# 半透明遮罩
|
||||||
|
overlay = pygame.Surface((self.width, self.height))
|
||||||
|
overlay.set_alpha(128)
|
||||||
|
overlay.fill((0, 0, 0))
|
||||||
|
self.screen.blit(overlay, (0, 0))
|
||||||
|
|
||||||
|
# 游戏结束文字
|
||||||
|
game_over_text = self.font_large.render("GAME OVER", True, self.colors['food'])
|
||||||
|
text_rect = game_over_text.get_rect(center=(self.width // 2, self.height // 2 - 50))
|
||||||
|
self.screen.blit(game_over_text, text_rect)
|
||||||
|
|
||||||
|
# 分数
|
||||||
|
score_text = self.font_medium.render(f"Final Score: {self.score}", True, self.colors['text'])
|
||||||
|
score_rect = score_text.get_rect(center=(self.width // 2, self.height // 2 + 20))
|
||||||
|
self.screen.blit(score_text, score_rect)
|
||||||
|
|
||||||
|
# 提示文字
|
||||||
|
hint_text = self.font_small.render("Press SPACE to Restart", True, self.colors['text'])
|
||||||
|
hint_rect = hint_text.get_rect(center=(self.width // 2, self.height // 2 + 80))
|
||||||
|
self.screen.blit(hint_text, hint_rect)
|
||||||
|
|
||||||
|
hint_text2 = self.font_small.render("Press ESC to Quit", True, self.colors['text'])
|
||||||
|
hint_rect2 = hint_text2.get_rect(center=(self.width // 2, self.height // 2 + 120))
|
||||||
|
self.screen.blit(hint_text2, hint_rect2)
|
||||||
|
|
||||||
|
def _draw_paused(self):
|
||||||
|
"""绘制暂停画面"""
|
||||||
|
# 半透明遮罩
|
||||||
|
overlay = pygame.Surface((self.width, self.height))
|
||||||
|
overlay.set_alpha(128)
|
||||||
|
overlay.fill((0, 0, 0))
|
||||||
|
self.screen.blit(overlay, (0, 0))
|
||||||
|
|
||||||
|
# 暂停文字
|
||||||
|
pause_text = self.font_large.render("PAUSED", True, self.colors['text'])
|
||||||
|
text_rect = pause_text.get_rect(center=(self.width // 2, self.height // 2))
|
||||||
|
self.screen.blit(pause_text, text_rect)
|
||||||
|
|
||||||
|
hint_text = self.font_small.render("Press P to Resume", True, self.colors['text'])
|
||||||
|
hint_rect = hint_text.get_rect(center=(self.width // 2, self.height // 2 + 60))
|
||||||
|
self.screen.blit(hint_text, hint_rect)
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
"""绘制游戏画面"""
|
||||||
|
# 清空屏幕
|
||||||
|
self.screen.fill(self.colors['background'])
|
||||||
|
|
||||||
|
# 绘制网格
|
||||||
|
self._draw_grid()
|
||||||
|
|
||||||
|
# 绘制食物
|
||||||
|
self._draw_food()
|
||||||
|
|
||||||
|
# 绘制蛇
|
||||||
|
self._draw_snake()
|
||||||
|
|
||||||
|
# 绘制分数
|
||||||
|
self._draw_score()
|
||||||
|
|
||||||
|
# 游戏结束画面
|
||||||
|
if self.game_over:
|
||||||
|
self._draw_game_over()
|
||||||
|
|
||||||
|
# 暂停画面
|
||||||
|
if self.paused:
|
||||||
|
self._draw_paused()
|
||||||
|
|
||||||
|
# 更新显示
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""运行游戏主循环"""
|
||||||
|
running = True
|
||||||
|
|
||||||
|
while running:
|
||||||
|
# 处理事件
|
||||||
|
running = self._handle_events()
|
||||||
|
|
||||||
|
# 更新游戏状态
|
||||||
|
self._update()
|
||||||
|
|
||||||
|
# 绘制画面
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
# 控制帧率
|
||||||
|
self.clock.tick(self.speed)
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("🐍 经典贪吃蛇游戏")
|
||||||
|
print("=" * 60)
|
||||||
|
print("\n游戏说明:")
|
||||||
|
print(" - 使用方向键 ↑↓←→ 或 WASD 控制蛇的移动")
|
||||||
|
print(" - 吃到红色食物可以得分并变长")
|
||||||
|
print(" - 撞墙或撞到自己则游戏结束")
|
||||||
|
print(" - 按 P 键暂停游戏")
|
||||||
|
print(" - 按 ESC 键退出游戏")
|
||||||
|
print(" - 按空格键重新开始")
|
||||||
|
print("\n每吃 5 个食物,速度会加快哦!")
|
||||||
|
print("=" * 60)
|
||||||
|
print("\n正在启动游戏...")
|
||||||
|
|
||||||
|
game = SnakeGame()
|
||||||
|
game.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user