南昌整站优化,德州建设信息网站,国家企业信用公示系统官方网站,新媒体运营好做吗在本篇博客中#xff0c;我们将一起来实现经典的贪吃蛇游戏#xff0c;使用 C 语言编写#xff0c;并在控制台中运行。这个小游戏会让你回忆起童年的经典游戏体验。我们将从游戏的初始化开始#xff0c;逐步实现游戏的各个功能#xff0c;包括蛇的移动、食物的生成、得分的…在本篇博客中我们将一起来实现经典的贪吃蛇游戏使用 C 语言编写并在控制台中运行。这个小游戏会让你回忆起童年的经典游戏体验。我们将从游戏的初始化开始逐步实现游戏的各个功能包括蛇的移动、食物的生成、得分的计算等等。最后我们将整个游戏逻辑串起来形成一个完整的贪吃蛇游戏。
初始化游戏
首先让我们来初始化游戏的一些必要组件。我们会使用 Windows API 来实现控制台窗口大小和颜色的设置以及键盘输入的获取。以下是初始化函数的代码
#include stdio.h
#include stdlib.h
#include stdbool.h
#include time.h
#include conio.h
#include windows.h#define WIDTH 40
#define HEIGHT 20
#define INITIAL_LENGTH 3enum Direction {UP,DOWN,LEFT,RIGHT
};struct Node {int x;int y;struct Node* next;
};// ...省略部分代码...int main() {system(mode con cols50 lines30); // 设置控制台窗口大小system(title 经典贪吃蛇游戏); // 设置控制台窗口标题init();// ...省略部分代码...releaseSnake();return 0;
}在初始化函数 init() 中我们初始化了游戏的一些状态包括蛇的初始位置、食物的位置、得分等。同时我们使用 srand() 函数来设置随机数种子以便在每次游戏开始时都能生成不同的食物位置。
绘制游戏界面
游戏界面的绘制是一个重要的部分。我们会使用 gotoxy() 函数来设置光标位置以及 setTextColor() 函数来设置文本颜色。以下是绘制函数的代码
void gotoxy(int x, int y) {COORD coord;coord.X x;coord.Y y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}void setTextColor(int color) {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}// ...省略部分代码...void draw() {// 设置控制台光标位置gotoxy(0, 0);// 画上边界for (int i 0; i WIDTH 2; i) {printf();}printf(\n);// 画中间部分和蛇身for (int i 0; i HEIGHT; i) {printf(|);for (int j 0; j WIDTH; j) {// ...省略部分代码...}printf(|\n);}// 画下边界for (int i 0; i WIDTH 2; i) {printf();}printf(\n);// 显示得分和提示信息printf(得分: %d\n, score);printf(使用 W, A, S, D 控制移动\n);printf(按下空格键开始下一局\n);
}在绘制函数中我们使用了循环来画出游戏界面的各个部分包括边界、蛇头、食物、蛇身、得分和提示信息。不同的元素使用不同的颜色来区分以增强游戏的可视化效果。
处理用户输入
用户输入是控制游戏进行的关键。我们使用 _kbhit() 和 _getch() 函数来获取键盘输入并根据用户的操作来改变蛇的移动方向。以下是处理输入的代码
void clearInputBuffer() {while (_kbhit()) {_getch();}
}// ...省略部分代码...void input() {if (_kbhit()) {int key _getch();clearInputBuffer(); // 清空输入缓冲区switch (key) {// ...省略部分代码...}}
}在处理输入函数中我们使用了 switch 语句来根据不同的按键进行相应的操作包括控制蛇的移动方向、结束游戏等。
移动蛇和游戏逻辑
游戏逻辑的核心在于蛇的移动和吃食物。我们使用一个链表来表示蛇的身体每个节点表示一个身体部位。以下是移动函数和游戏逻辑的代码
// ...省略部分代码...void move() {// 移动蛇头struct Node* newNode (struct Node*)malloc(sizeof(struct Node));newNode-next NULL;switch (direction) {// ...省略部分代码...}// ...省略部分代码...// 添加新节点到头部newNode-next head;head newNode;// 检查是否撞到自己的身体struct Node* current head-next;while (current ! NULL) {if (current-x head-x current-y head-y) {gameover true;break;}current current-next;}
}// ...省略部分代码...int main() {// ...省略部分代码...while (!gameover) {draw();input();if (gameover !startNextRound) {// ...省略部分代码...}if (!gameover) {move();Sleep(100); // 控制游戏速度}if (startNextRound) {// ...省略部分代码...}}// ...省略部分代码...
}在移动函数中我们首先根据当前的移动方向计算蛇头的新位置并创建一个新的节点来表示蛇头。然后我们检查是否吃到了食物如果吃到了就增加得分并重新生成食物。如果没有吃到食物我们删除蛇尾的节点实现蛇的移动。最后我们检查蛇是否撞到了自己的身体如果是则游戏结束。
完整游戏逻辑
在 main() 函数中我们将上述的各个功能整合在一起形成了一个完整的游戏逻辑。游戏会不断地循环进行直到游戏结束或玩家主动退出。游戏结束时会显示最终得分并等待用户按下任意键退出。
总结
通过本篇博客我们成功地实现了一个简单的控制台版贪吃蛇游戏。从游戏的初始化、绘制界面、处理用户输入到蛇的移动和游戏逻辑我们逐步构建了一个完整的游戏框架。这个小游戏不仅可以带我们回忆童年的游戏经历还可以锻炼我们编程的逻辑思维和综合能力。希望本篇博客对你有所帮助如果你有任何问题或建议欢迎在评论区留言
完整代码
#include stdio.h
#include stdlib.h
#include stdbool.h
#include time.h
#include conio.h
#include windows.h#define WIDTH 40
#define HEIGHT 20
#define INITIAL_LENGTH 3enum Direction {UP,DOWN,LEFT,RIGHT
};struct Node {int x;int y;struct Node* next;
};enum Direction direction;
struct Node* head;
struct Node* tail;
int foodX, foodY;
int score;
bool gameover;
bool startNextRound; // 用于标记是否开始下一局游戏void gotoxy(int x, int y) {COORD coord;coord.X x;coord.Y y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}void setTextColor(int color) {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}void clearInputBuffer() {while (_kbhit()) {_getch();}
}void init() {gameover false;direction RIGHT;head (struct Node*)malloc(sizeof(struct Node));head-x WIDTH / 2;head-y HEIGHT / 2;head-next NULL;tail head;for (int i 1; i INITIAL_LENGTH; i) {struct Node* newNode (struct Node*)malloc(sizeof(struct Node));newNode-x head-x - i;newNode-y head-y;newNode-next NULL;tail-next newNode;tail newNode;}score 0;srand((unsigned int)time(NULL));foodX rand() % WIDTH;foodY rand() % HEIGHT;startNextRound false;
}void releaseSnake() {while (head ! NULL) {struct Node* temp head;head head-next;free(temp);}
}void draw() {// 设置控制台光标位置gotoxy(0, 0);// 画上边界for (int i 0; i WIDTH 2; i) {printf();}printf(\n);// 画中间部分和蛇身for (int i 0; i HEIGHT; i) {printf(|);for (int j 0; j WIDTH; j) {if (i head-y j head-x) {setTextColor(12); // 颜色为12红色printf(); // 蛇头setTextColor(15); // 颜色为15白色} else if (i foodY j foodX) {setTextColor(14); // 颜色为14黄色printf(); // 食物setTextColor(15); // 颜色为15白色} else {struct Node* current head-next;bool printed false;while (current ! NULL) {if (current-x j current-y i) {setTextColor(10); // 颜色为10绿色printf(#); // 蛇身setTextColor(15); // 颜色为15白色printed true;break;}current current-next;}if (!printed) {printf( );}}}printf(|\n);}// 画下边界for (int i 0; i WIDTH 2; i) {printf();}printf(\n);// 显示得分和提示信息printf(得分: %d\n, score);printf(使用 W, A, S, D 控制移动\n);printf(按下空格键开始下一局\n);
}void input() {if (_kbhit()) {int key _getch();clearInputBuffer(); // 清空输入缓冲区switch (key) {case w:direction UP;break;case s:direction DOWN;break;case a:direction LEFT;break;case d:direction RIGHT;break;case x:gameover true;break;case :if (gameover) {startNextRound true;}break;default:break;}}
}void move() {// 移动蛇头struct Node* newNode (struct Node*)malloc(sizeof(struct Node));newNode-next NULL;switch (direction) {case UP:newNode-x head-x;newNode-y (head-y - 1 HEIGHT) % HEIGHT; // 从另一面出现break;case DOWN:newNode-x head-x;newNode-y (head-y 1) % HEIGHT; // 从另一面出现break;case LEFT:newNode-x (head-x - 1 WIDTH) % WIDTH; // 从另一面出现newNode-y head-y;break;case RIGHT:newNode-x (head-x 1) % WIDTH; // 从另一面出现newNode-y head-y;break;default:break;}// 检查是否吃到食物if (newNode-x foodX newNode-y foodY) {score;foodX rand() % WIDTH;foodY rand() % HEIGHT;}else {// 删除蛇的尾部节点struct Node* temp head;while (temp-next-next ! NULL) {temp temp-next;}free(temp-next);temp-next NULL;}// 添加新节点到头部newNode-next head;head newNode;// 检查是否撞到自己的身体struct Node* current head-next;while (current ! NULL) {if (current-x head-x current-y head-y) {gameover true;break;}current current-next;}
}int main() {system(mode con cols50 lines30); // 设置控制台窗口大小system(title 经典贪吃蛇游戏); // 设置控制台窗口标题init();while (!gameover) {draw();input();if (gameover !startNextRound) {setTextColor(12); // 颜色为12红色gotoxy(WIDTH / 2 - 4, HEIGHT / 2);printf(游戏结束);setTextColor(15); // 颜色为15白色gotoxy(WIDTH / 2 - 6, HEIGHT / 2 1);printf(最终得分%d, score);}if (!gameover) {move();Sleep(100); // 控制游戏速度}if (startNextRound) {releaseSnake();init();gameover false;startNextRound false;}}setTextColor(15); // 颜色为15白色gotoxy(WIDTH / 2 - 4, HEIGHT / 2 2);printf(按下任意键退出);_getch();releaseSnake();return 0;
}