迷宮遊戲就是玩家在地圖中移動,移動至終點則遊戲結束。
自己用文本文檔手打了個小地圖,0表示空白,1表示牆,檔案名随意,我改成了map.MapData。然後程式裡定義一個全局變量char Map[MapLenX][MapLenY];(長寬自定義)行為X,列為Y。定義char型常量RoadSymbol = '0', WallSymbol = '1', PlayerSymbol = '+'。
本遊戲為面向對象編寫的,是以就要設計一個類。資料需要一個坐标和一個bool型儲存是否到達終點。是以自定義了個結構體儲存坐标
struct point {
int x, y;
};
還需要構造函數,析構函數,然後寫個移動的函數PlayerMove(),再寫個判斷是否到達終點的函數CheckIfWin()。每走完一步就要重新整理螢幕,是以還需要寫個函數Refresh(),然後PlayerActor類就完成了。
class PlayerActor {
public:
point m_Location;
bool m_IfWin;
PlayerActor();
~PlayerActor();
void PlayerMove(int _Direc);
void Refresh(void);
void CheckIfWin(void);
};
構造函數析構函數先不着急, 先定義一下PlayerMove()。思路是先判斷是否可移動。若能,目前位置的地圖示記設為RoadSymbol, 移動即更新坐标,新坐标位置在地圖上标記為PlayerSymbol, 重新整理畫面,判斷輸赢。Refresh()思路為先用system("cls")清屏,然後逐行列印。若地圖上某點為RoadSymbol輸出空格, WallSymbol輸出'*', PlayerSymbol輸出'+'。
接下來定義玩家起始位置和終點PlayerStart和PlayerEnd并初始化。main函數大體流程如下:讀入地圖,執行個體化PlayerActor,當!m_IfWin時接收鍵盤按鍵來移動,當m_IfWIn時彈出提示框并結束。是以還需要一個全局函數PlayerControl來接收按鍵并調用PlayerMove()。
至此,構造函數的流程也明确了。初始化m_IfWin和m_Location,在地圖上表明玩家位置和重點位置,重新整理螢幕,沒了。然後再把能定義為常量的都定位常量,修改一下細節,就能得到一個簡陋的走迷宮遊戲了。
#include <iostream>
#include <cstdio>
#include "conio.h"
#include "windows.h"
struct point {
int x, y;
};
const point PlayerStart = {10, 2};
const point PlayerEnd = {2, 10};
const int MapLenX = 11, MapLenY = 10;
const char EndSymbol = '#', PlayerSymbol = '+', WallSymbol = '1', RoadSymbol = '0';
char Map[MapLenX][MapLenY];
const int MoveX[4] = {-1, 1, 0, 0}, MoveY[4] = {0, 0, -1, 1}; UP, DOWN, LEFT, RIGHT
const int _UP = 0, _DOWN = 1, _LEFT = 2, _RIGHT = 3;
class PlayerActor {
public:
point m_Location;
bool m_IfWin;
PlayerActor();
~PlayerActor();
void PlayerMove(int _Direc);
void Refresh(void);
void CheckIfWin(void);
};
PlayerActor::PlayerActor() {
m_IfWin = false;
this->m_Location.x = PlayerStart.x;
this->m_Location.y = PlayerStart.y;
Map[this->m_Location.x][this->m_Location.y] = PlayerSymbol;
Map[PlayerEnd.x][PlayerEnd.y] = EndSymbol;
PlayerActor::Refresh();
return;
}
PlayerActor::~PlayerActor() {
}
void PlayerActor::PlayerMove(int _Direct) {
if ( Map[this->m_Location.x+MoveX[_Direct]][this->m_Location.y+MoveY[_Direct]] == RoadSymbol
|| Map[this->m_Location.x+MoveX[_Direct]][this->m_Location.y+MoveY[_Direct]] == EndSymbol ) { // JUDGE IF CAN MOVE
Map[this->m_Location.x][this->m_Location.y] = RoadSymbol;
this->m_Location.x += MoveX[_Direct];
this->m_Location.y += MoveY[_Direct];
Map[this->m_Location.x][this->m_Location.y] = PlayerSymbol;
PlayerActor::Refresh();
PlayerActor::CheckIfWin();
}
return;
}
void PlayerActor::Refresh(void) {
system("cls"); //CLEAR SCREEN
for (int i=1; i<=MapLenX; i++) {
for (int j=1; j<=MapLenY; j++) {
if (Map[i][j] == RoadSymbol)
printf(" ");
else if (Map[i][j] == WallSymbol)
printf("* ");
else if (Map[i][j] == '+')
printf("%c ", PlayerSymbol);
else if (Map[i][j] == EndSymbol)
printf("%c ",EndSymbol);
}
printf("\n");
}
return;
}
void PlayerActor::CheckIfWin(void) {
if (this->m_Location.x == PlayerEnd.x && this->m_Location.y == PlayerEnd.y)
m_IfWin = true;
return;
}
void PlayerControl(PlayerActor* Player, int _KEY) {
switch (_KEY) {
case 119 : Player->PlayerMove(_UP); w 119
break;
case 115 : Player->PlayerMove(_DOWN); ///s 115
break;
case 97 : Player->PlayerMove(_LEFT); a 97
break;
case 100 : Player->PlayerMove(_RIGHT); d 100
break;
default:
break;
}
return;
}
int main() {
//READ MAP
freopen("map.MapData", "r", stdin);
for (int i=1; i<=MapLenX; i++) {
for (int j=1; j<=MapLenY; j++) {
std::cin >> Map[i][j];
}
}
//CREATE PLAYERACTOR
PlayerActor* Player = new PlayerActor;
while (!Player->m_IfWin) {
PlayerControl(Player, _getch());
}
system("cls");
MessageBox(NULL, "You Win!", "Congratulations!", MB_OK);
delete Player;
return 0;
}
地圖map.MapData:
1111111111
1000000001
1011111111
1010000001
1011111101
1000000101
1111110101
1000010101
1011110101
1000000001
1111111111