贪吃蛇(c++)

本文详细介绍了使用C++编写的贪食蛇游戏,涉及蛇的初始化、移动逻辑、碰撞检测和得分系统,玩家通过键盘控制蛇的上下左右移动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>

#define UP 1							//蛇的状态
#define DOWN 2
#define LEFT 3
#define RIGHT 4

typedef struct Snake {
	int x;
	int y;
	struct Snake* next;
}Snake;

//全局变量
int length = 58, width = 26;		//地图长宽
int score = 0, add = 10;			//总得分与每次吃食物得分。
int sleeptime = 200;				//每次运行的时间间隔
int status;							//控制方向
Snake* head, * food;				//蛇头指针,食物指针
Snake* q;							//遍历蛇的时候用到的指针
int endgamestatus = 0;				//游戏结束 1:撞到墙 2:咬到自己 3:主动退出

//声明
void Endgame();						//结束游戏
void Pos();							//控制光标位置
void CreateMap();					//创建地图
void InitSnake();					//初始化蛇身
int BitSelf();						//判断是否咬到自己
void BitWall();						//判断是否撞墙
void CreateFood();					//随机出现食物
void pause();						//暂停函数
void SnakeMove();					//移动,绑定键盘上下左右键
void GameCircle();					//控制游戏
void Welcome();						//开始界面
void GameStart();					//游戏初始化


void Pos(int x, int y) {
	COORD pos;									//位置
	HANDLE HOutput;								//句柄
	pos.X = x;
	pos.Y = y;
	HOutput = GetStdHandle(STD_OUTPUT_HANDLE);	//控制台输出句柄
	SetConsoleCursorPosition(HOutput, pos);		//控制光标位置函数
}

void CreateMap() {
	for (int i = 0; i < length; i += 2) {		//打印上下边框
		Pos(i, 0);
		printf("■");
		Pos(i, width);
		printf("■");
	}
	for (int i = 1; i < width; i++) {			//打印左右边框
		Pos(0, i);
		printf("■");
		Pos(length - 2, i);
		printf("■");
	}
}

void pause() {									//暂停
	while (1) {									//按空格后进入该函数循环
		Sleep(300);								//再次按空格跳出循环继续游戏
		if (GetAsyncKeyState(VK_SPACE)) {		//检查键盘(空格)
			break;
		}
	}
}

void InitSnake() {
	Snake* tail = (Snake*)malloc(sizeof(Snake));
	tail->x = 24;									//初始位置(24,5),3格长
	tail->y = 5;
	tail->next = nullptr;
	for (int i = 0; i < 4; i++) {
		head = (Snake*)malloc(sizeof(Snake));		//头插法
		head->next = tail;
		head->x = 24 + 2 * i;
		head->y = 5;
		tail = head;
	}
	while (tail != nullptr) {						//打印蛇身
		Pos(tail->x, tail->y);
		printf("■");
		tail = tail->next;
	}
}

int BitSelf() {
	Snake* self = head->next;
	while (self != nullptr) {
		if (self->x == head->x && self->y == head->y) {
			return 1;
		}
		self = self->next;
	}
	return 0;
}

void BitWall() {
	if (head->x == 0 || head->x == length - 2 || head->y == 0 || head->y == width) {
		endgamestatus = 1;
		Endgame();
	}
}

void CreateFood() {
	Snake* food_1 = (Snake*)malloc(sizeof(Snake));
	srand((unsigned)time(nullptr));
	while (food_1->x % 2 != 0)							//保证x为偶数
		food_1->x = rand() % (length - 6) + 2;
	food_1->y = rand() % (width - 2) + 1;
	q = head;
	while (q->next != nullptr) {
		if (q->x == food_1->x && q->y == food_1->y) {	//判断蛇身是否与食物重叠
			free(food_1);
			CreateFood();								//有重叠则重新放置
		}
		q = q->next;
	}
	Pos(food_1->x, food_1->y);
	food = food_1;
	printf("■");
}

