プログラミング

ポケモン預かりシステム編 ボックスの作成 PHPポケモン 86

PHP PHPポケモン ポケモン
ポケモン預かりシステム編 ボックスの作成 PHPポケモン 86

ポケモン預かりシステムの実装

今回は、前回ざっくりと仕様決めをした「ポケモン預かりシステム」を実装していきます。ボックス内では操作する項目が多いため、ボックス自体に1つの画面を用意して、できる限りPHPによる制御だけで完結できるように作成していきます。

 

ボックスクラスの作成

それではまず、今回の主軸となるボックスクラスを作成しましょう。以下、文中でのポケモン預かりシステムについては「ポケボックス」と表記していきます。

 

ポケモン預かりシステム(/Classes/Pokebox.php
<?php
// ポケモンボックス
class Pokebox
{
    /**
    * ポケモンの格納ボックス
    * @var array
    */
    protected $pokebox = [];
 
    /**
    * 選択中のボックス番号
    * @var integer|null
    */
    protected $selected = null;
 
    /**
    * @return void
    */
    public function __construct()
    {
        //
    }
 
    /**
    * 全ボックスの取得(暗号化状態で返却)
    * @return array
    */
    public function getPokebox(): array
    {
        return $this->pokebox;
    }
 
    /**
    * ボックスが選択状態になっているかの確認
    * @return boolean
    */
    public function isSelected(): bool
    {
        if(is_null($this->selected)){
            return false;
        }else{
            return true;
        }
    }
 
}

 

プロパティとして用意したのは、ボックスを管理するためのpokeboxと、現在選択中のボックスを判定するためのselectedの2つです。

メソッドには、ボックス内の情報をそのまま返却するgetPokeboxと、現在ボックスが選択された状態になっているかを確認するためのisSelectedの2つです。

 

起動

ポケボックスのクラスの役割についてですが、パソコンをイメージしてみるとわかりやすいでしょう。通常時は余計な処理を省くためにも停止状態としておき、必要な際に起動します

起動処理についてですが、ボックスを選択する(selectedプロパティへ値をセット)することが、起動状態かどうかの判定となります。なので、こちらをセットするためのメソッドをトレイトを作成して追加しましょう。

 

ポケボックスのボックス操作トレイト(/App/Traits/Class/Pokebox/ClassPokeboxTrait.php
<?php
trait ClassPokeBoxBoxTrait
{
 
    /**
    * ボックスを選択状態にする(起動)
    * @param box_number:integer
    * @return boolean
    */
    public function selectBox(int $box_number): bool
    {
        if(isset($this->pokebox[$box_number])){
            $this->selected = $box_number;
            return true;
        }else{
            return false;
        }
    }

 

ボックス自体は配列による添字管理のため、引数ではボックス番号を受け取ります。もしそそのボックスが存在していれば、selectedプロパティに値をセットしてtrueを返却、見つからなければfalseを返却します。

単純ですが、これが擬似的な起動処理となります。

 

終了

次にボックスの終了処理についてです。ボックス操作が終われば、原則としてボックスの選択状態は解除します。あくまで「起動」→「操作」→「終了」という一連の流れをルール付しておくことが目的の1つです。ボックス操作では、ポケモンオブジェクトの移動が伴うため、些細なエラーでもデータの消失に繋がります。それを回避するためにも、手順はある程度ルール化しています。

/**
* ボックスの選択を解除する
* @return void
*/
public function shutdown(): void
{
    $this->selected = null;
}

 

終了用のメソッド自体は単純で、selectedのプロパティに対してnullをセットするだけです。これで、起動・終了の基本的な処理が準備できました。

 

ボックスへのアクセス

次に、ボックスへのアクセス方法について見ていきましょう。まずはボックスを追加するためのメソッドです。

/**
* ボックスの追加
* @return integer
*/
protected function addBox(): int
{
    $this->pokebox[] = [];
    // 追加したボックス番号を返却
    return array_key_last($this->pokebox);
}

 

pokeboxのプロパティの最後に、新しい空の配列を追加しています。このとき、追加したボックスの番号をそのまま使用する可能性があるので、返り値ではpokeboxの最終キーを返却しています。

 

ボックスへのアクセスで最初に行われる処理は「ポケモンを預ける」です。なので、まずはボックスにポケモンを格納するためのメソッドを作成しましょう。

 

ポケボックスのポケモン管理用トレイト(/App/Traits/Class/Pokebox/ClassPokeboxPokemonTrait.php
<?php
trait ClassPokeboxPokemonTrait
{
    /**
    * ポケモンの追加
    * @param pokemon:object::Pokemon
    * @return boolean
    */
    public function addPokemon(object $pokemon): bool
    {
        // 引数の値を確認(ポケモンクラス、立場の確認)
        if(
            !is_a($pokemon, 'Pokemon') ||
            $pokemon->getPosition() !== 'friend'
        ){
            return false;
        }
        // ボックス番号の取得
        if(is_null($this->selected)){
            // 空きボックスの取得
            $free_box = array_fileter($this->pokebox, function($box){
                return count($box) < config('pokebox.max');
            });
            if(empty($free_box)){
                // ボックスに空きが無ければ新しくボックスを追加
                $box_number = $this->addBox();
            }else{
                // 空きボックスの先頭を取得
                $box_number = array_key_first($free_box);
            }
        }else{
            // 選択中のボックスに空きがあるかの確認
            if($this->pokebox[$this->selected] >= config('pokebox.max')){
                return false;
            }
            $box_number = $this->selected;
        }
        // 格納前に全回復させる
        $pokemon->recovery();
        // シリアライズして配列で格納(負荷軽減)
        $this->pokebox[$box_number][] = [
            'class' => get_class($pokemon),
            'name' => $pokemon->getNickname(),
            'level' => $pokemon->getLevel(),
            'object' => serializeObject($pokemon),
        ];
        // 格納完了
        return true;
    }
 
}

 

ポケモンを預ける際には比較的厳重なチェックを入れました。まずポケモンクラスであるかどうかの確認、ポケモンの立場の確認を行い、格納する値自体が正常なものかどうかを判断しています。

次に、ボックスの起動状態を確認して、起動状態であればその対象ボックスへの格納、そうでなければ最初の空きボックスを判定して格納します。

ボックスが起動状態でない場合の預け入れは、基本的に野生のポケモンを捕まえてパーティーへ追加できなかった際の処理です。ポケボックスへアクセスして預ける際には、現ソックとしてボックスを選択してからの預け入れとなります。

 

上記の条件がクリアできれば、ポケモンの体力を全回復させて、オブジェクトをシリアライズしてから配列として格納しました。アンシリアライズしなくても、一覧で最低情報が確認できるように、ポケモンクラス名、名前、レベルにはそれぞれキーを割り振って格納しています。

 

格納する形式が固まったので、次は預けたポケモンへアクセスするためのメソッドを用意しましょう。

/**
* 選択中のボックスへアクセス(復号化して返却)
* @return array
*/
public function accessBox(): array
{
    return array_map(function($pokemon){
        // オブジェクトを復号化して返却
        return unserializeObject($pokemon['object']);
    }, $this->pokebox[$this->selected] ?? []);
}

 

ポケモンの格納とは逆に、array_mapを使ってアンシリアライズ化して配列で返却しています。ボックスへのアクセスは、外部からの侵入を制限するためにもselectedプロパティのボックスに対してarray_mapをかけるようにしています。

 

以上で、ボックス操作に必要な基本的なメソッドが揃いました。

 

グローバルによる管理

ボックス自体、毎画面移管でアンシリアライズする必要がありません。ボックスクラスが必要なタイミングは、ボックス操作中またはポケモンを捕まえて手持ちがいっぱいの状態のみです。

なので、ボックスクラス自体のシリアライズ化はグローバル関数により必要な画面でのみ呼び出すようにしておきましょう。

<?php
$global_pokebox = $_SESSION['__pokebox'] ?? null;
// クラス読み込み
require_once($root_path.'/Classes/Pokebox.php');
 
/**
* ボックスの取得
* @return object::Pokebox
*/
function pokebox()
{
    global $global_pokebox;
    return $global_pokebox;
}
 
/**
* ボックスの初期化
* @return void
*/
function initPokebox()
{
    global $global_pokebox;
    $_SESSION['__pokebox'] = serializeObject(new Pokebox);
    $global_pokebox = $_SESSION['__pokebox'];
}
 
/**
* ボックスの起動
* @return void
*/
function startPokebox()
{
    global $global_pokebox;
    if($global_pokebox){
        // 復号化(オブジェクト状態でなければ)
        if(!is_object($global_pokebox)){
            $global_pokebox = unserializeObject($global_pokebox);
        }
    }else{
        // 初期化されていなければ新規作成
        $global_pokebox = new Pokebox;
    }
}
 
/**
* ボックスの終了
* @return void
*/
function shutdownPokebox()
{
    global $global_pokebox;
    // ボックスをシャットダウン状態にする
    if(is_object($global_pokebox)){
        $global_pokebox->shutdown();
    }else{
        $global_pokebox = unserializeObject($global_pokebox)->shutdown();
    }
    // 暗号化して格納
    $_SESSION['__pokebox'] = serializeObject($global_pokebox);
}
 
/**
* ボックスの保存
* @return void
*/
function savePokebox()
{
    global $global_pokebox;
    // 暗号化して格納
    $_SESSION['__pokebox'] = serializeObject($global_pokebox);
}

 

毎画面で行う処理は、セッション内のポケボックスをグローバル変数へ格納するだけです。ボックス操作が必要になる際はstartPokeboxでクラスそのものをアンシリアライズ、終了時にはクラスの状態をセッションに保存してからポケボックスのクラスをシリアライズします(shutdownPokebox)。

ポケモンの移管などを行えばボックス終了をせずに保存する必要があるので、保存単体の処理用の関数(savePokebox)も用意しています。

 

これで、ポケモン預かりシステムの根幹処理が揃いました。

 

まとめ

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

今回のPHPポケモンでは、ポケモン預かりシステムにおけるボックスの作成方法についてご紹介しました。

ポケモンに興味がある方、プログラミング学習に取り組んでいる方は、ぜひ参考にしてみてくださいね。

 

注目の記事

教師が勝ち組!?出会い&学習の超正統派マッチングサービスとは【ビジネス企画書】
ビジネスモデル
マーケティング
教師が勝ち組!?出会い&学習の超正統派マッチングサービスとは【ビジネス企画書】

  「出会いがない」   社会人になると多くの人が抱く悩みの1つです。職場の男女比率や年齢層が理由の人もいれば、同じ職場での出会いは求めていない人もいるでしょう。 今回はそんな「出会い」を解決するための企画「出会い&学習の超正統派マッチングサービス」について、企画案と考察をまとめました。   ...

オウムがえし編 PHPポケモン 68
プログラミング
PHP,PHPポケモン,ポケモン
オウムがえし編 PHPポケモン 68

オウムがえしとは 今回は久々に新しい技を実装します。それが「オウムがえし」です。 オウムがえし(ポケモンwiki) https://wiki.ポケモン.com/wiki/オウムがえし   初代で登場した技であり、序盤に登場するポッポやオニスズメがレベルアップで覚える技の1つです。最新世代ではオウムがえしという技は実...

ピカチュウから学ぶオブジェクト指向 〜レベルシステム導入編〜 3
プログラミング
PHP,PHPポケモン,オブジェクト指向,ポケモン
ピカチュウから学ぶオブジェクト指向 〜レベルシステム導入編〜 3

  大人気?シリーズ「ピカチュウから学ぶオブジェクト指向」、今回はレベルシステムの導入編です。   第1回(基礎編)、第2回(クラス継承編)で作成したPokemonとPikachuのクラスを使用するので、最初から学習したい人はぜひご参考ください。      レベルシステムの導入   ポケモンのゲ...

連続の技習得編 オブジェクトをセッションへ格納 PHPポケモン57
プログラミング
PHP,PHPポケモン,ポケモン
連続の技習得編 オブジェクトをセッションへ格納 PHPポケモン57

セッション経由でのオブジェクト引き継ぎ 技習得の処理が整ってきたので、ここで連続技習得・連続レベルアップ時にも問題なく動作するように作り込んでいきます。ですが、現状のモーダルをレスポンスやメッセージと同様に、そのまま引き継いだとしてもエラーが発生します。 その原因がセッション経由でのオブジェク...

PHPポケモン「バトルシステム編〜状態異常1〜」30
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜状態異常1〜」30

状態異常チェック 今回は少し先延ばししていた状態異常判定を一部作成していきましょう。 状態異常では「行動前」と「行動後」に判定するものに分けることができます。 行動前 まひ、ねむり、こおり  行動後 どく、もうどく、やけど   まずは簡単な行動前から実装していきます。行動前に判...

SNS拡散力アップ!PHPでOG画像付きリッチURLを自作する方法【Curl → Opengraph】
プログラミング
PHP,WordPress
SNS拡散力アップ!PHPでOG画像付きリッチURLを自作する方法【Curl → Opengraph】

  ブログやHPにサイトのURLをただ貼り付けても、どんなページなのか一目でわからないのでなかなか思うようにアクセスに繋がりません。 ですが、毎回のようにURL先の画像を準備したり、説明文を設定するのも大変ですし、ページタイトルや画像が差し替わってしまうことも考えられます。   今回はそういった手間...

PHPポケモン「バトルシステム編〜経験値の獲得〜」29
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜経験値の獲得〜」29

経験値の獲得 今まではポケモンに直接経験値を与えるというチートびっくりの仕様でしたが、バトルシステムも終盤に差し掛かってきたので「倒したポケモンから経験値を取得する」というごく当たりまえの仕様を導入していきます。   基礎経験値の設定 では、経験値の計算式に入る前に、必要なパラメーターを1つ用...

いかり編 PHPポケモン 42
プログラミング
PHP,PHPポケモン,ポケモン
いかり編 PHPポケモン 42

いかり(技)とは 2020年10月段階での最新シリーズである「ソード・シールド」では、今まであった技が使用不可能になっているものが数多くあります。その1つが「いかり」という技です。 いかり(ポケモンwiki) https://wiki.ポケモン.com/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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力