プログラミング

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

PHP PHPポケモン ポケモン
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ポケモンでは「状態変化」の実装方法をご紹介しました。

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

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

 

注目の記事

千利休から学ぶビジネスモデルの作り方3ステップ!守破離とは
ビジネスモデル
千利休から学ぶビジネスモデルの作り方3ステップ!守破離とは

  千利休の利休道歌に以下のような記述があります。 規矩作法 守り尽くして破るとも離るるとても本を忘るな    これは武道や芸道など学びの基礎として考えられ、創造過程のベースとして用いられてきました。これはビジネスモデルを作り上げるという観点から見ても非常に重要かつ、失敗する多くの人が疎...

PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20

バトルシステムの実装  今回はバトルシステムの中でもメインとなるダメージ計算と、命中判定の部分を実装していきます。   ダメージ計算  ポケモンのダメージ計算は初代から現在までそこまで大きな変化はありません。最新世代ではダメージに関係する要素(アイテム等)が多く、それにより補正値の修正はあります...

反動技編(はかいこうせん・とびひざげり)PHPポケモン40
プログラミング
PHP,PHPポケモン,ポケモン
反動技編(はかいこうせん・とびひざげり)PHPポケモン40

反動技とは ポケモンでは反動技というものがあります。反動によっても様々で、現在の仕組みのままでも実装可能なものや、新たに処理が必要なものまであります。なので、一律で反動技という同じ処理は出来ません。  反動技(ポケモンwiki) https://wiki.ポケモン.com/wiki/反動技 反動技(はんどうわざ...

手っ取り早く情報強者になる簡単な方法
雑記
アウトプット,インプット,ニュース
手っ取り早く情報強者になる簡単な方法

  ニュースや情報番組、討論番組をみると、出演者の方々の情報量の多さに圧倒されることがあります。 また、ユニークな考え方に共感を得る人も多いでしょう。   どうやって、情報を仕入れているのか? なぜそんなことまで知っているのか?   メディアで取り上げられているような人や、活躍している人の多く...

状態異常演出編 PHPポケモン 62
プログラミング
PHP,PHPポケモン,ポケモン
状態異常演出編 PHPポケモン 62

状態異常の演出 今回は「状態異常」にかかった際の動的な変更、演出を実装していきます。 どく状態になれば、メッセージに合わせて「どく」を表記、まひ状態になれば、メッセージに合わせて「まひ」をセットするという単純なものです。   返り値の変更 それではまず、状態異常をセットしてメッセージを生成して...

今からできる!ブログのアクセスを爆UPさせる3大SNS活用法
マーケティング
Facebook,Instagram,Twitter,ブロガー,ブログ
今からできる!ブログのアクセスを爆UPさせる3大SNS活用法

  ブログを収益化させたいけど、なかなかアクセス数が増えない 記事の質は高いのに、その良さをどうやって伝えれば良いかわからない   SEO対策をする上でも、収益化するためにも記事のクオリティは重要です。 しかし、せっかく良い記事を書いていても、そのブログや記事の存在を伝えることができなけれ...

PHPポケモン「バトルシステム編〜経験値の獲得〜」29
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜経験値の獲得〜」29

経験値の獲得 今まではポケモンに直接経験値を与えるというチートびっくりの仕様でしたが、バトルシステムも終盤に差し掛かってきたので「倒したポケモンから経験値を取得する」というごく当たりまえの仕様を導入していきます。   基礎経験値の設定 では、経験値の計算式に入る前に、必要なパラメーターを1つ用...

賢い集客でボロ儲け!?仕事や案件に困らない基本戦略・3選
マーケティング
賢い集客でボロ儲け!?仕事や案件に困らない基本戦略・3選

  「仕事はどうすればもらえるの?」 「集客って何すればいいかわからない」 「告知ってどんな媒体をどう使えばいいの?」   フリーランスで仕事の取り方がわからず苦戦している人や、サービスや商品は作ったものの集客の方法がわからず悩んでいる人のほとんどが、集客のテクニックばかりに目線がいってしま...

カテゴリ

SEO対策 イベント デザイン ネットワーク ビジネスモデル フリーランス プログラミング マーケティング ライティング 動画編集 雑記

タグ

5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach fortify function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jetstream jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO Sequel Pro Skype SNS SSH Symfony TCP/IP title Toastr Trait Twig Twitter UCC V系 WAN WebSub Wi-Fi wiki Windows WordPress XAMPP xml Xserver YouTube YouTuber Zoom アーティスト アウトプット アクセス層 アニメーション アフィリエイト イーブイ インターネット インプット エンジニア オブジェクト指向 お金配り クリック単価 クリック数 コミュニケーション能力 コロナ コンサルティング サムネイル システムエンジニア スタートアップ スタイルシート スパム データベース ディープフェイク デザイナー デザイン テレワーク ナンパ ニュース ネットワークモデル ノマドワーク バナー ピカチュウ ビジネス フィード フリーランス ブロガー ブログ プログラマー プログラミング プログラミング学習 プログラミング教育 プロトコル ホームページ制作 ポケモン マークアップ マーケティング メール リモートワーク レンダリング 三井住友 三宮 仕事依頼 児童デイ 児童発達支援 公開鍵 初心者 助成金 勉強法 営業 広告 広告収入 必勝マニュアル 放課後等デイサービス 朝活 楽天 深層学習 無線LAN 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 認証 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力