[玩耍]贪吃蛇

很久以前自己写着玩的,已经是上个学期的事情了,优化可能不是很好。但至少运行着不卡。。

用的Visual Studio2015,代码复制到别的编译器可能出问题。

成品地址:链接: http://pan.baidu.com/s/1nvKrL6T 密码: 57m5

实现的功能:蛇能跑能转弯能吃豆子(废话!);按空格暂停,所以进游戏时如果发现蛇动不了,那就是你按了空格,再按一下就好;同时有三种豆子,白色的就是普通的豆子,红色的加速效果,蓝色的减速效果。不能穿墙;还有吃到豆子会有系统警告声,不要被吓到,因为这是我让游戏发出声音的最简单的办法了;

因为是当时学编程以来第一次做个成品,于是做了个极其花哨的开始界面,代码里很多都是花在界面上了,其实都是没用的代码

如果最大化窗口,会花屏,按一下R键可以稍微恢复一点界面;游戏会生成一个文件,用于储存最高分,当然完全没有加密什么的,打开就能看到你的所有成绩,你要篡改成99999也是没问题的。

还有完之前关掉输入法,不然界面显示会有问题,界面出问题了按R键刷新

还有,游戏的对话框按钮鼠标不支持,用左右或上下选择,enter确认

//贪吃蛇
//全屏下一共横里236格,竖里55格
//本次横里80格(或者说是40格),竖里29格
#include<Windows.h>
#include<iostream>
#include<fstream>
#include<ctime>
#include<stdlib.h>
using namespace std;
//-----------------------
struct Xsnake {
	unsigned x, y;
	Xsnake* next;
}*head;
struct Xfood {
	unsigned x, y, colour;//colour:0white 1red 2blue
}Food;
unsigned Score = 0;
unsigned Max = 0;
unsigned Length = 5;
unsigned SleepTime = 150;
unsigned Direction = 8;
unsigned SnakeColour = 0;
int GameStatus = 0;//0:正常,1:ESC关闭游戏,2:撞墙,3:撞尾巴
				   //-----------------------
int main();
void XWelcome();
void Xstart();
void Xinterface();
void Xgame();
void Xend();
void Pos(unsigned, unsigned);
void SnakeShow(Xsnake*);
void GetSnake(Xsnake*);
Xsnake* SnakeAdd(Xsnake*, unsigned, unsigned);
Xsnake* SnakeMove(Xsnake*, unsigned);
Xsnake* SnakePush_back(Xsnake*, const unsigned, const unsigned);
inline void SnakeTail(Xsnake*, unsigned&, unsigned&);
inline void SnakeClear(unsigned, unsigned);
int SnakeBite(Xsnake*);
void SnakeKey(unsigned&);
void SnakeDel(Xsnake*);
void FoodCreate(Xsnake*, Xfood&);
void FoodShow(const Xfood&);
//-----------------------

