C++贪吃蛇,240+行,有菜单,能调数值。初学者练手

发布时间:2024年01月03日
#include <iostream>
#include <cstdlib>
#include <Windows.h>
#include <string>
#include <thread>
#include <ctime>
#include <vector>
using namespace std;
///初始化/
//贪吃蛇活动范围(正方形)
const int x = 12;
string arr[x][x];
void gamep() {
	for (int t = 0; t < x; t++)
	{
		for (int u = 0; u < x; u++)
		{
			arr[t][u] = "  ";
		}
	}
	for (int i = 0; i < x; i++)
	{
		arr[0][i] = "■ "; arr[x - 1][i] = "■ ";
		arr[i][0] = "■ "; arr[i][x - 1] = "■ ";
	}
}
//积分板
int sore = 0;
//豆子坐标
int spx; int spy;
//方向,0向上,1向左,2向下,3向右
int way = 3;
//速度
int defspeed = 500;
int impspeed;
int speed = defspeed;
//贪吃蛇位置
//头部
int defha = 3;int defhb = 4;
int ha = defha;int hb = defhb;
//身体
int* abody;int* bbody;
//长度
int deflen = 3;
int len = deflen;
//游戏开始和结束
bool over;//结束线程3
bool over2;//结束线程1

//菜单界面
void menu()
{
	system("cls"); 
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
	cout << "贪吃蛇小游戏:" << endl;
	cout << "游戏规则:WASD控制上左下右,空格加速,吃豆子变长,别咬到自己!:" << endl;
	SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
	cout << "菜单:" << endl;
	cout << "1:贪吃蛇长度:3" << endl;
	cout << "2:贪吃蛇速度:500" << endl;
	SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
	cout << "输入数字1,2修改贪吃蛇" << endl<< "按空格键开始游戏。" << endl;
	Sleep(100);
	while (1)
	{
		if (GetAsyncKeyState('1') & 0x8000) {
			cout << "1:贪吃蛇长度:(1~7)" << endl; cin >>deflen; break;
		}
		if (GetAsyncKeyState('2') & 0x8000) {
			cout << "2:贪吃蛇速度:(200~800)" << endl;cin >> defspeed; break;
		}
		if (GetAsyncKeyState(VK_SPACE) & 0x8000) {Sleep(speed); break; }
	}
	len = deflen;
	speed = defspeed;
	sore = 0;
	ha = defha;
	hb = defhb;
	over = true;
	over2 = false;
}

//随机豆子坐标
void poin(int* spx, int* spy)
{
	srand(static_cast<unsigned int>(time(nullptr)));
	*spx = rand() % (x - 2) + 1;
	*spy = rand() % (x - 2) + 1;
	arr[*spx][*spy] = "* ";
}

//打印图像     线程1
void pict()
{
	while (1) {
		while(over)
		{
			while (over) {
				for (int i = 0; i < x; i++)
				{
					for (int j = 0; j < x; j++) { cout << arr[i][j]; }cout << endl;
				}
				cout << "分数: " << sore << endl;//分数
				cout << "放向: " << way << endl;//方向
				cout << "长度: " << len << endl;//长度
				cout << "头坐标: " << ha <<" | " << hb << endl;//头坐标
				cout << "速度: " << speed << endl;//速度
				cout << "第一身体坐标: " << abody[1] << " | " << bbody[1] << endl;//第一身体坐标
				Sleep(speed-(defspeed/5));
				system("cls");
			}
			for (int i = 0; i < 3; i++)
			{
				system("cls"); Sleep(500);
				for (int i = 0; i < x; i++)
				{
					for (int j = 0; j < x; j++) { cout << arr[i][j]; }cout << endl;
				}
				Sleep(500);
			}
			cout << "Game over!!!" << endl << "得分:  " << sore << endl;
			Sleep(1000);
			cout << "按空格键继续游戏!"<<endl<<"按P键回到菜单";
			while (1) {
				if (GetAsyncKeyState('P') & 0x8000) { over2 = true; break; }//P键回到菜单
				if (GetAsyncKeyState(VK_SPACE) & 0x8000) {sore = 0;over = true; len = deflen; break; }
			}//空格继续
		}
		menu();
		while (over2);
	}
}