void SnakeMove() {

	Snake* nexthead = (Snake*)malloc(sizeof(Snake));
	BitWall();

	if (status == UP) {
		nexthead->x = head->x;
		nexthead->y = head->y - 1;
		nexthead->next = head;
		head = nexthead;
		q = head;
		//碰到食物
		if (nexthead->x == food->x && nexthead->y == food->y) {
			while (q != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			score += add;
			CreateFood();
		}
		else {
			while (q->next->next != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			printf("  ");
			free(q->next);
			q->next = nullptr;
		}
		if (BitSelf() == 1) {			//判断是否会咬到自己
			endgamestatus = 2;
			Endgame();
		}
	}

	if (status == DOWN) {
		nexthead->x = head->x;
		nexthead->y = head->y + 1;
		nexthead->next = head;
		head = nexthead;
		q = head;
		//碰到食物
		if (nexthead->x == food->x && nexthead->y == food->y) {
			while (q != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			score += add;
			CreateFood();
		}
		else {
			while (q->next->next != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			printf("  ");
			free(q->next);
			q->next = nullptr;
		}
		if (BitSelf() == 1) {
			endgamestatus = 2;
			Endgame();
		}
	}

	if (status == LEFT) {
		nexthead->x = head->x - 2;
		nexthead->y = head->y;
		nexthead->next = head;
		head = nexthead;
		q = head;
		//碰到食物
		if (nexthead->x == food->x && nexthead->y == food->y) {
			while (q != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			score += add;
			CreateFood();
		}
		else {
			while (q->next->next != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			printf("  ");
			free(q->next);
			q->next = nullptr;
		}
		if (BitSelf() == 1) {
			endgamestatus = 2;
			Endgame();
		}
	}

	if (status == RIGHT) {
		nexthead->x = head->x + 2;
		nexthead->y = head->y;
		nexthead->next = head;
		head = nexthead;
		q = head;
		//碰到食物
		if (nexthead->x == food->x && nexthead->y == food->y) {
			while (q != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			score += add;
			CreateFood();
		}
		else {
			while (q->next->next != nullptr) {
				Pos(q->x, q->y);
				printf("■");
				q = q->next;
			}
			Pos(q->next->x, q->next->y);
			printf("  ");
			free(q->next);
			q->next = nullptr;
		}
		if (BitSelf() == 1) {
			endgamestatus = 2;
			Endgame();
		}
	}
}

void GameCircle() {
	Pos(64, 15);
	printf("不能穿墙,不能咬到自己\n");
	Pos(64, 16);
	printf("用↑.↓.←.→分别控制蛇的移动.");
	Pos(64, 17);
	printf("ESC :退出游戏.space:暂停游戏.");
	Pos(64, 20);

	status = RIGHT;
	while (1) {
		Pos(64, 10);
		printf("得分:%d  ", score);
		Pos(64, 11);
		printf("每个食物得分:%d分", add);
		if (GetAsyncKeyState(VK_UP) && status != DOWN) 
			status = UP;
		else if (GetAsyncKeyState(VK_LEFT) && status != RIGHT) 
			status = LEFT;
		else if (GetAsyncKeyState(VK_RIGHT) && status != LEFT) 
			status = RIGHT;
		else if (GetAsyncKeyState(VK_DOWN) && status != UP) 
			status = DOWN;
		else if (GetAsyncKeyState(VK_SPACE)) 
			pause();
		else if (GetAsyncKeyState(VK_ESCAPE)) {
			endgamestatus = 3;
			break;
		}
		Sleep(sleeptime);
		SnakeMove();
	}
}

void Welcome() {
	Pos(40, 12);
	printf("欢迎来到贪食蛇游戏!");
	Pos(40, 25);
	system("pause");								//暂停函数
	system("cls");
	Pos(25, 12);
	printf("用↑.↓.←.→分别控制蛇的移动\n");
	system("pause");
	system("cls");
}

void Endgame() {
	system("cls");
	Pos(24, 12);
	if (endgamestatus == 1) {
		printf("您撞到墙了,游戏结束.");
	}
	else if (endgamestatus == 2) {
		printf("您咬到自己了,游戏结束.");
	}
	else if (endgamestatus == 3) {
		printf("您结束了游戏。");
	}
	Pos(24, 13);
	printf("您的得分是%d\n", score);
	exit(0);
}

void GameStart() {
	system("mode con cols=100 lines=30");
	Welcome();
	CreateMap();
	InitSnake();
	CreateFood();
}

int main() {
	GameStart();
	GameCircle();
	Endgame();
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值