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

刚学完了C语言,便尝试的写了贪吃蛇的代码,但是效果不佳,很多的bug,所以,这个学了C++,便重新的写了这个小游戏,用类来封装!~

先是头文件:

struct Snake
{
	int x, y;
};
class snake
{
public:
	snake()                             //构造函数
	{
		length = 3;
		s[2].x = 10;
		s[2].y = 10;
		s[1].x = 9;
		s[1].y = 10;
		s[0].x = 8;
		s[0].y = 10;
		up = right = left = down = 0;
	}
	~snake(){}
	void display();                    //显示蛇身函数
	void Rightmove();                  //右移函数
	void Leftmove();                   //左移函数
	void Upmove();                     //上移函数
	void Downmove();                   //下移函数
	int cheak();                       //检查是否撞墙或撞到自身
	void creat_food();                 //产生食物
	int eat_food();                    //吃食物
private:
	struct Snake s[100];               //先定义蛇身最长100
	int length;                        //当前蛇长度
	int x3, y3;                        //食物坐标
	int up, down, right, left;         //蛇的状态,是上移还是下移或...
};

void make_frame();                     //打印框架的函数
void show();                           //游戏开始倒计时函数
void gameover();                       //游戏结束函数
下面是各个函数的实现的cpp文件:

# include <iostream>
# include <Windows.h>
# include <time.h>
# include "snake.h"
# define MaxLen 20
# define MaxWen 30
using namespace std;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  //获取句柄
void gotoxy(HANDLE hOut, int x, int y)          //输出位置的函数
{
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(hOut, pos);
}

void snake::display()                       //打印蛇身
{
	for (int i = length - 1; i >= 0; i--)
	{
		if (i == length - 1)               //打印蛇头
		{
			gotoxy(hOut, s[i].x, s[i].y);  
			cout << char(15);
		}
		else                               //打印蛇身
		{
			gotoxy(hOut, s[i].x, s[i].y);
			cout << '*';
		}
	}
	gotoxy(hOut, 0, 22);
}
void snake::Rightmove()                  //右移
{
	right = 1; up = down = left = 0;
	int x1, x2, y1, y2;
	x1 = x2 = s[length - 1].x;
	y1 = y2 = s[length - 1].y;
	s[length - 1].x++;                        //蛇头x坐标自增
	for (int i = length - 2; i >= 0; i--)     //除了蛇头,其他的结点都等于它的上一个结点的坐标
	{
		x2 = s[i].x; y2 = s[i].y;
		s[i].x = x1; s[i].y = y1;
		x1 = x2; y1 = y2;
	}
	gotoxy(hOut, x2, y2);            //消除蛇移动遗留的 ‘*’
	cout << ' ';
}
void snake::Leftmove()               //左移
{
	left = 1; right = up = down = 0;
	int x1, x2, y1, y2;
	x1 = x2 = s[length - 1].x;
	y1 = y2 = s[length - 1].y;
	s[length - 1].x--;                        //同上
	for (int i = length - 2; i >= 0; i--)
	{
		x2 = s[i].x; y2 = s[i].y;
		s[i].x = x1; s[i].y = y1;
		x1 = x2; y1 = y2;
	}
	gotoxy(hOut, x2, y2);         //同上
	cout << ' ';
}
void snake::Downmove()            //下移
{
	down = 1; right = up = left = 0;
	int x1, x2, y1, y2;
	x1 = x2 = s[length - 1].x;
	y1 = y2 = s[length - 1].y;
	s[length - 1].y++;                        //同上
	for (int i = length - 2; i >= 0; i--)
	{
		x2 = s[i].x; y2 = s[i].y;
		s[i].x = x1; s[i].y = y1;
		x1 = x2; y1 = y2;
	}
	gotoxy(hOut, x2, y2);         //同上
	cout << ' ';
}
void snake::Upmove()              //上移
{
	up = 1; down = right = left = 0;
	int x1, x2, y1, y2;
	x1 = x2 = s[length - 1].x;
	y1 = y2 = s[length - 1].y;
	s[length - 1].y--;                      //同上
	for (int i = length - 2; i >= 0; i--)
	{
		x2 = s[i].x; y2 = s[i].y;
		s[i].x = x1; s[i].y = y1;
		x1 = x2; y1 = y2;
	}
	gotoxy(hOut, x2, y2);        //同上
	cout << ' ';
}
int snake::cheak()
{
	int flag = 0;
	for (int i = length - 2; i >= 0; i--)         //是否撞到自身
	{
		if (s[i].x == s[length - 1].x && s[i].y == s[length - 1].y)
		{
			flag = 1;     //是,标识符为1
			break;
		}
	}
	if (flag == 1 || (s[length - 1].x >= 30 + 1 || s[length - 1].x < 4) || (s[length - 1].y <= 1 || s[length - 1].y >= 20))
	{
		return 0;         //检测是否撞自身,或者撞墙
	}
	else
	{
		return 1;
	}
}
void snake::creat_food()          //产生食物坐标
{
xy:	x3 = (rand() % (25)) + 3;
	y3 = (rand() % (17)) + 2;
	for (int i = length - 1; i >= 0; i--)   //检查食物是否在蛇身上
	{
		if (s[i].x == x3 && s[i].y == y3)    //是就重新产生食物坐标
			goto xy;
	}
	gotoxy(hOut, x3, y3);       //显示食物
	cout << '*';
}
int snake::eat_food()
{
	if (s[length - 1].x == x3 && s[length - 1].y == y3)   //蛇头碰到食物
	{
		if (up == 1)                    //如果蛇是在上移,增加一个结点,为蛇头的上一个结点
		{
			s[length].x = x3;
			s[length].y = y3 - 1;
		}
		else if (down == 1)             //同上
		{
			s[length].x = x3;
			s[length].y = y3 + 1;
		}
		else if (right == 1)            //同上
		{
			s[length].x = x3 + 1;
			s[length].y = y3;
		}
		else if (left == 1)             //同上
		{
			s[length].x = x3 - 1;
			s[length].y = y3;
		}
		length++;                       //蛇长加1
		return 1;
	}
	else
		return 0;
}
void make_frame()                      //打印框架函数
{
	cout << "            贪吃蛇游戏" << endl;
	gotoxy(hOut, 2, 1);
	cout << "╔";
	for (int i = 4; i < 2 + MaxWen; i++)
	{
		gotoxy(hOut, i, 1);
		printf("=");
	}
	for (int i = 2; i < MaxLen; i++)
	{
		gotoxy(hOut, 2, i);
		printf("║");
	}
	gotoxy(hOut, 2 + MaxWen, 1);
	printf("╗");
	for (int i = 2; i < MaxLen; i++)
	{
		gotoxy(hOut, 2 + MaxWen, i);
		printf("║");
	}
	gotoxy(hOut, 2, MaxLen);
	printf("╚");
	gotoxy(hOut, 2 + MaxWen, MaxLen);
	printf("╝");
	for (int i = 4; i < 2 + MaxWen; i++)
	{
		gotoxy(hOut, i, MaxLen);
		printf("=");
	}
}
void show()                //显示操作方法和游戏开始倒计时
{
	gotoxy(hOut, 35, 5);
	cout << "↑:" << 'w';
	gotoxy(hOut, 35, 6);
	cout << "←:" << 'a';
	gotoxy(hOut, 35, 7);
	cout << "↓:" << 's';
	gotoxy(hOut, 35, 8);
	cout << "→:" << 'd';
	gotoxy(hOut, 16, 5);
	cout << '3';
	Sleep(1000);
	gotoxy(hOut, 16, 5);
	cout << '2';
	Sleep(1000);
	gotoxy(hOut, 16, 5);
	cout << '1';
	Sleep(1000);
	gotoxy(hOut, 16, 5);
	cout << ' ';
}
void gameover()              //游戏结束函数
{
	system("cls");
	system("color 3B");
	gotoxy(hOut, 14, 5);
	cout << "       GAME OVER!";
	gotoxy(hOut, 14, 6);
	cout << "PLAY AGAIN ? Y(yes) \ N(no)";
}

