プログラミング

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

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

 

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

 

注目の記事

20代起業家が教える「やっといて良かった」3つのコト
雑記
起業
20代起業家が教える「やっといて良かった」3つのコト

  「起業するために何を準備すべき?」 「やっておいて良かったことはありますか?」   独立や起業をしようと志している人のほとんどが、こういった質問を投げかけてきます。自分も同じような悩みを持った立場の時には似た質問をしていたので、その真意はよくわかります。   今回はそんな悩みを抱えて...

たった10分!?読むだけでプログラミングが上達する3原則
プログラミング
jQuery,プログラミング学習,初心者
たった10分!?読むだけでプログラミングが上達する3原則

  プログラミングがなかなか身につかない   学習をしているけど、自分で書くとなれば思うようにいかなかったり、覚えたはずなのにその使い方や応用方法がわからない人のほとんどが、作り方そのものが間違っている傾向にあります。   今回は、プログラミング初学者や、なかなかスキルアップができない人...

ポケモン入れ替え編 PHPポケモン 83
プログラミング
PHP,PHPポケモン,ポケモン
ポケモン入れ替え編 PHPポケモン 83

ポケモンの入れ替え 複数ポケモンの所有、そして並び替えの機能が整ったので、いよいよバトルでのポケモン交代機能を実装します。ポケモンがバトル中に交代する方法は大きく分けて以下の4つです。 プレイヤー操作による交代 ひんしによる交代 相手ポケモンの技による交代 味方ポケモンの技による交代 ...

戦闘用アイテム編 プラスパワー PHPポケモン96
プログラミング
PHP,PHPポケモン,ポケモン
戦闘用アイテム編 プラスパワー PHPポケモン96

戦闘用アイテムとは バトル中に使用できるアイテムはいくつかありますが、その中でも「バトル専用」のアイテムがあります。それが戦闘用アイテムであり、主にドーピングと呼ばれるものです。 アイテムカテゴリとして、プレイヤー対象(スプレーなど)、敵ポケモン対象(ボール類)、味方対象(キズぐすり)の3つに...

SEO対策で役立つ!ライティングスキルを向上させる3ステップ
ライティング
SEO,ブログ
SEO対策で役立つ!ライティングスキルを向上させる3ステップ

  ブログやメール、SNSなどライティングスキルが問われる場面が多く、それは質に直結しています。各プラットフォームによって特徴はありますが、基礎的な文章力自体がついていれば多様な場面で役立つことは間違いありません。 文章の質が高くなれば、ブログであればSEOに強い価値のあるサイトになりますし、SNS...

わざマシン編 習得 PHPポケモン105
プログラミング
PHP,PHPポケモン,ポケモン
わざマシン編 習得 PHPポケモン105

わざマシンによる技習得 前回、わざマシンのアイテムクラスを作成したので、今回は実際に使用するまでの処理を作成していきます。 まずは、アイテムクラスに使用時の処理(effectsメソッド)を増設しましょう。   わざマシン01(/Classes/Item/ItemTM01.php) <?php require_once(root_path('Classes').'...

迷惑メールはなぜ届く?amazonや楽天を騙る悪質メールへの対処法とは
ネットワーク
amazon,スパム,メール,楽天
迷惑メールはなぜ届く?amazonや楽天を騙る悪質メールへの対処法とは

「いきなり迷惑メールが届くようになった」 「Amazonや楽天を装ったメールはどうやって見分ければいいの?」   知らない人からいきなり連絡が届いたり、登録もしていないようなサービスからメールが届けば、それは詐欺メールかも知れません。 スマホやパソコンが一般的に普及して、ネットでの買い物やサービスを利用...

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

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

カテゴリ

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