プログラミング

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ポケモンでは「野生ポケモン遭遇編」をご紹介しました。

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

 

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

 

注目の記事

仕事用PCは2年で買い替えろ!その理由とは?
フリーランス
MacBook
仕事用PCは2年で買い替えろ!その理由とは?

  「あなたはパソコンをどのタイミングで買い替えますか?」   私は先日、2015年モデルのMacbookPro15インチから最新モデルのMacbookPro13インチに買い替えました。その理由は、メモリが32GBになったことや、15インチが持ち運びという点で見れば向いていないと判断したということ、そこそこの年数が経...

ポケモンセンター編 PHPポケモン 37
プログラミング
PHP,PHPポケモン,ポケモン
ポケモンセンター編 PHPポケモン 37

ポケモンセンター  バトルシステムを作る関係上、どうしてもダメージを受けることが多くなってきたので、そろそろポケモンセンターを建設(作成)します。 とは言っても、ポケモンセンターに行って交換やらボックス整理などができるわけではなく、ただ回復ポイントを設置するだけの簡単な処理です。   HPの回復 ...

get_template_partで引数を渡す方法(WordPress5.5以降)
プログラミング
PHP,WordPress
get_template_partで引数を渡す方法(WordPress5.5以降)

WordPress5.5へのバージョンアップで、大きく機能が追加されました。中には変更に戸惑っている人もいるかも知れませんが、個人的にはエンジニアの要望を大きく取り入れて自由度がアップした印象があります。 今回はその中でも、多くの方が待ち望んでいた「get_template_part」の変更点についてご紹介します。 ge...

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

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

会話スキルに自信がない人必見!会議やミーティングで失敗しないコツとは
雑記
Skype,Zoom
会話スキルに自信がない人必見!会議やミーティングで失敗しないコツとは

  話下手なので会議で置物状態 Zoomミーティングは発言しづらい 会議の時間が退屈で無駄   そんな悩みや不満を抱えている方はいませんか? 確かに会議は退屈ですし、話下手な人からすれば嫌な時間の1つかも知れませんね。 ですが、立ち回りのポイントを3つ押さえておくだけで、無駄・退屈だと感じて...

スキル習得で挫折しないための3ステップ
雑記
デザイン,ブログ,プログラミング
スキル習得で挫折しないための3ステップ

  せっかく高い教材を買ったのに、気づいたら積んでしまっている・・・   そんな悩み、あなたには有りませんか? 今回は、そんな方のための勉強方法をテーマに説明していきます。 正しい勉強方法を身に着けていれば、どういったメリットがあるのでしょうか? 三日坊主になりにくい いざという...

プログラミングを優しく解説!学んで得する3つの理由
プログラミング
プログラミング教育
プログラミングを優しく解説!学んで得する3つの理由

  プログラミング教育が始まるけど、そもそもよくわかっていない   2020年からは小学校がプログラミング学習が必修化され、翌年には中学校でも導入予定です。 しかし、保護者からすると全くわからず困惑していたり、教える先生たち教師陣からしてもよくわかっていないケースは少なくありません。   今回...

ゆびをふる編 PHPポケモン 69
プログラミング
PHP,PHPポケモン,ポケモン
ゆびをふる編 PHPポケモン 69

ゆびをふるとは 今回PHPポケモンで実装する技は「ゆびをふる」です。  ゆびをふる(ポケモンwiki) https://wiki.ポケモン.com/wiki/ゆびをふる   「ゆびをふる大会」というゆびをふるのみを使った大会なども開催されているということもあり、ポケモンの技の中でも初代から長く愛されてきた1つです。で...

カテゴリ

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