using namespace std;
#include <iostream>
#include<conio.h>
#include<Windows.h>
enum MapState//地图说明
{
ROAD,WALL,HEAD,BODY,FOOD//road路,wall墙,head头,body身子,food食物
};
//声明地图,空的
int map[15][15];
HANDLE h;//声明句柄h
//蛇最长有10个长度,内层数组存的是x,y,
int snake[20][2];
int curCount;//蛇当前长度 count连续的
int foodX;//声明食物的坐标x,y
int foodY;
/// <summary>
/// 记录是否死亡
/// </summary>
bool isDead;
/// <summary>
/// 初始化地图
/// </summary>
void Init();//初始化
/// <summary>
/// 展示地图
/// </summary>
void Show();//显示
/// <summary>
/// 画蛇,把蛇画到地图里
/// </summary>
void DrawSnake();
/// <summary>
/// 移动蛇
/// </summary>
void Move(char c);
/// <summary>
/// 生成食物
/// </summary>
void SetFoodPosition();
/// <summary>
/// 画出食物
/// </summary>
void DrawFood();
/// <summary>
/// 判断能移动的
/// </summary>
/// <returns></returns>
bool IsCanMove();
/// <summary>
/// 移动身体
/// </summary>
void MoveBody();
void samm(char a);
void null1();
int main()
{
srand(time(NULL));//随机数的种子
curCount = 3;//初始化的蛇的坐标
snake[0][0] = 5;
snake[0][1] = 5;
snake[1][0] = 5;
snake[1][1] = 6;
snake[2][0] = 5;
snake[2][1] = 7;
char dir = '1';
SetFoodPosition();//生成食物
while (true)
{
isDead = false;//初始死亡判断,false,没死
if (_kbhit())//判断按键
{
dir = _getch();
}
Init();//初始化地图
DrawSnake();//画蛇
DrawFood();//画食物
Show();//赋值图案
if (curCount==20)//蛇长度为10的时候打印通关,结束游戏
{
cout << endl<<" 恭喜通关";Sleep(1000);
cout << endl<< " 恭喜通关"; Sleep(1000);
cout << endl<< " 恭喜通关"; Sleep(1000);
cout << endl<< " 恭喜通关"; Sleep(1000);
/* int a;
cin >> a;*/
return 0;
}
Move(dir);//移动
if (isDead)//如果死亡,打印游戏结束,停止游戏
{
cout << endl;
cout << " Game Over" << endl;Sleep(1000);
cout << " 游戏结束" << endl; Sleep(1000);
cout << " 再来一次" << endl; Sleep(1000);
char a;
cin >> a;
samm(a);
return 1;
}
Sleep(100);//帧率
CONSOLE_CURSOR_INFO info;//隐藏光标
GetConsoleCursorInfo(h, &info);
info.bVisible = false;
SetConsoleCursorInfo(h, &info);
}
}
void null1() {
cout << " " << endl;
cout << " " << endl;
cout << " " << endl;
};
void samm(char a)
{
if (a=='1')
{
main();
}
else
{
cout << " 再见 " << endl; return;
}
};
/// <summary>
/// 画出食物
/// </summary>
void DrawFood()
{
map[foodY][foodX]=FOOD;//食物定义赋值到地图上的食物的坐标
};
void SetFoodPosition()//生成食物
{
foodX = rand() % 13 + 1;//生成食物坐标x,y
foodY = rand() % 13 + 1;
};
/// <summary>
/// 身体的移动,倒数第二节身子坐标赋值给最后一节身子坐标,
/// 以此类推,组成蛇身体的移动,蛇头不用赋值,
/// </summary>
void MoveBody()
{//下标比里面的空间多1,蛇头不赋值从1开始,所以大于0
for (int i = curCount-1; i>0; i--)
{
snake[i][0] = snake[i - 1][0];
snake[i][1] = snake[i - 1][1];
}
};//身子移动
/// <summary>
/// 判断x ,y这个坐标点是否能移动到这个位置
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
bool IsCanMove(int x,int y)//判断蛇移动的能移动的地方
{
MapState m = (MapState)map[y][x];//地图坐标赋值给枚举类型 用强转
switch (m)
{
case WALL://墙无法通过
isDead = true;//死亡判断,true,死了
return false;
case BODY://身子无法通过
//isDead = true;没有解决相反按键问题
return false;
case FOOD://食物可以通过
curCount++;//通过食物的时候,蛇长度加加
SetFoodPosition();//食物坐标刷新
return true;
}
return true;//其他的可以通过
};
void Move(char c)//蛇的移动
{
switch (c)
{
case 'W':
case 'w'://x,y-1 要移动的位置提前一格判定
if (IsCanMove(snake[0][0], snake[0][1] - 1))
{
MoveBody();
snake[0][1] --;
}
break;
case 'S':
case 's':
if (IsCanMove(snake[0][0], snake[0][1] + 1))
{
MoveBody();
snake[0][1]++;
}
break;
case 'A':
case 'a':
if (IsCanMove(snake[0][0]-1, snake[0][1] ))
{
MoveBody();
snake[0][0]--;
}
break;
case 'D':
case 'd':
if (IsCanMove(snake[0][0]+1, snake[0][1]))
{
MoveBody();
snake[0][0]++;
}
break;
default:
break;
}
};
void Init() //初始化地图,将墙,路赋值给到坐标
{ //获取句柄权限在初始化地图,统一初始化最好H
h = GetStdHandle(STD_OUTPUT_HANDLE);
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
if (i == 0 || i == 14 || j == 0 || j == 14)
{
map[i][j] = (int)WALL;
}
else
{
map[i][j] = (int)ROAD;
}
}
}
};//初始化
void Show()//展示地图
{
COORD W{ 0,0 };//坐标 1
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
W.X = j * 2; //2画图形之前设置位置
W.Y = i; //3
SetConsoleCursorPosition(h, W);//获取控制台光标位置(控制控制台)//4固定位置
WORD w ;//颜色
//SetConsoleTextAttribute(h, w);//控制文本
MapState m = (MapState)map[i][j];//枚举应用,将地图坐标赋值给枚举分类
switch (m)
{
case ROAD:
cout << " ";
break;
case WALL:
{w = 9;//颜色
SetConsoleTextAttribute(h, w);//控制文本
cout << "墙"; }
break;
case HEAD://需要开空间的时候用大括号
{w = 2;//颜色
SetConsoleTextAttribute(h, w);
cout << "■"; }
break;
case BODY:
{w = 4;//颜色
SetConsoleTextAttribute(h, w);
cout << "Λ"; }
break;
case FOOD:
{w = 6;//颜色
SetConsoleTextAttribute(h, w);}//控制文本
cout << "卐";
break;
}
}
};
}//显示
void DrawSnake() //画蛇
{
for (int i = 0; i < curCount; i++)
{
int x= snake[i][0];//代表x
int y= snake[i][1];//代表y x,y表示地图上的xy
if (i==0)
{
map [y][x] =(int) HEAD;//蛇头位置
}
else
{
map[y][x] =(int) BODY;//蛇身位置
}
}
};
视频在其他地方,感兴趣可以看看