贪吃蛇小游戏——我的第一篇博客
发布日期:2021-06-29 02:35:33 浏览次数:2 分类:技术文章

本文共 9468 字,大约阅读时间需要 31 分钟。

C语言入门者可制作的小游戏

欢迎来到我的博客

我是大一的新生,这是我的第一篇博客,我也是在最近学完了C语言基础,想在这里分享我制作的第一个小游戏——贪吃蛇。在制作贪吃蛇的过程中,我相当于复习了一遍C语言基础,又学习了一些关于C/C++的内容。希望大家能指正我的代码,我将会虚心接受大家的建议。

我的github:https://github.com/YYYYYYYYZ/game_by_yxf

游戏效果

可自定义边框大小、目标、速度。

效果1
在这里插入图片描述

思路

在最初制作贪吃蛇的时候我将其分为了

  • 界面部分
int main()                                                             //界面部分{
printf("输入'o'开始游戏,其他键结束游戏\n"); while (_getch() == 'o') {
eat = 0, gameover_eat = 0; system("cls"); printf("游戏以wsad操作,按'p'键可结束游戏\n请输入边界大小(长,宽)、速度、目标\n"); system("pause"); system("cls"); printf("长(建议50左右):"); scanf_s("%d", &lo); printf("宽(建议30左右):"); scanf_s("%d", &wi); printf("请输入速度(应为整数2左右):"); scanf_s("%d", &speed); printf("请输入目标(自然数):"); scanf_s("%d", &goal); system("cls"); printf("按任意键开始游戏"); switch (control()) {
case -1:system("cls"); printf("游戏结束-失败qwq\n目标为:%d\n最终成绩为:%d\n", goal, gameover_eat); break; default:system("cls"); printf("游戏结束-胜利ovo\n目标为:%d\n最终成绩为:%d\n", goal, eat); break; } printf("输入'o'重新开始游戏,其他键结束游戏\n"); }}
  • 命令指令行光标移动部分
void move(int x, int y)                                                 //命令指令行光标移动部分{
COORD point = {
(SHORT)x , (SHORT)y }; //光标要设置的位置x,y HANDLE HOutput = GetStdHandle(STD_OUTPUT_HANDLE); //使用GetStdHandle(STD_OUTPUT_HANDLE)来获取标准输出的句柄 SetConsoleCursorPosition(HOutput, point); //设置光标位置}
  • wsad的控制及蛇的生成部分
int control()                                                            //wsad的控制及蛇的生成部分{
Coordinate* c = (struct Coordinate*)calloc(goal + 3, 2 * sizeof(int));//动态生成结构体数组,为蛇的身躯 (*c).x = lo / 2 + rand() % 3 + 1; (*c).y = wi / 2 + rand() % 3 + 1; (*(c + 1)).x = (*(c + 2)).x = 0; (*(c + 1)).y = (*(c + 2)).y = 0; char temp = 'w', temp_ch = _getch(); char* ch = &temp_ch; int eat_1 = 0; while (1) //前后左右操作 {
if (eat == -1 || eat_1 == -1) {
return -1; } if (eat == goal) {
return 0; } switch (*ch) {
case 'w': temp = 'w'; edging_title(); //边界输出和计分板输出 check((*c).x, (*c).y); //吃的数量赋值和食物生成及检测和边界检测 eat_1 = snack_move(0, -1, ch, c); break; case 's': temp = 's'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(0, 1, ch, c); break; case 'a': temp = 'a'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(-1, 0, ch, c); break; case 'd': temp = 'd'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(1, 0, ch, c); break; case 'p':gameover_eat = eat; return -1; default: *ch = temp; break; } } free(c);}
  • 边框输出及计分板输出部分
void edging_title()                                                      //边界输出和计分板输出{
int l, w; for (w = 0; w < wi; w++) {
if (w == 0 || w == wi - 1) {
for (l = 0; l < lo; l++) {
printf("*"); } printf("\n"); } else {
printf("*"); for (l = 0; l < lo - 2; l++) {
printf(" "); } printf("*\n"); } } move(lo + 1, 0); printf("goal:%d", goal); move(lo + 1, 1); printf("score:%d", eat);}
  • 食物生成和检测及边界检测部分
void check(int x, int y)                                                //食物生成及检测和边界检测{
static int x_food, y_food; //防止被释放 if (x >= lo - 1 || x <= 0 || y >= wi - 1 || y <= 0) //边缘检测 {
gameover_eat = eat; eat = -1; } if (eat == 0) {
x_food = lo / 2; y_food = wi / 2; if (x == x_food && y == y_food) {
srand((unsigned)time(NULL)); //设种子 x_food = rand() % (lo - 3) + 2; y_food = rand() % (wi - 3) + 2; eat++; } } else if (x == x_food && y == y_food) {
srand((unsigned)time(NULL)); //设种子 x_food = rand() % (lo - 3) + 2; y_food = rand() % (wi - 3) + 2; eat++; } move(x_food, y_food); printf("x");}
  • 蛇的移动部分
int snack_move(int temp_x, int temp_y, char* ch, struct Coordinate* c)   //蛇移动{
for (int z = eat + 2; z > 0; z--) //检测蛇有没有撞自己 {
if ((*c).x == (*(c + z)).x && (*c).y == (*(c + z)).y) {
gameover_eat = eat; return -1; } } for (int i = eat + 2; i > 0; i--) {
(*(c + i)).x = (*(c + i - 1)).x; (*(c + i)).y = (*(c + i - 1)).y; } (*c).x += temp_x; (*c).y += temp_y; for (int j = eat + 2; j >= 0; j--) {
move((*(c + j)).x, (*(c + j)).y); printf("o"); } move(0, 0); if (_kbhit()) {
*ch = _getch(); } Sleep(speed * 50); system("cls"); return 0;}

