プログラミング

PHPポケモン「野生ポケモン遭遇編」18

PHP PHPポケモン ポケモン
PHPポケモン「野生ポケモン遭遇編」18

 

PHPポケモンが第18回にしていよいよバトルの第一歩、野生ポケモンとの遭遇編に突入です。

新しいコントローラーの作成と、バトル画面の作成、そしてポケモンデータの受け渡しなどを中心にご紹介します。

 

バトル画面の実装

 ポケモンのゲームでも、野生ポケモンが現れるとバトル画面へ移管します。今回も同画面のまま制御していくのは流石に大変になってきたので、バトル用の画面を新しく作成します。

 

バトル画面(/battle.php
<?php
 
require_once(__DIR__.'/Classes/Controller/BattleController.php');
require_once(__DIR__.'/Resources/Lang/Translation.php');

session_start();
$controller = new BattleController();
?>
<!DOCTYPE html>
<html lang="jp" dir="ltr">
<head>
    <meta charset="utf-8">
    <title>PHPポケモン-バトル-</title>
    <meta name="robots" content="noindex, nofollow" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <link rel="stylesheet" href="Resources/Assets/css/style.css">
</head>
<body>
    <header>
        <div class="container">
            <section>
                <div class="row">
                    <div class="col-12">
                        <h1>PHPポケモン-バトル-</h1>
                    </div>
                </div>
            </section>
        </div>
    </header>
    <main>
        <div class="container">
           
        </div>
    </main>
</body>
</html>

 

バトルアクションの追加

 まずはバトル画面へ移管するためのアクションを作成しましょう。

 

出力用ファイル(/index.php
<?php
 
require_once(__DIR__.'/Classes/Controller.php');
require_once(__DIR__.'/Resources/Lang/Translation.php');
 
session_start();
 
$controller = new Controller();
$action_path = '/';
$battle_path = '/battle.php';
 
?>
--省略
 
<div class="col-12 col-sm-6 mb-5">
    <h2 class="mb-3">メソッドの実行</h2>
    <?php if(is_object($controller->pokemon ?? null)): ?>
        <?php $_SESSION['pokemon'] = $controller->pokemon->export(); # ポケモンの情報をセッションに格納 ?>
        <?php include('Resources/Partials/Forms/change_nickname.php'); # ニックネームの変更?>
        <?php include('Resources/Partials/Forms/add_exp.php'); # 経験値の取得 ?>
        <?php include('Resources/Partials/Forms/battle.php'); # バトル ?>
        <?php include('Resources/Partials/Forms/reset.php'); # リセット ?>
    <?php else: ?>
        <?php include('Resources/Partials/Forms/select_pokemon.php'); ?>
    <?php endif; ?>
</div>

 

バトルフォーム(/Resources/Partials/Forms/battle.php
<form action="<?=$battle_path?>" method="post">
    <div class="input-group mb-3">
        <input class="btn btn-success" type="submit" value="バトル">
    </div>
</form>

 

内容は至って簡単です。新しくフォームを作成し、そのアクション(action)にバトル画面のパスを指定してsubmitしています。

 

 

コントローラーの作成

 バトル用画面でも記述していますが、バトル用のコントローラー(BattleController)も合わせて作成します。

 

バトル用コントローラー(/Classes/Controller/ BattleController.php
<?php

require_once(__DIR__.'/../AutoLoader.php');
require_once(__DIR__.'/../../Traits/ResponseTrait.php');
 
// コントローラー
class BattleController
{
    use ResponseTrait;
 
    /**
    * 敵ポケモン格納用
    * @var object
    */
    public $enemy;
 
    /**
    * 自ポケモン格納用
    * @var object
    */
    public $pokemon;
 
    /**
    * @return void
    */
    public function __construct()
    {
        $post = $_POST;
        $session = $_SESSION;
        // オートローダーの起動
        new AutoLoader();
        // 自ポケモンの格納
        $this->myPokemon($session['pokemon']);
        // 敵ポケモンの格納
        if(isset($session['enemy'])){
            $this->enemyPokemon($session['enemy']);
        }else{
            $this->enemyPokemon();
        }
    }
 
    /**
    * 自ポケモンの格納
    *
    * @param array $pokemon
    * @return void
    */
    private function myPokemon($pokemon)
    {
        $this->pokemon = new $pokemon['class_name']($pokemon);
    }
 
    /**
    * 敵ポケモンの格納
    *
    * @param array|null $pokemon
    * @return void
    */
    private function enemyPokemon($pokemon=null)
    {
        if(is_null($pokemon)){
            $this->enemy = new Fushigidane();
            $this->setMessage('野生の'.$this->enemy->getName().'が現れた!');
        }else{
            $this->enemy = new $pokemon['class_name']($pokemon);
        }
    }
 
}

 ※今後は、コントローラーも親クラスを継承する仕様に変更予定です

 

まずはプロパティから見ていきましょう。

/**
* 敵ポケモン格納用
* @var object
*/
public $enemy;
 
/**
* 自ポケモン格納用
* @var object
*/
public $pokemon;

 

自ポケモンの格納用には今までと同様にpokemonのプロパティに格納します。次に相手(野生ポケモン)用の格納プロパティとして、enemyを用意します。前回までは1匹のポケモンをやり取りする形式をとっていましたが、今回からは敵を含めた2匹分をやりとりします。ですが、引き継ぎ処理等は基本的に同じなので、そこまで複雑ではありません。

 

次にコンストラクタを見てみましょう。

/**
* @return void
*/
public function __construct()
{
    $post = $_POST;
    $session = $_SESSION;
    // オートローダーの起動
    new AutoLoader();
    // 自ポケモンの格納
    $this->myPokemon($session['pokemon']);
    // 敵ポケモンの格納
    if(isset($session['enemy'])){
        $this->enemyPokemon($session['enemy']);
    }else{
        $this->enemyPokemon();
    }
}

 

オートローダーはバトルでも活用するので、初めにインスタンス化しておきます。

次にmyPokemonというメソッドを使って前画面から引き継いだ自ポケモンのデータをプロパティへ格納します。敵ポケモンについては、開始時には新規作成2ターン名以降では前回画面から引き継ぐ必要があります。

/**
* 自ポケモンの格納
*
* @param array $pokemon
* @return void
*/
private function myPokemon($pokemon)
{
    $this->pokemon = new $pokemon['class_name']($pokemon);
}

 

myPokemonのメソッドでは、引き継ぎのインスタンスを作成しています。

 次に敵ポケモン格納用メソッド(enemyPokemon)についてです。

/**
* 敵ポケモンの格納
*
* @param array|null $pokemon
* @return void
*/
private function enemyPokemon($pokemon=null)
{
    if(is_null($pokemon)){
        $this->enemy = new Fushigidane();
        $this->setMessage('野生の'.$this->enemy->getName().'が現れた!');
    }else{
        $this->enemy = new $pokemon['class_name']($pokemon);
    }
}

 

引数指定がされていなければ、新しいインスタンスを作成します。今回はランダムではなく、フシギダネが野生で出てくるようにクラス名を指定しました。

ポケモンでは、ターンが進んでいくにつれて個体値が変更になることはありません。なので、前画面から敵のデータも引き継がれていれば、自ポケモン同様に引数をいれてインスタンス化をしています。

 

アクションの作成

 次にバトルアクションを作成します。初代ポケモンのバトルシステムでは以下の4アクションがあるので、それを一つずつに再現していきましょう。

  • たたかう
  • どうぐ
  • ポケモン
  • にげる

  

にげる

 今回は最も簡単なアクション(にげる)を作成します。にげるというアクションは、バトルから離脱することが目的なので、前の画面(index.php)へ移管させるという処理にします。本来、100%逃げられるということはありませんが、バトル要素が実装されていない現状、その判定は今回無視しておきます。

 

バトル画面(/battle.php
<section>
    <div class="row">
        <div class="col-12 col-sm-6 mb-5">
            <h2 class="mb-3">メソッドの実行</h2>
            <?php $_SESSION['pokemon'] = $controller->pokemon->export(); # 自ポケモンの情報をセッションに格納 ?>
            <?php $_SESSION['enemy'] = $controller->enemy->export(); # 敵ポケモンの情報をセッションに格納 ?>
            <?php # 覚えている技 ?>
            <table class="table table-bordered table-hover mb-3">
                <thead class="thead-light">
                    <tr>
                        <th scope="col">使える技</th>
                        <th scope="col">タイプ</th>
                        <th scope="col">PP</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach($controller->pokemon->getMove() as $move): ?>
                        <tr>
                            <th scope="row" class="w-50"><?=$move->getName()?></th>
                            <td><?=$move->getType()->getName()?></td>
                            <td><?=$move->getPp()?>/<?=$move->getPp()?></td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
            <form action="/" method="post">
                <div class="input-group mb-3">
                    <input type="hidden" name="action" value="retreat">
                    <input class="btn btn-danger" type="submit" value="逃げる">
                </div>
            </form>
        </div>
        <div class="col-12 col-sm-6 mb-5">
            <h2 class="mb-3">実行結果</h2>
            <div class="result-box border p-3 mb-3">
                <?php foreach($controller->getMessages() as list($msg, $status)): ?>
                    <?php if($status == 'error') $class = 'text-danger'; ?>
                    <?php if($status == 'success') $class = 'text-success'; ?>
                    <p class="<?=$class ?? ''?>"><?=$msg?></p>
                <?php endforeach; ?>
            </div>
        </div>
    </div>
</section>

 

技は現状選択できませんが、自ポケモンが正常に引き継がれているかを確認するために用意しています。

逃げるアクションはリセットと同様の形式で、actionキーのhidden要素に対してにげる(retreat)をセットして送るだけのフォームを用意しておきます。フォームのactionについてですが、にげるは前の画面(index.php)へ移管するためのものなので、今回はルートを指定しています。

※もしにげるの判定を実装する場合は、一度battle.phpに対してリクエストを送り、判定の結果成功であればindex.phpへ返却するという処理が必要になります。

 

それでは、にげるのアクションが選択されたときの判定を、indexのコントローラー(Controller.php)に追加しましょう。

 

コントローラー(/Classes/Controller.php
/**
* アクション
*
* @param string $action(method_name)
* @param mixed $param
* @return void
*/
private function action($action, $param)
{
    // リセットの処理
    if($action === 'reset' || is_null($this->pokemon)){
        // 初期化
        $this->pokemon = null;
        $_POST = [];
        $_SESSION = [];
        return;
    }
    // にげるの処理
    if($action === 'retreat'){
        $this->setMessage('逃げ切れた', 'success');
        unset($_SESSION['enemy']);
        return;
    }
    // 呼び出せるメソッドか判別
    if(is_callable([$this->pokemon, $action])){
        // メソッド実行結果を$resultに格納
        $result = $this->pokemon
        ->$action($param);
        switch ($action) {
            // 経験値の取得
            case 'setExp':
            $this->pokemon = $result;
            break;
        }
        // Pokemonクラスに溜まったメッセージを取得
        $this->setMessage($this->pokemon->getMessages());
    }else{
        $this->setMessage('このアクションは使用できません', 'error');
    }
}

 

処理自体は単純です。retreatのアクションが起こった際は別処理で、メッセージをセットしてからセッションに溜まったenemyをunset(削除)しています。これで、自ポケモンは引き継がれた状態でバトルから抜け出すことができます。

 

以下、敵ポケモンの表示を追加したバトル画面の最終コードです。

 

バトル画面(/battle.php
<?php
 
require_once(__DIR__.'/Classes/Controller/BattleController.php');
require_once(__DIR__.'/Resources/Lang/Translation.php');

session_start();
 
$controller = new BattleController();

?>
<!DOCTYPE html>
<html lang="jp" dir="ltr">
<head>
    <meta charset="utf-8">
    <title>PHPポケモン-バトル-</title>
    <meta name="robots" content="noindex, nofollow" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <link rel="stylesheet" href="Resources/Assets/css/style.css">
</head>
<body>
    <header>
        <div class="container">
            <section>
                <div class="row">
                    <div class="col-12">
                        <h1>PHPポケモン-バトル-</h1>
                    </div>
                </div>
            </section>
        </div>
    </header>
    <main>
        <div class="container">
            <section>
                <div class="row">
                    <?php # 敵ポケモン詳細 ?>
                    <div class="col-6">
                        <p><?=$controller->enemy->getName()?> Lv:<?=$controller->enemy->getLevel()?></p>
                    </div>
                    <div class="col-6">
                        <img src="/Resources/Assets/img/pokemon/dots/<?=get_class($controller->enemy)?>.gif" alt="<?=$controller->enemy->getName()?>">
                    </div>
                </div>
            </section>
            <section>
                <div class="row">
                    <div class="col-12 col-sm-6 mb-5">
                        <h2 class="mb-3">メソッドの実行</h2>
                        <?php $_SESSION['pokemon'] = $controller->pokemon->export(); # 自ポケモンの情報をセッションに格納 ?>
                        <?php $_SESSION['enemy'] = $controller->enemy->export(); # 敵ポケモンの情報をセッションに格納 ?>
                        <?php # 覚えている技 ?>
                        <table class="table table-bordered table-hover mb-3">
                            <thead class="thead-light">
                                <tr>
                                    <th scope="col">使える技</th>
                                    <th scope="col">タイプ</th>
                                    <th scope="col">PP</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach($controller->pokemon->getMove() as $move): ?>
                                    <tr>
                                        <th scope="row" class="w-50"><?=$move->getName()?></th>
                                        <td><?=$move->getType()->getName()?></td>
                                        <td><?=$move->getPp()?>/<?=$move->getPp()?></td>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                        <form action="/" method="post">
                            <div class="input-group mb-3">
                                <input type="hidden" name="action" value="retreat">
                                <input class="btn btn-danger" type="submit" value="逃げる">
                            </div>
                        </form>
                    </div>
                    <div class="col-12 col-sm-6 mb-5">
                        <h2 class="mb-3">実行結果</h2>
                        <div class="result-box border p-3 mb-3">
                            <?php foreach($controller->getMessages() as list($msg, $status)): ?>
                                <?php if($status == 'error') $class = 'text-danger'; ?>
                                <?php if($status == 'success') $class = 'text-success'; ?>
                                <p class="<?=$class ?? ''?>"><?=$msg?></p>
                            <?php endforeach; ?>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>
</body>
</html>

 

 

※複数のポケモンをやり取りすることになったので、画像を追加しました。とはいっても、ドット絵をお借りして表示しているだけです。

 

あとは、にげるボタンを押して、正常に前の画面へ戻ることができれば完了です。

 

 

まとめ

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

今回のPHPポケモンでは「野生ポケモン遭遇編」をご紹介しました。

画面移管は適切に行えば、その分無駄な判定処理が少なく済みます。ですが、そのためにどのようにデータを渡せば良いかが重要になります。

 

現在プログラミング学習に取り組んでいる方は、ぜひ参考にしてくださいね。

 

注目の記事

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

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

【Laravel】論理削除対応型existsバリデーションの実装方法
プログラミング
Laravel,PHP
【Laravel】論理削除対応型existsバリデーションの実装方法

  Laravelでは多くのバリデーションが提供されていますが、論理削除を使用している場合はそのままでは使えないものが複数あります。 今回は紐付けをする際に存在チェックで使用するexistsのソフトデリート対応のバリデーションを実装する方法をご紹介します。     カスタムバリデーションの追加   存...

【無料】早起きをして神戸へ行こう!「為になる雑談朝活」
イベント
三宮,朝活,神戸
【無料】早起きをして神戸へ行こう!「為になる雑談朝活」

  朝活を実施することになりましたので、その目的な概要をまとめました。 神戸三宮での開催を予定しておりますので、もしお近くにお住まいの方で日時が会いましたらご参加ください。 土日祝辺りで週1日程度の不定期開催を予定しています。学びにつながる、けど参加しやすい雑談形式ということを主としています...

本当に価値のある宣伝方法 〜多くの人が実践している【間違った努力】とは〜
マーケティング
Facebook,note,Twitter,YouTube,集客
本当に価値のある宣伝方法 〜多くの人が実践している【間違った努力】とは〜

  YouTubeやTwitter、Facebookやnoteなど、いろんなサービスを使った集客方法があります。集客という視点ではなく、それ自体に人を集めたいという人も多いでしょう。   フォロワーやチャンネル登録者数を増やすために、多くの人が様々な取り組みをしていますが、その中でもひときわ意味のないことをただ繰り返して...

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

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

ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41
プログラミング
PHP,PHPポケモン,ポケモン
ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41

ダメージ固定技とは PHPポケモンでも作成したダメージ計算機能ですが、ポケモンの技の中にはそれを必要としない技がいくつかあります。それが「固定ダメージ技」です。 ポケモンwiki(ダメージ固定技) https://wiki.ポケモン.com/wiki/ダメージ固定技 ステータスに依存せず、わざ自体にダメージ量が決...

初心者向けのブログで稼ぐ方法【アフィリエイト編:Google AdSense】
SEO対策
Google AdSense,アフィリエイト,クリック単価,クリック数,ブログ,広告収入
初心者向けのブログで稼ぐ方法【アフィリエイト編:Google AdSense】

  ブログを始めたほとんどの人が アフィリエイトで稼ぎたい   という強い思いを持っているのではないでしょうか。しかし現実は厳しく、広告の審査さえ通らず挫折してしまうといったことは多いです。 中には審査が通っているが、全然広告収入が得られないという人もいるでしょう。 毎日ブログを書いているの...

連続攻撃技と一撃必殺技編 PHPポケモン39
プログラミング
PHP,PHPポケモン,ポケモン
連続攻撃技と一撃必殺技編 PHPポケモン39

連続攻撃技とは 追加効果だけでは処理できない技が、初代に限定していても数多くあります。その一つが「連続攻撃技」です。  連続攻撃技 https://wiki.ポケモン.com/wiki/連続攻撃技 連続攻撃技はさらに4パターンに分かれる。 攻撃回数が2回固定であるもの 攻撃回数が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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力