進化の石
ピカチュウさんもそろそろ進化したがっているので、β版の公開に向けて進化の石を実装していきます。しかし、イーブイなど特別な進化先や条件を持ったポケモンを考慮すると、少し実装が手間取りそうだったので、今回は構成部分のみのまとめとなっておりますので、ご了承ください。
アイテムクラスの作成
まずはアイテムクラスからの作成です。現在PHPポケモンで登場するポケモンの中では石による進化はピカチュウのみです。なので「かみなりのいし」を実装していきましょう。
かみなりのいし(/Classes/Item/ItemThunderStone.php)
<?php
require_once(root_path('Classes').'Item.php');
/**
* かみなりのいし
*/
class ItemThunderStone extends Item
{
/**
* 正式名称
* @var string
*/
public const NAME = 'かみなりのいし';
/**
* 説明文
* @var string
*/
public const DESCRIPTION = 'ある 特定の ポケモンを 進化させる 不思議な 石。稲妻の 模様が ある。';
/**
* カテゴリ
* @var string::general|health|ball|important|machine
*/
public const CATEGORY = 'general';
/**
* 最大所有数
* @var integer
*/
public const MAX = 99;
/**
* 買値
* @var integer
*/
public const BID_PRICE = 3000;
/**
* 売値
* @var integer
*/
public const SELL_PRICE = 1500;
/**
* 対象
* @var string::friend|enemy|player|friend_battle
*/
public const TARGET = 'friend';
/**
* 使用できるタイミング
* @var array
*/
public const TIMING = ['home'];
/**
* 使用できるポケモン
* @var array
*/
public const POKEMON = [
'Pikachu', 'Eievui'
];
/**
* アイテム効果
* @return array
*/
public static function effects($pokemon)
{
// 効果なし
if(!in_array(get_class($pokemon), static::POKEMON, true)){
return [
'message' => '使っても効果がないよ',
'result' => false,
];
}
// 進化判定の結果を返却
return [
'result' => $pokemon->judgeEvolve(get_class()),
'action' => 'evolve',
];
}
}
最新作の金額と説明文をwiki参考に作成しました。初代ポケモンではかみなりのいしで進化できるポケモンは「ピカチュウ」と「イーブイ」の2匹のみです。第8世代からレアコイルも初代且つかみなりのいしで進化することができるポケモンとなりましたが、進化先が第4世代のジバコイルのため、今回は除外しています。
使用できるポケモン
進化の石実装に辺り注目すべきポイントは「使用できるポケモン」をアイテムクラスに対して用意していることです。バックエンド(PHP)側のみの処理だけで考えると、ポケモン側にもたせても問題有りませんし、寧ろそちらの方がポケモンを基準として考えられるため都合が良いように思われますが、フロント側(JavaScript)で考えた場合の判定が難しくなってしまいます。
ゲームの流れに沿ってフロント画面を作成するとなれば、かみなりのいしを選択してポケモン一覧モーダルを開いた際に、使用できるポケモンと使用できないポケモンを画面上に表記する必要があります。判定基準がポケモン側にあると、アイテムの使用有無に関わらず常に「ポケモンが使用できるアイテムの有無」をノードに対して保管して置かなければなりません。
あくまで処理や判定自体はバックエンドで行うため、ノード操作によりフロント側を通過してきたとしても支障はありませんが、今後拡張していくに当たって保守性が悪くなると感じたのでアイテム側に対象を保管する仕様にしました。こちらは、わざマシンでも同様の方法を予定しています。
※どうしてもアイテムクラスによる保管が難しいと感じた場合は、configファイルを使った一括管理も検討予定です
進化先の分岐
では、進化先の分岐についてです。ピカチュウは進化条件が「かみなりのいし」というだけで進化先はライチュウで固定となっています(リージョンフォームは除く)。現在の仕様で問題ありませんが、イーブイに関しては使った石に合わせて進化先を変更しなければなりません。
以前の記事で「静的変数」を使った進化先の保管方法をご紹介しましたが、PHPポケモンの仕様上、進化画面へのリダイレクトが入る関係上、静的変数を書き換えてから画面移管してしまうため不都合が生じました。
なので、ポケモンクラスに対して定数として進化先・進化前の定数をNULLで用意、更に空文字の進化先プロパティ(protected)も用意した2段構成で判定をします。
※進化前は知る限りどのポケモンも1択なので、こちらはプロパティ不要です
ポケモンクラス(/Classes/Pokemon.php)
// ポケモン
abstract class Pokemon
{
/**
* 定数
*/
public const BEFORE_CLASS = null;
public const AFTER_CLASS = null;
/**
* 進化後のクラス(進化先に分岐があるポケモン用)
* @var string
*/
protected $after_class = '';
更に進化先クラスの取得用としてgetメソッドを用意します。こちらでは定数を優先して返却します。
ポケモンget関係トレイト(/App/Traits/Class/Pokemon/ClassPokemonGetTrait.php)
/**
* 進化後のクラスを取得する
* @return string
*/
public function getAfterClass(): string
{
// 定数→プロパティの順番で取得
return static::AFTER_CLASS ?? $this->after_class;
}
もしインスタンス化していないポケモンの進化先を判定する際には定数をコール、インスタンス化したポケモンの進化先を判別する際にはメソッドを活用します。イーブイなどの進化先が複数いるポケモンは、個別に定数を設定せず石を使用した時点でプロパティに対象をセットすることで判定します。
進化条件の作成
アイテムクラスとポケモンクラスの構成が固まったので、最後にポケモン個別の進化条件について作成しましょう。ピカチュウのクラスに対して進化判定用のメソッドを追加します。
ピカチュウ(/Classes/Pokemon/Pikachu.php)
/**
* 進化条件の分岐
* @param args:array
* @var boolean
*/
public function judgeEvolve(...$args): bool
{
list($item) = $args;
if($item === 'ItemThunderStone'){
// 進化フラグを立てる
$this->evolve_flg = true;
}
// 結果を返却
return $this->evolve_flg;
}
引数には可変長引数を使用しました。ポケモンによっては進化条件が異なり、受け取る引数が異なることを想定したのが理由です。こちらも空(false返却)のメソッドを親クラスに作成しています。
進化先の分岐があるポケモンは、このタイミングでプロパティに進化先を格納することで、進化画面へ移管しても判定結果を残した状態で処理を進めることができます。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「進化の石」の実装に向けた構成を紹介しました。
プログラミング学習に取り組んでいる方や、興味がある方は、ぜひ参考にしてみてくださいね。