用c语言写一个贪吃蛇小游戏
时间: 2024-01-06 07:04:10 浏览: 74
好的,可以给你提供一个基于控制台的贪吃蛇小游戏的代码,你可以参考一下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define WIDTH 40 // 游戏区宽度
#define HEIGHT 20 // 游戏区高度
#define MAX_LENGTH (WIDTH-2)*(HEIGHT-2) // 贪吃蛇最大长度
#define SNAKE_INIT_LENGTH 3 // 贪吃蛇初始长度
#define SPEED 150 // 贪吃蛇移动速度
/* 定义坐标结构体 */
typedef struct {
int x;
int y;
} Pos;
/* 定义方向枚举 */
typedef enum {
UP,
DOWN,
LEFT,
RIGHT
} Direction;
/* 定义游戏状态枚举 */
typedef enum {
WIN,
LOSE,
PLAYING,
QUIT
} GameState;
/* 定义全局变量 */
Pos food; // 食物位置
Pos snake[MAX_LENGTH]; // 贪吃蛇位置
int snake_length = SNAKE_INIT_LENGTH; // 贪吃蛇长度
Direction direction = RIGHT; // 初始方向
GameState state = PLAYING; // 初始游戏状态
int score = 0; // 分数
/* 设置光标位置 */
void gotoxy(int x, int y) {
COORD pos = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
/* 隐藏光标 */
void hideCursor() {
CONSOLE_CURSOR_INFO cci;
cci.bVisible = FALSE;
cci.dwSize = sizeof(cci);
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
/* 设置控制台窗口大小 */
void setConsoleSize() {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SMALL_RECT sr = {0, 0, WIDTH, HEIGHT};
SetConsoleWindowInfo(handle, TRUE, &sr);
COORD size = {WIDTH+1, HEIGHT+1};
SetConsoleScreenBufferSize(handle, size);
}
/* 画游戏边框 */
void drawBorder() {
int i;
for (i = 0; i <= WIDTH; ++i) {
gotoxy(i, 0);
printf("#");
gotoxy(i, HEIGHT);
printf("#");
}
for (i = 0; i <= HEIGHT; ++i) {
gotoxy(0, i);
printf("#");
gotoxy(WIDTH, i);
printf("#");
}
}
/* 画分数 */
void drawScore() {
gotoxy(WIDTH+2, 2);
printf("SCORE: %d", score);
}
/* 画食物 */
void drawFood() {
gotoxy(food.x, food.y);
printf("@");
}
/* 画贪吃蛇 */
void drawSnake() {
int i;
for (i = 0; i < snake_length; ++i) {
gotoxy(snake[i].x, snake[i].y);
printf("%c", i == 0 ? '*' : 'o');
}
}
/* 随机生成食物位置 */
void generateFood() {
srand((unsigned int)time(NULL));
while (1) {
int x = rand() % (WIDTH-2) + 1;
int y = rand() % (HEIGHT-2) + 1;
int i;
for (i = 0; i < snake_length; ++i) {
if (x == snake[i].x && y == snake[i].y) {
break;
}
}
if (i == snake_length) {
food.x = x;
food.y = y;
break;
}
}
}
/* 判断方向是否合法 */
int isValidDirection(Direction dir) {
if (dir == UP && direction == DOWN) {
return 0;
} else if (dir == DOWN && direction == UP) {
return 0;
} else if (dir == LEFT && direction == RIGHT) {
return 0;
} else if (dir == RIGHT && direction == LEFT) {
return 0;
}
return 1;
}
/* 判断游戏是否结束 */
int isGameOver() {
int i;
for (i = 1; i < snake_length; ++i) { // 贪吃蛇头碰到自己的身体
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
return 1;
}
}
if (snake[0].x == 0 || snake[0].x == WIDTH || snake[0].y == 0 || snake[0].y == HEIGHT) { // 贪吃蛇头碰到墙壁
return 1;
}
return 0;
}
/* 更新贪吃蛇位置 */
void updateSnake() {
int i;
for (i = snake_length-1; i > 0; --i) { // 从尾巴开始更新
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
switch (direction) { // 更新头部位置
case UP:
--snake[0].y;
break;
case DOWN:
++snake[0].y;
break;
case LEFT:
--snake[0].x;
break;
case RIGHT:
++snake[0].x;
break;
}
}
/* 处理按键事件 */
void handleInput() {
int ch = _getch();
switch (ch) {
case 'w':
case 'W':
case 72:
if (isValidDirection(UP)) {
direction = UP;
}
break;
case 's':
case 'S':
case 80:
if (isValidDirection(DOWN)) {
direction = DOWN;
}
break;
case 'a':
case 'A':
case 75:
if (isValidDirection(LEFT)) {
direction = LEFT;
}
break;
case 'd':
case 'D':
case 77:
if (isValidDirection(RIGHT)) {
direction = RIGHT;
}
break;
case 27: // ESC 退出游戏
state = QUIT;
break;
}
}
/* 清除控制台的所有输出 */
void clearScreen() {
gotoxy(0, 0);
int i, j;
for (i = 0; i < HEIGHT; ++i) {
for (j = 0; j < WIDTH+1; ++j) {
printf(" ");
}
}
gotoxy(0, 0);
}
/* 开始游戏 */
void playGame() {
gotoxy(WIDTH/2-4, HEIGHT/2);
printf("PRESS ANY KEY TO START");
_getch();
clearScreen();
drawBorder();
generateFood();
drawFood();
while (state == PLAYING) { // 游戏循环
drawScore();
drawSnake();
Sleep(SPEED);
updateSnake();
clearScreen();
drawBorder();
drawFood();
drawSnake();
handleInput();
if (snake[0].x == food.x && snake[0].y == food.y) { // 贪吃蛇吃到食物
++snake_length;
score += 10;
generateFood();
}
if (isGameOver()) { // 游戏结束
state = LOSE;
clearScreen();
gotoxy(WIDTH/2-4, HEIGHT/2);
printf("GAME OVER!");
_getch();
}
}
}
/* 主函数 */
int main() {
setConsoleSize();
hideCursor();
playGame();
return 0;
}
```
注意:代码中可能存在输入法的兼容问题,编码方式建议使用 UTF-8,避免乱码问题。同时,代码中利用了 Windows 控制台的一些特性,对于不同操作系统可能存在兼容性问题,需要进行适当的调整。
阅读全文