请注意: 1.这是c++代码,请建立.cpp文件而不是.c文件,然后将代码拷贝进去,再使用c++编译器进行编译运行。
2.因为使用了一些c++11标准当中的语法,所以c++编译器的编译标准至少需要设置到c++11以上,不然会报错。编译标准可以在你的IDE里设置,或者使用命令行编译时附加-std=c++11选项。
3.代码中使用了getch()函数,用于无回显的接收用户输入;使用了kbhit()函数用于判断用户是否按下键盘。但是如果你在visual studio中直接运行本代码可能会报错,你可以将上述两个函数替换为_getch()函数和_kbhit()函数就可以了。
1.数据结构分析:这里我采用双向队列的数据结构存储蛇身节点,目的是:方便,减少屏闪。并且双向队列也能更好的体现贪吃蛇本身的特点。有利于实现,且效率也较高。
2.程序运行分析程序开始用户随机按下w,a,s,d中任意按键开始游戏并且作为蛇运动的初始方向(如果刚开始觉得蛇的运动速度太慢可以键入’v’使变为当前运行素的1.25倍速,键入’b’则会使之变为当前速度的2/3倍速),然后进入循环持续游戏直到游戏结束,显示分数之后用户输入任意按键退出游戏。
3.难点分析 1.蛇移动怎么显示?这也就是我采用双向队列的原因,蛇每运动一步,就从双向队列中弹出队尾,然后将新的队首(即蛇头)压入队列首部,然后再清除蛇尾打印蛇身即可,不需要对贪吃蛇全部进行清楚以及打印,可以极大的减少程序运行过程中出现的闪烁现象。如果吃到食物那么本次运动就会在将蛇尾变为蛇头的同时再加入一个蛇身达到使蛇身长度加一的目的(我认为双向队列更能从本质上体现贪吃蛇本来的特点,而每次弹出队尾,加入队首而不对中间的蛇身进行改变也使程序变得更加简洁,运行更流畅)
2.怎么控制吃到食物后蛇的速度的变化?最开始我设置初始速度为1000(即:Sleep()函数的参数为1000)每次吃到食物就将速度乘以0.8以此达到加速的目的。但我发现到后面速度越来越快没有上限,根本无法控制。 解法:设置一个上限为MaxSpeed,则速度为 MaxSpeed + Index,MaxSpeed 保持不变且较小作为蛇速度的渐进上限,每次乘以0.8(可自定义)则乘到Index上面,这样的话速度就不会无限制的上升。
3.怎么解决屏幕闪烁?解:不要使用system(“cls”);清屏函数,使用函数SetConsoleCursorPosition控制光标填充空格进行覆盖能大大减少屏闪问题!!这一点要注意了!
4.一些废话1.首先肯定是存储蛇身的数据结构方面,有很多种选择:链表,双向队列,循环队列,vector甚至数组都可以用来存储蛇身。 2.最开始以为这个比较简单…上手就开始写写废了一次,提醒大家在写程序(特别是这种结构比较复杂且步骤较多的程序)时一定要先进行规划,想清楚要使用的数据结构以及构建方式,想清楚再写,避免浪费时间。
5.源代码下面是源代码,还需要什么功能大家可以在此基础上进行改动。
#include#include#include#include#include#includeusing namespace std;struct Snake {//蛇类结构体char image;short x, y; //坐标};class snakeGame {public:snakeGame();void printMap();// 控制光标移动void gotoxy(short x, short y) {hOut = GetStdHandle(STD_OUTPUT_HANDLE); //获取句柄pos = {x, y};SetConsoleCursorPosition(hOut, pos); //移动光标}//隐藏光标void HideCursor(){HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态}// 初始化蛇身,可根据需要更改初始长度void initSnake() {snake.push_front({'@', width / 2, height / 2});for (int i=0; i