c++ 实现贪吃蛇(含技术难点解析和完整代码)

您所在的位置:网站首页 贪吃蛇双人模式代码是什么 c++ 实现贪吃蛇(含技术难点解析和完整代码)

c++ 实现贪吃蛇(含技术难点解析和完整代码)

2024-05-26 07:52| 来源: 网络整理| 查看: 265

文章目录 0.参考资料1 技术难点1.1 关于光标的移动1.2 关于蛇的移动1.2.1 从键盘上读取输入1.2.2 蛇的移动 1.3 食物的生成 2.完整代码

0.参考资料

借鉴了这位大佬的博客及代码,在其基础上进行了修改,特此鸣谢。 https://blog.csdn.net/qq_45359344/article/details/103254166

1 技术难点 1.1 关于光标的移动

这一步需要手写一个gotoxy的函数,其中涉及到的一些知识点见下链接: 关于COORD https://zhidao.baidu.com/question/243419995.html 关于handle https://blog.csdn.net/qq_31967569/article/details/102726894 这里需要注意的是COORD里的x,y是指的横纵坐标,而我们(或者只有我)平常在使用二维数组时习惯按照线性代数中矩阵的表达形式,即第一维放纵坐标,第二维放横坐标。所以这里的x,y要反着赋值(这个bug d了好久qwq)

void gotoxy(int x,int y) { COORD pos;//COORD是一种自带结构体,表示一个字符在控制台屏幕上的坐标 HANDLE han=GetStdHandle(STD_OUTPUT_HANDLE); //从标准输出设备里取出一个句柄 pos.X=y,pos.Y=x; SetConsoleCursorPosition(han,pos);//定位光标的函数 } 1.2 关于蛇的移动

主要有两种实现方式,一种使用指针加链表,一种使用数组。笔者选择的是数组的方式,这种方法代码量略大,且较为丑陋,但是易于理解。每次操作后只需要清空蛇尾(如果吃到食物就不用),打印蛇头,以及将蛇身的坐标顺次移动。

1.2.1 从键盘上读取输入

用kbhit()和getch()函数

1.2.2 蛇的移动

需要注意的是如果此时蛇是向上移动的话,点击向下移动是无效的。所以需要将蛇的运动状态记录下来。而在写switch,case时注意要写default,即不进行操作时,保持原运动状态。

1.3 食物的生成

一个简单的srand制造随机数就可以实现。需要注意的是,需要判断食物是否和当前蛇的位置重合,方法是暴力(枚举蛇的每一块)。可以写成一个函数来实现。

2.完整代码 #include #include #include #include #include #include using namespace std; #define frame_width 50 #define frame_height 25 typedef struct{ int x,y; } Food; typedef struct{ int x[100],y[100],len,state; } Snake; void gotoxy(int x,int y); //最重要的一个函数,控制光标的位置 void print_map(); void get_newfood();//生成新食物 bool check_foodinsnake();//检查新食物有没有在蛇身上 void move_snake(); void check_foodeating(); bool check_snakealive(); //需要用到的全局变量 int score; Snake snake; Food food; bool check_eaten; int main() { system("color 0B"); do { system("cls"); print_map(); score=0,check_eaten=0; //贪吃蛇的每回合运行控制 while(1) { check_foodeating();//system("pause"); move_snake(); Sleep(max(50,300-score));//控制速度(与长度呈反比) if(!check_snakealive()) break; } printf("Game Over!\n"); printf("1:Restart\t2:exit\n"); char com2; cin>>com2; if(com2=='2') break; }while(1); } void gotoxy(int x,int y) { COORD pos;//COORD是一种自带结构体,表示一个字符在控制台屏幕上的坐标 HANDLE han=GetStdHandle(STD_OUTPUT_HANDLE); //从标准输出设备里取出一个句柄 pos.X=y,pos.Y=x; SetConsoleCursorPosition(han,pos);//定位光标的函数 } void print_map() { //打印墙壁 for(int i=0;i gotoxy(0,i); printf("#"); gotoxy(frame_height-1,i); printf("#"); } //蛇身初始化 snake.len=3; snake.state='w'; snake.x[1]=frame_height/2; snake.y[1]=frame_width/2; gotoxy(snake.x[1],snake.y[1]); printf("@"); for(int i=2;i for(int i=1;i srand(time(0)); food.x=rand()%(frame_height-2)+1; food.y=rand()%(frame_width-2)+1; }while(check_foodinsnake()); gotoxy(food.x,food.y); cout gotoxy(snake.x[snake.len],snake.y[snake.len]); printf(" "); } //将除蛇头外的其他部分向前移动 for(int i=snake.len;i>1;i--) snake.x[i]=snake.x[i-1], snake.y[i]=snake.y[i-1]; //移动蛇头 switch(com) { case 'w': { if(snake.state=='s') //如果命令与当前方向相反不起作用 snake.x[1]++; else snake.x[1]--,snake.state='w'; break; } case 's': { if(snake.state=='w') snake.x[1]--; else snake.x[1]++,snake.state='s'; break; } case 'a': { if(snake.state=='d') snake.y[1]++; else snake.y[1]--,snake.state='a'; break; } case 'd': { if(snake.state=='a') snake.y[1]--; else snake.y[1]++,snake.state='d'; break; } default: //按其余键保持状态前进 { if(snake.state=='s') snake.x[1]++; else if(snake.state=='w') snake.x[1]--; else if(snake.state=='d') snake.y[1]++; else if(snake.state=='a') snake.y[1]--; break; } } gotoxy(snake.x[1],snake.y[1]); printf("@"); check_eaten=0; gotoxy(frame_height,0); } void check_foodeating() { if(snake.x[1]==food.x&&snake.y[1]==food.y) { score+=10; check_eaten=1; gotoxy(12,frame_width+3); printf("Your score:%d",score); snake.len++; get_newfood(); } } bool check_snakealive() { //检查有没有撞到墙 if(snake.x[1]==0||snake.x[1]==frame_height-1||snake.y[1]==0||snake.y[1]==frame_width-1)//撞墙 return 0; //检查有没有吃到自己 for(int i=2;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3