知识点
结构体,循环,函数,枚举,数组
玩法
1.通过控制w,s,a,d来实现人物的移动,或者上下左右。
2.将三个箱子推到洞中游戏胜利。
3.将箱子推到四周墙边会自动判定失败
创作历程
1.头文件及调用命名空间
#include<iostream>
#include<Windows.h>
using namespace std;
2.宏定义
#define KEY_DOWN(vk_code) GetAsyncKeyState(vk_code) & 0x8000
#define VK_ESCAPE 0x1B
#define VK_RETURN 0x0D
3.枚举
//枚举
enum
{
E_GAME_MENU,
E_GAME_MAP,
E_GAME_WIN,
E_GAME_OVER
};
enum
{
E_MENU_START,
E_MENU_SET,
E_MENU_EXIT
};
enum
{
E_OVER_AGAIN,
E_OVER_EXIT
};
4.结构体创建玩家,箱子和洞
struct SPlayer
{
int nRow;
int nCol;
int nRowBk; //玩家的备份坐标
int nColBk;
};
struct SBox
{
int nRow;
int nCol;
int nRowBk; //箱子的备份坐标
int nColBk;
};
struct SHole
{
int nRow;
int nCol;
};
5.清屏函数(只管用就好了)
void gotoxy(int x, int y) //清屏函数
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
6.主函数中实现游戏逻辑
int main()
{
int arrMap[20][20] = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
{1,4,0,1,0,0,0,1,0,1,0,0,0,0,0,1,2,1,4,1},
{1,4,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,4,1},
{1,4,0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,4,1},
{1,4,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,4,1},
{1,4,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,4,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
{1,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
{1,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,4,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
{1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,1},
{1,4,0,0,1,0,0,0,0,0,0,0,0,0,1,1,2,0,4,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,1},
{1,4,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,1,4,1},
{1,4,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
{1,4,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4,1},
{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
int nMenuState = 0;
int nOverState = 0;
int nGameScene = 0;
int nPushIndex = 0; //定义一个指数来记录当前推的箱子
bool bClear = false;
bool bPutBox = false;
SPlayer player;
player.nRow = 14;
player.nCol = 9;
SBox arrBox[3];
arrBox[0].nRow = 12;
arrBox[0].nCol = 8;
arrBox[1].nRow = 12;
arrBox[1].nCol = 9;
arrBox[2].nRow = 12;
arrBox[2].nCol = 10;
SHole arrHole[3];
arrHole[0].nRow = 3;
arrHole[0].nCol = 16;
arrHole[1].nRow = 6;
arrHole[1].nCol = 8;
arrHole[2].nRow = 13;
arrHole[2].nCol = 16;
while (1)
{
gotoxy(0, 0); //每一帧都进行清屏,防止出现死循环
if (nGameScene == E_GAME_MENU)
{
if (KEY_DOWN(VK_RETURN))
{
if (nMenuState == E_MENU_START)
{
nGameScene = E_GAME_MAP;
}
else if (nMenuState == E_MENU_EXIT)
{
system("cls");
exit(0);
}
}
if (KEY_DOWN(VK_UP))
{
nMenuState--;
if (nMenuState < E_MENU_START)
{
nMenuState = E_MENU_EXIT;
}
}
else if (KEY_DOWN(VK_DOWN))
{
nMenuState++;
if (nMenuState > E_MENU_EXIT)
{
nMenuState = E_MENU_START;
}
}
if (nMenuState == E_MENU_START)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏菜单 ■" << endl;
cout << "■ ■" << endl;
cout << "■ ->开始游戏 ■" << endl;
cout << "■ 游戏设置 ■" << endl;
cout << "■ 退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
else if (nMenuState == E_MENU_SET)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏菜单 ■" << endl;
cout << "■ ■" << endl;
cout << "■ 开始游戏 ■" << endl;
cout << "■ ->游戏设置 ■" << endl;
cout << "■ 退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
else if (nMenuState == E_MENU_EXIT)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏菜单 ■" << endl;
cout << "■ ■" << endl;
cout << "■ 开始游戏 ■" << endl;
cout << "■ 游戏设置 ■" << endl;
cout << "■ ->退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
}
else if (nGameScene == E_GAME_MAP)
{
if (KEY_DOWN(VK_ESCAPE)) //退出
{
nGameScene = E_GAME_MENU;
bClear = true;
}
//将玩家的坐标保存起来
player.nRowBk = player.nRow;
player.nColBk = player.nCol;
if (KEY_DOWN(VK_UP))
{
player.nRow--;
}
else if (KEY_DOWN(VK_DOWN))
{
player.nRow++;
}
else if (KEY_DOWN(VK_LEFT))
{
player.nCol--;
}
else if (KEY_DOWN(VK_RIGHT))
{
player.nCol++;
}
//如果撞墙就将玩家的坐标改为备份坐标
if (arrMap[player.nRow][player.nCol] == 1)
{
player.nRow = player.nRowBk;
player.nCol = player.nColBk;
}
for (int i = 0; i < 3; i++)
{
arrBox[i].nRowBk = arrBox[i].nRow;
arrBox[i].nColBk = arrBox[i].nCol;
}
for (int i = 0; i < 3; i++)
{
if (player.nRow == arrBox[i].nRow && player.nCol == arrBox[i].nCol)
{
arrBox[i].nRow += player.nRow - player.nRowBk;
arrBox[i].nCol += player.nCol - player.nColBk;
nPushIndex = i;
}
}
//当两个箱子相撞时,推的箱子和玩家返回备份坐标
for (int i = 0; i < 3; i++)
{
if (arrBox[nPushIndex].nRow == arrBox[i].nRow && arrBox[nPushIndex].nCol == arrBox[i].nCol && i != nPushIndex)
{
arrBox[nPushIndex].nRow = arrBox[nPushIndex].nRowBk;
arrBox[nPushIndex].nCol = arrBox[nPushIndex].nColBk;
player.nRow = player.nRowBk;
player.nCol = player.nColBk;
}
}
//防止将箱子推进墙中
if (arrMap[arrBox[nPushIndex].nRow][arrBox[nPushIndex].nCol] == 1)
{
arrBox[nPushIndex].nRow = arrBox[nPushIndex].nRowBk;
arrBox[nPushIndex].nCol = arrBox[nPushIndex].nColBk;
player.nRow = player.nRowBk;
player.nCol = player.nColBk;
}
//计算推进箱子的数量
int nCount = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (arrBox[i].nRow == arrHole[j].nRow && arrBox[i].nCol == arrHole[j].nCol)
{
nCount++;
}
}
}
//绘制地图
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
bool bDrawBox = false;
for (int n = 0; n < 3; n++)
{
if (arrBox[n].nRow == i && arrBox[n].nCol == j)
{
bDrawBox = true;
}
}
if (arrMap[i][j] == 1)
{
cout << "■";
}
else if (bDrawBox)
{
cout << "●";
}
else if (arrMap[i][j] == 2)
{
cout << "坑";
}
else if (player.nRow == i && player.nCol == j)
{
cout << "玩";
}
else if (arrMap[i][j] == 4)
{
cout << " ";
}
else if (arrMap[i][j] == 0)
{
cout << " ";
}
}
cout << endl;
}
//判断胜利
if (nCount == 3)
{
nGameScene = E_GAME_WIN;
bClear = true;
}
//判断失败
for (int i = 0; i < 3; i++)
{
if (arrMap[arrBox[i].nRow][arrBox[i].nCol] == 4)
{
nGameScene = E_GAME_OVER;
bClear = true;
}
}
if (bClear)
{
system("cls");
bClear = false;
}
}
else if (nGameScene == E_GAME_WIN)
{
if (KEY_DOWN(VK_RETURN))
{
//重置游戏
if (nOverState == E_OVER_AGAIN)
{
for (int i = 0; i < 3; i++)
{
arrMap[arrHole[i].nRow][arrHole[i].nCol] = 2;
}
player.nRow = 14;
player.nCol = 9;
arrBox[0].nRow = 12;
arrBox[0].nCol = 8;
arrBox[1].nRow = 12;
arrBox[1].nCol = 9;
arrBox[2].nRow = 12;
arrBox[2].nCol = 10;
nGameScene = E_GAME_MAP;
}
else if (nOverState == E_OVER_EXIT)
{
system("cls");
exit(0);
}
}
if (KEY_DOWN(VK_UP))
{
nOverState--;
if (nOverState < 0)
{
nOverState = 1;
}
}
else if (KEY_DOWN(VK_DOWN))
{
nOverState++;
if (nOverState > 1)
{
nOverState = 0;
}
}
if (nOverState == E_OVER_AGAIN)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏胜利 ■" << endl;
cout << "■ ■" << endl;
cout << "■ ->再玩一次 ■" << endl;
cout << "■ 退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
else if (nOverState == E_OVER_EXIT)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏胜利 ■" << endl;
cout << "■ ■" << endl;
cout << "■ 再玩一次 ■" << endl;
cout << "■ ->退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
}
else if (nGameScene == E_GAME_OVER)
{
if (KEY_DOWN(VK_RETURN))
{
//重置游戏
if (nOverState == E_OVER_AGAIN)
{
for (int i = 0; i < 3; i++)
{
arrMap[arrHole[i].nRow][arrHole[i].nCol] = 2;
}
player.nRow = 14;
player.nCol = 9;
arrBox[0].nRow = 12;
arrBox[0].nCol = 8;
arrBox[1].nRow = 12;
arrBox[1].nCol = 9;
arrBox[2].nRow = 12;
arrBox[2].nCol = 10;
nGameScene = E_GAME_MAP;
}
else if (nOverState == E_OVER_EXIT)
{
system("cls");
exit(0);
}
}
if (KEY_DOWN(VK_UP))
{
nOverState--;
if (nOverState < 0)
{
nOverState = 1;
}
}
else if (KEY_DOWN(VK_DOWN))
{
nOverState++;
if (nOverState > 1)
{
nOverState = 0;
}
}
if (nOverState == E_OVER_AGAIN)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏失败 ■" << endl;
cout << "■ ■" << endl;
cout << "■ ->再玩一次 ■" << endl;
cout << "■ 退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
else if (nOverState == E_OVER_EXIT)
{
cout << "■■■■■■■■■■■■■" << endl;
cout << "■ ■" << endl;
cout << "■ 游戏失败 ■" << endl;
cout << "■ ■" << endl;
cout << "■ 再玩一次 ■" << endl;
cout << "■ ->退出游戏 ■" << endl;
cout << "■ ■" << endl;
cout << "■■■■■■■■■■■■■" << endl;
}
}
Sleep(80); //暂停程序80ms
}
system("pause");
return 0;
}
注意事项
1.要在终端设置中将下图设置为Windows控制台主机
作用:防止乱码