PHPポケモン記事も記念すべき第77回を迎えることができ、これもひとえに皆様のお力があってのことです。いろんな方のご協力もあり(ドット絵とかドット絵とかドット絵とか)見た目はかなりゲームらしくなってきました。
しかし、肝心のゲーム要素が本家と比べればまだまだ機能も少なく未実装の項目も多いので、これを機に展開力を持たせるべくいろんな要素を追加していきます。
ポケモンプロパティの追加
さて、ポケモンのプロパティとして様々な値を割り当ててきましたが、原作にはまだまだ及びません。初代がベースとなるので特性などの機能はしばらく先ですが、まだゲームを楽しむための要素は数多くあるので、それらを追加しつつ、機能実装を視野に入れていきましょう。
全国図鑑No
ポケモンといえば、バトルはもちろんコレクター要素も楽しみの1つです。中でもポケモン図鑑をいっぱいにするというのが、ゲームストーリー上はオーキドより課せられた指名でもあります。
なので、図鑑を作るために必要な要素である「全国図鑑No」をポケモンのプロパティとして割り当てていきましょう。
ピカチュウ(/Classes/Pokemon/Pikachu.php)
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Pokemon.php');
// ピカチュウ
class Pikachu extends Pokemon
{
/**
* ポケモンナンバー
* @var integer
*/
protected $number = 25;
アニメポケモンの主人公ポケモンでもあるピカ様は、誰もが知っているように全国図鑑Noが025です。プログラムで管理する都合上、数値として保管しておくほうが都合良さそうだったので、数値としてnumberというプロパティにセットしました。
ただ、図鑑に表示する場合などには3桁ゼロ埋め表記も使いたくなるので、こちらは取得メソッド側に処理を加えて対応します。
ポケモン情報取得用トレイト(/App/Traits/Class/Pokemon/ClassPokemonGetTrait.php)
<?php
trait ClassPokemonGetTrait
{
/**
* ナンバーを取得する
* @param zero_fill:boolean
* @return integer|string
*/
public function getNumber($zero_fill=false)
{
if($zero_fill){
// ゼロ埋め
$zero = '';
// ゼロ必要数の算出
$zero_count = 3 - strlen($this->number);
for ($i=0; $i < $zero_count; $i++) {
$zero = $zero.'0';
}
// ゼロ埋め返却
return $zero.$this->number;
}else{
// ナンバー返却
return $this->number;
}
}
引数で数値かゼロ埋めを判別できる仕様です。これで状況に応じた値を受け取ることができるようになりました。
捕捉率
2つ目の追加プロパティは「捕捉率」です。これはポケモンの捕まえやすさに影響するため、今後パーティーを編成していくためには無くてはならない値の1つになります。
捕捉率は低ければ低いほど捕まえにくい(レアリティが高い)という仕様です。最大255の数値で表記され、伝説のポケモンなどは最小の3が割り当てられています。
では、全国図鑑Noと同じくピカチュウの捕捉率について見てみましょう。
/**
* 捕捉率
* @var integer
*/
protected $capture = 190;
ピカチュウの捕捉率は190で、全体で見れば比較的捕まえやすいポケモンです。ただ、序盤では捕獲用アイテム(ボール)の性能が低いということもあり、捕まえづらさは感じる絶妙なラインとなっています。それに対して御三家は、通常野生では出てくることがないポケモンのため、捕捉率が45と低くなっています。
こちらは全国図鑑Noとは異なり、そのままの値が取得できれば良いので、getCaptureメソッドでは、引数指定なしでそのままの値を返却するようにしています。
重さ
最後に追加するプロパティは「重さ」です。こちらは初代でも図鑑に表示するための値として用意されていましたが、バトルでは使われることがありませんでした。しかし、第3世代からは「けたぐり」が重さに合わせて威力が変動したり、バトルにおいても把握して置かなければならない値となりました。
こちらもピカチュウを例にプロパティを割り当てていきましょう。
/**
* 重さ
* @var numeric
*/
protected $weight = 6.0;
重さは小数点第1位までが設定されており一部の技威力にも関係してくるため、int型ではなくnumeric型で保管します。
こちらも捕捉率同様、getWeightというメソッドを作成してそのままの値を返却させます。
けたぐりの実装
では、今回追加したプロパティを使って、新しい技「けたぐり」を実装しましょう。
けたぐり(ポケモンwiki)
初代・第2世代では威力50、追加効果として「30%の確率でひるみ」という技仕様でしたが、第3世代からは「相手の重さによって威力が変動する」という内容に変更されました。
まずは技クラスの基本部分から作成していきましょう。
けたぐり(/Classes/Move/MoveLowKick.php)
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
// けたぐり
class MoveLowKick extends Move
{
/**
* 正式名称
* @var string
*/
protected $name = 'けたぐり';
/**
* 説明文
* @var string
*/
protected $description = '相手の重さによって威力が変わる。';
/**
* タイプ
* @var string
*/
protected $type = 'TypeFighting';
/**
* 分類
* @var string(physical:物理|special:特殊|status:変化)
*/
protected $species = 'physical';
/**
* 威力
* @var integer|null
*/
protected $power = null;
/**
* 命中率
* @var integer
*/
protected $accuracy = 100;
/**
* 使用回数
* @var integer
*/
protected $pp = 20;
/**
* 対象
* @var string
*/
protected $target = 'enemy';
}
威力は対象がいなければ算出できないため、変化技や固定ダメージ技と同様にnullとしています。
威力の算出
それでは威力の算出方法についてです。けたぐりの威力値判定は以下の通りです。
第六世代以降
~9.9kg:20
10.0kg~24.9kg:40
25.0kg~49.9kg:60
50.0kg~99.9kg:80
100.0kg~199.9kg:100
200.0kg~:120
威力は最小値が20で、そこから20区切りで最大120まで上昇します。重さを上記の最低値と比較して、以上であれば20を加算するという処理を組めば威力の算出自体はさほど複雑ではありません。
ですが、変更した威力値を返す方法が現在のPHPポケモンの仕組みではできません。威力補正値用のメソッド(powerCorrection)を使えば算出できますが、ベースとなる威力自体がnullのため乗算すれば0になってしまいます。
威力を20で設定していれば乗算することで算出は可能ですが、本来威力の設定がない技に対して、処理の都合で値を組み込むこともしたくありません。
フラグや分岐を追加して威力値を取得することもできますが、そもそもバトルメソッド自体が複雑化しているため、できるだけその辺りも最小限に抑えておきたいので、威力補正値の計算処理に対してNull合体演算子を用いることで対応します。
攻撃トレイト(/App/Traits/Service/Battle/ServiceBattleAttackTrait.php)
// attackSuccessメソッド内
// 補正込みの技威力を取得(けたぐり等を考慮してnullの場合は1をセット)
$power = ($move->getPower() ?? 1) * $move->powerCorrection($atk_pokemon, $def_pokemon);
getPowerでは通常数値が返却されますが、けたぐりなどの威力変動がある技はnullが返ります。それを威力補正値で正常算出できるように、nullであれば1をセットするようにしました。
これなら、powerCrrectionメソッドで威力値計算をして返却することでそのままの威力を使うことが可能になります。
けたぐり(/Classes/Move/MoveLowKick.php)
/**
* 威力補正値の取得
*
* @param mixed
* @return integer
*/
public function powerCorrection(...$args)
{
/**
* @param Pokemon:object $atk 攻撃ポケモン
* @param Pokemon:object $def 防御ポケモン
*/
list($atk, $def) = $args;
// 防御ポケモンの重さを取得
$weight_list = [0, 10, 25, 50, 100, 200];
$power = array_map(function($weight) use($def){
if($def->getWeight() >= $weight){
return 20;
}else{
return 0;
}
}, $weight_list);
// 威力合計値を補正値として返却
return array_sum($power);
}
array_mapを使って配列内に威力を溜め、最終的にarray_sumで合計値を返却するようにしました。
これで、指定の重さ以上であれば20が上乗せされていくことで重さに対する威力を返すことができます。
実際にけたぐりを使ってみましょう。
おわかりいただけただろうか・・・
フシギダネの重さは6.9kg、それに対してフシギバナの重さは100.0kgです。フシギダネには威力20、フシギバナには威力120が算出されるため、フシギバナの方がダメージ量が多くなっていますね。
個体値によって防御力に差はありますが、種族値で見ればフシギバナの方が圧倒的に防御力が高いため、それに対して上回るダメージを与えられたということは、重さに合わせた威力算出がされているということになります。
これで、けたぐりの実装は完了です。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「ポケモンプロパティの追加」と「けたぐりの実装」についてご紹介しました。
ポケモンに興味がある方、プログラミング学習に取り組んでいる方は、ぜひ参考にしてみてくださいね。