トレーナー戦
いよいよPHPポケモンでもトレーナー戦の実装に取り掛かっていきます。バトルシステム自体は野生ポケモンと同じですが、トレーナーバトルでは以下の項目が追加、または制限を設けることになります。
- 複数匹のポケモン
- 逃げられない
- 捕まえられない
- 賞金
複数匹のポケモン
ざっくりと必要な項目は、上記の4つです。トレーナーはプレイヤーと同じく、最大6匹のポケモンを所有することができるため、1匹倒しても戦闘終了とはいきません。
逃げられない
「逃げる」という判定も不要なため、こちらは「降参」という項目で置き換えます。降参した場合は通信対戦と同じく「負け」という判定を行います。こちらは通常のポケモンバトルではないためPHP独自の仕様で実装となります。
捕まえられない
野生ポケモンはボールを投げることで捕まえられますが、相手トレーナーが所有しているポケモンはそうはいきません。なので、ボールが使用されたとしても捕獲判定は行わず、処理自体をストップさせアラートを表示させる必要があります。
賞金
トレーナー戦に勝利することで、賞金が貰えます。それに対して、敗北することで所有しているおこづかいが半分失われます。これらはトレーナー情報作成時に賞金を割り当てることで、実装します。
トレーナー情報の作成
それではまず、トレーナー情報の作成から初めましょう。プレイヤーと同様にパーティー管理ができるように、クラスとして「Trainer」を用意します。
トレーナー(/Classes/Trainer.php)
<?php
/**
* トレーナー情報
*/
class Trainer
{
/**
* 名前
* @var string
*/
protected $name = '';
/**
* パーティー
* @var array
*/
protected $party = [];
/**
* 持ち物
* [[class => string, count => int|null], ...]
* @var array
*/
protected $items = [];
}
初代では設定されていませんでしたが、第2世代からはそれぞれのトレーナーに名前が割り振られていたので、格納用にnameのプロパティを用意しました。
プレイヤーと同じくパーティー格納用のプロパティ、そして今後アイテムの仕様も考慮した上でアイテムプロパティも同じように準備しました。
ポケモンクラスなどは、これを親クラスとしてそれぞれのポケモン情報を作成していましたが、トレーナーにはそこまで膨大な設定値が必要ありません。なので、クラスではなく配列としてファイルを準備しました。
トレーナー情報(/Config/trainer.php)
<?php
# トレーナー情報
return [
'cool_trainer' => [
'name' => 'エリートトレーナー',
'level' => 1, # 必要なプレイヤーレベル
],
];
まずはトレーナーの大きな括りとして、configファイルにフィールド情報と同じ要領で値を用意しました。世代によって異なりますが「虫取り少年」や「エリートトレーナー」など複数に解れているため、これらをカテゴリとしてプレイヤーレベルを割り当てていきます。
次に、どんなポケモンを所有しているかなど、トレーナー個別の情報をStorageに作成していきます。
エリートトレーナー ユウキ(/Storage/Database/Trainer/cool_trainer/yuuki.php)
<?php
return [
'name' => 'ユウキ',
'money' => 500,
'lines' => [
'lose' => 'やるね',
'win' => 'まだまだだね',
],
'party' => [
[ # 1匹目(ライチュウ)
'class' => 'Raichu',
'level' => 3,
'move' => [
'MoveThunder', 'MoveGrowl', 'MoveQuickAttack', 'MoveMegaPunch'
],
],
[ # 2匹目(ピジョン)
'class' => 'Pigeon',
'level' => 3,
],
[ # 3匹目(リザード)
'class' => 'Lizardo',
'level' => 3,
'move' => [
'MoveLeer', 'MoveRage', 'MoveSlash', 'MoveFlamethrower'
],
'ev' => [
'H' => '6',
'A' => '0',
'B' => '0',
'C' => '252',
'D' => '0',
'S' => '252',
],
],
],
];
PHPの配列で用意、こちらをincludeで読み込むという方式です。
もしexcelなどで管理したい方は、csv形式でデータを準備すると管理がスムーズです。今回は読み込みの手間も考えて配列形式を採用しています。
トレーナー演出とデータの読み込み
linesキーに登録されているメッセージは、勝利時・敗北時に表示されるメッセージです。
通常トレーナーではそこまで重要視されない要素ですが、ジムリーダーなどの特別なトレーナー戦を実装するためには必要になるので、こちらも指定できるようにしています。
では、作成した設定データをTrainerクラスに読み込むようメソッドを追加していきましょう。
トレーナー(/Classes/Trainer.php)
<?php
/**
* トレーナー情報
*/
class Trainer
{
/**
* 名前
* @var string
*/
protected $name = '';
/**
* パーティー
* @var array
*/
protected $party = [];
/**
* 持ち物
* [[class => string, count => int|null], ...
* @var array
*/
protected $items = [];
/**
* セリフ
* @var array
*/
protected $lines = [
'win' => '修行が必要だね',
'lose' => '次は勝つよ',
];
/**
* @param trainer:array
* @param category:string
* @return void
*/
public function __construct(array $trainer, string $category)
{
$this->init($trainer, $category);
}
/**
* 初期化
* @param trainer:array
* @param category:string
* @return void
*/
private function init(array $trainer, string $category): void
{
// トレーナーカテゴリ
$this->category = $category;
// トレーナー名の生成
$this->name = $trainer['name'];
// パーティーの生成
$this->generateParty($trainer['party']);
// セリフの格納
if(isset($trainer['lines'])){
$this->lines = $trainer['lines'];
}
// 賞金
$this->money = $trainer['money'] ?? 100;
}
/**
* パーティーの生成
* @param party:array
* @return void
*/
private function generateParty(array $party): void
{
$this->party = array_map(function($data){
// ポケモンのインスタンスを生成
$pokemon = new $data['class']($data['level'] ?? 10);
// トレーナー用のポケモンに書き換え
return $pokemon->initTrainerPokemon($data);
}, $party);
}
/**
* トレーナーカテゴリを取得
* @return string
*/
public function getCategory(): string
{
return $this->category;
}
/**
* トレーナーカテゴリ名を取得
* @return string
*/
public function getCategoryName(): string
{
return config('trainer.'.$this->category.'.name');
}
/**
* 名前の取得
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* カテゴリ名付きの名前を取得
* @return string
*/
public function getPrefixName(): string
{
return config('trainer.'.$this->category.'.name').'の、'.$this->name;
}
/**
* パーティーを取得
* @return array
*/
public function getParty(): array
{
return $this->party;
}
/**
* 所有数を取得
* @return integer
*/
public function getPartyCount(): int
{
return count($this->party);
}
/**
* 空き数を取得
* @return array
*/
public function getPartyEmptyCount(): int
{
return 6 - count($this->party);
}
/**
* セリフの取得
* @param situation:string
* @return string
*/
public function getLine($situation): string
{
return '「'.($this->lines[$situation] ?? '...').'」';
}
/**
* ポケモン情報を取得
* @param order:integer
* @return object::Pokemon|null
*/
public function getPartner(int $order)
{
return $this->party[$order] ?? null;
}
}
configに作成したのが第2引数の$category、トレーナー情報として用意した配列が第1引数の$trainerになっています。こちらを、initメソッドで当てはめていくという仕様です。
パーティーの生成では、レベル指定がなければ10レベルでポケモンを生成しています。
さらに、ポケモンクラスに追加したトレーナー用のメソッドについても見てみましょう。
ポケモンクラス(/Classes/Pokemon.php)
/**
* トレーナーポケモン用の初期化
* @param data:array
* @return object::this
*/
public function initTrainerPokemon(array $data): object
{
// 指定した技への書き換え
if(isset($data['move'])){
// 技が存在していれば、初期化して再セット
$this->move = [];
foreach($data['move'] as $move){
$this->setMove($move);
}
}
// 個体値の書き換え
if(isset($data['iv'])){
// もしポケモン個別で設定があれば、優先
$this->iv = $data['iv'];
}else{
// オール10(標準)
$this->iv = array_map(function(){
return 10;
}, $this->iv);
}
// 努力値の書き換え
if(isset($data['ev'])){
$this->ev = $data['ev'];
}
// 全回復状態にする
$this->recovery();
return $this;
}
こちらはトレーナーポケモン専用のメソッドです。
技の指定があればそちらを採用、なければレベルに合わせたレベルアップ技をそのまま採用しています。個体値は指定がなければオール10、努力値は指定がなければ0としています。
この辺りは、ジムリーダーなど特別なトレーナーでは個別設定した値が使えるようにしました。
ポケモン生成後には、HPの個体値が変更になっていることも考慮して、全回復の処理を挟んでいます。
これで、トレーナー専用のポケモンとトレーナー情報の生成準備が整いました。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「トレーナ戦に向けたトレーナ情報の作成」についてご紹介しました。
次回はバトルシステムへの組み込みをしていきますので、ぜひ参考にしてみてくださいね。