先頭のポケモンを選出
前回パーティーのプロパティを準備して、複数(6匹)のポケモンを持ち歩けるようにすることを想定しました。
今回は、そこからバトル画面への連動をさせる部分までを作り込んでいきましょう。
複数のポケモンを所有している場合、戦闘が始まって繰り出されるのは「ひんし状態を除く一番上のポケモン」です。現在は1匹しか所有できないため、ひんし状態になっていればバトルに参加すること自体ができませんが、これを複数匹想定の構成へ変更します。
ホームコントローラー用トレイト(/App/Traits/Controller/HomeControllerTrait.php)
<?php
/**
* ホームコントローラー用トレイト
*/
trait HomeControllerTrait
{
/**
* 引き継ぎ処理
* @return void
*/
protected function takeOver()
{
// パーティーにセット
$this->party = $this->unserializeObject($_SESSION['__data']['party']);
}
/**
* 戦闘に参加するポケモン番号を取得
*
* @return integer
*/
protected function getFightPokemonOrder()
{
$orders = array_filter($this->party, function($partner){
return $partner->getRemainingHp() > 0;
});
if(empty($orders)){
return null;
}else{
return array_key_first($orders);
}
}
}
getFigthPokemonOrderというメソッドを新しく追加しました。array_filterを使って、パーティーのHPが0超過(瀕死ではない)ポケモンだけを抽出し、その先頭のキーを返却しています。
array_filterでは抽出した値のキーがそのままです。なので、最初のキーを返却することで、パーティープロパティに格納されている、戦闘に参加できるポケモン番号が取得できます。
ポケモン番号の格納
戦闘に参加できる先頭のポケモンを判定することができるようになったので、このメソッドをコントローラーに追記しましょう。
ホームコントローラー(/App/Controllers/Home/HomeController.php)
<?php
$root_path = __DIR__.'/../../..';
require_once($root_path.'/App/Controllers/Controller.php');
// サービス
require_once($root_path.'/App/Services/Home/RecoveryService.php');
// トレイト
require_once($root_path.'/App/Traits/Controller/HomeControllerTrait.php');
// ホーム用コントローラー
class HomeController extends Controller
{
use HomeControllerTrait;
/**
* @return void
*/
public function __construct()
{
// 親コンストラクタの呼び出し
parent::__construct();
// 引き継ぎ
$this->takeOver();
// 分岐処理
$this->branch();
// 親デストラクタの呼び出し
parent::__destruct();
}
/**
* アクションに合わせた分岐
* @return void
*/
private function branch()
{
try {
switch ($_POST['action'] ?? '') {
/******************************************
* リセット
*/
case 'reset':
$_SESSION['__route'] = 'initial';
header("Location: ./", true, 307);
// exit;
break;
/******************************************
* ポケモンセンター
*/
case 'recovery':
$service = new RecoveryService($this->party);
$service->execute();
break;
/******************************************
* バトル
*/
case 'battle':
$order = $this->getFightPokemonOrder();
if(is_null($order)){
setMessage('バトルに参加できるポケモンがいません');
break;
}
$_SESSION['__data']['order'] = $order;
$_SESSION['__route'] = 'battle';
$_SESSION['__token'] = $_POST['__token'];
header("Location: ./", true, 307);
break;
/******************************************
* アクション未選択 or 実装されていないアクション
*/
default:
break;
}
} catch (\Exception $ex) {
// 初期画面へ移管
$_SESSION['__route'] = 'initial';
header("Location: ./", true, 307);
exit;
}
}
}
array_filterで抽出した結果が空であれば、nullを返却するようにしているので、is_nullで判定して一致すれば「バトル不可」としています。もし、値が取得できていればそれをorderセッションに格納して次の画面へ移管させます。
次にバトルコントローラー側の引き継ぎ処理についてみてみましょう。
バトルコントローラー用トレイト(/App/Traits/Controller/BattleControllerTrait.php)
/**
* 引き継ぎ処理
* @return void
*/
protected function takeOver()
{
// にげるの実行回数を引き継ぎ
if(isset($_SESSION['__data']['run'])){
$this->run = $_SESSION['__data']['run'];
}
// フィールド状態を引き継ぎ
if(isset($_SESSION['__data']['field'])){
$this->field = $_SESSION['__data']['field'];
}
// ポケモン番号の引き継ぎ
$this->order = $_SESSION['__data']['order'];
// パーティーの引き継ぎ
$this->party = $this->unserializeObject($_SESSION['__data']['party']);
// 敵ポケモンの引き継ぎ
if(isset($_SESSION['__data']['enemy'])){
$this->enemy = $this->unserializeObject($_SESSION['__data']['enemy']);
// 前ターンの状態をプロパティに格納
$this->before['enemy'] = clone $this->enemy;
}
// 戦闘中のポケモンをプロパティにセット
$this->pokemon = $this->party[$this->order];
// 前ターンの状態をプロパティに格納
$this->before['friend'] = clone $this->pokemon;
}
新しくorderというプロパティを設けて、ポケモン番号を保管する仕様に変更しました。ただ、配列内のポケモンを毎回取り出すとなれば手間なので、オーダーに合わせたポケモンをポケモンプロパティに格納するようにして、今までの既存の処理はそのままにしています。
こうすることで、パーティー内のポケモンとポケモンプロパティの値に差異が生まれません。
実際のバトル画面を見てみましょう。
問題なくパーティーからポケモンを抽出して、今までと同じ状態を作り上げることができました。
交代機能はまだ未実装ですが、ポケモン一覧が見られるようにしています。
ポケモンセンターの拡張
パーティーという扱いでポケモンを格納する方法に変更したため、全ポケモンに回復処理がなされるように、ポケモンセンターを拡張しましょう。
回復用サービス(/App/Services/Home/RecoveryService.php)
<?php
$root_path = __DIR__.'/../../..';
// 親クラス
require_once($root_path.'/App/Services/Service.php');
/**
* 全回復(ポケモンセンター)
*/
class RecoveryService extends Service
{
/**
* @var object Pokemon
*/
private $party;
/**
* @return void
*/
public function __construct($party)
{
$this->party = $party;
}
/**
* @return void
*/
public function execute()
{
foreach($this->party as $partner){
$this->recovery($partner);
}
setMessage([
['お預かりしたポケモンたちは、皆元気になりましたよ'],
['またのご利用お待ちしております']
]);
}
/**
* 全回復
*
* @return void
*/
private function recovery($partner)
{
// HP回復
$partner->calRemainingHp('reset');
// 状態異常解除
$partner->releaseSa();
// PP回復
$partner->calRemainingPp('reset');
}
}
処理自体は単純で、foreachを使って1匹ずつに同じ処理を与えています。array_mapなどを使って全ポケモンに同じ処理を施してもらっても構いません。
これで、パーティーを作成した際に複数のポケモンを所有、回復処理ができるようになりました。
まとめ
いかがだったでしょうか。
今回のPHPポケモンは、パーティーから戦闘に参加させるポケモンを選出する方法をご紹介しました。
現在プログラミング学習に取り組んでいたり、興味を持っている方は、是非参考にしてみてくださいね。