プログラミング

フレンドリィショップ編 開店準備 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ポケモン「オートローダー編」16
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「オートローダー編」16

  今までは技やタイプを一括requireという荒業で対応していましたが、フシギダネ系列の技を実装した際に「こんなん全部読み込んでられるか!」と流石になったので、簡易ながらオートローダーを実装していきます。 そして、実装したらしたで色々と問題も浮かび上がってきたので、このあたりは回を進めて行きなが...

PHPポケモン「レスポンス機能編」メッセージの返却 12
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「レスポンス機能編」メッセージの返却 12

  第12回PHPポケモンは「レスポンス機能編」です。 メッセージやデータのやり取り部分を、よりシステム風に作成していきます。   第1回はコチラ   レスポンス(Response)の実装  今までは結果(メッセージ等)はechoを使って出力していましたが処理が行われたタイミングで出力されてしまうため...

WordPressで作ったサイトで実装するワンランク上のSEO対策
SEO対策
PHP,WordPress,プログラミング
WordPressで作ったサイトで実装するワンランク上のSEO対策

  WordPressでSEOに強いサイトを運営したい   近年、ブログを採用せずともWordPressを使用したサイト作りが増えてきました。 その理由には更新の手軽さはもちろん、優秀なプラグインが揃っていることでSEO対策に強いサイト作りが簡単だということが大きいです。   今回は、WordPressのブログやサイトで役立...

ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41
プログラミング
PHP,PHPポケモン,ポケモン
ダメージ固定技編(ちきゅうなげ・カウンター) PHPポケモン 41

ダメージ固定技とは PHPポケモンでも作成したダメージ計算機能ですが、ポケモンの技の中にはそれを必要としない技がいくつかあります。それが「固定ダメージ技」です。 ポケモンwiki(ダメージ固定技) https://wiki.ポケモン.com/wiki/ダメージ固定技 ステータスに依存せず、わざ自体にダメージ量が決...

手っ取り早く情報強者になる簡単な方法
雑記
アウトプット,インプット,ニュース
手っ取り早く情報強者になる簡単な方法

  ニュースや情報番組、討論番組をみると、出演者の方々の情報量の多さに圧倒されることがあります。 また、ユニークな考え方に共感を得る人も多いでしょう。   どうやって、情報を仕入れているのか? なぜそんなことまで知っているのか?   メディアで取り上げられているような人や、活躍している人の多く...

フリーランスが見積書を作るときに押さえておきたい3つのポイント+α
フリーランス
フリーランス,仕事依頼,独立,見積書
フリーランスが見積書を作るときに押さえておきたい3つのポイント+α

  仕事の依頼がきたけど、どれぐらいの金額を提示すればいいかわからない   駆け出しのフリーランスや、これから独り立ちしようとしている人に多い悩みです。 今回はそういった方のために「フリーランスが見積書を作るときに押さえておきたい3つのポイント+α」についてご紹介します。     時給...

【無料】早起きをして神戸へ行こう!「為になる雑談朝活」
イベント
三宮,朝活,神戸
【無料】早起きをして神戸へ行こう!「為になる雑談朝活」

  朝活を実施することになりましたので、その目的な概要をまとめました。 神戸三宮での開催を予定しておりますので、もしお近くにお住まいの方で日時が会いましたらご参加ください。 土日祝辺りで週1日程度の不定期開催を予定しています。学びにつながる、けど参加しやすい雑談形式ということを主としています...

Zoomも飲み屋もなくならない 〜コロナ収束後の本当の世界〜
雑記
YouTube,Zoom,コロナ,テレワーク,リモートワーク
Zoomも飲み屋もなくならない 〜コロナ収束後の本当の世界〜

  新型コロナウイルスのニュースが絶えない毎日を過ごす中、コロナの内容に一度も触れていませんでしたがそろそろ触れておこうと思います。   マイナスな内容は不安を煽るような推測はSNSやニュースでイヤというほど目にしているので、可能性を感じられる内容と現実をお届けします。   コロナが収束した時、この...

カテゴリ

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