//检测键盘输入   线程2
void cinkb()
{
	while (1)
	{
		while (1) {
			if (GetAsyncKeyState('W') & 0x8000 && way != 2) { way = 0; Sleep(speed); break; }
			if (GetAsyncKeyState('A') & 0x8000 && way != 3) { way = 1; Sleep(speed); break; }
			if (GetAsyncKeyState('S') & 0x8000 && way != 0) { way = 2; Sleep(speed); break; }
			if (GetAsyncKeyState('D') & 0x8000 && way != 1) { way = 3; Sleep(speed); break; }
			if (GetAsyncKeyState(VK_SPACE) & 0x8000) { speed = defspeed / 5; break; }
			Sleep(10);// 等待一段时间,避免过于频繁地检测按键
			speed = defspeed;
		}
		while (over2);
	}
}

//贪吃蛇主体   线程3
void actionpoint(int spx, int spy, int* pway)
{
	abody = new int[len]; bbody = new int[len];
	while(1){
		//无敌时间
		int SuperArmor = 0;
		//初始化身体
		for (int i = 0; i < len; i++) { abody[i] = ha; bbody[i] = hb; }
		//初始化随机豆子
		if (over)
			poin(&spx, &spy);
		while (over) {
			/贪吃蛇移动速度//
			Sleep(speed);
			//咬自己死亡/
			if (SuperArmor > 5) {
				for (int i = 0; i < len; i++) {
					if (ha == abody[i] && hb == bbody[i]) { over = false; break; }
				}
			}
			SuperArmor++;
			声明贪吃蛇和豆子位置/
			gamep();//图像刷新
			arr[abody[len - 1]][bbody[len - 1]] = "  ";//尾巴变空格
			arr[spx][spy] = "* ";//豆子
			for (int i = 0; i < len; i++) { arr[abody[i]][bbody[i]] = "□ "; }//身体
			arr[ha][hb] = "? ";  //头
			///吃豆=加分+加长度//
			if (ha == spx && hb == spy) {
				poin(&spx, &spy);
				sore++;
				//创建动态临时数组
				int* temabody = new int[len + 1];
				int* tembbody = new int[len + 1];
				//拷贝a数组并增长赋值
				for (int i = 0; i < len; i++)
				{
					temabody[i] = abody[i];
				}
				temabody[len] = abody[len - 1];
				abody = temabody;
				//拷贝b数组并增长赋值
				for (int i = 0; i < len; i++)
				{
					tembbody[i] = bbody[i];
				}
				tembbody[len] = bbody[len - 1];
				bbody = tembbody;
				//增加长度
				len++;
			}
			///缩进贪吃蛇身体
			for (int i = 1; i < len; i++)//身体缩进
			{
				abody[len - i] = abody[len - i - 1]; bbody[len - i] = bbody[len - i - 1];
			}
			abody[0] = ha; bbody[0] = hb;//头部跟踪
			///控制头部运动方向//
			switch (*pway) {
			case 0: if (ha != abody[0] + 1) { ha--; break; }
			case 1: if (hb != bbody[0] + 1) { hb--; break; }
			case 2: if (ha != abody[0] - 1) { ha++; break; }
			case 3: if (hb != bbody[0] - 1) { hb++; break; }
			}
			/循环穿墙运动
			if (ha < 1) { ha = x - 2; }//穿上
			if (ha >= x - 1) { ha = 1; }//穿下
			if (hb < 1) { hb = x - 2; }//穿左
			if (hb >= x - 1) { hb = 1; }//穿右
		}
	}
}

int main()
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_FONT_INFOEX fontInfo;
	fontInfo.cbSize = sizeof(CONSOLE_FONT_INFOEX);
	GetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
	fontInfo.dwFontSize.X = 25; // 设置字体宽度
	fontInfo.dwFontSize.Y = 40; // 设置字体高度
	SetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
	menu();
	thread thread3(actionpoint, spx, spy, &way);//贪吃蛇主体 线程
	thread thread2(cinkb);//录入键盘 线程
	thread thread1(pict);//显示图像 线程
	thread1.join();
	thread2.join();
	thread3.join();
	return 0;
}

详细说明都在源码上,默认参数基本都可调。

文章来源:https://blog.csdn.net/2301_81450492/article/details/135352041
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。