代码说明与要点
1. 核心数据结构
- 游戏区域:使用二维字符数组
board[WIDTH][HEIGHT]
表示 - 蛇体:蛇头用
Position
结构,蛇身用Position
数组存储 - 方向控制:枚举类型
Direction
管理移动方向
2. 关键函数功能
函数 | 功能 | 复习要点 |
---|---|---|
initGame() |
初始化游戏状态 | 边界生成、蛇初始位置、食物生成 |
drawGame() |
渲染游戏界面 | 使用system("cls") 清屏实现动画效果 |
controlInput() |
处理键盘输入 | _kbhit() 和_getch() 的非阻塞输入处理 |
updateGame() |
更新游戏逻辑 | 蛇身移动算法、碰撞检测、吃食物判定 |
generateFood() |
随机生成食物 | 确保食物不在墙上或蛇身上 |
3. 核心算法实现
- 蛇身移动:从尾部向前逐节更新位置
- 碰撞检测:
- 墙壁碰撞:检查坐标是否在边界内
- 自身碰撞:遍历蛇身坐标比对
- 食物生成:使用
rand()
在合法区域随机生成
4. 编译运行说明
- 环境要求:Windows系统 + 支持conio.h的编译器(如GCC/MinGW)
- 编译命令:
gcc snake_game.c -o snake.exe
- 控制方式:
- WASD键控制方向
- X键退出游戏
- 吃到食物(
$
)得分,撞墙或自身游戏结束
5. 扩展建议
- 难度分级:通过修改
Sleep()
参数调整游戏速度 - 高分记录:添加文件I/O保存历史最高分
- 游戏暂停:增加空格键暂停功能
- 视觉效果:使用Windows API添加颜色支持
游戏完整演示:蛇初始长度3分,通过吃食物增加长度和分数,移动速度恒定150ms/帧。
游戏结束显示最终得分
此实现包含了贪吃蛇的核心逻辑,代码结构清晰,适合学习游戏循环设计、状态管理和控制台交互编程。复习时可重点关注游戏状态机转换和蛇身移动算法的实现细节。
#include <stdio.h>
#include <stdlib.h>
#include <conio.h> // 键盘输入处理
#include <windows.h> // 控制台操作和延时
#include <time.h> // 随机数种子
#include <stdbool.h> // 布尔类型支持
// 游戏区域尺寸
#define WIDTH 40
#define HEIGHT 20
// 游戏元素符号
#define BLANK ' '
#define WALL '#'
#define SNAKE_HEAD '@'
#define SNAKE_BODY 'o'
#define FOOD '$'
// 方向控制
enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN };
enum GameState { RUNNING, GAME_OVER, WIN };
// 坐标结构
struct Position {
int x;
int y;
};
// 全局游戏状态
int score = 0;
int snakeLength = 3;
enum Direction dir = RIGHT;
enum GameState state = RUNNING;
struct Position head;
struct Position body[WIDTH * HEIGHT];
struct Position food;
char board[WIDTH][HEIGHT];
// 函数声明
void initGame();
void drawGame();
void updateGame();
void controlInput();
void generateFood();
bool checkCollision();
void gameOver();
int main() {
srand((unsigned int)time(NULL)); // 随机数种子
initGame();
while (state == RUNNING) {
drawGame();
controlInput();
updateGame();
Sleep(150); // 控制游戏速度
}
if (state == GAME_OVER) {
gameOver();
}
return 0;
}
// 初始化游戏
void initGame() {
// 初始化游戏区域
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1) {
board[x][y] = WALL; // 边界墙
} else {
board[x][y] = BLANK; // 空白区域
}
}
}
// 初始化蛇位置(居中)
head.x = WIDTH / 2;
head.y = HEIGHT / 2;
board[head.x][head.y] = SNAKE_HEAD;
// 初始化蛇身
for (int i = 0; i < snakeLength; i++) {
body[i].x = head.x - i - 1;
body[i].y = head.y;
board[body[i].x][body[i].y] = SNAKE_BODY;
}
// 生成第一个食物
generateFood();
}
// 绘制游戏界面
void drawGame() {
system("cls"); // 清屏
// 绘制游戏区域
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
printf("%c", board[x][y]);
}
printf("\n");
}
// 显示分数
printf("Score: %d\n", score);
printf("Controls: WASD to move, X to quit\n");
}
// 处理用户输入
void controlInput() {
if (_kbhit()) { // 检测键盘输入
switch (_getch()) {
case 'w': if (dir != DOWN) dir = UP; break;
case 's': if (dir != UP) dir = DOWN; break;
case 'a': if (dir != RIGHT) dir = LEFT; break;
case 'd': if (dir != LEFT) dir = RIGHT; break;
case 'x': state = GAME_OVER; break;
}
}
}
// 生成食物
void generateFood() {
int x, y;
do {
x = rand() % (WIDTH - 2) + 1;
y = rand() % (HEIGHT - 2) + 1;
} while (board[x][y] != BLANK); // 确保位置为空
food.x = x;
food.y = y;
board[x][y] = FOOD;
}
// 更新游戏状态
void updateGame() {
// 保存旧尾部位置
struct Position prevTail = body[snakeLength - 1];
// 移动蛇身(从尾部向前更新)
for (int i = snakeLength - 1; i > 0; i--) {
body[i] = body[i - 1];
board[body[i].x][body[i].y] = SNAKE_BODY;
}
body[0] = head; // 新的第一节身体
// 根据方向移动蛇头
switch (dir) {
case UP: head.y--; break;
case DOWN: head.y++; break;
case LEFT: head.x--; break;
case RIGHT: head.x++; break;
}
// 检测碰撞
if (checkCollision()) {
state = GAME_OVER;
return;
}
// 检查是否吃到食物
if (head.x == food.x && head.y == food.y) {
score += 10;
snakeLength++;
board[prevTail.x][prevTail.y] = SNAKE_BODY; // 保留尾部
generateFood();
} else {
// 清除旧尾部
board[prevTail.x][prevTail.y] = BLANK;
}
// 更新蛇头位置
board[head.x][head.y] = SNAKE_HEAD;
}
// 碰撞检测
bool checkCollision() {
// 撞墙检测
if (head.x <= 0 || head.x >= WIDTH - 1 ||
head.y <= 0 || head.y >= HEIGHT - 1) {
return true;
}
// 撞自身检测
for (int i = 0; i < snakeLength; i++) {
if (head.x == body[i].x && head.y == body[i].y) {
return true;
}
}
return false;
}
// 游戏结束处理
void gameOver() {
system("cls");
printf("========================\n");
printf(" GAME OVER!\n");
printf(" Final Score: %d\n", score);
printf("========================\n");
printf("Press any key to exit...");
_getch(); // 等待按键退出
}
资源推荐:
C/C++学习交流君羊 << 点击加入