贪吃蛇小游戏——我的第一篇博客
发布日期:2021-06-29 02:35:33
浏览次数:2
分类:技术文章
本文共 9468 字,大约阅读时间需要 31 分钟。
C语言入门者可制作的小游戏
欢迎来到我的博客
我是大一的新生,这是我的第一篇博客,我也是在最近学完了C语言基础,想在这里分享我制作的第一个小游戏——贪吃蛇。在制作贪吃蛇的过程中,我相当于复习了一遍C语言基础,又学习了一些关于C/C++的内容。希望大家能指正我的代码,我将会虚心接受大家的建议。
我的github:https://github.com/YYYYYYYYZ/game_by_yxf游戏效果
可自定义边框大小、目标、速度。
思路
在最初制作贪吃蛇的时候我将其分为了
- 界面部分
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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2024年04月09日 16时41分56秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Java-Activiti插件(eclipse、idea)-包含说明书
2019-04-29
nginx更改Error页面404等等页面指向
2019-04-29
jdk1.8新特性 lambda Optional 备忘记录
2019-04-29
Goland-golang:could not launch process: decoding dwarf section info at offset 0x0: too short
2019-04-29
个人第一个go样例,gin+gorm
2019-04-29
go-redis,最简单的增删改查还有json
2019-04-29
go get失败解决方案,推荐解决方案
2019-04-29
Mac上UltraEdit v18.00.0.22 分享
2019-04-29
go转换json,并且打印报文
2019-04-29
go中gorm和pg的common数据库配置
2019-04-29
go中gin框架支持的简单上传下载读取csv等文件
2019-04-29
go 闭包
2019-04-29
go 捕获处理error
2019-04-29
Input dispatching timed out 导致anr问题分析
2019-04-29
主线程中Thread.Sleep()是否会导致ANR
2019-04-29
Android 为什么主线程的looper 一直循环不会ANR
2019-04-29