欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

利用C/C++实现较完整贪吃蛇游戏

时间:2021-05-17 08:39:48|栏目:C代码|点击:

记得在大一时刚学习c/c++语言,学到一半突然想用这门语言做一些小游戏出来,首先想到的便是贪吃蛇。于是本人利用空余时间写出了这么一个简单的小游戏。

由于当时的我还没有能力构造出用户界面,故直接使用dos界面运行。那么问题来了,如何让一个字符在dos界面上自由移动???对于这个问题我采用的解决方案是实现gotoxy函数来控制指针位置从而实现字符的移动。那么我们就先来实现这个函数。

gotoxy 函数并非系统函数,我将其储存于 gotoxy.h 的头文件中方便调用。

gotoxy.h

#include <windows.h> 
void gotoxy(int x,int y) 
{ 
 COORD pos; 
 pos.X = x - 1; 
 pos.Y = y - 1; 
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); 
} 

现在我们已经能够利用 gotoxy 函数对指针进行控制,那么实现字符的移动则只需将原来位置的字符清除,然后利用此函数移动指针到想去的坐标后打印字符即可。

在对此函数进行测试的时候,我发现了一个重要的问题,因为代码是一行一行的运行,那么在等待我输入方向的时候,其他代码是无法执行的,这意味这我的蛇只能是我给一下方向它移动一下,那么该如何使得字符在等待我输出方向的同时自行移动呢???对于这个问题有两个解决方案:一、创建线程(对于当时的我来说线程还很陌生) 二、利用 kbhit() 非阻塞函数(百度一下,你就知道)。当然我选择的是第二个方案,再配合使用 getch() 函数即可完美实现方向的输入。

该游戏的两个难点都解决了,话不多说 ↓

(由于没有涉及什么算法,加之年少,代码显得过于冗长)

这里主要运用到的知识有这些:结构体,srand(), rand(), kbhit(), getch(), Sleep().

/*******************http://blog.csdn.net/lcsy000**********************/ 
 
#include<iostream> 
#include"gotoxy.h" 
#include<windows.h> 
#include<conio.h> 
#include<time.h> 
using namespace std; 
char direction_a,direction_b; //方向a、b,用于方向的限制 
int scores,num,fool_x,fool_y,speed=100; //得分、num用于蛇身起步、食物x坐标、食物y坐标 
bool end; //结束标记 
struct node //蛇身结点 
{ 
 int x,y; 
 node *next; 
}*head=NULL,*p,*tail; 
 
void init(); //初始化开始界面 
void start(); //游戏开始入场 
void init_snake(); //初始化蛇身 
void delete_snake(); //删除蛇身 
void control(); //方向控制 
void move(); //蛇身移动 
void limit(); //方向限制 
void panduan(); //配合limit限制方向 
void fool(); //食物的出现以及食物被吞 
void isEnd(); //结束判断 
void zhuangwei(); //撞尾判断 
void zhuangqiang(); //撞墙判断 
 
