和小白一起做贪吃蛇吧!会C++就可以上车!
小白第一次写文章,如有不足之处,欢迎大家指出!
因为本人是新手,所以尽量使用通俗易懂的话,没有太多专业术语,不太会用目录,大佬还请多多包涵!
前言:本文所有的方向用8,2,4,6表示,对应小键盘上的↑,↓,←,→,这么做可以直观地看出方向,方便程序的编写。
考虑到有读者可能不了解一些游戏必备的函数,所以我做了简要的介绍,大佬请跳过*部分。
首先,我们定义一个Snake类封装贪吃蛇游戏,并声明一些基本的变量和成员函数:
class Snake {
private:
signed char**map;//游戏地图
int length;//蛇的长度
int head[2];//蛇头坐标
int tail[2];//蛇尾坐标
char direction;//描述蛇的移动方向:8-↑,2-↓,4-←,6-→
char speed;//蛇的速度
void print()const; //显示游戏地图的函数
int move() ;//移动函数:0-正常移动,1-撞墙,2-咬到自己
void turn(int const&kbinput) ;//转弯函数
void create() ;//生成食物的函数
}
核心设计思路:
游戏地图map为二维数组,如果数组元素map[ i ][ j ]的值为0,代表该位置什么也没有;如果map[ i ][ j ]的值>0,代表该位置是蛇的身体;如果 -1 == map[ i ][ j ],代表该位置是食物;如果map[ i ][ j ] > 0,代表该位置是蛇的头部。
如果把蛇的头部和身体都用一个定值来表示,则我们无法描述蛇的形状,也无从得知蛇头在哪里;所以我们不妨用8,2,4,6作为方向指针来描述蛇的身体,用-8,-2,-4,-6作为方向指针来描述蛇的头部。蛇的身体任何位置沿蛇的身体指向头部,蛇的头部指向蛇的身体,如果这段解释很难读懂,请看下面的例子:
例1:蛇头向右,长度为5的一条蛇,可以表示为:→→→→←即6 6 6 6 (-4)
例2:蛇头向右的一条蛇
→→→↓□□□→←
□□□→→→→↑
可以表示为:
6 6 6 2 0 0 0 6 (-4)
0 0 0 6 6 6 6 8
移动函数move():
我们很容易想到,蛇的移动可以通过“加头去尾”实现,即把蛇尾去掉,在蛇的移动方向加上新的蛇头。这个过程可以拆分成蛇头操作和蛇尾操作:
1)蛇头操作:先现在的蛇头,在移动后将成为蛇的身体;然后根据蛇的移动方向,生成一个新的蛇头:
int move() {//返回值:0-正常移动,1-撞墙,2-咬到自己
//direction是描述蛇的移动方向的变量成员:8-↑,2-↓,4-←,6-→
switch (direction) {
int front;//判断蛇头前方有无障碍物的变量
case 8://向上移动
if (head[0]) {
if ((front = map[head[0] - 1][head[1]]) > 0)return 2;//如果蛇头上方是蛇的身体,则咬到自己,返回2
map[head[0]--][head[1]] = 8;//当前蛇头位置指向新蛇头位置(上)
map[head[0]][head[1]] = -2;//新蛇头位置指向蛇身
return 0;//正常移动,返回0
}
else return 1;//如果0==head[0]则撞墙,返回1
case 2://向下移动
if (head[0] < maxRow - 1) {
if ((front = map[head[0] + 1][head[1]]) > 0)return 2;//如果蛇头下方是蛇的身体,则咬到自己,返回2
map[head[0]++][head[1]] = 2;//当前蛇头位置指向新蛇头位置(下)
map[head[0]][head[1]] = -8;//新蛇头位置指向蛇身
return 0;//正常移动,返回0
}
else return 1;//如果maxRow-1==head[0]则撞墙,返回1
case 4://向左移动
if (head[1]) {
if ((front = map[head[0]][head[1] - 1]) > 0)return 2;//如果蛇头左方是蛇的身体,则咬到自己,返回2
map[head[0]][head[1]--] = 4;//当前蛇头位置指向新蛇头位置(左)
map[head[0]][head[1]] = -6;//新蛇头位置指向蛇身
return 0;//正常移动,返回0
}
else return 1;//如果0==head[1]则撞墙,返回1
case 6://向右移动
if (head[1] < maxCol - 1) {
if ((front = map[head[0]][head[1] + 1]) > 0) return 2;//如果蛇头右方是蛇的身体,则咬到自己,返回2
map[head[0]][head[1]++] = 6;//当前蛇头位置指向新蛇头位置(右)
map[head[0]][head[1]] = -4;//新蛇头位置指向蛇身
return 0;//正常移动,返回0
}
else return 1;//如果maxCol-1==head[0]则撞墙,返回1
2)蛇尾操作:由于蛇尾是沿蛇的身体指向蛇头的,所以只需要将蛇尾指向的位置设为新的蛇尾,我们将下面这段代码补充到move()函数中
switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;//如果蛇尾指向上,则蛇尾横坐标-1
case 2:map[tail[0]++][tail[1]] = 0; break;//如果蛇尾指向下,则蛇尾横坐标+1
case 4:map[tail[0]][tail[1]--] = 0; break;//如果蛇尾指向左,则蛇尾纵坐标-1
case 6:map[tail[0]][tail[1]++] = 0; break;//如果蛇尾指向上,则蛇尾纵坐标+1
}
这样我们就完成了移动函数move()的定义,其他的函数相对简单,需要的读者可以继续往下看:
转弯函数turn():
需要注意的是,不是所有情况下都可以改变蛇的方向,比如蛇正在往右走,就不能把方向设置成左,也没必要把方向设置成右
//根据参数kbint来调整蛇的方向
void turn(int const&kbinput) {
switch (kbinput) {
case 8:if (4 == direction || 6 == direction)direction = 8; break;//如果蛇左右移动,则把方向设置成上
case 2:if (4 == direction || 6 == direction)direction = 2; break;//如果蛇左右移动,则把方向设置成下
case 4:if (8 == direction || 2 == direction)direction = 4; break;//如果蛇上下移动,则把方向设置成左
case 6:if (8 == direction || 2 == direction)direction = 6; break;//如果蛇上下移动,则把方向设置成右
}
}
生成食物的函数create():
*食物是随机生成的,需要用到rand()函数,该函数在头文件或<stdlib.h>中,rand()函数的功能是返回一个0~RAND_MAX的随机值,RAND_MAX是一个很大的值,在本文中不做介绍,请读者自行查阅。
*需要注意的是,rand()函数返回的是一个假随机值,要得到相对真的随机值,需要设置随机数的种子为随机值,时间是随机的,所以我们用时间作为种子:
#include<cstdlib>
//将下面的代码放在游戏开始前
srand((unsigned)time(NULL));
设置了随机数的种子后,我们就可以使用随机数了:
void create() {
int position[2];//食物的坐标
do {
position[0] = rand() % maxRow;//食物的行坐标为随机数除最大行数的余数,这样可以得到0到maxRow-1的一个随机数
position[1] = rand() % maxCol;//食物的列坐标为随机数除最大列数的余数,这样可以得到0到maxCol-1的一个随机数
} while (map[position[0]][position[1]]);//不能在蛇的身体上生成食物
map[position[0]][position[1]] = -1;//按照我们的规定,在地图上把食物用-1表示
}
完成了生成食物函数的书写,我们需要进一步完善移动函数move():
还记得move()函数的实现原理吗?“加头去尾”。那么吃到了食物后,我们希望蛇的长度增加,为了实现这个功能,应该"加头不去尾":
//在move()函数中加入条件判断语句,向上移动为例:
if (front < 0) { create(); length++; }//如果蛇头前方是食物,则食物会被吃掉->调用create()新生成一个食物,蛇的长度增加
//以下部分不变
else switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;
case 2:map[tail[0]++][tail[1]] = 0; break;
case 4:map[tail[0]][tail[1]--] = 0; break;
case 6:map[tail[0]][tail[1]++] = 0; break;
}
显示游戏地图的函数print()很简单,读者可以根据自己的喜好书写。
有了移动,转弯,生成食物和显示的函数,游戏的核心已经完备,下面我们在Snake类中添加一个GameStart()函数,用来集成这些函数,实现基本的游戏功能,不过在这之前我们先了解2个重要的函数:
*_getch()函数,和getchar()函数相似,不过_getch()函数可以直接读取键盘输入的字符,不用再敲击回车键,适合用来做控制台游戏。
*_kbhit()函数,如果有键盘输入,则返回一个非零值,否则返回零值。这个函数是非阻塞的,它不会暂停游戏的进程。我们希望不按键盘时蛇也会动,所以这个函数是必要的。
*以上2个函数在头文件<conio.h>中,这是一个非标准库。
用_getch()函数和_kbhit()函数完成基本游戏功能:
#include<conio.h>
public:
void GameStart() {
srand((unsigned)time(NULL));//设置随机数的种子
while (true) {
print();//显示地图
//如果_kbhit()函数检测到键盘输入,则调用_getch()函数读取,否则游戏进程继续
if (_kbhit())switch (_getch()) {
case'w':case'W':turn(8); break;//如果输入w,则调用转弯函数turn(),参数为上
case's':case'S':turn(2); break;//如果输入s,则调用转弯函数turn(),参数为下
case'a':case'A':turn(4); break;//如果输入a,则调用转弯函数turn(),参数为左
case'd':case'D':turn(6); break;//如果输入d,则调用转弯函数turn(),参数为右
}
if (move());//GameOver//如果move()函数的返回非零值,则游戏失败,游戏失败后怎么做请读者自行设计
}
}
有了游戏的基本框架,我们再来设计一些能丰富游戏性的功能:
我们希望蛇的长度增加时,游戏速度会加快,在设计这个功能之前,我们先了解Sleep()函数,知道CLOCK_PER_SEC的读者请跳过
Sleep()函数可以暂停游戏的进程,暂停的时间取决于参数,例如:
Sleep(1000);//休眠1000个单位时间,不是1000秒!
一般来说1秒有1000个单位时间,所以暂停几秒就Sleep几千。
在GameStart()函数中加入下面的代码,达到控制游戏速度的目的:
Sleep(1000/speed);//speed是蛇的速度
蛇的速度应该和蛇的长度相关,需要一定的计算公式,但是我们第一次编程时可能不知道多少合适,所以用宏来编写:
#define _SPEED(_LENGTH) _LENGTH-3//例如:蛇的速度=蛇的长度-3,速度公式宏读者可以自由改写
//将下面的代码加在create()函数末尾,因为生成了食物则蛇的长度一定发生了改变,则速度应该随之改变
speed=_SPEED(length);
到这里,简易的贪吃蛇游戏就写完了,最后附上完整代码:
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
/*作者的话:
**游戏名称:OC贪吃蛇/OCSnake
**游戏版本:1.0
**游戏规则:WSAD控制光标,空格暂停,ENTER确定,ESC退出
*/
//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
#include<iostream>
#include<string>
#include<Windows.h>
#include<ctime>
#include<conio.h>
using namespace std;
#define _SPEED(_LENGTH) _LENGTH>6?_LENGTH:6//蛇的速度
#define _SCORE(_LENGTH) _LENGTH//游戏得分
//贪吃蛇
class Snake {
public:
//默认构造函数
Snake() :length(3), direction(6), speed(3), maxRow(10), maxCol(15), initLength(3) {
map = new signed char*[maxRow];
int count;
for (count = 0; count < maxRow; count++) {
map[count] = new signed char[maxCol];
memset(map[count], 0, maxCol);
}
head[0] = 0; head[1] = 2;
tail[0] = 0; tail[1] = 0;
for (count = 0; count < 2; count++)
map[0][count] = 6;
map[0][count] = -4;
system("title OCSnake");
system(string("mode con cols=" + to_string(2 * maxCol + 4) + " lines=" + to_string(maxRow + 2)).c_str());
create();
}
//构造函数:MRow>=8,MCol>=10
Snake(int const&MRow, int const&MCol, int const&init_length = 3) :direction(6), maxRow(MRow), maxCol(MCol), initLength(init_length) {
length = initLength;
map = new signed char*[maxRow];
int count;
for (count = 0; count < maxRow; count++) {
map[count] = new signed char[maxCol];
memset(map[count], 0, maxCol);
}
head[0] = 0; head[1] = initLength - 1;
tail[0] = 0; tail[1] = 0;
for (count = 0; count < initLength - 1; count++)
map[0][count] = 6;
map[0][count] = -4;
system("title OCSnake");
system(string("mode con cols=" + to_string(2 * maxCol + 4) + " lines=" + to_string(maxRow + 2)).c_str());
create();
}
//游戏开始
void GameStart() {
srand((unsigned)time(NULL));
LABEL_MAIN_WINDOW://主窗口标签
if (MainWindow())
if (QuitOrNot())goto LABEL_MAIN_WINDOW;
else exit(0);
else if (ChooseMode())goto LABEL_MAIN_WINDOW;
Sleep(CLOCKS_PER_SEC);
char pause_before_continue = 0;
while (true) {
print();
if (pause_before_continue) { Sleep(CLOCKS_PER_SEC); pause_before_continue = 0; }
if (_kbhit())switch (_getch()) {
case'w':case'W':turn(8); break;
case's':case'S':turn(2); break;
case'a':case'A':turn(4); break;
case'd':case'D':turn(6); break;
case 27:case 32: LABEL_PAUSE_WINDOW://暂停窗口
if (0 == pause()) {
if (0 == ReturnToMainWindow())goto LABEL_MAIN_WINDOW;
else goto LABEL_PAUSE_WINDOW;
}pause_before_continue = 1;
break;
}if (move()) { Sleep(CLOCKS_PER_SEC); score(); goto LABEL_MAIN_WINDOW; }
Sleep(CLOCKS_PER_SEC / speed);
}
}
//析构函数
~Snake() {
int count;
for (count = 0; count < maxCol; count++)
delete[]map[count];
delete[]map;
}
private:
signed char**map;//地图
int length;//蛇的长度
int head[2];//蛇头坐标
int tail[2];//蛇尾坐标
char direction;//移动方向:8-↑,2-↓,4-←,6-→
char speed;//蛇的速度
const char maxRow;//地图最大行数
const char maxCol;//地图最大列数
const char initLength;//初始蛇长
char mode;//游戏模式:0-正常模式,1-无障碍模式
//打印
void print()const {
int i, j; signed char judge;
for (i = 0; i < maxCol + 2; i++)cout << "□";
cout << endl;
for (i = 0; i < maxRow; i++) {
cout << "□";
for (j = 0; j < maxCol; j++) {
judge = map[i][j];
if (0 == judge)cout << " ";
else if (judge > 0)cout << "■";
else if (-1 == judge)cout << "◇";
else cout << "¤";
}cout << "□" << endl;
}for (i = 0; i < maxCol + 2; i++)cout << "□";
}
//移动:0-正常移动,1-撞墙,2-咬到自己
int move() {
int front;
if (0 == mode) {
switch (direction) {
case 8:
if (head[0]) {
if ((front = map[head[0] - 1][head[1]]) > 0)return 2;
map[head[0]--][head[1]] = 8;
map[head[0]][head[1]] = -2;
if (front < 0) { create(); length++; }
else switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;
case 2:map[tail[0]++][tail[1]] = 0; break;
case 4:map[tail[0]][tail[1]--] = 0; break;
case 6:map[tail[0]][tail[1]++] = 0; break;
}return 0;
}
else return 1;
case 2:
if (head[0] < maxRow - 1) {
if ((front = map[head[0] + 1][head[1]]) > 0)return 2;
map[head[0]++][head[1]] = 2;
map[head[0]][head[1]] = -8;
if (front < 0) { create(); length++; }
else switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;
case 2:map[tail[0]++][tail[1]] = 0; break;
case 4:map[tail[0]][tail[1]--] = 0; break;
case 6:map[tail[0]][tail[1]++] = 0; break;
}return 0;
}
else return 1;
case 4:
if (head[1]) {
if ((front = map[head[0]][head[1] - 1]) > 0)return 2;
map[head[0]][head[1]--] = 4;
map[head[0]][head[1]] = -6;
if (front < 0) { create(); length++; }
else switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;
case 2:map[tail[0]++][tail[1]] = 0; break;
case 4:map[tail[0]][tail[1]--] = 0; break;
case 6:map[tail[0]][tail[1]++] = 0; break;
}return 0;
}
else return 1;
case 6:
if (head[1] < maxCol - 1) {
if ((front = map[head[0]][head[1] + 1]) > 0) return 2;
map[head[0]][head[1]++] = 6;
map[head[0]][head[1]] = -4;
if (front < 0) { create(); length++; }
else switch (map[tail[0]][tail[1]]) {
case 8:map[tail[0]--][tail[1]] = 0; break;
case 2:map[tail[0]++][tail[1]] = 0; break;
case 4:map[tail[0]][tail[1]--] = 0; break;
case 6:map[tail[0]][tail[1]++] = 0; break;
}return 0;
}
else return 1;
default:return -1;
}
}
else {
char judge;
switch (direction) {
case 8:
if (head[0]) {
if ((front = map[head[0] - 1][head[1]]) > 0)return 2;
map[head[0]--][head[1]] = 8;
map[head[0]][head[1]] = -2;
}
else {
if ((front = map[maxRow - 1][head[1]]) > 0)return 2;
map[head[0]][head[1]] = 8; head[0] = maxRow - 1;
map[head[0]][head[1]] = -2;
}
if (front < 0) { create(); length++; }
else {
judge = map[tail[0]][tail[1]]; map[tail[0]][tail[1]] = 0;
switch (judge) {
case 8: if (tail[0])tail[0]--; else tail[0] = maxRow - 1; break;
case 2: if (tail[0] < maxRow - 1)tail[0]++; else tail[0] = 0; break;
case 4: if (tail[1])tail[1]--; else tail[1] = maxCol - 1; break;
case 6:if (tail[1] < maxCol - 1)tail[1]++; else tail[1] = 0; break;
}
}return 0;
case 2:
if (head[0] < maxRow - 1) {
if ((front = map[head[0] + 1][head[1]]) > 0)return 2;
map[head[0]++][head[1]] = 2;
map[head[0]][head[1]] = -8;
}
else {
if ((front = map[0][head[1]]) > 0)return 2;
map[head[0]][head[1]] = 2; head[0] = 0;
map[head[0]][head[1]] = -8;
}
if (front < 0) { create(); length++; }
else {
judge = map[tail[0]][tail[1]]; map[tail[0]][tail[1]] = 0;
switch (judge) {
case 8: if (tail[0])tail[0]--; else tail[0] = maxRow - 1; break;
case 2: if (tail[0] < maxRow - 1)tail[0]++; else tail[0] = 0; break;
case 4: if (tail[1])tail[1]--; else tail[1] = maxCol - 1; break;
case 6:if (tail[1] < maxCol - 1)tail[1]++; else tail[1] = 0; break;
}
}return 0;
case 4:
if (head[1]) {
if ((front = map[head[0]][head[1] - 1]) > 0)return 2;
map[head[0]][head[1]--] = 4;
map[head[0]][head[1]] = -6;
}
else {
if ((front = map[head[0]][maxCol - 1]) > 0)return 2;
map[head[0]][head[1]] = 4; head[1] = maxCol - 1;
map[head[0]][head[1]] = -6;
}
if (front < 0) { create(); length++; }
else {
judge = map[tail[0]][tail[1]]; map[tail[0]][tail[1]] = 0;
switch (judge) {
case 8: if (tail[0])tail[0]--; else tail[0] = maxRow - 1; break;
case 2: if (tail[0] < maxRow - 1)tail[0]++; else tail[0] = 0; break;
case 4: if (tail[1])tail[1]--; else tail[1] = maxCol - 1; break;
case 6:if (tail[1] < maxCol - 1)tail[1]++; else tail[1] = 0; break;
}
}return 0;
case 6:
if (head[1] < maxCol - 1) {
if ((front = map[head[0]][head[1] + 1]) > 0) return 2;
map[head[0]][head[1]++] = 6;
map[head[0]][head[1]] = -4;
}
else {
if ((front = map[head[0]][0]) > 0) return 2;
map[head[0]][head[1]] = 6; head[1] = 0;
map[head[0]][head[1]] = -4;
}
if (front < 0) { create(); length++; }
else {
judge = map[tail[0]][tail[1]]; map[tail[0]][tail[1]] = 0;
switch (judge) {
case 8: if (tail[0])tail[0]--; else tail[0] = maxRow - 1; break;
case 2: if (tail[0] < maxRow - 1)tail[0]++; else tail[0] = 0; break;
case 4: if (tail[1])tail[1]--; else tail[1] = maxCol - 1; break;
case 6:if (tail[1] < maxCol - 1)tail[1]++; else tail[1] = 0; break;
}
}return 0;
default:return -1;
}
}
}
//转弯
void turn(int const&kbinput) {
switch (kbinput) {
case 8:if (4 == direction || 6 == direction)direction = 8; break;
case 2:if (4 == direction || 6 == direction)direction = 2; break;
case 4:if (8 == direction || 2 == direction)direction = 4; break;
case 6:if (8 == direction || 2 == direction)direction = 6; break;
}
}
//生成食物
void create() {
int position[2];
do {
position[0] = rand() % maxRow;
position[1] = rand() % maxCol;
} while (map[position[0]][position[1]]);
map[position[0]][position[1]] = -1;
speed = _SPEED(length);
}
//暂停游戏:0-返回主界面,1-继续游戏
int pause() {
int i, j; signed char judge;
for (i = 0; i < maxCol + 2; i++)cout << "□";
cout << endl;
for (i = 0; i < maxRow / 2 - 3; i++) {
cout << "□";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "□" << endl;
}
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "◣ "; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■◣ "; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■■◣"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■■◤"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■◤ "; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
cout << "□"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "◤ "; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "□" << endl;
for (; i < maxRow - 6; i++) {
cout << "□";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "□" << endl;
}
for (i = 0; i < maxCol + 2; i++)cout << "□";
judge = _getch();
while (judge != 27 && judge != 32)judge = _getch();
return 27 == judge ? 0 : 1;
}
//主界面:0-开始,1-退出
int MainWindow() {
system("cls");
char cursor = 0, position = 0;
do {
unsigned short i, j;
for (i = 0; i < maxCol + 2; i++)cout << "■";
cout << endl;
for (i = 0; i < maxRow / 2 - 1; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}
cout << "■"; for (j = 0; j < maxCol - 8; j++)cout << ' '; cout << "OC贪吃蛇/OCSnake"; for (j = 0; j < maxCol - 8; j++)cout << ' '; cout << "■" << endl;
cout << "■"; for (j = 0; j < maxCol - 4; j++)cout << ' '; cout << "开始游戏";
if (0 == position)cout << "←"; for (j = 2 - 2 * position; j < maxCol - 4; j++)cout << ' '; cout << "■" << endl;
cout << "■"; for (j = 0; j < maxCol - 4; j++)cout << ' '; cout << "退出游戏";
if (position)cout << "←"; for (j = 2 * position; j < maxCol - 4; j++)cout << ' '; cout << "■" << endl;
for (; i < maxRow - 3; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}
for (i = 0; i < maxCol + 2; i++)cout << "■";
cursor = _getch();
if (('w' == cursor || 'W' == cursor) && position)position--;
else if (('s' == cursor || 'S' == cursor) && 0 == position)position++;
else if (27 == cursor)return 1;
} while (cursor != '\r');
return position;
}
//退出确认窗口:0-是,1-否
int QuitOrNot() {
char cursor = 0, position = 0;
do {
unsigned short i, j;
for (i = 0; i < maxCol + 2; i++)cout << "■";
cout << endl;
for (i = 0; i < maxRow / 2 - 1; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}
cout << "■"; for (j = 0; j < maxCol - 6; j++)cout << ' '; cout << "要结束游戏吗"; for (j = 0; j < maxCol - 6; j++)cout << ' '; cout << "■" << endl;
cout << "■"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "是 否"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■" << endl;
if (0 == position) { cout << "■"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol + 1; j++)cout << ' '; cout << "■" << endl; }
else { cout << "■"; for (j = 0; j < maxCol + 1; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■" << endl; }
for (; i < maxRow - 3; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}for (i = 0; i < maxCol + 2; i++)cout << "■";
cursor = _getch();
if (('a' == cursor || 'A' == cursor) && position)position--;
else if (('d' == cursor || 'D' == cursor) && 0 == position)position++;
else if (27 == cursor)return 1;
} while (cursor != '\r');
return position;
}
//返回主菜单:0-是,1-否
int ReturnToMainWindow() {
char cursor = 0, position = 0;
do {
unsigned short i, j;
for (i = 0; i < maxCol + 2; i++)cout << "■";
cout << endl;
for (i = 0; i < maxRow / 2 - 1; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}
cout << "■"; for (j = 0; j < maxCol - 7; j++)cout << ' '; cout << "要返回主菜单吗"; for (j = 0; j < maxCol - 7; j++)cout << ' '; cout << "■" << endl;
cout << "■"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "是 否"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■" << endl;
if (0 == position) { cout << "■"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol + 1; j++)cout << ' '; cout << "■" << endl; }
else { cout << "■"; for (j = 0; j < maxCol + 1; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol - 3; j++)cout << ' '; cout << "■" << endl; }
for (; i < maxRow - 3; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}for (i = 0; i < maxCol + 2; i++)cout << "■";
cursor = _getch();
if (('a' == cursor || 'A' == cursor) && position)position--;
else if (('d' == cursor || 'D' == cursor) && 0 == position)position++;
else if (27 == cursor)return 1;
} while (cursor != '\r');
return position;
}
//结算界面
void score() {
int count; signed char judge;
system("cls");
for (count = 0; count < maxCol/2-2; count++)cout << endl;
for (count = 0; count < maxCol - 2; count++)cout << ' '; cout << "游戏结束" << endl;
for (count = 0; count < maxCol - 6; count++)cout << ' '; cout << "你的最终得分为:" << _SCORE(length - initLength);
for (count = 0; count < maxRow; count++) {
map[count] = new signed char[maxCol];
memset(map[count], 0, maxCol);
}
head[0] = 0; head[1] = initLength - 1;
tail[0] = 0; tail[1] = 0;
for (count = 0; count < initLength - 1; count++)
map[0][count] = 6;
map[0][count] = -4;
direction = 6;
length = initLength; create();
judge = _getch();
while (judge != 27 && judge != '\r')judge = _getch();
}
//模式选择窗口:0-开始游戏,1-返回主菜单
int ChooseMode() {
char cursor = 0, position = 0;
do {
unsigned short i, j;
for (i = 0; i < maxCol + 2; i++)cout << "■";
cout << endl;
for (i = 0; i < maxRow / 2 - 1; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}
cout << "■"; for (j = 0; j < maxCol - 7; j++)cout << ' '; cout << "请选择游戏模式"; for (j = 0; j < maxCol - 7; j++)cout << ' '; cout << "■" << endl;
cout << "■"; for (j = 0; j < maxCol - 6; j++)cout << ' '; cout << "正常 无障碍"; for (j = 0; j < maxCol - 6; j++)cout << ' '; cout << "■" << endl;
if (0 == position) { cout << "■"; for (j = 0; j < maxCol - 5; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol + 3; j++)cout << ' '; cout << "■" << endl; }
else { cout << "■"; for (j = 0; j < maxCol + 2; j++)cout << ' '; cout << "↑"; for (j = 0; j < maxCol - 4; j++)cout << ' '; cout << "■" << endl; }
for (; i < maxRow - 3; i++) {
cout << "■";
for (j = 0; j < maxCol; j++)cout << " ";
cout << "■" << endl;
}for (i = 0; i < maxCol + 2; i++)cout << "■";
cursor = _getch();
if (('a' == cursor || 'A' == cursor) && position)position--;
else if (('d' == cursor || 'D' == cursor) && 0 == position)position++;
else if (27 == cursor)return 1;
} while (cursor != '\r');
mode = position;
return 0;
}
};
int main() {
Snake OCSnake;
OCSnake.GameStart();
return 0;
}
有需要的话会再写一个无障碍模式的教程,觉得我说得不明白的话请在评论区批评指正,总之希望能帮到读者,感谢阅读!