C++实现推箱子游戏
设计地图
使用二维数组搭建地图,
其中0为虚空、1为墙壁、2为玩家、3为箱子、4为目标点。
int map[HEIGHT][WIDTH] =
{{1, 1, 1, 1, 1, 1, 1, 1},{1, 0, 0, 4, 0, 0, 0, 1},{1, 0, 0, 0, 0, 0, 0, 1},{1, 0, 0, 3, 0, 3, 4, 1},{1, 4, 0, 3, 2, 0, 0, 1},{1, 0, 0, 0, 3, 0, 0, 1},{1, 0, 0, 0, 4, 0, 0, 1},{1, 1, 1, 1, 1, 1, 1, 1}
};
可以根据实际需求改变地图,记得将HEIGHT和WIDTH的值按地图大小改变。
地图实例化
设计出来的地图需要将其可视化,即打印到屏幕上。遍历数组所有元素,使用switch语句将各个元素转化为可视化图形。
void drawMap()
{for (int i = 0; i < width; i++){for (int j = 0; j < lenth; j++){switch (map[i][j]){case 1: cout << "* "; //墙壁break;case 2:cout << "P "; //玩家break;case 3: cout << "+ "; //箱子break;case 4:cout << "G "; //目标break;case 0:cout << " "; //空气break;}}cout << endl;}
}
玩家定位
原理同地图实例化,遍历数组,找出玩家所在位置,为玩家建立一个坐标(x,y)
for (int i = 0; i < width; i++)
{for (int j = 0; j < lenth; j++){if (map[i][j] == 2){x = i;y = j;}}
}
注意将x,y定义在全局下。
方向控制
这里以玩家向上移动进行举例。
当玩家向上移动时
上方是空气
if (map[x-1][y] == 0){map[x-1][y] = map[x][y];map[x][y] = 0;}
此时玩家移动到了上方的位置,原来的地方变成了空气。
上方是箱子
if (map[x - 1][y] == 3){if (map[x - 2][y] == 0){map[x - 2][y] = map[x - 1][y];map[x - 1][y] = map[x][y];map[x][y] = 0;}else if (map[x - 2][y] == 4){box--;map[x - 2][y] = map[x - 1][y];map[x - 1][y] = map[x][y];map[x][y] = 0;}}
其中分为箱子的上方是空气和箱子上方是目标点。
记得在该函数结束时更新玩家的坐标
x = x - 1;
y = y;
其他三个方位同理。
控制方式
同样使用switch语句将键盘输入的内容判断,进行操控。在游戏进行当中,需要一个无限循环来防止游戏中断。
while(true)
{ system("cls");if (box == 0){break;}drawMap();char tap;cin >> tap;switch (tap){case 'w':moveUP();break;case 's':moveDown();break;case 'd':moveRight();break;case 'a':moveLeft();break;}
}
判断结束
定义一个整形箱子数量,当未移动到指定位置的箱子数量为零,则跳出死循环,程序结束。
遍历数组,查询箱子的个数
for (int i = 0; i < width; i++)
{for (int j = 0; j < lenth; j++){if (map[i][j] == 4){box++;}}
}
若箱子为零,程序结束
if (box == 0)
{break;
}
源码
#include<iostream>using namespace std;
const int lenth = 8;
const int width = 8;
int x, y;
int box = 0;int map[width][lenth] =
{{1, 1, 1, 1, 1, 1, 1, 1},{1, 0, 0, 4, 0, 0, 0, 1},{1, 0, 0, 0, 0, 0, 0, 1},{1, 0, 0, 3, 0, 3, 4, 1},{1, 4, 0, 3, 2, 0, 0, 1},{1, 0, 0, 0, 3, 0, 0, 1},{1, 0, 0, 0, 4, 0, 0, 1},{1, 1, 1, 1, 1, 1, 1, 1}
};void drawMap()
{for (int i = 0; i < width; i++){for (int j = 0; j < lenth; j++){switch (map[i][j]){case 1: cout << "* "; //墙壁break;case 2:cout << "P "; //玩家break;case 3: cout << "+ "; //箱子break;case 4:cout << "G "; //目标break;case 0:cout << " "; //空气break;}}cout << endl;}
}void findP()
{for (int i = 0; i < width; i++){for (int j = 0; j < lenth; j++){if (map[i][j] == 2){x = i;y = j;}if (map[i][j] == 4){box++;}}}
}void moveUP()
{if (map[x-1][y] == 0){map[x-1][y] = map[x][y];map[x][y] = 0;}if (map[x - 1][y] == 3){if (map[x - 2][y] == 0){map[x - 2][y] = map[x - 1][y];map[x - 1][y] = map[x][y];map[x][y] = 0;}else if (map[x - 2][y] == 4){box--;map[x - 2][y] = map[x - 1][y];map[x - 1][y] = map[x][y];map[x][y] = 0;}}x = x - 1;y = y;
}void moveDown()
{if (map[x + 1][y] == 0){map[x + 1][y] = map[x][y];map[x][y] = 0;}if (map[x + 1][y] == 3){if (map[x + 2][y] == 0){map[x + 2][y] = map[x + 1][y];map[x + 1][y] = map[x][y];map[x][y] = 0;}else if (map[x + 2][y] == 4){map[x + 2][y] = map[x + 1][y];map[x + 1][y] = map[x][y];map[x][y] = 0;box--;}}x = x + 1;y = y;
}void moveRight()
{if (map[x][y+1] == 0){map[x][y+1] = map[x][y];map[x][y] = 0;}if (map[x][y+1] == 3){if (map[x][y+2] == 0){map[x ][y+2] = map[x][y+1];map[x ][y+1] = map[x][y];map[x][y] = 0;}else if (map[x][y+2] == 4){map[x][y + 2] = map[x][y + 1];map[x][y + 1] = map[x][y];map[x][y] = 0;box--;}}x = x;y = y + 1;
}void moveLeft()
{if (map[x][y - 1] == 0){map[x][y - 1] = map[x][y];map[x][y] = 0;}if (map[x][y - 1] == 3){if (map[x][y - 2] == 0){map[x][y - 2] = map[x][y - 1];map[x][y - 1] = map[x][y];map[x][y] = 0;}else if (map[x][y - 2] == 4){map[x][y - 2] = map[x][y - 1];map[x][y - 1] = map[x][y];map[x][y] = 0;box--;}}x = x;y = y - 1;
}
int main()
{findP();while(true){ system("cls");if (box == 0){break;}drawMap();char tap;cin >> tap;switch (tap){case 'w':moveUP();break;case 's':moveDown();break;case 'd':moveRight();break;case 'a':moveLeft();break;}}cout << "U WIN!!!!!!!!!!" << endl;system("pause");
}