状態異常チェック
今回は少し先延ばししていた状態異常判定を一部作成していきましょう。
状態異常では「行動前」と「行動後」に判定するものに分けることができます。
- 行動前
まひ、ねむり、こおり
- 行動後
どく、もうどく、やけど
まずは簡単な行動前から実装していきます。行動前に判定するものは、基本的には「行動可不可」です。アイテムなどを使用すればターン経過は行われないため、攻撃メソッド(attack)の最初にチェック判定を追加しましょう。
バトルコントローラー(/Classes/Controller/BattleController.php)
/**
* 攻撃
* (攻撃→ダメージ計算→ひんし判定)
*
* @param object $atk_pokemon
* @param object $def_pokemon
* @param object $move
* @return boolean (true:相手を戦闘不能にした)
*/
protected function attack($atk_pokemon, $def_pokemon, $move)
{
// 行動チェック(状態異常)
if(!$this->checkBeforeSa($atk_pokemon)){
// 行動失敗
return;
}
checkBeforeSaというメソッドを使い、行動可(true)または行動不可(false)を受け取ります。こちらはチェック格納トレイトに作成します。
チェック格納トレイト(/Traits/Battle/CheckTrait.php)
/**
* アタック前の状態異常チェック
*
* @param object Pokemon
* @return boolean
*/
protected function checkBeforeSa($pokemon)
{
if(!empty($pokemon->getSa())){
// 状態異常をインスタンス化
$class_name = $pokemon->getSa();
$sa = new $class_name;
switch ($class_name) {
/**
* まひ
*/
case 'SaParalysis':
// 1/4の確率で行動不能
if(random_int(1, 4) === 1){
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
/**
* こおり
*/
case 'SaFreeze':
// 1/5の確率でこおり解除
if(random_int(1, 5) === 1){
// こおり解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// 行動不可
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
/**
* ねむり
*/
case 'SaSleep':
if(in_array($pokemon->getSa('turn'), [2, 3], true)){
// 2,3ターン目は1/2で解除
if(random_int(0, 1)){
// ねむり解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// 行動不可
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
}elseif($pokemon->getSa('turn') >= 4){
// 4ターン目(以降)は解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// それ以外(0,1ターン目)は失敗
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
/**
* ひんし
*/
case 'SaFainting':
return false;
break;
/**
* その他
*/
default:
return true;
break;
}
// 行動可
return true;
}else{
// 状態異常にかかっていない
return true;
}
}
かかっている状態異常は1つだけなので、switchを使って判定します。それでは1つずつ見ていきましょう。
まひ
まひ状態の行動判定は以下の通りです。
1/4の確率で技が使えない。
まひ(ポケモンwiki)
25%の確率で行動不能になります。こちらは自動解除されることはないので、単純に1/4の確率でfalseを返却し、メッセージをセットするだけです。
/**
* まひ
*/
case 'SaParalysis':
// 1/4の確率で行動不能
if(random_int(1, 4) === 1){
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
random_intを使い1〜4の乱数を生成して、1であれば行動失敗になります。trueは最終結果として返却するのでreturn不要です。
ねむり
次にねむり状態の判定を行います。行動と解除の判定は以下の通りです。
眠るターン数 2〜4
ねむり(ポケモンwiki)
最大4ターン眠ることになるので、4ターン目には確定解除、2〜3ターン目にはランダムで解除されるという判定を行います。
/**
* ねむり
*/
case 'SaSleep':
if(in_array($pokemon->getSa('turn'), [2, 3], true)){
// 2,3ターン目は1/2で解除
if(random_int(0, 1)){
// ねむり解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// 行動不可
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
}elseif($pokemon->getSa('turn') >= 4){
// 4ターン目(以降)は解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// それ以外(0,1ターン目)は失敗
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
※技「ねむる」等の関係上、ターン数をセットして引いていくという処理が本来正しいようです。作ってから気づいたので後ほど修正予定です。
こおり
最後にこおり状態の行動と解除判定です。
攻撃が出来なくなる。
第二世代以降は、わざを出すときに一定の確率で治る。第二世代は25/256、第三世代以降は20%の確率で治る。
こおり(ポケモンwiki)
/**
* こおり
*/
case 'SaFreeze':
// 1/5の確率でこおり解除
if(random_int(1, 5) === 1){
// こおり解除
$pokemon->releaseSa();
$this->setMessage($sa->getRecoveryMessage($pokemon->getPrefixName()));
}else{
// 行動不可
$this->setMessage($sa->getFalseMessage($pokemon->getPrefixName()));
return false;
}
break;
これで状態異常による行動判定が完成です。
経過ターン数の進行
次に経過ターン数を状態異常にセットします。ねむり状態などターン数が解除に関係するものに対して必要な処理となります。
※こちらもターン数セットの仕様を導入した際は不要になる予定です
ポケモンクラス(/Classes/Pokemon.php)
/**
* 状態異常の解除
*
* @return void
*/
public function releaseSa()
{
if($this->getSa() !== 'SaFainting'){
$this->sa = [];
}
}
ターンの経過処理は攻撃メソッド(attack)の最初に追加しておきます。
攻撃用トレイト(/Traits/Battle/AttackTrait.php)
/**
* 攻撃
* (攻撃→ダメージ計算→ひんし判定)
*
* @param object $atk_pokemon
* @param object $def_pokemon
* @param object $move
* @return boolean (true:相手を戦闘不能にした)
*/
protected function attack($atk_pokemon, $def_pokemon, $move)
{
// ターンの進行
$atk_pokemon->addTurn();
// 行動チェック(状態異常)
if(!$this->checkBeforeSa($atk_pokemon)){
// 行動失敗
return;
}
これで状態異常判定の追加が完了です。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「状態異常による行動判定」の方法をご紹介しました。
ゲームづくりに興味がある人は、ぜひ参考にしてくださいね。