- 上一章地址:juejin.im/post/5cbf25…
遊戲邏輯開發進度:■■■■□□□□□□□□
本章結束開發進度:■■■■■■■■□□□□
上一章的答案
createPlayer
方法其實就是建立一個Player
物件,然後指定座標,放入$players
陣列中,但是怎麼區分追捕者
和躲藏者
呢?我們可以用最簡單粗暴的方法,先來後到。
Game類:
public function createPlayer($playerId, $x, $y)
{
$player = new Player($playerId, $x, $y);
if (!empty($this->players)) {
$player->setType(Player::PLAYER_TYPE_HIDE);
}
$this->players[$playerId] = $player;
}
複製程式碼
第一個新增的將會使用Player
類預設的追捕者
,第二個新增的將$player
物件設定為躲藏者
。
playerMove()
方法也很簡單,通過傳入的$direction
變數,增減對應$player
的x
或y
座標,應該直接呼叫$player
的移動方法,所以需要新增兩部分程式碼:
Game類:
public function playerMove($playerId, $direction)
{
$this->players[$playerId]->{$direction}();
}
複製程式碼
Player類:
public function up()
{
$this->x--;
}
public function down()
{
$this->x++;
}
public function left()
{
$this->y--;
}
public function right()
{
$this->y++;
}
複製程式碼
嘗試列印地圖
目前我們三個實體類的基礎遊戲邏輯就寫得差不多了,但是我們的遊戲到現在都還沒執行過,我們需要一個能直觀看到地圖、玩家的畫面。
請童鞋們自己嘗試在Game
類中新增printGameMap()
方法,列印遊戲地圖。
- 在
Game
類中有一個變數$gameMap
就是我們的遊戲地圖物件。 Map
類中也有了getMapData()
方法能夠獲取地圖陣列資料,
Game類:
public function printGameMap()
{
$mapData = $this->gameMap->getMapData();
foreach ($mapData as $line) {
foreach ($line as $value) {
if (empty($value)) {
echo "牆,";
} else {
echo " ";
}
}
echo PHP_EOL;
}
}
複製程式碼
列印地圖的程式碼很簡單,就是遍歷我們的地圖資料,當陣列裡的元素值為0
的時候就是牆
,否則就是路
,路
就不用輸出文字啦~
回到我們的test.php
,我們將在這裡呼叫新寫的printGameMap()
方法輸出地圖資料。由於我們要使用了composer
的自動載入機制,所以要先在test.php
檔案的開頭加上以下程式碼:
require_once __DIR__ . '/vendor/autoload.php';
複製程式碼
引入autoload.php
檔案後,我們就能愉快的使用名稱空間了,童鞋們記得要引入Game
類哦。
test.php:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use App\Manager\Game;
$redId = "red_player";
$blueId = "blue_player";
//建立遊戲控制器
$game = new Game();
//新增玩家
$game->createPlayer($redId, 6, 1);
//新增玩家
$game->createPlayer($blueId, 6, 10);
//移動座標
$game->playerMove($redId, 'up');
//列印地圖
$game->printGameMap();
複製程式碼
在控制檯輸入以下程式碼,執行test.php
檔案:
php test.php
複製程式碼
如果童鞋們的程式碼沒問題的話,控制檯應該會輸出以下內容:
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
牆, 牆,
牆, 牆, 牆,牆,
牆,牆,牆,牆, 牆, 牆, 牆,牆,
牆, 牆, 牆,
牆, 牆,牆,牆,牆,
牆, 牆, 牆,
牆, 牆,牆, 牆, 牆,
牆, 牆, 牆, 牆,牆,
牆, 牆,牆, 牆, 牆, 牆,
牆, 牆,
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
複製程式碼
加入玩家座標
光輸出地圖的資料可是不夠的,我們還要把玩家的座標加在地圖裡面,請童鞋們優化printGameMap()
方法,使他能夠輸出兩個玩家的位置。
Game
類中的變數$players
儲存了兩個Player
物件。Player
類中的變數$x
和$y
儲存了玩家的座標,$type
儲存了該物件的型別,但是好像是私有變數?如何獲取類中的私有變數呢?
Player類:
public function getType()
{
return $this->type;
}
public function getX()
{
return $this->x;
}
public function getY()
{
return $this->y;
}
複製程式碼
我們首先需要在Player
類中新增一個方法getType()
獲取物件的型別,getX()
、getY()
獲取玩家的座標資料。
在列印地圖資料之前,將玩家的地圖座標,以及型別標識放進$mapData
中,但由於我們的地圖裡1
是路,玩家型別中1
是追捕者
,直接放進去就會搞混了玩家和路的值,所以我們要在玩家型別的值上進行+1
操作再放進地圖,並且增加一個文字對映陣列。
test.php
中createPlayer()
傳入的座標資料小心不要和地圖上的牆
重疊了哦
Game類:
public function printGameMap()
{
$mapData = $this->gameMap->getMapData();
$font = [2 => '追', 3 => '躲'];
/* @var Player $player */
foreach ($this->players as $player) {
$mapData[$player->getX()][$player->getY()] = $player->getType() + 1;
}
foreach ($mapData as $line) {
foreach ($line as $item) {
if (empty($item)) {
echo "牆,";
} elseif ($item == 1) {
echo " ";
} else {
echo $font[$item] . ',';
}
}
echo PHP_EOL;
}
}
複製程式碼
重新執行一次我們的test.php
檔案,應該就會輸出以下內容:
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
牆, 牆,
牆, 牆, 牆,牆,
牆,牆,牆,牆, 牆, 牆, 牆,牆,
牆, 牆, 牆,
牆,追, 牆,牆,牆,牆,
牆, 牆, 躲,牆,
牆, 牆,牆, 牆, 牆,
牆, 牆, 牆, 牆,牆,
牆, 牆,牆, 牆, 牆, 牆,
牆, 牆,
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
複製程式碼
追捕者
和躲藏者
就顯示出來啦,並且由於我們列印地圖前呼叫playerMove()
方法移動追捕者
並傳入了up
,追捕者
的座標在地圖上往上走了一步。
增加地圖判斷
我們嘗試把追捕者
再往上走兩步試試,在test.php
檔案中再呼叫兩次playerMove()
方法並列印地圖,執行test.php
檔案:
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
牆, 牆,
牆, 牆, 牆,牆,
牆,追,牆,牆, 牆, 牆, 牆,牆,
牆, 牆, 牆,
牆, 牆,牆,牆,牆,
牆, 牆, 躲,牆,
牆, 牆,牆, 牆, 牆,
牆, 牆, 牆, 牆,牆,
牆, 牆,牆, 牆, 牆, 牆,
牆, 牆,
牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,牆,
複製程式碼
哦嚯,我們的追捕者
走到牆
上面了,這誰頂得住啊。目前的playerMove()
方法是不完整的,需要在其中再加入一個方法canMoveToDirection()
去判斷傳入的方向是否可以移動。
- 每個
Player
物件可以獲取當前座標。 - 根據傳入的
$direction
方向計算出目標座標。 Game
類中可以獲取到地圖的資料。
Game類:
public function playerMove($playerId, $direction)
{
$player = $this->players[$playerId];
if ($this->canMoveToDirection($player, $direction)) {
$player->{$direction}();
}
}
private function canMoveToDirection($player, $direction)
{
}
複製程式碼
本章的Homework就在這裡啦,請童鞋們一定要儘量獨立完成哦,我們將在下一章進行解答。
當前目錄結構:
HideAndSeek
├── app
│ ├── Manager
│ │ └── Game.php
│ └── Model
│ ├── Map.php
│ └── Player.php
├── composer.json
├── test.php
└── vendor
├── autoload.php
└── composer
複製程式碼