void Pos(unsigned x, unsigned y) {
	COORD p;
	p.X = y;p.Y = x;
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(h, p);
}
void XWelcome() {
	Pos(5, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(5, 50);cout << "  / ̄ ̄ ̄Y ̄ ̄。\  ";
	Pos(6, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(6, 50);cout << " l        l  ";
	Pos(7, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(7, 50);cout << "ヽ,,,,,/  ̄ ̄ ̄ ヽ  ";
	Pos(8, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(8, 50);cout << " |:::::        l ";
	Pos(9, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(9, 50);cout << " |:::    __  __ |  ";
	Pos(10, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(10, 50);cout << " (6   \●   ● 丨 ";
	Pos(11, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(11, 50);cout << " !       )..(  l  ";
	Pos(12, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(12, 50);cout << "  ヽ      (三) l  ";
	Pos(13, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(13, 50);cout << "  /\    二   ノ   ";
	Pos(14, 50);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
	cout << "                     ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
	Pos(14, 50);cout << " / ⌒ヽ. ‘ー—一\  ";
	Sleep(80);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
	Pos(12, 71);cout << ".";Sleep(120);
	Pos(12, 71);cout << " 。";Sleep(120);
	Pos(12, 71);cout << "  o";Sleep(120);
	Pos(12, 71);cout << "   o";Sleep(120);
	Pos(12, 71);cout << "     0";Sleep(120);
	Pos(12, 76);cout << " ";
	Pos(11, 84);cout << "o";Sleep(120);
	Pos(11, 84);cout << " ";
	Pos(10, 85);cout << ".";Sleep(120);
	Pos(10, 85);cout << " ";
}
void Xstart() {
	XWelcome();
	const CONSOLE_CURSOR_INFO cursor{ (DWORD)100,FALSE };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
	head = new Xsnake;
	head->x = 11;head->y = 38;
	head->next = nullptr;
	head = SnakeAdd(head, 10, 38);head = SnakeAdd(head, 9, 38);
	head = SnakeAdd(head, 8, 38);head = SnakeAdd(head, 7, 38);
	ifstream i("snake_data.dat");
	if (!i) i.close();
	else {
		unsigned s;
		while (i >> s)
			if (s > Max)Max = s;
		i.close();
	}
	Pos(16, 48);cout << "载入完毕,";system("pause");
	Pos(16, 48);cout << "  贪吃蛇     by蟹脑板              ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 160);
	Pos(18, 50);cout << "    开 始 游 戏    ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
	Pos(20, 50);cout << "    退 出 游 戏    ";
	int YN = 8;
	while (!GetAsyncKeyState(VK_RETURN)) {
		if (GetAsyncKeyState(VK_UP)) {
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 160);
			Pos(18, 50);cout << "    开 始 游 戏    ";
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
			Pos(20, 50);cout << "    退 出 游 戏    ";
			YN = 8;
		}
		if (GetAsyncKeyState(VK_DOWN)) {
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
			Pos(18, 50);cout << "    开 始 游 戏    ";
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 160);
			Pos(20, 50);cout << "    退 出 游 戏    ";
			YN = 4;
		}
	}
	if (YN == 4) exit(0);
	system("cls");
}
void Xinterface() {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 136);
	Pos(0, 0);
	cout << "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\n";//80x
	for (unsigned i = 1;i <= 28;++i)cout << "■\n";
	for (unsigned i = 1;i <= 28;++i) {
		Pos(i, 78);
		cout << "■";
	}
	cout << endl;
	cout << "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
	Pos(2, 88);cout << "得分:" << Score;
	Pos(3, 88);cout << "长度:" << Length;
	Pos(4, 88);cout << "速度:" << 300 - SleepTime;
	Pos(5, 88);cout << "历史最高成绩:" << Max;
}
void Xgame() {
	Xinterface();
	unsigned tail_x = 0, tail_y = 0;
	FoodCreate(head, Food);
	FoodShow(Food);
	while (Length < 1026) {
		if (Food.x == head->x && Food.y == head->y) {
			if (SnakeColour == 1)SleepTime += 40;
			else if (SnakeColour == 2)SleepTime -= 40;
			if (Food.colour == 1) {
				SleepTime -= 40;
				Score += 8;
			}
			else if (Food.colour == 2) {
				SleepTime += 40;
				Score -= 6;
			}
			SnakeColour = Food.colour;
			Score += 10;
			++Length;
			head = SnakePush_back(head, tail_x, tail_y);
			FoodCreate(head, Food);
			FoodShow(Food);
			if (SleepTime > 80) SleepTime -= 3;
			Pos(2, 93);cout << Score;
			Pos(3, 93);cout << Length;
			Pos(4, 93);cout << 300 - SleepTime;
			Pos(5, 101);cout << Max;
			char bel = 7;cout << bel;
		}
		else SnakeClear(tail_x, tail_y);
		SnakeTail(head, tail_x, tail_y);
		SnakeShow(head);
		Sleep(SleepTime);
		SnakeKey(Direction);
		if (Direction == 0) {
			GameStatus = 1;
			break;
		}
		head = SnakeMove(head, Direction);
		if (head->x == 0 || head->x == 29 || head->y == 0 || head->y == 78) {
			GameStatus = 2;
			break;
		}
		if (SnakeBite(head)) {
			GameStatus = 3;
			break;
		}
	}
}
void Xend() {
	ofstream o("snake_data.dat", ios_base::app);
	if (!o) o.close();
	else {
		o << Score << endl;
		o.close();
	}
	switch (GameStatus)
	{
	case 1: {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 224);
		Pos(10, 17);cout << "  提示                                    ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
		Pos(11, 17);cout << "▏                                      ▕";
		Pos(12, 17);cout << "▏                                      ▕";
		Pos(13, 17);cout << "▏▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▕\n";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		Pos(12, 19);cout << "即将退出,";
		break;
	}
	case 2: {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 207);
		Pos(10, 17);cout << "  失败                                    ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
		Pos(11, 17);cout << "▏                                      ▕";
		Pos(12, 17);cout << "▏                                      ▕";
		Pos(13, 17);cout << "▏▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▕\n";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		Pos(12, 19);cout << "您撞墙了,";
		break;
	}
	case 3: {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 223);
		Pos(10, 17);cout << "  失败                                    ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 13);
		Pos(11, 17);cout << "▏                                      ▕";
		Pos(12, 17);cout << "▏                                      ▕";
		Pos(13, 17);cout << "▏▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▕\n";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		Pos(12, 19);cout << "撞到自己,";
		break;
	}
	default: {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 175);
		Pos(10, 17);cout << "  恭喜                                    ";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
		Pos(11, 17);cout << "▏                                      ▕";
		Pos(12, 17);cout << "▏                                      ▕";
		Pos(13, 17);cout << "▏▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▕\n";
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		Pos(12, 19);cout << "恭喜通关,";
		break;
	}
	}
	Pos(12, 28);system("pause");
	Pos(27, 88);SnakeDel(head);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 191);
	Pos(10, 17);cout << "  提示                                    ";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 11);
	Pos(11, 17);cout << "▏                                      ▕";
	Pos(12, 17);cout << "▏                                      ▕";
	Pos(13, 17);cout << "▏                                      ▕";
	Pos(14, 17);cout << "▏                                      ▕";
	Pos(15, 17);cout << "▏▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▕\n";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
	Pos(12, 19);cout << "是否再玩一局?";
	Pos(14, 24);cout << "  是  ";
	Pos(14, 46);cout << "  否  ";
	int YN = 6;
	while (!GetAsyncKeyState(VK_RETURN)) {
		if (GetAsyncKeyState(VK_LEFT)) {
			YN = 4;
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 191);
			Pos(14, 24);cout << "  是  ";
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
			Pos(14, 46);cout << "  否  ";
		}
		if (GetAsyncKeyState(VK_RIGHT)) {
			YN = 6;
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
			Pos(14, 24);cout << "  是  ";
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 191);
			Pos(14, 46);cout << "  否  ";
		}
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
	if (YN == 4) {
		Score = 0;
		Max = 0;
		Length = 5;
		SleepTime = 150;
		Direction = 8;
		SnakeColour = 0;
		main();
	}
	else Pos(29, 88);
}
void FoodCreate(Xsnake* s, Xfood& f) {
	srand((unsigned)time(0));
	do {
		f.y = 2 * (rand() % 38 + 1);
		f.x = rand() % 28 + 1;
		while (s) {
			if (s->x == f.x&&s->y == f.y) break;
			s = s->next;
		}
	} while (s);
	f.colour = rand() % 8;
	if (f.colour > 2) f.colour = 0;
}
void FoodShow(const Xfood& f) {
	Pos(f.x, f.y);
	if (f.colour == 1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
	else if (f.colour == 2)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
	cout << "●";
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
}
Xsnake* SnakeAdd(Xsnake* s, unsigned xx, unsigned yy) {
	Xsnake* n = new Xsnake;
	n->x = xx;n->y = yy;
	n->next = s;
	return n;
}
Xsnake* SnakeMove(Xsnake* s, unsigned direction) {
	Xsnake* h = s;
	Xsnake* n = s;
	while (s->next) {
		n = s;
		s = s->next;
	}
	s->next = h;
	n->next = nullptr;
	switch (direction)
	{
	case 4: s->y = (s->next)->y - 2, s->x = (s->next)->x;break;
	case 6: s->y = (s->next)->y + 2, s->x = (s->next)->x;break;
	case 8: s->x = (s->next)->x - 1, s->y = (s->next)->y;break;
	case 2: s->x = (s->next)->x + 1, s->y = (s->next)->y;break;
	default: exit(1);
	}
	return s;
}
int SnakeBite(Xsnake* s) {
	unsigned xx = s->x, yy = s->y;
	while (s->next) {
		s = s->next;
		if (s->x == xx&&s->y == yy) return 1;
	}
	return 0;
}
Xsnake* SnakePush_back(Xsnake* s, const unsigned xx, const unsigned yy) {
	Xsnake* ss = s;
	while (s->next) s = s->next;
	Xsnake* n = new Xsnake;
	n->x = xx, n->y = yy;
	n->next = nullptr;
	s->next = n;
	return ss;
}
inline void SnakeTail(Xsnake* s, unsigned& xx, unsigned& yy) {
	while (s->next)s = s->next;
	xx = s->x;yy = s->y;
}
inline void SnakeClear(unsigned xx, unsigned yy) {
	if (xx&& yy) {
		Pos(xx, yy);cout << "  ";
	}
}
void SnakeDel(Xsnake* s) {
	Xsnake* n;
	int i = 0;
	while (s) {
		n = s;
		s = s->next;
		delete n;
		++i;
	}
	cout << "本次游戏中贪吃蛇长度为" << i << '.';
}
void SnakeShow(Xsnake* s) {
	if (SnakeColour == 1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
	else if (SnakeColour == 2)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
	while (s) {
		Pos(s->x, s->y);cout << "■";
		s = s->next;
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
}
void SnakeKey(unsigned& d) {
	if (GetAsyncKeyState(VK_UP) && d != 2) d = 8;
	else if (GetAsyncKeyState(VK_DOWN) && d != 8) d = 2;
	else if (GetAsyncKeyState(VK_LEFT) && d != 6) d = 4;
	else if (GetAsyncKeyState(VK_RIGHT) && d != 4) d = 6;
	else if (GetAsyncKeyState(VK_SPACE)) {
		Pos(14, 35);cout << "暂   停";
		do {
			Sleep(200);
		} while (!GetAsyncKeyState(VK_SPACE));
		Pos(14, 35);cout << "       ";
		SnakeShow(head);
		FoodShow(Food);
	}
	else if (GetAsyncKeyState(VK_ESCAPE)) d = 0;
	else if (GetAsyncKeyState(0x52)) Xinterface(), FoodShow(Food);
}

//-----------------------
int main()
{
	system("mode con cols=120 lines=30");
	system("cls");
	Pos(0, 0);
	Xstart();
	Xgame();
	Xend();
	return 0;
}
//-----------------------

截图:



posted @ 2016-07-19 14:21  蟹脑板  阅读(176)  评论(0编辑  收藏  举报