プログラミング

フレンドリィショップ編 開店準備 PHPポケモン 75

PHP PHPポケモン ポケモン
フレンドリィショップ編 開店準備 PHPポケモン 75

アイテム(どうぐ)

PHPポケモンもバトル機能が一通り揃ってきたので、新機能として「アイテム」の実装に取り掛かります。

アイテムにも色々ありますが、技やポケモンのクラス同様に、初代で登場したアイテムから順番に取り揃えていきましょう。

 

キズぐすりの実装

ポケモンのどうぐ、一番手は「キズぐすり」です。RPGでは欠かせない回復アイテムの1つで、ポケモンの体力を少量回復させる効果をもっています。

スプレー式の キズぐすり。 ポケモン 1匹の HP 20だけ 回復する。

 

アイテムにも、それぞれに効果や使用タイミングがあるため、ポケモンや技同様にクラスによる管理をしていきましょう。

まずはアイテムの親クラス(Item)を作成します。

 

アイテムクラス(/Classes/Item.php
<?php
 
// どうぐ
abstract class Item
{
 
    /**
    * @return void
    */
    public function __construct()
    {
        //
    }
 
    /**
    * 名称の取得
    * @return string
    */
    public function getName()
    {
        return $this->name;
    }
 
    /**
    * カテゴリの取得
    * @return string
    */
    public function getCategory()
    {
        return $this->category;
    }
 
    /**
    * 説明文の取得
    * @return string
    */
    public function getDescription()
    {
        return $this->description;
    }
 
    /**
    * 最大保有数の取得
    * @return integer|null
    */
    public function getMax()
    {
        return $this->max;
    }
 
    /**
    * 買値の取得
    * @return integer
    */
    public function getBidPrice()
    {
        return $this->bid_price;
    }
 
    /**
    * 売値の取得
    * @return integer
    */
    public function getSellPrice()
    {
        return $this->sell_price;
    }
 
}

 

アイテムに持たせるパラメーターを取得するためのメソッドを、親クラスに持たせています。

次に、キズぐすりのクラスを作成しましょう。

 

キズぐすり(/Classes/Item/Potion.php
<?php
$root_path = __DIR__.'/../..';
require_once($root_path.'/Classes/Item.php');
 
// キズぐすり
class ItemPotion extends Item
{
 
    /**
    * 正式名称
    * @var string
    */
    protected $name = 'キズぐすり';
 
    /**
    * 説明文
    * @var string
    */
    protected $description = 'スプレー式のキズぐすり。ポケモン1匹のHPを20だけ回復する。';
 
    /**
    * カテゴリ
    * @var string::general|health|ball|important|machine
    */
    protected $category = 'health';
 
    /**
    * 最大所有数
    * @var integer
    */
    protected $max = 99;
 
    /**
    * 買値
    * @var integer
    */
    protected $bid_price = 200;
 
    /**
    * 売値
    * @var integer
    */
    protected $sell_price = 100;
 
    /**
    * 対象
    * @var string::pokmeon|player
    */
    protected $target = 'pokemon';
 
    /**
    * 使用できるタイミング
    * @var array
    */
    protected $timing = ['battle', 'home'];
 
    /**
    * 効果
    * @return array
    */
    public function effects($pokemon)
    {
        $before = $pokemon->getRemainingHp();
        if($before < $pokemon->getStats('HP')){
            // HP20回復
            $after = $pokemon->calRemainingHp('add', 20);
            $message = $pokemon->getPrefixName().'のHPが'.($after - $before).'回復した';
        }else{
            // 効果なし
            $message = '使っても効果がないよ';
        }
        // メッセージを返却
        return [
            'message' => $message
        ];
    }
 
}

 

まずカテゴリプロパティ(category)についてです。

初代では、アイテムのカテゴリ分けがされておらず、見にくい状態になっていましたが、第2世代からは「ボール」「わざマシン」「大切なもの」などを分けて格納できるようになりました。PHPポケモンでも見やすさ重視で、初代アイテムで実装する項目をカテゴリ分けしていきます。

 

対象(target)使用できるタイミング(timing)については、必要になる可能性が想定されたので設定しました。 

効果メソッド(effects)は、技と同様に配列でメッセージを返却する仕様にしていますが、こちらもバトルやホーム画面へアイテムを使用する機能を組み込みながら調整予定です。

  

フレンドリィショップ

アイテムを実装しても、手に入れる手段がなければ意味がありません。なので、ダミーで準備していたフレンドリィショップに商品を陳列させていきましょう。

 

商品準備

フレンドリィショップへ陳列させる商品は、そのままHTMLの要素として容易せず、configを活用します。

 

ショップconfig/Config/shop.php
<?php
return [
    'ItemPotion'
];

 

現在はキズぐすりしか用意をできていないため、配列としてキズぐすりのクラスだけを返却しています。

次に、コントローラーでフレンドリィショップ用の配列を作成し、ホーム画面から簡単に呼び出せるようにしましょう。

 

ホームコントローラー用トレイト(/Traits/Controller/HomeControllerTrait.php
<?php
 
/**
* ホームコントローラー用トレイト
*/
trait HomeControllerTrait
{
 
    /**
    * 戦闘に参加するポケモン番号を取得
    *
    * @return integer
    */
    protected function getFightPokemonOrder()
    {
        $orders = array_filter($this->party, function($partner){
            return $partner->getRemainingHp() > 0;
        });
        if(empty($orders)){
            return null;
        }else{
            return array_key_first($orders);
        }
    }
 
    /**
    * ショップ情報の取得
    * @return array
    */
    public function getShop()
    {
        return array_map(function($item){
            return new $item;
        },config('shop'));
    }
 
}

 

array_mapを使って、取得したショップ配列の要素をオブジェクトに変換して返しています。どこからでもインスタンス化できるように、Itemディレクトリをオートローダーの対象にしておきましょう。

 

フレンドリィショップではポケモンセンターと違い、購入や売却などいくつか操作が必要になるため、モーダルとして用意します。

 

フレンドリィショップモーダル(/Resources/Partials/Home/Modals/shop.php)
<!-- Modal -->
<div class="modal fade" id="shop-modal" tabindex="-1" role="dialog" aria-labelledby="shop-modal-title" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="shop-modal-title">フレンドリィショップ</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                <?php # ナビ ?>
                <nav class="nav nav-pills nav-justified btn-group mb-3" id="shop-modal-tab">
                    <a class="btn btn-outline-success nav-item nav-link active" id="shop-modal-buy-tab" data-toggle="tab" href="#shop-modal-buy" role="tab" aria-controls="shop-modal-buy" aria-selected="true" data-type="buy">購入</a>
                    <a class="btn btn-outline-info nav-item nav-link" id="shop-modal-sell-tab" data-toggle="tab" href="#shop-modal-sell" role="tab" aria-controls="shop-modal-sell" aria-selected="true" data-type="sell">売却</a>
                </nav>
                <?php # 購入 ?>
                <div class="tab-content mb-3" id="shop-modal-tab-content">
                    <div class="tab-pane fade show active" id="shop-modal-buy" role="tabpanel" aria-labelledby="shop-modal-buy-tab">
                        <form method="post" data-form="shop">
                            <input type="hidden" name="action" value="shop">
                            <input type="hidden" name="do" value="buy">
                            <div class="mb-3 p-3 bg-light">
                                <div class="input-group">
                                    <select class="custom-select col-8" name="order" data-form="buy">
                                        <option value="" selected>----</option>
                                        <?php foreach($controller->getShop() as $order => $item): ?>
                                            <option value="<?=$order?>" data-price="<?=$item->getBidPrice()?>" data-item="<?=$item->getName()?>">
                                                <?=$item->getName()?>(<?=$item->getBidPrice()?>円)
                                            </option>
                                        <?php endforeach; ?>
                                    </select>
                                    <select class="custom-select col-4" name="count" data-form="buy">
                                        <option value="">----</option>
                                        <?php for($i=1;$i<100;$i++): ?>
                                            <option value="<?=$i?>"><?=$i?> 個</option>
                                        <?php endfor; ?>
                                    </select>
                                </div>
                            </div>
                            <div class="alert alert-success" id="shop-buy-calculator" role="alert">
                                <div class="form-group row">
                                    <label class="col-3 col-form-label">おこづかい</label>
                                    <div class="col-9 text-right">
                                        <p class="form-control-plaintext">
                                            <span class='mr-2'><?=$player->getMoney()?></span>円
                                        </p>
                                    </div>
                                </div>
                                <hr>
                                <div class="form-group row">
                                    <label class="col-3 col-form-label">内訳</label>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-buy-item-name"></span>
                                        </p>
                                    </div>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-buy-item-price"></span>
                                        </p>
                                    </div>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-buy-item-count"></span>
                                        </p>
                                    </div>
                                </div>
                                <hr>
                                <div class="form-group row mb-0">
                                    <label class="col-3 col-form-label">合計</label>
                                    <div class="col-9 text-right">
                                        <p class="form-control-plaintext font-weight-bolder">
                                            <span id="shop-buy-total-price" class="mr-2"></span>
                                        </p>
                                    </div>
                                </div>
                                <p data-alert="buy" class="text-danger text-right mb-0 mt-2" style="display:none;">
                                    おこづかいが足りません
                                </p>
                            </div><!-- aleart -->
                            <button type="submit" class="btn btn-success btn-block" id="shop-buy-submit" disabled>購入</button>
                        </form>
                    </div><!-- buy -->
                    <?php # 売却 ?>
                    <div class="tab-pane fade show" id="shop-modal-sell" role="tabpanel" aria-labelledby="shop-modal-sell-tab">
                        <form method="post" data-form="shop">
                            <input type="hidden" name="action" value="shop">
                            <input type="hidden" name="do" value="sell">
                            <div class="mb-3 p-3 bg-light">
                                売却
                            </div>
                            <div class="alert alert-info" id="shop-sell-calculator" role="alert">
                                <div class="form-group row">
                                    <label class="col-3 col-form-label">おこづかい</label>
                                    <div class="col-9 text-right">
                                        <p class="form-control-plaintext">
                                            <span class='mr-2'><?=$player->getMoney()?></span>円
                                        </p>
                                    </div>
                                </div>
                                <hr>
                                <div class="form-group row">
                                    <label class="col-3 col-form-label">内訳</label>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-sell-item-name"></span>
                                        </p>
                                    </div>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-sell-item-price"></span>
                                        </p>
                                    </div>
                                    <div class="col-3 text-right">
                                        <p class="form-control-plaintext">
                                            <span id="shop-sell-item-count"></span>
                                        </p>
                                    </div>
                                </div>
                                <hr>
                                <div class="form-group row mb-0">
                                    <label class="col-3 col-form-label">合計</label>
                                    <div class="col-9 text-right">
                                        <p class="form-control-plaintext font-weight-bolder">
                                            <span id="shop-sell-total-price" class="mr-2"></span>
                                        </p>
                                    </div>
                                </div>
                            </div><!-- aleart -->
                            <button type="submit" class="btn btn-info btn-block" id="shop-sell-submit" disabled>売却</button>
                        </form>
                    </div><!-- sell -->
                </div>
                <input type="hidden" id="player-remaining-money" value="<?=$player->getMoney()?>">
            </div><!-- Modal body -->
        </div><!-- Modal content -->
    </div><!-- Modal dialog -->
</div><!-- Modal  -->

  

ショップの見た目はPHPポケモンオリジナルのものとなっています。アイテムをテーブルとして準備する場合、それぞれにフォームを用意するか、jQueryを使って選択した値をセットしてsubmitしなければなりません。今回はそれらの手間をひとまとめにできるよう、セレクトボックスを採用しました。

 

ポケモンでは、私達が使っているようなネットショップとは異なり、複数のアイテムを一気に購入することはできません。なので、PHPポケモンでもアイテムは1種類ずつ購入する仕様を採用しました。

 

計算機の作成

ポケモンではアイテムと数を選択すると、確認画面としてその合計金額が表示されます。確認画面を入れる場合、もう1枚モーダルを表示する必要があるので、その手間を省くためにPHPポケモンでは購入画面に計算機の機能を持たせました。

選択したアイテムと個数の値をjQueryで受け取り、計算結果を画面上に出力させます。

 

フレンドリィショップ用JS/Pulibc/Assets/js/Home/shop.js
/*----------------------------------------------------------
// 初期化する関数
----------------------------------------------------------*/
 
// おこづかい
var money = $('#player-remaining-money').val();
 
/**
* フレンドリィショップ
* @function change
* @return void
**/
var shopInit = function(){
    $('form[data-form="shop"] select').on('change', function(){
        // フォームの判別
        var form = $(this).data('form');
        // 必要値の取得
        var order_option = $('[data-form="' + form + '"][name="order"] option:selected')
        var price = order_option.data('price');
        var item = order_option.data('item');
        var count = $('[data-form="' + form + '"][name="count"]').val();
        // アイテムが選択されていなければ、計算機をリセット
        if(!item || !count){
            calculatorReset(form);
            return;
        }
        // 合計金額の算出
        var total = price * count;
        // 計算機に値をセット
        $('#shop-' + form + '-item-name').text(item);
        $('#shop-' + form + '-item-price').text(price + ' 円');
        $('#shop-' + form + '-item-count').text(count + ' 個');
        $('#shop-' + form + '-total-price').text(total + ' 円');
        if(money < total){
            $('#shop-' + form + '-submit').prop('disabled', true);
            $('[data-alert="' + form + '"]').show();
        }else{
            $('#shop-' + form + '-submit').prop('disabled', false);
            $('[data-alert="' + form + '"]').hide();
        }
    });
}
 
/**
* モーダル起動時の初期化
* @function change
* @return void
**/
var showModalInit = function(){
    $('#shop-modal').on('show.bs.modal', function(){
        $.each(['buy', 'sell'], function(index, value){
            formReset(value);
            calculatorReset(value);
        })
    });
}
 
/**
* タブクリック時の初期化
* @function change
* @return void
**/
var shopTabInit = function(){
    $('#shop-modal-tab .nav-link').on('click', function(){
        var form = $(this).data('type');
        formReset(form);
        calculatorReset(form);
    });
}
 
/*----------------------------------------------------------
// 処理内で呼び出す関数
----------------------------------------------------------*/
 
/**
* 計算機の初期化
* @param form:string
* @return void
**/
var calculatorReset = function(form){
    $('#shop-' + form + '-item-name').text('-');
    $('#shop-' + form + '-item-price').text('-');
    $('#shop-' + form + '-item-count').text('-');
    $('#shop-' + form + '-total-price').text('-');
    $('[data-alert="' + form + '"]').hide();
    $('#shop-' + form + '-submit').prop('disabled', true);
}
 
/**
* フォームの初期化
* @param form:string
* @return void
**/
var formReset = function(form){
    $('[data-form="'+ form +'"]').val('');
}
 
/*----------------------------------------------------------
// 初期化
----------------------------------------------------------*/
jQuery(function($){
    shopInit();
    shopTabInit();
    showModalInit();
});

 

セレクトボックスの変更を取得し、金額と個数で合計金額を算出、おこづかいが足りているかを判別しています。

フォームではDOMの直接書き換えを考慮して、アイテムクラスや金額を直接飛ばさず、アイテム番号と必要数のみで判別しています。

 

それでは、ショップ計算機の動きを確認してみましょう。

 

計算機が正常に機能していることが確認できました。これで、フレンドリィショップの開店準備は完了です。

 

まとめ

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

今回のPHPポケモンでは「アイテムの実装」と「フレンドリィショップの開店準備」についてご紹介しました。

プログラミング学習に取り組んでいる方や、興味を持たれている方は、ぜひ参考にしてみてくださいね。

 

注目の記事

ポケモン図鑑編 PHPポケモン 88
プログラミング
PHP,PHPポケモン,ポケモン
ポケモン図鑑編 PHPポケモン 88

ポケモン図鑑とは ポケモンに出会ったり、仲間にしたりすると、ポケモン図鑑のデータがどんどんと埋まっていきます。PHPポケモンでもこの仕組みを実現させるために、ポケモン図鑑を作成していきましょう。   クラスによる管理 ポケモン図鑑はクラス管理をしていきます。プレイヤー1人に対して1つのポケモン図...

忘れさせる技選択 前編(覚えるのを諦める) PHPポケモン 55
プログラミング
PHP,PHPポケモン,ポケモン
忘れさせる技選択 前編(覚えるのを諦める) PHPポケモン 55

忘れさせる技の選択 PHPポケモンでは技習得時に忘れさせる技の選択が出来ず、古いものから順番に消えていっていました。ですが、これでは主力技として使っているものが、覚えたくもない技に消されてしまうということが起こってしまいます。 実際のゲームでも、技を覚えようとした際に既に最大数の4枠が埋まっていれ...

PHPポケモン「アクション制御編」27
プログラミング
JavaScript,jQuery,PHP,PHPポケモン,ポケモン
PHPポケモン「アクション制御編」27

  今回のPHPポケモンでは主に画面の作り込みをしていきます。 とは言っても、ガッチリCSSを書いてよりゲームらしい見た目にするわけではなく、あくまで「ゲームシステムを再現するため」だけに整えていくのが目的です。   ということで、今回はPHPよりもBootstrapさんとjQueryさんに活躍してもらいます。   ...

PHPポケモン「バトルシステム編〜HP計算〜」26
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜HP計算〜」26

HP計算 これまでに実装したダメージ計算ですが、計算はできていてもお互いに相手ポケモンのHPを削ることはできませんでした。なので、今回は実際のバトルのように、HPに対してダメージを与えるという仕組みを作成していきます。   残りHP ここで必要になるのが「残りHP」という概念です。今までステータス上のHP...

PHPポケモン「バトルシステム実装編〜ランク補正〜」22
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜ランク補正〜」22

ランク補正とは  ポケモンでは通常ステータスとは違い、バトル中にのみ変化するステータスが存在します。初代仕様であれば、「なきごえ」や「かたくなる」といった変化技により「こうげき」や「ぼうぎょ」の強化や弱体化をさせるものです。これはバトル中であれば引き継がれるものですが、交代やバトルが終了すればリ...

壁技編(リフレクター・ひかりのかべ)PHPポケモン 51
プログラミング
PHP,PHPポケモン,ポケモン
壁技編(リフレクター・ひかりのかべ)PHPポケモン 51

壁技とは 前回実装した「しろいきり」と同じく、初代から実装されたフィールド効果技が存在します。それが「壁技」です。 壁(ポケモンwiki) https://wiki.ポケモン.com/wiki/壁 壁とは、バトルにおける場の状態の一種、およびその場を形成するわざの総称。わざとしては第一世代から存在するが、場の状...

大半のネットワークビジネスが成立しない理由とは【権利収入の落とし穴】
マーケティング
MLM
大半のネットワークビジネスが成立しない理由とは【権利収入の落とし穴】

  誘われたけど、欠点が上手く説明できない 権利収入って本当にもらえるの?   ネットワークビジネスと聞けば、良い印象を抱かない人がほとんどでしょう。ですが、「何故?」と問われて説明できる人は意外にも少数派です。 そして、SNSを積極的に活用している人ならば、一度は誘いを受けたことがあるの...

PHPポケモン「バトルシステム実装編〜補正値計算・乱数・急所〜」21
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜補正値計算・乱数・急所〜」21

バトルシステムの実装  今回は「急所」と「乱数」と「タイプ一致」の判定と補正を実装していきます。 ちなみにですが、ポケモンwikiを熟読したところ、補正値の計算にも順番があり、計算後に小数点の切り捨てや五捨五超入をするなど、そこそこ複雑な計算順序がありましたが、今回はそこまで精密に再現せず、補正値(...

カテゴリ

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