わざマシンとは
ポケモンはレベルアップ以外でも技を習得することができます。それが「わざマシン」というアイテムです。
わざマシン(ポケモンwiki)
最新世代では「技レコード」というものが有り、使い切りとなっています。初代ではわざマシン自体も使い切りでしたが、第5世代からは何度でも使えるという仕様に変更されました。ひでんマシンも初代から存在していましたが、こちらは現在廃止されているため、PHPポケモンでも不要とします。
※ひでんマシンはあくまでストーリーを進める上で必要なものであり、ストーリーが現段階で存在していないPHPポケモンでは実装する必要性がないと判断しました
使用できるポケモン
前回作成した「進化の石」と同様に、わざマシンにも使えるポケモンや使えないポケモンが設定されています。使用可否はアイテム自体に持たせる方が都合良いのですが、進化の石と異なりわざマシンでは大量のポケモン情報を格納する必要があります。そのため、わざマシンではconfigファイルを使った管理をします。
最初は、初代わざマシン01の「メガトンパンチ」から実装しましょう。
わざマシン01(/Classes/Item/ItemTM01.php)
<?php
require_once(root_path('Classes').'Item.php');
/**
* わざマシン01
*/
class ItemTM01 extends Item
{
/**
* 正式名称
* @var string
*/
public const NAME = 'わざマシン01';
/**
* 説明文
* @var string
*/
public const DESCRIPTION = '';
/**
* カテゴリ
* @var string::general|health|ball|important|machine
*/
public const CATEGORY = 'machine';
/**
* 技(わざマシンのみ)
* @var string
*/
public const MOVE = 'MoveMegaPunch';
/**
* 最大所有数
* @var integer
*/
public const MAX = 1;
/**
* 買値
* @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 string
*/
public const POKEMON = 'tm.MoveMegaPunch';
}
アイテム効果は次回作成しますので、まずは設定部分のみを作り込み、整えていきましょう。
わざマシンでは習得する技を格納しておく必要があるので、新しく定数としてMOVEを用意、対象技クラス名を格納しました。
対象となるポケモンには、配列ではなく文字列としてconfigファイルの位置を指定しています。
指定したconfigファイルは以下の通りです。
わざマシンconfig
<?php
return [
// メガトンパンチ
'MoveMegaPunch' => [
'Hitokage', 'Lizardo', 'Lizardon', 'Zenigame', 'Kamail', 'Kamex', 'Pikachu', 'Raichu', 'Mew'
],
];
現在実装されているポケモンだけでも、相当な量となります。キーをわざマシン番号ではなく技クラスを割り当てた理由としては、可視性を良くするためです。
では、定数に設定されている値をアイテムによって異なる場所から取得できるよう判別するために、対象ポケモン取得用の静的メソッドを作成しましょう。
アイテムクラス(/Classes/Item.php)
<?php
/**
* どうぐ
*/
abstract class Item
{
/**
* 使用できるポケモンの取得
* @return array
*/
public static function getUsePokemon(): array
{
// 未設定のアイテム
if(!defined('static::POKEMON')){
return [];
}
// 設定されているポケモン
if(is_array(static::POKEMON)){
// 配列の場合はそのまま返却
return static::POKEMON;
}else{
// 文字列の場合はconfigから返却
return config(static::POKEMON) ?? [];
}
}
定数の存在確認は、definedを用いています。こちらは文字列として指定することでクラス定数の確認に使用できます。
defined(PHPマニュアル)
アイテムによっては対象ポケモンが設定されていないため、まず定義済みかどうかをチェック、その後値がどのような状態で格納されているかを判別しています。
対象ポケモンが1匹だったとしても、配列形式で返却してjson_encodeをしてフロント側へ渡しています。そのため、配列で設定されていなければconfig指定とみなしてconfigデータを取得して返却しています。
アイテム一覧の作成
次にアイテム一覧の作成です。わざマシンの説明文には、格納されている技や、その技の説明文が表示されて欲しいところです。しかし、アイテム個別に技クラスの説明文と同じものを格納するのは手間ですし、クラス定数に別クラス定数を指定するのもあまり良いとは言えません。
なので、フロント側でアイテムカテゴリに応じた分岐を作成して表示する値を変更しましょう。
クラス定数先のクラス定数へのアクセス
ここで頭を悩ませるポイントが「クラス定数先のクラス定数へのアクセス方法」についてです。
例えば、わざマシン01で覚えられる技クラスの説明文を取得しようとすると
ItemTM01::MOVE::DESCRIPTION;
こういった記述でアクセスができそうですね。しかしこれではエラーが返ってきてしまい、肝心の技クラスの説明文へアクセスすることは出来ません。
この場合、定数をクラスに見立てて直接コールすることは出来ないので、一度変数に格納してしまえば期待通りの結果が得られます。
$move = ItemTM01::MOVE;
$move::DESCRIPTION;
しかし、せっかくフロントで使用するのであれば、毎回変数を定義せずに1行にまとめて記述したいですよね。そんな時はconstantという関数を使用します。
constant(PHPマニュアル)
constantを使って定数先のクラスの定数(技説明文)にアクセスする方法は以下の通りです。
constant(ItemTM01::MOVE. '::DESCRIPTION');
まずはアイテムのMOVEへアクセス、そこから文字列として::DESCRIPTIONをつなげることで、目的の定数までたどり着くことができました。
ちなみに、更にその先へアクセスする場合は以下の用に記述することで出来ます。
constant(ClassName::NEXTCLASS .'::NEXTCLASS')::NAME;
では、実際にわざマシンのアイテム欄にconstant関数を使って、格納されている技情報を出力しましょう。
アイテム一覧の行(/Resources/Partials/Common/Modals/Item/item-row.php)
<?php # 利用可能 ?>
<tr data-category="<?=$category?>"
data-target="<?=$item['class']::TARGET?>"
data-use="<?=var_export($item['class']::allowUsed(getPageName()), true)?>"
data-trash="<?=var_export($item['class']::allowTrashed(), true)?>"
data-owned="<?=$item['count']?>"
data-order="<?=$item['order']?>"
<?php # わざマシンでは名称横に技名・説明文には技説明を使用する ?>
<?php if($category === 'machine'): ?>
data-description="<?=constant($item['class']::MOVE.'::DESCRIPTION')?>"
data-name="<?=$item['class']::NAME.'('.constant($item['class']::MOVE.'::NAME').')'?>"
<?php else: ?>
data-description="<?=$item['class']::DESCRIPTION?>"
data-name="<?=$item['class']::NAME?>"
<?php endif; ?>
<?php # 使用できるポケモン ?>
<?php if(!empty($item['class']::getUsePokemon())): ?>
data-pokemon='<?=json_encode($item['class']::getUsePokemon())?>'
<?php endif; ?>
class="item-row">
<td class="w-75">
<img src="/Assets/img/item/class/<?=$item['class']?>.png" alt="<?=$item['class']::NAME?>" class="mr-1" />
<?=$item['class']::NAME?>
</td>
<td class="w-25 text-right"><?=$item['count']?> 個</td>
</tr>
期待通りの値が表示、アイテム使用ポケモンの選択判定も正常に機能していますね。
これでわざマシンクラスの作成と、フロント側の処理は完了です。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「わざマシンの準備」についてクラスの実装方法をご紹介しました。
次回はわざマシン使用の処理を作成予定です。
現在プログラミング学習に取り組んでいる方は、ぜひ参考にしてみてくださいね。