int main () 
{ 
 srand((unsigned)time(NULL)); 
 init(); 
 cin>>direction_a; 
 if(direction_a!='y'&&direction_a!='Y') 
 return 0; 
 do 
 { 
 system("cls"); //清除屏幕 
 end=false; 
 start(); 
 delete_snake(); 
 init_snake(); 
 scores=0; 
 num=0; 
 fool_x=(rand() % (79-2+1))+ 2; 
 fool_y=(rand() % (22-2+1))+ 2; 
 gotoxy(fool_x,fool_y); 
 cout<<"0"; 
 direction_a=getch(); 
 while(direction_a!='d'&&direction_a!='s'&&direction_a!='w') direction_a=getch(); 
 while(true) 
 { 
 if(num&&direction_a!='d'&&direction_a!='s'&&direction_a!='w'&&direction_a!='a') 
 { 
 direction_a=direction_b; 
 } 
 control(); 
 fool(); 
 Sleep(speed); 
 if(kbhit()) //kbhit 非阻塞函数 
 { 
 direction_a=getch(); //使用 getch 函数获取键盘输入 
 limit(); 
 } 
 panduan(); 
 num=1; 
 zhuangqiang(); 
 zhuangwei(); 
 if(end) break; 
 } 
 }while(direction_a=='y'||direction_a=='Y'); 
 return 0; 
} 
void init() 
{ 
 gotoxy(35,8); 
 cout<<"★贪 吃 蛇★"; 
 gotoxy(36,10); 
 cout<<"开始请输入y:"; 
} 
void start() 
{ 
 for(int i=0;i<=79;i++) 
 { 
 Sleep(10); 
 cout<<"*"; 
 gotoxy(i+1,24); 
 cout<<"*"; 
 gotoxy(i+2,1); 
 } 
 gotoxy(1,2); 
 for(int i=0;i<=21;i++) 
 { 
 Sleep(20); 
 cout<<"*"; 
 for(int j=0;j<=77;j++) cout<<" "; 
 cout<<"*"; 
 } 
} 
void init_snake()  
{ 
 int n=3; 
 head=new node; 
 tail=head; 
 head->x=40; 
 head->y=12; 
 while(n--) 
 { 
 p=new node; 
 tail->next=p; 
 p->x=tail->x-1; 
 p->y=tail->y; 
 tail=p; 
 } 
 tail->next=NULL; 
 node *q=head->next; 
 gotoxy(head->x,head->y); 
 cout<<'#'; 
 while(q!=NULL) 
 { 
 gotoxy(q->x,q->y); 
 cout<<'*'; 
 q=q->next; 
 } 
} 
void delete_snake() 
{ 
 while(head!=NULL) 
 { 
 node *q=head; 
 head=q->next; 
 delete q; 
 } 
} 
void move() 
{ 
 gotoxy(tail->x,tail->y); 
 cout<<" "; 
 gotoxy(head->next->x,head->next->y); 
 cout<<'*'; 
 gotoxy(head->x,head->y); 
 cout<<'#'; 
 node *q=tail; 
 tail=head; 
 while(tail->next!=q) 
 { 
 tail=tail->next; 
 } 
 tail->next=NULL; 
 delete q; 
} 
void control() 
{ 
 node *q=new node; 
 q->next=head; 
 q->x=head->x; 
 q->y=head->y; 
 head=q; 
 switch(direction_a) 
 { 
 case 'w': head->y--;break; 
 case 's': head->y++;break; 
 case 'a': head->x--;break; 
 case 'd': head->x++;break; 
 default : break; 
 } 
 move(); 
} 
void limit() 
{ 
 
 if(direction_b=='s'&&direction_a=='w') direction_a='s'; 
 if(direction_b=='w'&&direction_a=='s') direction_a='w'; 
 if(direction_b=='a'&&direction_a=='d') direction_a='a'; 
 if(direction_b=='d'&&direction_a=='a') direction_a='d'; 
} 
void panduan() 
{ 
 if(direction_a=='s') direction_b='s'; 
 if(direction_a=='w') direction_b='w'; 
 if(direction_a=='d') direction_b='d'; 
 if(direction_a=='a') direction_b='a'; 
} 
void fool() 
{ 
 node *q; 
 if(head->x==fool_x&&head->y==fool_y) 
 { 
 fool_x=(rand() % (79-2+1))+ 2; 
 fool_y=(rand() % (22-2+1))+ 2; 
 gotoxy(fool_x,fool_y); 
 cout<<"0"; 
 num=0; 
 scores++; 
 node *q=new node; 
 q->x=tail->x; 
 q->y=tail->y; 
 tail->next=q; 
 tail=q; 
 tail->next=NULL; 
 } 
 q=head; 
 while(q!=NULL) 
 { 
 if(q->x==fool_x&q->y==fool_y) 
 { 
 fool_x=(rand() % (79-2+1))+ 2; 
 fool_y=(rand() % (22-2+1))+ 2; 
 gotoxy(fool_x,fool_y); 
 cout<<"*"; 
 q=head; 
 continue; 
 } 
 q=q->next; 
 } 
} 
void isEnd() 
{ 
 end=true; 
 Sleep(600); 
 system("cls"); 
 gotoxy(35,8); 
 cout<<"您 输 啦 ~"; 
 gotoxy(33,10); 
 cout<<"您的分数为: "<<scores; 
 gotoxy(31,12); 
 cout<<"重新开始请输入y:"; 
 cin>>direction_a; 
} 
void zhuangwei() 
{ 
 node *q=head->next; 
 while(q!=NULL) 
 { 
 if(head->x==q->x&&head->y==q->y) 
 { 
 isEnd(); 
 break; 
 } 
 q=q->next; 
 } 
} 
void zhuangqiang() 
{ 
 if(head->x==80||head->x==1||head->y==24||head->y==1) 
 isEnd(); 
} 


效果图:

>

由于考虑到游戏的各种 BUG 故自定义函数很多,有兴趣的朋友可以自行改动一些函数对比效果。

关于C++小游戏的更多精彩内容请点击专题: 《C++经典小游戏》 学习了解

上一篇:详解C++语言中的加法运算符与赋值运算符的用法

栏    目:C代码

下一篇:C语言for语句用法详解

本文标题:利用C/C++实现较完整贪吃蛇游戏

本文地址:http://www.codeinn.net/misctech/122961.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有