总代码

#include 
#include
#include
#include
#include
int control();int snack_move(int temp_x, int temp_y, char* ch, struct Coordinate* c);void edging_title();void move(int x, int y);void check(int x, int y);int goal, speed, lo, wi, eat, gameover_eat;struct Coordinate //存储x,y{
int x; int y;}*c;int main() //界面部分{
printf("输入'o'开始游戏,其他键结束游戏\n"); while (_getch() == 'o') {
eat = 0, gameover_eat = 0; system("cls"); printf("游戏以wsad操作,按'p'键可结束游戏\n请输入边界大小(长,宽)、速度、目标\n"); system("pause"); system("cls"); printf("长(建议50左右):"); scanf_s("%d", &lo); printf("宽(建议30左右):"); scanf_s("%d", &wi); printf("请输入速度(应为整数2左右):"); scanf_s("%d", &speed); printf("请输入目标(自然数):"); scanf_s("%d", &goal); system("cls"); printf("按任意键开始游戏"); switch (control()) {
case -1:system("cls"); printf("游戏结束-失败qwq\n目标为:%d\n最终成绩为:%d\n", goal, gameover_eat); break; default:system("cls"); printf("游戏结束-胜利ovo\n目标为:%d\n最终成绩为:%d\n", goal, eat); break; } printf("输入'o'重新开始游戏,其他键结束游戏\n"); }}void move(int x, int y) //命令指令行光标移动部分{
COORD point = {
(SHORT)x , (SHORT)y }; //光标要设置的位置x,y HANDLE HOutput = GetStdHandle(STD_OUTPUT_HANDLE); //使用GetStdHandle(STD_OUTPUT_HANDLE)来获取标准输出的句柄 SetConsoleCursorPosition(HOutput, point); //设置光标位置}int control() //wsad的控制及蛇的生成部分{
Coordinate* c = (struct Coordinate*)calloc(goal + 3, 2 * sizeof(int));//动态生成结构体数组,为蛇的身躯 (*c).x = lo / 2 + rand() % 3 + 1; (*c).y = wi / 2 + rand() % 3 + 1; (*(c + 1)).x = (*(c + 2)).x = 0; (*(c + 1)).y = (*(c + 2)).y = 0; char temp = 'w', temp_ch = _getch(); char* ch = &temp_ch; int eat_1 = 0; while (1) //前后左右操作 {
if (eat == -1 || eat_1 == -1) {
return -1; } if (eat == goal) {
return 0; } switch (*ch) {
case 'w': temp = 'w'; edging_title(); //边界输出和计分板输出 check((*c).x, (*c).y); //吃的数量赋值和食物生成及检测和边界检测 eat_1 = snack_move(0, -1, ch, c); break; case 's': temp = 's'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(0, 1, ch, c); break; case 'a': temp = 'a'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(-1, 0, ch, c); break; case 'd': temp = 'd'; edging_title(); check((*c).x, (*c).y); eat_1 = snack_move(1, 0, ch, c); break; case 'p':gameover_eat = eat; return -1; default: *ch = temp; break; } } free(c);}void edging_title() //边界输出和计分板输出部分{
int l, w; for (w = 0; w < wi; w++) {
if (w == 0 || w == wi - 1) {
for (l = 0; l < lo; l++) {
printf("*"); } printf("\n"); } else {
printf("*"); for (l = 0; l < lo - 2; l++) {
printf(" "); } printf("*\n"); } } move(lo + 1, 0); printf("goal:%d", goal); move(lo + 1, 1); printf("score:%d", eat);}void check(int x, int y) //食物生成及检测和边界检测部分{
static int x_food, y_food; //防止被释放 if (x >= lo - 1 || x <= 0 || y >= wi - 1 || y <= 0) //边缘检测 {
gameover_eat = eat; eat = -1; } if (eat == 0) {
x_food = lo / 2; y_food = wi / 2; if (x == x_food && y == y_food) {
srand((unsigned)time(NULL)); //设种子 x_food = rand() % (lo - 3) + 2; y_food = rand() % (wi - 3) + 2; eat++; } } else if (x == x_food && y == y_food) {
srand((unsigned)time(NULL)); //设种子 x_food = rand() % (lo - 3) + 2; y_food = rand() % (wi - 3) + 2; eat++; } move(x_food, y_food); printf("x");}int snack_move(int temp_x, int temp_y, char* ch, struct Coordinate* c) //蛇移动{
for (int z = eat + 2; z > 0; z--) //检测蛇有没有撞自己 {
if ((*c).x == (*(c + z)).x && (*c).y == (*(c + z)).y) {
gameover_eat = eat; return -1; } } for (int i = eat + 2; i > 0; i--) {
(*(c + i)).x = (*(c + i - 1)).x; (*(c + i)).y = (*(c + i - 1)).y; } (*c).x += temp_x; (*c).y += temp_y; for (int j = eat + 2; j >= 0; j--) {
move((*(c + j)).x, (*(c + j)).y); printf("o"); } move(0, 0); if (_kbhit()) {
*ch = _getch(); } Sleep(speed * 50); system("cls"); return 0;}

心得

C语言一本书是完全不够用的,在制作的过程中,我查询了许多资料比如:C语言光标移动到指定位置、rand()的使用、非阻塞的输入函数kbhit()等等。

转载地址:https://blog.csdn.net/YYYYYYYYZ8/article/details/109384710 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:网页设计初学者可制作的简单网页——我的第二篇博客
下一篇:在Linux下掌握arm和操作系统(2)--开发环境最小系统

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月09日 16时41分56秒