PHPポケモン「バトルシステム編〜状態変化〜」32
2020年9月28日 (最終更新日:2020/9/28 18:30)

PHPポケモン「バトルシステム編〜状態変化〜」32

PHPポケモン「バトルシステム編〜状態変化〜」32

状態変化とは

 状態異常の実装が完了したので、いよいよ状態変化の実装に移ります。PHPポケモンで実装する状態変化とは以下の4つです。

  1. こんらん
  2. ひるみ
  3. バインド
  4. やどりぎのタネ

 

上記4つを実装していきます。状態異常と異なり、技によっては追加になる可能性があります

※いかり状態など

 

状態異常と異なる点は、バトル終了とともに解除されるということと、複数の状態変化が併用できるという点です。

また、こちらも状態異常と同じく攻撃前と攻撃後、どちらかの判定に属することになりますので、そちらも踏まえながら1つずつ説明と実装をしていきます。

 

まずは状態変化の親クラスとなるStateChangeを作成します。

 

状態変化(/Classes/StateChange.php
<?php
 
// 状態変化
abstract class StateChange
{
 
    /**
    * インスタンス作成時に実行される処理
    *
    * @return void
    */
    public function __construct()
    {
        //
    }
 
    /**
    * 名称の取得
    *
    * @return string
    */
    public function getName()
    {
        return $this->name;
    }
 
    /**
    * 状態変化にかかった際のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getSickedMessage($pokemon, $param='Standard')
    {
        if(is_array($this->sicked_msg)){
            return str_replace('::pokemon', $pokemon, $this->sicked_msg[$param]);
        }else{
            return str_replace('::pokemon', $pokemon, $this->sicked_msg);
        }
 
    }
 
    /**
    * 既に状態変化にかかっている際のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getSickedAlreadyMessage($pokemon, $param='Standard')
    {
        if(is_array($this->sicked_already_msg)){
            return str_replace('::pokemon', $pokemon, $this->sicked_already_msg[$param]);
        }else{
            return str_replace('::pokemon', $pokemon, $this->sicked_already_msg);
        }
 
    }
 
    /**
    * 状態変化にかかった際のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getTurnMessage($pokemon, $param='Standard')
    {
        if(is_array($this->turn_msg)){
            return str_replace('::pokemon', $pokemon, $this->turn_msg[$param]);
        }else{
            return str_replace('::pokemon', $pokemon, $this->turn_msg);
        }
 
    }
 
    /**
    * 行動失敗時のメッセージを取得
    *
    * @param string $pokemon
    * @return string
    */
    public function getFalseMessage($pokemon, $param='Standard')
    {
        if(is_array($this->false_msg)){
            return str_replace('::pokemon', $pokemon, $this->false_msg[$param]);
        }else{
            return str_replace('::pokemon', $pokemon, $this->false_msg);
        }
    }
 
    /**
    * 回復時のメッセージを取得
    *
    * @param string $pokemon
    * @param string $param
    * @return string
    */
    public function getRecoveryMessage($pokemon, $param='Standard')
    {
        if(is_array($this->recovery_msg)){
            return str_replace('::pokemon', $pokemon, $this->recovery_msg[$param]);
        }else{
            return str_replace('::pokemon', $pokemon, $this->recovery_msg);
        }
    }
 
}

 

状態異常とほとんど同じ内容ですが、メッセージを取り出す際に配列かどうかをチェックしている点が異なります。こちらは後ほど説明します。

 

次に、ポケモンに対して状態変化を格納するためのプロパティ(sc)を用意しましょう。

 

ポケモンクラス(/Classes/Pokemon.php
/**
* 状態変化(バトル後リセット)
* ScConfusion           こんらん
* ScFlinch              ひるみ
* ScLeechSeed           やどりぎのタネ
* ScBind                バインド
* @var array [sc_class_name(string) => ['turn' => turn(integer), 'param' => param(string)]]
*/
protected $sc = [];

状態異常ではクラス名をキーにしてターン数が値として格納されていましたが、状態変化では配列を値として格納して、その中にturnparamのキーに割り当てられた値を持っています。ターンには経過または残ターン数が入ります。paramについては、今回実装する中ではバインド状態で使用します。

 

次にチェック用のメソッドを作成しましょう。

 

チェック格納トレイト(/Traits/Battle/CheckTrait.php
/**
* アタック前の状態変化チェック
*
* @param object Pokemon
* @return boolean
*/
protected function checkBeforeSc($pokemon)
{
    $sc = $pokemon->getSc();
    if(empty($sc)){
        // 状態変化にかかっていない
        return true;
    }
 
    // ここに分岐
 
    // 行動可
    return true;
}
 
 
/**
* アタック後の状態変化チェック
*
* @param object Pokemon
* @return boolean (false:ひんし)
*/
protected function checkAfterSc($sicked_pokemon, $enemy_pokemon)
{
    // 状態変化を取得
    $sc = $sicked_pokemon->getSc();
    if(empty($sc)){
        // 状態異常にかかっていない
        return true;
    }
 
    // ここに分岐
 
    // ひんし状態ではない
    return true;
}

 

行動前のチェックでは状態異常同様に引数で対象ポケモンのインスタンスを受け取っていますが、行動後では第2引数で相手ポケモン(状態変化をかけた側)のインスタンスを受け取っておきます。これは、やどりぎのタネで回復処理が必要になるためです。

 

ポケモンインスタンスから呼び出しているgetScのメソッドについてですが、こちらは単純に状態変化すべてを返却しています。

 

Get格納トレイト(Traits/Pokemon/GetTrait.php
/**
* 現在の状態変化を取得する
* @return array
*/
public function getSc()
{
    return $this->sc;
}

 

最後に、作成したチェック関数をそれぞれ状態異常と同じタイミングで呼び出しておきましょう。

 

攻撃用トレイト(/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)
{
    // 行動チェック(状態異常・状態変化)
    if(!$this->checkBeforeSa($atk_pokemon) || !$this->checkBeforeSc($atk_pokemon)){
        // 行動失敗
        return;
    }

 

バトルコントローラー(/Classes/Controller/BattleController.php)

/**
* アクション
*
* @param string $action
* @param mixed $param
* @return void
*/
private function action($action, $param)
{
    // 敵ポケモンの技をインスタンス化
    $e_move = $this->getInstance($this->aiSelectMove());
    switch ($action) {
        /**
        * にげる
        */
        case 'run':
        $this->run++;
        if($this->checkRun()){
            $this->endBattle();
        }
        $this->setMessage('逃げられない!');
        // 敵ポケモンの攻撃
        $p_damage = $this->attack($this->enemy, $this->pokemon, $e_move);
        break;
        /**
        * たたかう
        */
        case 'fight':
        // 自ポケモンの技をインスタンス化
        $p_move = $this->getInstance($param);
        // 行動順の判定
        $order_array = $this->orderMove(
            [$this->pokemon, $this->enemy, $p_move],
            [$this->enemy, $this->pokemon, $e_move],
        );
        // 行動順にforeachでattackメソッドを実行
        foreach($order_array as list($atk, $def, $move)){
            if($this->attack($atk, $def, $move)){
                // 相手をひんし状態にした
                break;
            }
        }
        // 行動順にforeachでcheckAfterSaとcheckAfterScを実行
        foreach($order_array as list($atk, $def, $move)){
            if(!$this->checkAfterSa($atk) || !$this->checkAfterSc($atk, $def)){
                // ひんし状態になった
                break;
            }
        }
        $this->setMessage('行動を選択してください');
        break;
    }
}

 

これで状態変化の下準備は完了です。それではそれぞれの状態変化に合わせた処理と分岐を作成していきましょう。

  

こんらん

 まずは「こんらん」についてです。おなじみポケモンWikiを参考にします。

14ターン(第一世代では17ターン)の間、1/3(第六世代までは1/2)の確率で威力40の物理攻撃を自分にする。ただし、反動で動けない間や、ねむり、こおり、ひるみ、なまけなどになっているターンはカウントせず、自分への攻撃も起こらない。

こんらん(ポケモンwiki

 

ねむりと同様に、状態変化をセットする際にターン数をセットして、毎ターン残数を引いていきます。眠りとは異なり、失敗時には「自らを攻撃する」という処理が入るため、ダメージ計算とひんし判定が必要になります。

 

まずはこんらんのクラスを作成します。

 

こんらん(/Classes/StateChange/ScConfusion.php
<?php
require_once(__DIR__.'/../StateChange.php');
 
// こんらん
class ScConfusion extends StateChange
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'こんらん';
 
    /**
    * 状態変化にかかった際のメッセージ
    * @var string
    */
    protected $sicked_msg = '::pokemonは、混乱した';
 
    /**
    * すでにこの状態変化にかかっている際のメッセージ
    * @var string
    */
    protected $sicked_already_msg = '::pokemonは、既に混乱している';
 
    /**
    * ターンチェック時に表示されるメッセージ
    * @var string
    */
    protected $turn_msg = '::pokemonは、こんらんしている';
 
    /**
    * 行動失敗
    * @var string
    */
    protected $false_msg = '::pokemonは、わけも分からず自分を攻撃した';
 
    /**
    * 回復時に表示されるメッセージ
    * @var string
    */
    protected $recovery_msg = '::pokemonはこんらんが解けた';
 
}

 

次にこんらんのチェックを作成します。こんらんは行動前に判定が行われるため、checkBeforeScに分岐を記述しましょう。

 

チェック格納トレイト(/Traits/Battle/CheckTrait.php
/**
* こんらん
*/
if(isset($sc['ScConfusion'])){
    $confusion = new ScConfusion;
    // こんらんのターンカウントを進める
    $pokemon->goScTurn('ScConfusion');
    if($sc['ScConfusion']['turn'] <= 0){
        // こんらん解除
        $pokemon->releaseSc('ScConfusion');
        $this->setMessage($confusion->getRecoveryMessage($pokemon->getPrefixName()));
    }else{
        // こんらんしている旨のメッセージ
        $this->setMessage($pokemon->getPrefixName().'は混乱している');
        // 1/3の確率で行動失敗
        if(!random_int(0, 2)){
            // 行動失敗(自分に威力40の物理ダメージ)
            $this->setMessage($confusion->getFalseMessage($pokemon->getPrefixName()));
            // ダメージ計算
            $damage = $this->calDamage(
                $pokemon->getLevel(),                   # レベル
                $pokemon->getStats('Attack', true),     # 物理攻撃値(補正値込み)
                $pokemon->getStats('Defense', true),    # 物理防御値(補正値込み)
                40, # 技の威力
                1,  # 補正値
            );
            // ダメージ計算
            $pokemon->calRemainingHp('sub', $damage);
            // ひんしチェック
            $this->checkFainting($pokemon);
            return false;
        }
    }
}

 

処理の最初にターンカウントを進め、カウントが0以下であれば混乱を解除しています。もし解除されていなければ、そこから更に分岐が入ります。1/3の確率で失敗の判定となるため、random_intで0〜2の乱数をとり、0(false)であれば攻撃失敗という仕組みです。

 

状態変化を解除するためのreleaseScはポケモンクラスに作成しておきましょう。

 

ポケモンクラス(/Classes/Pokemon.php
/**
* 状態変化の解除
*
* @param string $class
* @return void
*/
public function releaseSc($class)
{
    unset($this->sc[$class]);
}

  

自傷攻撃

 こんらんの行動失敗判定は、威力40の物理攻撃を自身に行うというものです。なので、ここで自身に対してダメージ計算を行なっています。

// 行動失敗(自分に威力40の物理ダメージ)
$this->setMessage($confusion->getFalseMessage($pokemon->getPrefixName()));
// ダメージ計算
$damage = $this->calDamage(
    $pokemon->getLevel(),                   # レベル
    $pokemon->getStats('Attack', true),     # 物理攻撃値(補正値込み)
    $pokemon->getStats('Defense', true),    # 物理防御値(補正値込み)
    40, # 技の威力
    1,  # 補正値
);
// ダメージ計算
$pokemon->calRemainingHp('sub', $damage);
// ひんしチェック
$this->checkFainting($pokemon);
return false;

 

これで分岐が完成しました。こんらん状態は「あやしいひかり」を使って検証しましょう。

 

あやしいひかり(/Classes/Move/ConfuseRay.php
<?php
require_once(__DIR__.'/../Move.php');
 
// あやしいひかり
class ConfuseRay extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'あやしいひかり';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手をこんらん状態にする。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Ghost';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 100;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 10;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 相手をこんらん状態にする
        $msg = $def->setSc('ScConfusion', random_int(1, 4));
        // メッセージをセット
        $this->setMessage($msg);
    }

}

 

ポケモンメソッドに対して使用しているsetScは以下の通りです。

 

Set格納トレイト(/Traits/Pokemon/SetTrait.php
/**
* 状態変化をセットする
* @param string|array $class
* @param integer $turn
* @param string $param
* @return string
*/
public function setSc($class, $turn=0, $param='Standard')
{
    // 状態変化の引き継ぎ処理
    if(is_array($class)){
        $this->sc = $class;
        return;
    }
    // セットできる状態異常一覧
    $sc_list = [
        'ScConfusion', 'ScFlinch', 'ScLeechSeed', 'ScBind',
    ];
    // クラスチェック
    if(!in_array($class, $sc_list, true) || !class_exists($class)){
        // 不正なクラス
        return '指定された状態変化は存在しません';
    }
    $sc = new $class;
    // 状態変化のセット確認
    if(isset($this->sc[$class])){
        // 既に同じ状態変化にかかっている
        return $sc->getSickedAlreadyMessage($this->getPrefixName(), $param);
    }else{
        // 状態変化をセット
        $this->sc[$class] = [
            'turn' => $turn,
            'param' => $param,
        ];
        return $sc->getSickedMessage($this->getPrefixName(), $param);
    }
}

 

setSaと似た処理になりますが、こちらは複数を許可しています。また、paramの項目がある関係上、第3引数でparamの値を指定できる仕様になっています。

 

以下、出力結果です。

 

 

 

 

 

 

 

ひるみ

 次に「ひるみ」を実装しましょう。こちらもポケモンwikiを参考にしていきます。

そのターンのみ、行動できなくなる。

ひるみ(ポケモンwiki

 

ひるみ状態のクラスは以下の通りです。

 

ひるみ(/Classes/StateChange/ScFlinch.php
<?php
require_once(__DIR__.'/../StateChange.php');
 
// ひるみ
class ScFlinch extends StateChange
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'ひるみ';
 
    /**
    * 状態変化にかかった際のメッセージ
    * @var string
    */
    protected $sicked_msg = '::pokemonは、ひるんだ';
 
}

 

こちらも行動の有無に関わる状態変化のため、行動前(checkBeforeSc)のメソッドに判定を追加しましょう。

 

チェック格納トレイト(/Traits/Battle/CheckTrait.php
/**
* ひるみ
*/
if(isset($sc['ScFlinch'])){
    $flinch = new ScFlinch;
    // 行動失敗
    return false;
}
 
/**
* こんらん
*/

 

ここで注意すべき点は、こんらんの前に記述するということです。その理由は、こんらんにあります。

ただし、反動で動けない間や、ねむり、こおり、ひるみ、なまけなどになっているターンはカウントせず、自分への攻撃も起こらない。

 

これは、ひるんでいればこんらんの判定自体が行われないことになります。なので、ひるみの判定はこんらんよりも先に実行します。

 

解除タイミング

 ひるみは1ターン限りの状態変化です。なので、状態異常をセットした後にはそのターンの最後に解除する必要があります。なので、checkAfterScに解除処理を追加しましょう。

/**
* アタック後の状態変化チェック
*
* @param object Pokemon
* @return boolean (false:ひんし)
*/
protected function checkAfterSc($sicked_pokemon, $enemy_pokemon)
{
    // ひるみ解除
    $sicked_pokemon->releaseSc('ScFlinch');

 

 それでは「かみつく」を使って出力結果を見てみましょう。

 

かみつく(/Classes/Move/Bite.php
<?php
require_once(__DIR__.'/../Move.php');
 
// かみつく
class Bite extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'かみつく';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '30%の確率で敵をひるませる。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Dark';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'physical';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = 60;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 100;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 25;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        // 30%の確率
        if(30 < random_int(0, 100)){
            // random_intで31以上が生成されたら失敗
            return;
        }
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 相手をひるませる
        $msg = $def->setSc('ScFlinch');
        // メッセージをセット
        $this->setMessage($msg);
    }

}

 

 

 

 

バインド

 次に「バインド」状態の状態変化を作成します。こちらは聞き慣れないひとが多いかも知れませんが、「まきつく」や「しめつける」などの技を使った際に用いられる縛り状態の状態変化です。

バインドとは、ポケモンの状態変化の一つ。

第六世代までは、しめつける状態と呼ばれていた。

 

交代や逃げることができなくなる。

テレポートで戦闘を終わらせることができない。第八世代からはプレイヤーがテレポートを使用する場合はバインド状態でも交代することができるが、野生ポケモンがテレポートを使用する場合は失敗する。

ターンごとにダメージを受ける。

第五世代までは、最大HP1/16

第六世代からは、最大HP1/8

最後のターンは解除メッセージのみでダメージは受けない(第三世代以降)

第二世代まで、ダメージを受けるターン数は拘束されるターン数より1ターン多い。第三世代から、ダメージを受けるターン数と拘束されるターン数は同じ。

バインド(ポケモンwiki

 

そこそこ条件付をしなければなさそうですが、現在実装されているシステムに付与する要素は「毎ターンダメージを受ける」という点のみです。

 

そして、第1世代の技の中でこのバインド状態にできる技は以下の3つのみです。

  1.  しめつける
  2. まきつく
  3. ほのおのうず

 

ほのおのうずとしめつける

 ここで1点問題が出てきました。同じバインド状態といっても、「まきつく」や「しめつける」と違い、「ほのおのうず」でバインド状態にすると出力されるメッセージが異なるという点です。なので、ここで事前に用意したparamを使用します。

 

バインド(/Classes/StateChange/ScBind.php
<?php
require_once(__DIR__.'/../StateChange.php');
 
// バインド
class ScBind extends StateChange
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'バインド';
 
    /**
    * 状態変化にかかった際のメッセージ
    * @var string
    */
    protected $sicked_msg = [
        'Standard' => '::pokemonは、しめつけられた',
        'FireSpin' => '::pokemonは、ほのおのうずに閉じ込められた',
    ];
 
    /**
    * ターンチェック時に表示されるメッセージ
    * @var string
    */
    protected $turn_msg = [
        'Standard' => '::pokemonは、しめつけられている',
        'FireSpin' => '::pokemonは、ほのおのうずに巻き込まれている',
    ];
 
    /**
    * ターンチェック時に表示されるメッセージ
    * @var string
    */
    protected $recovery_msg = [
        'Standard' => '::pokemonは、しめつけから開放された',
        'FireSpin' => '::pokemonは、ほのおのうずから抜け出した',
    ];
 
}

 

各メッセージにキーを割り振りました。これでバインド状態の際にパラメーターを差し込んでいれば、それに合ったメッセージを取り出すことができます。

 

バインド状態の判定は「行動後」に行うため、checkAfterScに判定を追加しましょう。

 

チェック格納トレイト(/Traits/Battle/CheckTrait.php
/**
* バインド
*/
if(isset($sc['ScBind'])){
    // 最大HPの1/8ダメージを受ける
    $bind = new ScBind;
    // バインドのターンカウントを進める
    $sicked_pokemon->goScTurn('ScBind');
    if($sc['ScBind']['turn'] <= 0){
        // バインド解除
        $sicked_pokemon->releaseSc('ScBind');
        $this->setMessage($bind->getRecoveryMessage($sicked_pokemon->getPrefixName(), $sc['ScBind']['param']));
    }else{
        // 小数点以下切り捨て
        $damage = (int)($sicked_pokemon->getStats('HP') / 8);
        if($damage){
            // 最小ダメージ数は1
            $damage = 1;
        }
        // ダメージ計算
        $sicked_pokemon->calRemainingHp('sub', $damage);
        // メッセージ
        $this->setMessage($bind->getTurnMessage($sicked_pokemon->getPrefixName(), $sc['ScBind']['param']));
        // ひんし判定
        if($this->checkFainting($sicked_pokemon)){
            return false;
        }
    }
}

 

こちらは毒ダメージの判定や、こんらんの解除チェック判定を組み合わせたような処理になります。メッセージを取得する際には、そのパラメーターを引数として渡してバインド状態に合ったメッセージを受け取ります。

 

今回は「ほのおのうず」を使って確認してみましょう。

 

ほのおのうず(/Classes/Move/FireSpin.php
<?php
require_once(__DIR__.'/../Move.php');
 
// ほのおのうず
class FireSpin extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'ほのおのうず';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手をバインド状態にし、2〜5ターン連続でHPを減らし続ける。相手は逃げたり交換したりすることができなくなる。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Fire';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'special';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = 35;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 85;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 15;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 相手をバインド状態にする
        $msg = $def->setSc('ScBind', random_int(4, 5), 'FireSpin');
        // メッセージをセット
        $this->setMessage($msg);
    }

}

 

 

 

  

やどりぎのタネ

 最後は「やどりぎのタネ」状態を実装します。他と違い、ダメージを与え且つ回復するという味方と相手どちらにも処理が必要になる状態変化です。checkAfterScの第2引数はこのために使用します。

毎ターン最大HP1/8(第一世代では1/16)が減り、相手のHPがその分回復する(小数点は切捨て)

やどりぎのタネ_(状態変化)(ポケモンwiki

 

では「やどりぎのタネ」の状態変化クラスを作成しましょう。

 

やどりぎのタネ:状態変化(/Classes/StateChange/ScLeechSeed.php
<?php
require_once(__DIR__.'/../StateChange.php');
 
// やどりぎのタネ
class ScLeechSeed extends StateChange
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'やどりぎのタネ';
 
    /**
    * 状態変化にかかった際のメッセージ
    * @var string
    */
    protected $sicked_msg = '::pokemonは、やどりぎのタネを植え付けられた';
 
    /**
    * すでにこの状態変化にかかっている際のメッセージ
    * @var string
    */
    protected $sicked_already_msg = '::pokemonは、既にやどりぎのタネを植え付けられている';
 
    /**
    * ターンチェック時に表示されるメッセージ
    * @var string
    */
    protected $turn_msg = 'やどりぎのタネが::pokemonの体力を吸収している';
 
}

 

体力の吸収

 次に「やどりぎのタネ」のチェック処理を作成します。

処理自体は至って簡単です。状態変化にかかっているポケモン($sicked_pokemon)にダメージを与え、相手ポケモン($enemy_pokemon)のHPを回復させます。こちらも行動後(checkAfterSc)に記述します。

 

チェック格納トレイト(/Traits/StateChange/ScLeechSeed.php
/**
* やどりぎのタネ
*/
if(isset($sc['ScLeechSeed'])){
    // 最大HPの1/8HPを吸収する
    $leech_seed = new ScLeechSeed;
    // 小数点以下切り捨て
    $damage = (int)($sicked_pokemon->getStats('HP') / 8);
    if($damage){
        // 最小ダメージ数は1
        $damage = 1;
    }
    // ダメージ計算
    $sicked_pokemon->calRemainingHp('sub', $damage);
    // 回復
    $enemy_pokemon->calRemainingHp('add', $damage);
    // メッセージ
    $this->setMessage($leech_seed->getTurnMessage($sicked_pokemon->getPrefixName()));
    // ひんし判定
    if($this->checkFainting($sicked_pokemon)){
        return false;
    }
}

 

ダメージ判定の後に、回復処理を行なっています。「やどりぎのタネ」を使って出力結果をみてみましょう。

 

やどりぎのタネ:技(Classes/Move/LeechSeed.php
<?php
require_once(__DIR__.'/../Move.php');
 
// やどりぎのタネ
class LeechSeed extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'やどりぎのタネ';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手をやどりぎのタネ状態にし、毎ターン相手の最大HPの1/8を奪って、その分自分のHPを回復を回復させる。自分が交代しても効果は続く。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'Grass';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = 90;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 10;
 
    /**
    * 優先度
    * @var integer
    */
    protected $priority = 0;
 
    /**
    * 追加効果
    *
    * @param array $args
    * @return void
    */
    public function effects(...$args)
    {
        /**
        * @param Pokemon $atk 攻撃ポケモン
        * @param Pokemon $def 防御ポケモン
        */
        list($atk, $def) = $args;
        // 相手をやどりぎのタネ状態にする
        $msg = $def->setSc('ScLeechSeed');
        $this->setMessage($msg);
    }
 
}

 

 

 

 

 

状態変化はバトル中のみ引き継ぎの必要があるため、敵ポケモン(enemy)と同様にsessionに格納して保管、引き継ぎ処理を追加しておきましょう。

以上で状態変化の処理実装は完了です。

 

まとめ

いかがだったでしょうか。

今回のPHPポケモンでは「状態変化」の実装方法をご紹介しました。

ポケモンには様々な状態変化があり、シリーズを経る毎に実装されています。バトルに置いては一つの楽しみ要素であり、さらに戦略的に用いられるものなど数多くあります

ゲームづくりに興味がある人は、ぜひ参考にしてみてくださいね。

 

Copyright © 2016-2020 YQUAL All Rights Reserved.