C++ 实现贪吃蛇游戏(免费附源码)

经典贪吃蛇游戏

上源码

#include <iostream>
#include <ctime>
#include <windows.h>
#pragma comment(lib,"User32.lib")
using namespace std;

#define U 1
#define D 2
#define L 3 
#define R 4 //蛇的状态 U:上 D:下 L:左 R:右

//蛇身的一个节点
struct snake
{
	int x;
	int y;
	struct snake *next;
};

int score = 0, add = 10;//总得分与每次吃食物得分
int status, sleeptime = 200;//每次运行方向和时间间隔
snake *head, *food;//蛇头指针和食物指针
snake *q;//遍历蛇的时候用到的指针
int endgamestatus = 0;//游戏结束的情况 1:撞到墙 2:咬到自己 3:主动退出游戏

//设置光标位置
void Pos(int x, int y)
{
	COORD pos;
	pos.X = x;
	pos.Y = y;
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOutput, pos); // 移动光标
}

//开始界面
void welcometogame()
{
	Pos(34, 10);
	cout << "*******************************" << endl;
	Pos(40, 12);
	cout << "欢迎来到贪吃蛇游戏!" << endl;
	Pos(34, 14);
	cout << "*******************************" << endl;
	Pos(39, 16);
	cout << "Programed By ITHusky" << endl;
	Pos(40, 18);
	system("pause");
	system("cls"); // 清屏
	Pos(44, 9);
	cout << "游戏规则如下" << endl;
	Pos(30, 10);
	cout << "****************************************" << endl;
	Pos(31, 12);
	cout << "用 ↑.↓.←.→ 分 别 控 制 蛇 的 移 动" << endl;
	Pos(37, 14);
	cout << "F1 为 加 速,F2 为 减 速" << endl;
	Pos(33, 16);
	cout << "加 速 将 能 得 到 更 高 的 分 数" << endl;
	Pos(30, 18);
	cout << "****************************************" << endl;
	Pos(40, 20);
	system("pause");
	system("cls");
}

//创建地图
void creatMap()
{
	int i;
	for (i = 0; i < 58; i += 2)//打印上下边框
	{
		Pos(i, 0);
		cout << "■";
		Pos(i, 26);
		cout << "■";
	}
	for (i = 1; i < 26; i++)//打印左右边框
	{
		Pos(0, i);
		cout << "■";
		Pos(56, i);
		cout << "■";
	}
}

//初始化蛇身
void initsnake()
{
	snake *tail;
	int i;
	tail = (snake*)malloc(sizeof(snake));//从蛇尾开始,头插法,以x,y设定开始的位置
	tail->x = 24;
	tail->y = 5;
	tail->next = NULL;
	for (i = 1; i <= 4; i++)//蛇初始长度
	{
		head = (snake*)malloc(sizeof(snake));
		head->next = tail;
		head->x = 24 + 2 * i;
		head->y = 5;
		tail = head;
	}
	while (tail != NULL)//从头到尾,输出蛇身
	{
		Pos(tail->x, tail->y);
		cout << "■";
		tail = tail->next;
	}
}

//随机出现食物
void createfood()
{
	snake *food_1;
	srand((unsigned)time(NULL));
	food_1 = (snake*)malloc(sizeof(snake));
	while ((food_1->x % 2) != 0)//保证为偶数,使得食物能与蛇头对齐
	{
		food_1->x = rand() % 52 + 3;
	}
	food_1->y = rand() % 24 + 1;
	q = head;
	while (q->next == NULL)
	{
		if (q->x == food_1->x && q->y == food_1->y)//判断蛇身是否与食物重合
		{
			free(food_1);
			createfood();//递归
		}
		q = q->next;
	}
	if (food_1->x == 0 || food_1->x >= 58)//修改随机生成的数字
		food_1->x = 2;
	if (food_1->y == 0 || food_1->y >= 26)
		food_1->y = 2;
	Pos(food_1->x, food_1->y);
	food = food_1;
	cout << "■";
}

//游戏初始化
void gamestart()
{
	system("mode con cols=100 lines=30");//调整控制台尺寸
	welcometogame();
	creatMap();
	initsnake();
	createfood();
}

//结束游戏
void endgame()
{
	system("cls");
	Pos(28, 10);
	cout << "*****************************************" << endl;
	Pos(34, 12);
	if (endgamestatus == 1)
	{
		cout << "对不起,您撞到墙了。游戏结束!" << endl;
	}
	else if (endgamestatus == 2)
	{
		cout << "对不起,您咬到自己了。游戏结束!" << endl;
	}
	else if (endgamestatus == 3)
	{
		cout << "您已经结束了游戏";
	}
	Pos(34, 14);
	cout << "您的得分是:" << score;
	Pos(28, 16);
	cout << "*****************************************" << endl;
	Pos(34, 18);
	system("pause");
	exit(0);
}

