プログラミング

フレンドリィショップ編 開店準備 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ポケモン「野生ポケモン遭遇編」18
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「野生ポケモン遭遇編」18

  PHPポケモンが第18回にしていよいよバトルの第一歩、野生ポケモンとの遭遇編に突入です。 新しいコントローラーの作成と、バトル画面の作成、そしてポケモンデータの受け渡しなどを中心にご紹介します。   バトル画面の実装  ポケモンのゲームでも、野生ポケモンが現れるとバトル画面へ移管し...

たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは
マーケティング
コロナ,フリーランス,ホームページ制作,助成金
たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは

  仕事の依頼が全然来ない・・・ 営業しても話を聞いてくれない・・・   その多くが営業力以上に、営業をすべきタイミングがわかっていない人がほとんどです。 実は助成金等を活用することで、行政書士などの職業以外でも仕事を受注することは可能になります。   今回は筆者が、たった2日で200万...

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

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

プログラミングで躓く人必見!一人前になるためのSDCとは
プログラミング
プログラミング学習
プログラミングで躓く人必見!一人前になるためのSDCとは

  「プログラミング学習を始めたけど中々身につかない」 「挑戦したいけど何から始めればいいかわからない」   プログラミング教育が始まるとともに、プログラミング学習のニーズも日々高まってきています。ですが、興味はあっても中々挑戦までは至らなかったり、始めたは良いものの現実は厳しく躓いてし...

PHPポケモン(α)第1回目の大型アプデ
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン(α)第1回目の大型アプデ

第1回目 大型アップデートについて 本日、PHPポケモンの大型アップデートをしました。 今回のアップデートには全体的なデザインチェンジが含まれているため、今まで遊んでくれていた人も、新鮮な気持ちで初められることができるはずです。   デザインについては、PHPを使った開発をしている人からすれば馴...

戦闘不能による交代編 PHPポケモン84
プログラミング
PHP,PHPポケモン,ポケモン
戦闘不能による交代編 PHPポケモン84

戦闘不能による交代 ポケモンが戦闘不能になった際、もし手持ちに戦える状態のポケモンが残っていれば「交代」か「逃げる」の2択になります。今までは手持ちポケモンが1匹のみで判定を行っていたので、今回は交代の選択肢も含めて勝負の判定の見直しをしていきます。   パーティーを含めた勝負判定 味方または...

放物線アニメーション編 PHPポケモン 81
プログラミング
PHP,PHPポケモン,ポケモン
放物線アニメーション編 PHPポケモン 81

ボールアニメーション 前回までに作成した捕獲判定処理を使って、ボールのアニメーションを作成します。 捕獲演出は以下の通りです。  味方側から相手に向かってボールを投げる 相手ポケモンの前でボールを開く 捕獲判定で算出した揺れ回数分ボールを揺らす   捕まえた際は、ボールの揺れをストップ...

千利休から学ぶビジネスモデルの作り方3ステップ!守破離とは
ビジネスモデル
千利休から学ぶビジネスモデルの作り方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 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 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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 認証 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力