主函数的cpp文件:

# include <iostream>
# include <Windows.h>
# include <conio.h>
# include "snake.h"
using namespace std;
char ch;
int main()
{
	while (1)
	{
		snake sn;                //声明对象
		system("cls");           //清屏
		system("color 3B");      //背景和字体颜色调整
		make_frame();            //打印框架
		sn.display();            //显示蛇
		show();                  //游戏开始
		sn.creat_food();         //产生食物
		while (sn.cheak())       //检查是否死亡
		{	
			sn.Rightmove();      //右移
			sn.display();        //显示蛇身
			if (sn.eat_food())   //检查是否吃到食物
			{
				sn.creat_food(); //重新产生食物
				sn.display();
			}
			Sleep(500);          //等待500Ms
		p:	if (_kbhit())                      //是否有按键
			{
				ch = _getch();
				if (ch == 97 || ch == 100)
					goto p;
				if (ch == 115 || ch == 119)
					break;
			}
		}
	pp:	switch (ch)            //有按键
	{
		case 119:              //上移的情况
		{
				while (sn.cheak())
				{
					sn.Upmove();
					sn.display();
					if (sn.eat_food())
					{
						sn.creat_food();
						sn.display();
						Sleep(300);
					}
					Sleep(500);
				pw:	if (_kbhit())
				{
						ch = _getch();
						if (ch == 119 || ch == 115)
							goto pw;
						if (ch == 97 || ch == 100)
							goto pp;
				}
				}
		}break;
		case 97:               //左移的情况
		{
			   while (sn.cheak())
			   {   
				   sn.Leftmove();
				   sn.display();
				   if (sn.eat_food())
				   {
					   sn.creat_food();
					   sn.display();
				   }
				   Sleep(500);
			   pa: if (_kbhit())
			   {
					   ch = _getch();
					   if (ch == 97 || ch == 100)
						   goto pa;
					   if (ch == 115 || ch == 119)
						   goto pp;
			   }
			   }
		}break;
		case 115:                //下移的情况
		{
				while (sn.cheak())
				{	
					sn.Downmove();	
					sn.display();
					if (sn.eat_food())
					{
						sn.creat_food();
						sn.display();
						Sleep(300);
					}
					Sleep(500);
				ps:	if (_kbhit())
				{
						ch = _getch();
						if (ch == 115 || ch == 119)
							goto ps;
						if (ch == 97 || ch == 100)
							goto pp;
				}
				}
		}break;
		case 100:                   //右移的情况
		{
				while (sn.cheak())
				{
					sn.Rightmove();	
					sn.display();
					if (sn.eat_food())
					{
						sn.creat_food();
						sn.display();
					}	
					Sleep(500);
				pd:	if (_kbhit())
					{
						ch = _getch();
						if (ch == 100 || ch == 97)
							goto pd;
						if (ch == 119 || ch == 115)
							goto pp;
					}
				}
		}break;
		default:
			break;
	}
		gameover();            //显示游戏结束,是否重玩
	py:	ch = _getch();
		if (ch == 110)         //否
		{
			system("cls");
			break;
		}
		else if (ch == 121)   //是
			continue;
		else
			goto py;
	}
	return 0;
}

下面是游戏的截图:




控制台的实现,不是很美观,主要是由于上下和左右的间隙不一样大,所以看起来不是很好看,但总体还是实现了贪吃蛇!~

有什么好的意见,可以跟我提!!

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值