//不能穿墙
void cantcrosswall()
{
	if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
	{
		endgamestatus = 1;
		endgame();
	}
}

//判断是否咬到了自己
int biteself()
{
	snake *self;
	self = head->next;
	while (self != NULL)
	{
		if (self->x == head->x && self->y == head->y)
		{
			return 1;
		}
		self = self->next;
	}
	return 0;
}

//蛇前进:上U 下D 左L 右R
void snakemove()
{
	cantcrosswall();
	snake *nexthead;
	nexthead = (snake*)malloc(sizeof(snake));
	if (status == U)
	{
		nexthead->x = head->x;
		nexthead->y = head->y - 1;
		if (nexthead->x == food->x && nexthead->y == food->y)//如果下一个有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			score = score + add;
			createfood();
		}
		else//如果没有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q->next->next != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			cout << "  ";
			free(q->next);
			q->next = NULL;
		}
	}
	if (status == D)
	{
		nexthead->x = head->x;
		nexthead->y = head->y + 1;
		if (nexthead->x == food->x && nexthead->y == food->y)//有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			score = score + add;
			createfood();
		}
		else//没有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q->next->next != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			cout << "  ";
			free(q->next);
			q->next = NULL;
		}
	}
	if (status == L)
	{
		nexthead->x = head->x - 2;
		nexthead->y = head->y;
		if (nexthead->x == food->x && nexthead->y == food->y)//有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			score = score + add;
			createfood();
		}
		else//没有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q->next->next != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			cout << "  ";
			free(q->next);
			q->next = NULL;
		}
	}
	if (status == R)
	{
		nexthead->x = head->x + 2;
		nexthead->y = head->y;
		if (nexthead->x == food->x && nexthead->y == food->y)//有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			score = score + add;
			createfood();
		}
		else//没有食物
		{
			nexthead->next = head;
			head = nexthead;
			q = head;
			while (q->next->next != NULL)
			{
				Pos(q->x, q->y);
				cout << "■";
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			cout << "  ";
			free(q->next);
			q->next = NULL;
		}
	}
	if (biteself() == 1)//判断是否会咬到自己
	{
		endgamestatus = 2;
		endgame();
	}
}

//暂停
void pause()
{
	while (1)
	{
		Sleep(300);
		if (GetAsyncKeyState(VK_SPACE))
		{
			break;
		}
	}
}

//控制游戏 
void gamecircle()
{
	Pos(64, 15);
	cout << "不能穿墙,不能咬到自己" << endl;
	Pos(64, 16);
	cout << "用↑.↓.←.→分别控制蛇的移动!";
	Pos(64, 17);
	cout << "F1 为加速,F2 为减速" << endl;
	Pos(64, 18);
	cout << "ESC:退出游戏,space:暂停游戏!";
	status = R;//初始运动方向
	while (true)
	{
		Pos(64, 10);
		cout << "得分:" << score;
		Pos(64, 11);
		cout << "每个食物得分:" << add;
		if (GetAsyncKeyState(VK_UP) && status != D)
		{
			status = U;
		}
		else if (GetAsyncKeyState(VK_DOWN) && status != U)
		{
			status = D;
		}
		else if (GetAsyncKeyState(VK_LEFT) && status != R)
		{
			status = L;
		}
		else if (GetAsyncKeyState(VK_RIGHT) && status != L)
		{
			status = R;
		}
		else if (GetAsyncKeyState(VK_SPACE))
		{
			pause();
		}
		else if (GetAsyncKeyState(VK_ESCAPE))
		{
			endgamestatus = 3;
			break;
		}
		else if (GetAsyncKeyState(VK_F1))
		{
			if (sleeptime >= 50)//运行时间间隔最小值50ms
			{
				sleeptime = sleeptime - 30;
				add = add + 2;//单个食物加2分
				if (sleeptime == 320)
				{
					add = 2;//防止减到1之后再加回来有错
				}
			}
		}
		else if (GetAsyncKeyState(VK_F2))
		{
			if (sleeptime < 350)//运行时间间隔最大值350ms
			{
				sleeptime = sleeptime + 30;
				add = add - 2;
				if (sleeptime == 350)
				{
					add = 1;//保证最低分为1
				}
			}
		}
		Sleep(sleeptime);
		snakemove();
	}
}

void main()
{
	gamestart();
	gamecircle();
	endgame();
}

参考转载请附上本文链接

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值