プログラミング

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ポケモン「バトルシステム編〜経験値の獲得〜」29
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜経験値の獲得〜」29

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

構成見直し編(クラス名) PHPポケモン49
プログラミング
PHP,PHPポケモン,ポケモン
構成見直し編(クラス名) PHPポケモン49

構成の見直し 今回は全体構成の見直しをします。ディレクトリについては変更ありませんが、ファイル名とクラス名について大幅な修正をかけていきます。   クラス名の重複回避 まず、クラス名の重複についてです。状態異常・状態変化の子クラスでは重複回避のために接頭語を着けて管理していましたが、他にも重複...

命中率補正と交代技編 PHPポケモン 45
プログラミング
PHP,PHPポケモン,ポケモン
命中率補正と交代技編 PHPポケモン 45

命中率補正とは ダメージ計算や行動順判定には補正(ランク)を計算した結果を反映していましたが、命中率補正についてはまだ未実装だったため、今回はこちらを作成していきたいと思います。 まずはwikiを参考に、計算方法を見ていきましょう。 命中(ポケモンwiki) https:// wiki.ポケモン.com/wiki/命中 第...

ネコにこばん編 PHPポケモン73
プログラミング
PHP,PHPポケモン,ポケモン
ネコにこばん編 PHPポケモン73

ネコにこばんとは 初代ポケモンでは、基本的にトレーナーとのバトルでしかお金を増やすことができず、もし手持ち金が0円の状態で金が必要なイベントが発生すると詰んでしまうという隠された落とし穴がありました。 ですが、初代でも唯一トレーナー意外からお金を得る方法があります。それが「ネコにこばん」という...

フリーランスが打ち合わせで押さえておきたい3つのポイント【収入アップします】
フリーランス
フリーランス,営業
フリーランスが打ち合わせで押さえておきたい3つのポイント【収入アップします】

  フリーランスになれば、デザイナーやプログラマーといった制作をメインとする仕事の人でもクライアントと打ち合わせをしなければいけません。 特に独立や起業前のキャリアとして営業職に縁がなかった人からすれば、打ち合わせが苦手な人は多いはずです。   今回は、そういった営業ベタでやり方が分からない...

未経験からWeb系エンジニアとしてフリーランスになる現実的な方法教えます【軌道に乗れば起業も可能】
フリーランス
エンジニア,フリーランス,プログラミング学習,独立,起業
未経験からWeb系エンジニアとしてフリーランスになる現実的な方法教えます【軌道に乗れば起業も可能】

  セカンドキャリアとしてプログラミングやデザインを学習したい   そう考えてスクールを受講したり、独学で始める人が増えていますが、そのほとんどが実らずに挫折してしまいます。 ですが、学習方法と経験の積み方や職の選び方さえ間違えなければ、技術を身につけてフリーランスとして活動することも難しく...

これってスパム?amazon・paypalを装う悪質メールの対処方法とは
ネットワーク
amazon,Paypal,Xserver,スパム,三井住友,楽天,迷惑メール
これってスパム?amazon・paypalを装う悪質メールの対処方法とは

定期更新、役立つコラムのコーナー!   今回の注目したのは「迷惑(悪質)メールについて」です。   以前はamazonや楽天を名乗る業者から届いた迷惑メールについて紹介、その対処方法について取り上げましたが、今回は更にレベルアップしたスパムがいくつか届いたので、それらも紹介がてら、騙されないため...

V系バンド必見!?アーティスト衣装販売サービスは成功するか?【ビジネス企画書】
ビジネスモデル
ECショップ,V系,アーティスト,コンサルティング,スタートアップ
V系バンド必見!?アーティスト衣装販売サービスは成功するか?【ビジネス企画書】

  この記事は、私の考えたビジネスモデルを紹介するコーナーです。考えるだけで辞めたものや、コストやリスクを考えて断念したもの、そこまでニーズがないと判断したものなど様々なので、読んだ方は自分なりの見解や根拠を踏まえて判断したり、各自ビジネスの参考資料としてご活用ください。   今回は...

カテゴリ

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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力