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

640?wx_fmt=gif

利用空余时间写出了这么一个简单的小游戏,直接使用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();	
}

效果图:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

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

640?wx_fmt=png

640?wx_fmt=png

它,

不仅仅是一个码

扫码关注

C++资源免费送

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值