首先,非常感谢白家名大佬参考提供的思路与方法,非常感谢!
void gotoxy(int x, int y) //光标定位
{
COORD pos = {
x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
这个函数需要用windows.h头文件,能把光标移动到指定的坐标位置,参考:光标定位
有了这个函数,就可以在指定位置生成蛇头,蛇身以及食物了。
通过系统命令可以:
system("mode con cols=a lines=b "); //设置控制台窗口大小
system("title xxxxxx"); //设置控制台的标题
这里设置窗口大小为88*28,并将标题改为贪吃蛇。
利用刚才定义好的gotoxy函数即可在指定位置生成食物
gotoxy(x, y); //在确认好的位置输出食物
cout << "★";
但是为了让食物能够随机生成,所以需要利用rand()函数函数介绍
因为我们设置的食物★在控制台中所占位置为2*2的,所以88*28的控制台食物的x最大为86,y最大为24.
所以食物类:
//食物类
class Food
{
private:
int m_x;
int m_y;
public:
void randfood() //随机产生一个食物
{
srand((int)time(NULL));//利用时间添加随机数种子,需要ctime头文件
L1:
m_x = rand() % (85) + 2;//2~86
m_y = rand() % (25) + 2;//2~26
if (m_x % 2) //如果食物的x坐标不是偶数则重新确定食物的坐标
goto L1;
gotoxy(m_x, m_y); //在确认好的位置输出食物
cout << "★";
}
int getFoodm_x() //返回食物的x坐标
{
return m_x;
}
int getFoodm_y() //返回食物的y坐标
{
return m_y;
}
食物生成时还要注意,如果生成的食物与蛇身重合,那么要重新生成一次,这点在蛇类里解决。
为什么食物坐标需要偶数:
本来不明白为什么,后来通过询问原作者明白了原因
我们创建的蛇是这样的:
在图片中我们可以看出,蛇各部位的长和宽是等长的,而实际上控制台中x和y是这样子的:
这里可以看出,控制台两个x坐标才相当于一个y坐标
后面设计的蛇头初始位置x坐标为偶数,如果食物是奇数的,那么蛇头将碰不到食物
在控制台中用■■■■■■●来表示蛇
这里需要用到两个函数
conio.h 头文件里包含 _getch() 和 _kbhit()两个函数
_getch()函数作用:
getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!百度百科 这个函数用来读取从键盘输入的字符来进行操作
_kbhit()函数作用:
kbhit()是一个C和C++函数,用于非阻塞地响应键盘输入事件。其中文可译为“键盘敲击”(keyboard hit)。百度百科,它的的功能是: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0,因为它无论有没有都会返回,所以称为非阻塞函数,而getch() 在执行时,检测按下什么键,如果不按键就不返回所以称为阻塞函数 这里用kbhit()来检测键盘是否有输入
构建一个游戏结束时的界面:
//游戏结束时设计一个界面输出“游戏结束”以及分数
void finmatt(const int score)
{
system("cls");//清屏然后输出
gotoxy(40, 14);
cout << "游戏结束";
gotoxy(40, 16);
cout << "得分:" << score;
gotoxy(0, 26);
exit(0);//exit为C++的退出函数 exit(0)表示程序正常退出,非0表示非正常退出
}
贪吃蛇结束有两种可能:1是蛇头触碰到墙,即边界,2是蛇头碰触到蛇身
撞墙:蛇头的x坐标或者y坐标超出边界的范围即是撞墙
撞到自己:遍历自身,如果蛇头的xy坐标都与蛇身相同则是撞到自身。
//游戏结束
void finishgame(const int score)
{
//撞墙
if (snakecoor[0].x >= 88 || snakecoor[0].x < 0 || snakecoor[0].y >= 28 || snakecoor[0].y < 0)
finmatt(score);
//撞到自身
for (int i = 1; i < snakecoor.size(); i++)
if (snakecoor[0].x == snakecoor[i].x && snakecoor[0].y == snakecoor[i].y)
finmatt(score);
}
同时,还需要将蛇的位置初始化并且构造一个蛇运动的函数,将它们都封装进蛇类里。
蛇类:
//蛇类
class Snake
{
private:
struct Snakecoor//定义一个蛇的坐标机构
{
int x;
int y;
};
vector<Snakecoor> snakecoor;//将坐标存入vector容器中
//判断并改变前进方向的函数
void degdir(Snakecoor& nexthead) //定义新的蛇头变量