跟着《游戏开发:世嘉新人培训教材》一书中推箱子游戏的逻辑写的推箱子游戏,整体代码不长,也没有特别难以理解的逻辑,后续看看自己能否进行一定的改进,增加游戏难度和代码的运行速度。
#include<iostream>//长
const int gHeight = 5;
//宽
const int gWidth = 8;
//游戏场景
const char gStageData[] = "\
########\n\
# .. p #\n\
# oo #\n\
# #\n\
########\n";enum Object {OBJ_SPACE, //无物体OBJ_WALL, //墙壁OBJ_GOAL, //目的地OBJ_BLOCK, //箱子OBJ_BLOCK_ON_GOAL, //箱子到达目的地OBJ_PLAYER, //玩家OBJ_PLAYER_ON_GOAL, //玩家到达目的地OBJ_UNKONW //未知,错误位置
};//初始化函数
void initialize(Object* state, int height, int width, const char* stage);
//绘制初始游戏窗口函数
void draw(Object* state, int height, int width);
void findPlayer(Object* state, int& playerX, int& playerY, int height, int width);
//更新游戏窗口函数
void update(Object* state, int height, int width, char input);
//确认是否通关函数
bool checkClear(Object* state, int height, int width);int main() {Object* state = new Object[gHeight*gWidth];initialize(state, gHeight, gWidth, gStageData);//主循环while (true) {draw(state, gHeight, gWidth);//确认是否通关if (checkClear(state,gHeight,gWidth) == true) {break;}std::cout << "w:前,s:后,a:左,b:右 \n";//获取输入char input;std::cin >> input;update(state,gHeight,gWidth,input);}delete[] state;std::cout << "恭喜通关\n";
}void initialize(Object* state, int height, int width, const char* stageData) {const char* temp = stageData; //读取地图数据int x = 0; //行int y = 0; //宽while (*temp != NULL) {Object t;switch (*temp) {case '#':t = OBJ_WALL; break;case ' ':t = OBJ_SPACE; break;case 'p':t = OBJ_PLAYER; break;case 'P':t = OBJ_PLAYER_ON_GOAL; break;case '.':t = OBJ_GOAL; break;case 'o':t = OBJ_BLOCK; break;case 'O':t = OBJ_BLOCK_ON_GOAL; break;case '\n':x++; y = 0; t = OBJ_UNKONW; break;default:t = OBJ_UNKONW; break;}temp++;//传入数据if (t != OBJ_UNKONW) {state[x * width + y] = t;y++;}}
}void draw(Object* state, int height, int width) {const char block[] = { ' ','#', '.', 'o','O','p', 'P' };for (int x = 0; x < height; x++) {for (int y = 0; y < width; y++) {Object temp = state[x * width + y];std::cout << block[temp];}//换行std::cout << '\n';}
}void findPlayer(Object* state, int& playerX, int& playerY, int height, int width ) {for (int i = 0; i < gWidth * gHeight; i++) {if (state[i] == OBJ_PLAYER || state[i] == OBJ_PLAYER_ON_GOAL) {playerX = i % width;playerY = i / width;break;}}
}void update(Object* state, int height, int width, char input) {//移动量int dx = 0;int dy = 0;switch (input) {case 'a':dx = -1; break;case 'd':dx = 1; break;case 'w':dy = -1; break;case 's':dy = 1; break;}//找到玩家的位置int playerX = 0;int playerY = 0;findPlayer(state, playerX, playerY, height, width);//移动后的坐标位置int tx = dx + playerX;int ty = dy + playerY;//移动失败的情况if (tx < 0 || tx > width || ty < 0 || ty > height) {return;}//移动成功int player = width * playerY + playerX; //玩家位置int tp = width * ty + tx; //预计移动到的位置//目标位置是空位或者目的地,玩家可以移动if (state[tp] == OBJ_SPACE || state[tp] == OBJ_GOAL) {//预计移动的位置为目的地,将该点转换为玩家在目的地上的状态,否者仍是目的地状态state[tp] = (state[tp] == OBJ_GOAL) ? OBJ_PLAYER_ON_GOAL : OBJ_PLAYER;//玩家当前的位置为在目的地上,移动之后将这个点转换为目的地,否者为空位state[player] = (state[player] == OBJ_PLAYER_ON_GOAL) ? OBJ_GOAL : OBJ_SPACE;}//目标位置有箱子else if (state[tp] == OBJ_BLOCK || state[tp] == OBJ_BLOCK_ON_GOAL){//箱子的移动int boxX = tx + dx;int boxY = ty + dy;//到达游戏边界 不能移动if (boxX < 0 || boxX > width || boxY < 0 || boxY > height) {return;}int box = width * boxY + boxX; //箱子预计移动的位置if (state[box] == OBJ_SPACE || state[box] == OBJ_GOAL) {state[box] = (state[box] == OBJ_GOAL) ? OBJ_BLOCK_ON_GOAL : OBJ_BLOCK;state[tp] = (state[tp] == OBJ_BLOCK_ON_GOAL) ? OBJ_PLAYER_ON_GOAL : OBJ_PLAYER;state[player] = (state[player] == OBJ_PLAYER_ON_GOAL) ? OBJ_GOAL : OBJ_SPACE;}}
}bool checkClear(Object* state, int height, int width) {for (int i = 0; i < height * width; i++) {if (state[i] == OBJ_BLOCK)return false;}return true;
}