#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;
}
详细说明都在源码上,默认参数基本都可调。