记得在大一时刚学习c/c++语言,学到一半突然想用这门语言做一些小游戏出来,首先想到的便是贪吃蛇。于是本人利用空余时间写出了这么一个简单的小游戏。
由于当时的我还没有能力构造出用户界面,故直接使用dos界面运行。那么问题来了,如何让一个字符在dos界面上自由移动???对于这个问题我采用的解决方案是实现gotoxy函数来控制指针位置从而实现字符的移动。那么我们就先来实现这个函数。
gotoxy 函数并非系统函数,我将其储存于 gotoxy.h 的头文件中方便调用。
gotoxy.h
#include
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
#include"gotoxy.h"
#include
#include
#include
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<
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<
}
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<
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<
gotoxy(31,12);
cout<
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++经典小游戏》 学习了解
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。