プログラミング

オウムがえし編 PHPポケモン 68

PHP PHPポケモン ポケモン
オウムがえし編 PHPポケモン 68

オウムがえしとは

今回は久々に新しい技を実装します。それが「オウムがえし」です。

オウムがえし(ポケモンwiki

 

初代で登場した技であり、序盤に登場するポッポやオニスズメがレベルアップで覚える技の1つです。最新世代ではオウムがえしという技は実装されなくなった数少ない技の1つでもあります。

それもそのはず、判定がかなり面倒で特別処理が必要な技1つだからです。

※実際の理由は知りません

 

コピーできない技

まず、オウムがえしの技詳細を見てみましょう。

相手が最後に使った技を出す。

 

技名の通り、相手が使った技をそっくりそのまま返してあげる(コピーして使う)のが、この技の仕様となっています。ですが、すべての技をコピーできるわけではありません

 

自分を対象とする技

「せいちょう」や「きあいだめ」など、自身に対してのみ影響を与える技はコピーできません。

自分のフィールドを対象とする技

「しろいきり」や「リフレクター」など、味方フィールドに影響を与える技はコピーできません。

他の技が出る技

「オウムがえし」や「ゆびをふる」など、その技を使うことで別の技が発動する技はコピーできません。

例外

「わるあがき」や「カウンター」はコピーできません。

 

この通り、意外にもコピーできない技は多くあり、それらが相手の最後に使った技と該当する場合は失敗の判定を返す必要があります。

 

ターゲットの設定

まず、大きな括りとして「自分または味方(フィールド)を対象とする技」はコピーできません。なので、技クラスに対して技の対象(target)を設定することで判定ができるようにします。

 

技クラスへのプロパティ追加
/**
* 対象(使ったポケモンから見た立場)
* @var string::friend|enemy
*/
protected $target = 'enemy';

 

この値を取得できるように、親クラスにはgetTargetというメソッドを追加しておきましょう。これで、オウムがえしを発動した際にtargetを確認することで判定することが可能です。

 

では、オウムがえしの技クラスを作成しましょう。

 

オウムがえし(/Classes/Move/MoveMirrorMove.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Move.php');
 
// オウムがえし
class MoveMirrorMove extends Move
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'オウムがえし';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = '相手が最後に使った技を出す。';
 
    /**
    * タイプ
    * @var string
    */
    protected $type = 'TypeFlying';
 
    /**
    * 分類
    * @var string(physical:物理|special:特殊|status:変化)
    */
    protected $species = 'status';
 
    /**
    * 威力
    * @var integer
    */
    protected $power = null;
 
    /**
    * 命中率
    * @var integer
    */
    protected $accuracy = null;
 
    /**
    * 使用回数
    * @var integer
    */
    protected $pp = 20;
 
    /**
    * 対象(使ったポケモンから見た立場)
    * @var string
    */
    protected $target = 'enemy';
 
    /**
    * オウム返し専用効果
    *
    * @param Pokemon $def 防御ポケモン
    * @param battle_state:object::BattleState バトル状態
    * @return mixed
    */
    public function exMirrorMove($def, $battle_state)
    {
        $black_list = [
            // オウム返し・カウンター・わるあがき・ものまね
            get_class(), 'MoveCounter', 'MoveStruggle', 'Mimic'
        ];
        // 相手が最後に使用した技を取得
        $move_class = $battle_state->getLastMove($def->getPosition());
        // 技が取得できない、またはコピーできない技一覧と一致すれば失敗
        if(
            empty($move_class) ||
            in_array($move_class, $black_list, true)
        ){
            return false;
        }
        // 取得した技をインスタンス化
        $move = new $move_class;
        if($move->getTarget() === 'friend'){
            return false;
        }
        // 成功(技のインスタンスを返却)
        return $move;
    }
 
}

 

オウムがえしでは特別処理が入るため、effectschargeとは違う専用メソッド(exMirrorMove)を作成しました。

まず、先程作成したプロパティ(target)を使って判定できない例外技をブラックリストとして配列を用意します。現在わかる範囲で「オウムがえし」「カウンター」「わるあがき」「ものまね」を用意しました。

※ゆびをふるはターゲット不定のため外しました。ただ、不定を導入する必要がなさそうであれば、自分(friend)の設定にする予定です

 

引数では、判定に必要な相手ポケモンとバトル状態のオブジェクトを取得しています。

まず、バトルオブジェクトから最後に使用した技を取り出します。

※こちらは次項で説明します

もし技使用前(初ターン等)であったり、ブラックリストの技と一致した場合は失敗の判定としてfalseを返却します。その2つをクリアできれば、技をインスタンス化してターゲットを確認、friendであれば失敗とみなしfalseを返却します。

 

技成功の場合は、そのまま取得した技のインスタンスを返り値とします。これで、失敗ならfalse、成功ならコピーできた技を攻撃トレイトへ伝えることができます。

 

バトルシステムへの実装

それでは、バトルで使えるようにするため、バトルシステム内にオウムがえしの判定処理を実装していきましょう。

  

最後に使用した技

まず、前項で登場したバトルシステムから最後に使用した技を取得するための処理を追加します。

 

バトル状態クラス(/Classes/BattleState.php
<?php
/**
* バトル状態クラス
*/
class BattleState
{
 
--省略
 
    /**
    * 最後に使用した技
    * @var array
    */
    private $last_moves;
 
    /**
    * @return void
    */
    public function __construct()
    {
        $this->init();
    }
 
    /**==================================================================
    * 初期化・初期値
    ==================================================================**/
 
    /**
    * 初期化
    * @return void
    */
    public function init() :void
    {
        $this->run = 0;
        $this->dafaultFields();
        $this->dafaultTurnDamages();
        $this->dafaultLastMoves();
    }
 
--省略
 
    /**
    * 最後に使用した技の初期値
    * @return void
    */
    public function dafaultLastMoves() :void
    {
        $this->last_moves = [
            'friend' => '',
            'enemy' => '',
            'all' => '',
        ];
    }
 
--省略
 
    /**==================================================================
    * 最後に使用した技
    ==================================================================**/
 
    /**
    * 最後に使用した技(クラス)の取得
    * @param position:string::friend|enemy|all
    * @return string
    */
    public function getLastMove(string $position = 'all')
    {
        return $this->last_moves[$position];
    }
 
    /**
    * 最後に使用した技(クラス)の格納
    * @param move:object|string::Move
    * @param position:string::friend|enemy
    * @return void
    */
    public function setLastMove(string $position, $move)
    {
        // オブジェクト・文字列(クラス名)両方を許可
        if(is_object($move)){
            $class = get_class($move);
        }else{
            $class = $move;
        }
        $this->last_moves[$position] = $class;
        $this->last_moves['all'] = $class;
    }
 
}

 

他のステータスと同じように、初期値を用意してセット、取得と格納用のメソッドを用意しました。1点異なる点は「すべての最終技」としてallの値をセットできるという点です。こちらは使うかどうかわかりませんが、技や状況によっては必要になる可能性を考慮して実装しておきました。

 

次に、最後に使用した技を格納するタイミングについてです。

ゲームの仕様を確認できていませんが、PHPポケモンでは「発動した技」を最後に使用した技とみなして格納する仕様にしました。

 

例えば以下のような流れが発生したケースで考えてみてください。

「敵:たいあたり」

→「味方:オウムがえし(たいあたり)」

→「敵:オウムがえし(???)」

 

上記の場合、敵が使用した「オウムがえし」ではどの技を返すのが正解なのかです。実際に試してみるとわかるかも知れませんが、技をそのまま格納すると「オウムがえし」が選ばれることになり失敗となります。ですが、実際に発動した技を考慮すれば「たいあたり」をコピーしなければなりません。

PHPポケモンでは「たいあたり」を返せるように、attackメソッドの返り値として技オブジェクトを返却し、attackメソッド直後に最後に使用した技を格納しました。

 

バトルサービス(/App/Services/Battle/FightService.php
/**
* 行動順に攻撃処理
*
* @return boolean (false: ひんしポケモン有り)
*/
private function actionAttack($orders)
{
    foreach($orders as list($atk, $def, $move)){
        // 攻撃ポケモンの怒り解除
        $atk->releaseSc('ScRage');
        // 攻撃(返り値に使用した技を受け取る)
        $attack_move = $this->attack($atk, $def, $move);
        // 最後に使用した技を格納
        $this->battle_state
        ->setLastMove($atk->getPosition(), $attack_move);
        // バトル終了のレスポンスチェック(交代技など)
        if(getResponse('end')){
            break;
        }
        // ひんしチェック
        $this->fainting = [
            $atk->getPosition() => $this->checkFainting($atk),
            $def->getPosition() => $this->checkFainting($def),
        ];
        // どちらかがひんし状態なら処理終了
        if($this->fainting['friend'] || $this->fainting['enemy']){
            $result = false;
            break;
        }
    } # endforeach
    // 結果返却
    return $result ?? true;
}

 

attackメソッドのreturnのタイミングでは、すべて技オブジェクトを返却しています。これで、最終技をバトル状態クラスに格納しています。

 

オウムがえしの特別処理

それでは、attackメソッド内でオウムがえしの判定を追加していきましょう。

 

攻撃トレイト(/App/Traits/Service/Battle/ServiceBattleAttackTrait.php
/**
* 攻撃
* (攻撃→ダメージ計算→ひんし判定)
*
* @param atk_pokemon:object::Pokemon
* @param def_pokemon:object::Pokemon
* @param move:object::Move
* @return object::Move
*/
protected function attack(object $atk_pokemon, object $def_pokemon, object $move) :object
{
    // 補正値の初期化
    $this->m = 1;
    // 行動チェック(状態異常・状態変化)
    if(
        !$this->checkBeforeSa($atk_pokemon) ||
        !$this->checkBeforeSc($atk_pokemon)
    ){
        // 行動失敗
        return $move;
    }
    // 「わるあがき」の確認とPP消費処理
    if(!$this->checkEnabledMove($move, $atk_pokemon)){
        setMessage($atk_pokemon->getPrefixName().'は出すことのできる技がない');
    }
    // 「オウムがえし」の特別処理
    if(get_class($move) === 'MoveMirrorMove'){
        $mirror_move = $this->attackMirrorMove($atk_pokemon, $def_pokemon, $move);
        if(!$mirror_move){
            // 技失敗
            setMessage('しかし上手く決まらなかった');
            return $move;
        }else{
            // ミラー技をセット
            $move = $mirror_move;
        }
    }
    // チャージチェック
    $charge = $move->charge($atk_pokemon);
    if($charge){
        // チャージターンなら行動終了
        setMessage($charge);
        return $move;
    }
 
--省略

 

チャージチェック前にオウムがえしの特別処理を行いました。処理内容が多いのでメソッド分けをしています。

attackMirrorMoveの中身は以下の通りです。

/**
* オウムがえしの特別処理
*
* @param atk:object::Pokemon
* @param def:object::Pokemon
* @param move:object::Move
* @return mixed::Move|false
*/
private function attackMirrorMove($atk, $def, $move)
{
    // オウムがえしで「チャージ状態」になっているかどうかを確認
    $charge = $atk->getChargeMove();
    if($charge){
        return new $charge;
    }
    // オウムがえしで「あばれる状態」になっているかどうかを確認
    $thrash = $atk->getThrashMove();
    if($thrash){
        return new $thrash;
    }
    // オウム返しの発動メッセージ
    setMessage($atk->getPrefixName().'は'.$move->getName().'を使った!');
    return $move->exMirrorMove($def, $this->battle_state);
}

 

ここで注目すべきポイントは「チャージ状態」と「あばれる状態」についてです。この2つの状態ではループが発生するため、状態変化にかかっていれば選択された技がそのまま実行されます。ただオウムがえしの判定をするだけでは「あばれる」をコピーした際に2回目の実行では「あばれる」が選択されず、永久に解除されないという状態に陥ってしまいます。チャージ技をコピーした場合も同じです。

それを回避するためにも2つ状態であれば、オウムがえしの特別処理ではなく「あばれる状態の技」または「チャージ状態の技」を抽出して返却します。

この2つの状態に当てはまらなければ、オウムがえしの処理を発生させ、コピーできた技を返却します。

 

では、実際にオウムがえしを使ってみましょう。

 

通常技に対する「オウムがえし」 

 

「あばれる」に対する「オウムがえし」

 ※「あばれる」は検証用に威力を20にしています。また、ライチュウも検証用として「あばれる」しか使いません

 

それぞれ正常に処理が返りました。これで「オウムがえし」の実装は完了です。

 

まとめ

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

今回のPHPポケモンでは「オウムがえしの実装方法」をご紹介しました。

プログラミング学習に取り組んでいる方や、ゲームづくりに興味がある人は、ぜひ参考にしてみてくださいね。

 

注目の記事

レビューがアフィになる!?SNS式ECサイトとは【ビジネス企画書】
ビジネスモデル
ECショップ,SNS
レビューがアフィになる!?SNS式ECサイトとは【ビジネス企画書】

  多くの人が利用しているSNS 副業やフリーランスに人気なアフィリエイト   それぞれの良い点を上手く利用すれば、完成するビジネスはないか?と考えて思い浮かんだ企画です。 今回は「レビューがアフィになる!?SNS式ECサイトとは」について、新時代のショッピングモール式ネットショップの企画をご紹...

HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44
プログラミング
PHP,PHPポケモン,ポケモン
HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44

HPバーアニメーション それでは前回に続き、HPバーのアニメーションづくりをしていきましょう。前回、メッセージに合わせてレスポンスを返却するというサーバー側の仕組みを作成しました。なので、今回はそれをフロント側で受け取り、タイミングよくアニメーションで再現します。   フロント側(js)の処理 前回...

捕獲処理実装編 PHPポケモン 80
プログラミング
PHP,PHPポケモン,ポケモン
捕獲処理実装編 PHPポケモン 80

捕獲処理の作成 前回モンスターボールのクラスを作成したので、今回は捕獲判定までの一連の処理を仕上げていきます。サービス自体は他のアイテムと一緒にするためItemServiceを呼び出し、その中で使用されたアイテムを判断して分岐を作ります。   バトル中のアイテムサービス(/App/Services/Battle/ItemService.ph...

知らなきゃ損!表記ゆれに強いSEO対策とは「オーガニック検索ユーザーを増やそう」
SEO対策
description,keyword,meta,title
知らなきゃ損!表記ゆれに強いSEO対策とは「オーガニック検索ユーザーを増やそう」

  「なかなかオーガニック検索の割合が増えない」 「どういったSEO対策をすればいいかわからない」   ブログやサイト運営者の方で、思うように成果が出ないと悩んでいる人は、まだまだSEO対策が十分ではない可能性があります。そして、SEO対策の中でも知らないと損する一つが「表記ゆれ」への対応です。 ...

フリーランスなら心がけておきたい3つのルール【仕事と遊びは両立させろ】
フリーランス
フリーランス,独立
フリーランスなら心がけておきたい3つのルール【仕事と遊びは両立させろ】

  フリーランスになっても不安がいっぱい   会社というものに縛られないというのは楽なイメージがありますが、それ相応の不安がついてまわります。 その結果、会社員へと舞い戻ってしまうと再度そこから抜け出すことは非常に困難です。   今回は、現在活動している人や、これから独立しようとしている...

アーカイブのディスクリプションを管理画面で設定する方法【SEOに強いWordPressブログ・サイト作り】
プログラミング
PHP,SEO,WordPress
アーカイブのディスクリプションを管理画面で設定する方法【SEOに強いWordPressブログ・サイト作り】

  WordPressで作ったサイトやブログはSEO対策がしやすいという利点があり、より検索に強いサイトへ仕上げることができます。 ですが、SEO対策に特化しているテーマでもアーカイブページのディスクリプション設定ができないものは多く、別で設定する必要があるものがほとんどです。   今回は、より検索で強く...

【変数とは】初心者が最短でPHPを使えるようになるための実践的な学び方
プログラミング
HTML,PHP,プログラミング学習
【変数とは】初心者が最短でPHPを使えるようになるための実践的な学び方

  ※PHP初心者へ向けた内容となりますので、ある程度HTMLの知識がある方を対象とした内容になります。予めご了承ください。    Webプログラミングを学ぶ方はHTML、そしてCSSを学び、そしてJavascriptやPHPという順に学んでいくひとが多いでしょう。 私も実際に、似たような手順で学んでいきました。   ...

フリーランスの仕事の取り方教えます!この3つを押さえておけばOKです【企業も応用可】
フリーランス
フリーランス,独立,起業
フリーランスの仕事の取り方教えます!この3つを押さえておけばOKです【企業も応用可】

  仕事ってどうやってとればいいの?   独立したい、起業したいと考えている人の多くが、仕事はどうやってとればいいのかと悩んで足踏みしています。 実は、基本的な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 function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO 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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力