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

标签: CC++ 游戏 贪吃蛇
12923人阅读 评论(2) 收藏 举报

记得在大一时刚学习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++语言实现贪吃蛇

1.完美的贪吃蛇 #include #include #include #include #define N 21 #include using namespace std; void gotox...
  • qq_35038153
  • qq_35038153
  • 2017年04月19日 20:20
  • 5434

简单贪吃蛇游戏的C++实现

我大概在一个多月前把自己上学期写的c代码的贪吃蛇游戏push到csdn上,并且说c风格的贪吃蛇写起来有些麻烦(贪吃蛇游戏的c语言实现),准备用面向对象的c++再写一遍。现在我们专业恰好刚教完了c++,...
  • luojj26
  • luojj26
  • 2016年04月13日 08:36
  • 4371

C++游戏编程之贪吃蛇(新手向,大量注释)

  • 2016年08月27日 19:28
  • 8.65MB
  • 下载

经典游戏---贪吃蛇从C++代码实现

小时候都玩过贪吃蛇这个经典的小游戏,在我们的普通手机里似乎都是必备的。它伴随着我们的童年,经历了好多好多时光。它带给我们了许多的乐趣。 学习了c++这门编程语言后,我就想着能不能把它做出来,在我查看了...
  • u014552726
  • u014552726
  • 2014年05月31日 00:09
  • 60108

经典游戏---贪吃蛇从C++代码实现

本文转载自:http://blog.csdn.net/shawn_hou/article/details/27734217 1.   题目描述 小时候都玩过贪吃蛇这个经典的小游戏,在我们的...
  • Robin_Ge
  • Robin_Ge
  • 2017年02月12日 09:32
  • 5809

贪吃蛇(C++ OpenGL)

系统地看了C++ primar,加上之前用过OpenGL库,于是心血来潮想要写一个简单的贪吃蛇游戏玩玩。1.类间关系和类图   我设计了四个类,分别是Draw(用于绘制),Board(负责记录蛇身的...
  • popvip44
  • popvip44
  • 2016年06月12日 19:17
  • 2198

C++贪吃蛇的简单实现版

近期看完C++Primer,决定小试身手,碰巧看到某博主用C++实现了贪吃蛇,所以我也决定试一试。 C++编程的核心思想之一就是OO思维(面向对象思维),需要一定的抽象能力,同样还需要更好的封装。...
  • coderhuhy
  • coderhuhy
  • 2015年03月18日 18:30
  • 6407

贪吃蛇小游戏 C++实现

#include #include #include #include using namespace std; // 刷新当前屏幕 inline void Refresh(char q[][22],...
  • zhouyusong_bupt
  • zhouyusong_bupt
  • 2016年04月05日 09:47
  • 1342

C++版贪吃蛇游戏

这是以前写的C++版贪吃蛇游戏,也是我学C++时的课程设计题目。通过这个游戏的开发,使我对编程有了更大的兴趣,也对自己逐渐有了信心。     贪吃蛇游戏的设计思路如下:       1)用二维数组来...
  • u012027907
  • u012027907
  • 2013年09月28日 01:08
  • 7468

贪吃蛇~~C++控制台实现!

刚学完了C语言,便尝试的写了贪吃蛇的代码,但是效果不佳,很多的bug,所以,这个学了C++,便重新的写了这个小游戏,用类来封装!~ 先是头文件: struct Snake { int x, y;...
  • qq_25425023
  • qq_25425023
  • 2015年03月05日 22:40
  • 5168
    个人资料
    等级:
    访问量: 3万+
    积分: 328
    排名: 24万+
    文章分类
    文章存档
    最新评论