学习C语言也差不多学完了想做一个游戏,而贪吃蛇和俄罗斯方块都是非常经典的游戏,在网上也找到了许多相关的参考资料,便动手做了,这个游戏室控制台版的
游戏流程图
函数模块
函数名 |
函数功能 |
CursorPosition |
光标定位函数 |
CreateSnake |
蛇初始化函数 |
ShowWall |
显示墙体 |
UpdateSnake |
更新界面上的蛇体、分数、等级、食物 |
CollisionDetection |
判断蛇是否咬到自己 |
RandFood |
随机产生食物 |
Move |
控制方向 |
程序代码
#include <stdio.h> #include<windows.h> #include<conio.h> #include<time.h> #define CWALL printf("■")//代替墙体符号 #define CSNAKE1 printf("●")//代替蛇头符号 #define CSNAKE printf("○")//代替蛇身符号 #define CFOOD printf("◇")//代替食物符号 //蛇结构 struct Snake { int x,y;//坐标 Snake *next;//蛇身体(结点) }; //全局变量 int Food; int Food_x;//食物坐标X int Food_y;//食物坐标Y int Direction;//方向变量(1:上 2:左 3:下 4:右) int Grade;//等级(速度) int Score;//得分 //蛇头节点 Snake* snake1 =(Snake*)malloc(sizeof(Snake)); //光标坐标定位函数 void CursorPosition(int x,int y) { COORD pos;//坐标结构 pos.X = x-1;//x坐标 pos.Y = y-1;//y坐标 //得到控制台的输出句柄 HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE); //将坐标设置成光标的坐标 SetConsoleCursorPosition(Out,pos); } //蛇初始化创建函数 void CreatSnake() { //蛇身体结点 Snake* snake2= (Snake*)malloc(sizeof(Snake)); //蛇头的坐标 snake1->x=13; snake1->y=5; //蛇身体的坐标 snake2->x=11; snake2->y=5; //将蛇身体接到蛇头后 snake1->next=snake2; //清空蛇身体的指针域 snake2->next=NULL; } //显示墙体 void ShowWall() { int i; //列墙体 for(i=2;i<=24;++i) { CursorPosition(1,i); CWALL; CursorPosition(61,i); CWALL; CursorPosition(79,i); CWALL; } //行墙体 for(i=1;i<=80;i+=2) { CursorPosition(i,1); CWALL; CursorPosition(i,24); CWALL; } } //更新界面上的蛇体、分数、等级、食物 void UpdateSneak() { Snake *p; p=snake1; CursorPosition(p->x,p->y);//将光标移到蛇头上 CSNAKE1;//打印蛇头 p=p->next; while(p!=NULL) { CursorPosition(p->x,p->y);//将光标移到蛇身体的位置上 CSNAKE;//显示蛇身体 p=p->next; } CursorPosition(Food_x,Food_y);//将光标移到食物的位置上 CFOOD;//显示食物 CursorPosition(67,16);//将光标移到显示分数的位置上 printf("得分: %d\n",Score);//显示分数 CursorPosition(67,19);//将光标移到显示游戏等级的位置上 printf("等级: %d\n",Grade);//显示游戏等级 } //判断蛇是否碰到墙或者咬到自己 int CollisionDetection() { Snake *p; p=snake1->next; //通过蛇头的横坐标和纵坐标判断蛇是否碰到墙 if(snake1->x==1||snake1->x==61||snake1->y==1 || snake1->y==24) { return 1; } //通过蛇头的坐标和蛇身体的坐标判断蛇是否咬到自己 while(!(p->x == snake1->x && p->y == snake1->y)) { if(p->next==NULL) { return 0; } p=p->next; } return 1; } //随即产生食物 void RandFood() { if(Food==0) { //随机种子(用于生成变化的随机数) srand((int)time(0)); //通过食物的横坐标使得食物在游戏区域内 Food_y = rand() % 20 + 3; //通过食物的纵坐标使得食物在游戏区域内 int temp = rand() % 56 + 3; if(temp % 2 == 0)//当食物的纵坐标为0时 { Food_x = temp + 1;//纵坐标加1 } else { Food_x = temp; } Food=1; } } //移动控制 void Move(); //游戏流程 void Game() { while(1) { //当蛇咬到自己或者撞到墙 if(1 == CollisionDetection()) { return;//退出循环 } //当按键盘上的上时 if(GetAsyncKeyState(VK_UP) && Direction!=3) { Direction=1; goto start; } //当按键盘上的左时 if(GetAsyncKeyState(VK_LEFT) && Direction!=4) { Direction=2; goto start; } //当按键盘上的下时 if(GetAsyncKeyState(VK_DOWN) && Direction!=1) { Direction=3; goto start; } //当按键盘上的右时 if(GetAsyncKeyState(VK_RIGHT) && Direction!=2) { Direction=4; goto start; } start: RandFood();//随机生成食物 Move();//移动贪吃蛇 UpdateSneak();//更新游戏中的数据 Sleep(330-Grade*30);//控制贪吃蛇移到的速度 } } //---------------------------------------------------------------------------- void main() { while(1) { Score=0; Grade=0; Direction=4; system("cls"); CursorPosition(30,12); printf("输入游戏等级:[1-10]\n"); CursorPosition(38,14); printf("__\b\b"); scanf("%d",&Grade); while(Grade<1 || Grade>10) { system("cls"); CursorPosition(30,12); printf("输入游戏等级:[1-10]\n"); CursorPosition(38,14); printf("__\b\b"); scanf("%d",&Grade); } system("cls"); ShowWall();//显示墙体 CreatSnake();//创建一条贪吃蛇 UpdateSneak();//更新游戏中的数据 Game(); system("cls"); CursorPosition(29,12); printf("你输了! 得 %d 分\n",Score); CursorPosition(29,14); printf("按任意键继续/退出(q)\n"); if(getch()=='q') { exit(1); } else { continue; } } } //----------------------------------------------------------------------------- void Move() { Snake* q; //定义一个临时结点 Snake* temp = (Snake*)malloc(sizeof(Snake)); if(1 == Direction)//向上移动 { //当蛇头碰倒食物时 if((snake1->x == Food_x) && (snake1->y ==Food_y+1)) { //将临时结点的坐标变为食物坐标 temp->x=Food_x; temp->y=Food_y; //将蛇头挂到临时结点的后面 temp->next=snake1; //临时结点变成头结点(临时结点变成蛇头) snake1=temp; Food=0;//标志位,标志食物被蛇吃了 //计算分数,分数分数的增加数为游戏的等级数 Score+=(1*Grade); } else { //要移动的方向向上(Windows中的坐标左上角为坐标原点,没有负数) temp->x = snake1->x; temp->y = snake1->y-1; //将蛇头接到新蛇头后面 temp->next=snake1; //body1表示蛇头 snake1=temp; //遍历结点到蛇尾 q=snake1; while((q->next)->next !=NULL) { q=q->next; } //将光标移到蛇尾 CursorPosition((q->next)->x,(q->next)->y); printf(" "); //去掉蛇尾,并且释放蛇尾结点的内存 free(q->next); q->next=NULL; } } if(Direction==2)//向左移动 { //当蛇头碰倒食物时 if((snake1->x == Food_x+2) && (snake1->y == Food_y)) { //将临时结点的坐标变为食物坐标 temp->x=Food_x; temp->y=Food_y; //将蛇头挂到临时结点的后面 temp->next=snake1; //临时结点变成头结点(临时结点变成蛇头) snake1=temp; Food=0;//标志位,标志食物被蛇吃了 //计算分数,分数分数的增加数为游戏的等级数 Score+=(1*Grade); } else { temp->x=snake1->x-2; temp->y=snake1->y; temp->next=snake1; snake1=temp; //遍历结点到尾结点 q=snake1; while((q->next)->next!=NULL) { q=q->next; } //将光标移到蛇尾 CursorPosition((q->next)->x,(q->next)->y); printf(" "); //去掉蛇尾,并且释放蛇尾结点的内存 free(q->next); q->next=NULL; } } if(Direction==3)//向下移动 { //当蛇头碰倒食物时 if((snake1->x == Food_x) && (snake1->y == Food_y-1)) { //将临时结点的坐标变为食物坐标 temp->x=Food_x; temp->y=Food_y; //将蛇头挂到临时结点的后面 temp->next=snake1; //临时结点变成头结点(临时结点变成蛇头) snake1=temp; Food=0;//标志位,标志食物被蛇吃了 //计算分数,分数分数的增加数为游戏的等级数 Score+=(1*Grade); } else { //要移动的方向向下(Windows中的坐标左上角为坐标原点,没有负数) temp->x=snake1->x; temp->y=snake1->y+1; //将蛇头接到新蛇头后面 temp->next=snake1; //body1表示蛇头 snake1=temp; //遍历结点到尾结点 q=snake1; while((q->next)->next!=NULL) { q=q->next; } //将光标移到蛇尾 CursorPosition((q->next)->x,(q->next)->y); printf(" "); //去掉蛇尾,并且释放蛇尾结点的内存 free(q->next); q->next=NULL; } } if(Direction==4)//向右移动 { //当蛇头碰倒食物时 if((snake1->x == Food_x-2) && (snake1->y == Food_y)) { //将临时结点的坐标变为食物坐标 temp->x=Food_x; temp->y=Food_y; //将蛇头挂到临时结点的后面 temp->next=snake1; //临时结点变成头结点(临时结点变成蛇头) snake1=temp; Food=0;//标志位,标志食物被蛇吃了 //计算分数,分数分数的增加数为游戏的等级数 Score+=(1*Grade); } else { temp->x=snake1->x+2; temp->y=snake1->y; temp->next=snake1; snake1=temp; //遍历结点到蛇尾 q=snake1; while((q->next)->next!=NULL) { q=q->next; } //将光标移到蛇尾 CursorPosition((q->next)->x,(q->next)->y); printf(" "); //去掉蛇尾,并且释放蛇尾结点的内存 free(q->next); q->next=NULL; } } }
执行结果:
时间: 2024-12-10 09:25:10