プログラミング

ポケモン預かりシステム編 ボックスの作成 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ポケモンでは、ポケモン預かりシステムにおけるボックスの作成方法についてご紹介しました。

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

 

注目の記事

【完全未経験OK】プログラミングの始め方 〜学習方法を解説します!〜
プログラミング
CSS,HTML,JavaScript,MAMP,PHP,XAMPP,フリーランス,プログラミング,独立,起業
【完全未経験OK】プログラミングの始め方 〜学習方法を解説します!〜

  プログラミングって難しい   そういう人は多いですね。しかしそんなことは有りません。 言語という点で比較すれば、英語やフランス語など第二言語を学ぶ方が難しいと言えます。   プログラミングの需要は年々高まり、今や最高潮とも言える域まで来ています。 なぜそこまで需要が高いのか?   ...

成功に近い3つの思考「楽して稼ぐ」「知識オタク」「資産形成は無駄」
雑記
成功に近い3つの思考「楽して稼ぐ」「知識オタク」「資産形成は無駄」

  「楽して稼ぎたい」   人間誰しも、そう考えているはずです。これは正しく、成功するためには必要な思考です。 それを「楽に稼ぐ方法なんてない」と無理やり押さえつけてしまう人は、完全に本質が見えておらず、その大半に「楽して稼げない自分を認められてない」というマイナス因子が含まれてい...

PHPポケモン「わざ編〜チャージ技の実装〜」34
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「わざ編〜チャージ技の実装〜」34

チャージ技とは ポケモンの技は数多く存在していて、その中でも特別な処理が必要なものがいくつかあります。その1つが「チャージ技」です。 ※チャージ技とはポケモン上で用いられている用語ではありません   現在実装している初代御三家+ピカチュウの初代レベルアップ技の中では以下の2つがあります。 ロ...

レベルアップ時のステータス表示編 PHPポケモン 48
プログラミング
PHP,PHPポケモン,ポケモン
レベルアップ時のステータス表示編 PHPポケモン 48

ステータスの表示 前回経験値バーのアニメーションとレベルアップ時の動的な変更を実装しましたが、レベルアップ時に表示されるステータスの実装は先送りにしていました。なので今回はそのステータス表示を作成しましょう。   ステータスはメッセージとして返却せずに、小モーダルを起動させるという方法で対応しま...

状態異常演出編 PHPポケモン 62
プログラミング
PHP,PHPポケモン,ポケモン
状態異常演出編 PHPポケモン 62

状態異常の演出 今回は「状態異常」にかかった際の動的な変更、演出を実装していきます。 どく状態になれば、メッセージに合わせて「どく」を表記、まひ状態になれば、メッセージに合わせて「まひ」をセットするという単純なものです。   返り値の変更 それではまず、状態異常をセットしてメッセージを生成して...

PHPポケモン「バトルシステム実装編〜タイプ相性の判定〜」デモ&配布有り 19
プログラミング
jQuery,PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム実装編〜タイプ相性の判定〜」デモ&配布有り 19

  システムを組むなら、仕様書や設計書はしっかり作りましょう。   ということで、またまたフォルダ移動やページ分けなどを見えないところでやりました。正直説明すると全く進まなくなりそうなので、改修部分は必要最低限にします。 結論、説明しません。(コード配布するので許してください)   そして今...

ピカチュウから学ぶオブジェクト指向 〜クラス継承編〜 2
プログラミング
PHP,PHPポケモン,オブジェクト指向,ポケモン
ピカチュウから学ぶオブジェクト指向 〜クラス継承編〜 2

  ピカチュウから学ぶオブジェクト指向の第2弾はオブジェクトの継承についてです。 前回作成したピカチュウクラスを使用するので、もし基礎的な内容を学習したい人は、以下の記事を参考にしてください。   オブジェクトの継承が理解できれば、複雑で規模の大きなシステムを構築することができるようになり...

なぜ(・・? あなたはMacを使うのか?
雑記
AWS,Linux,MacBook,OS,Windows
なぜ(・・? あなたはMacを使うのか?

  あなたが使っているPCはなんですか?   たまに聞かれることがあります。 そこで「Macを使っています」と答えると「何故?」という次の問いが返ってくることがあります。   あなたがもしMacを使っているのであれば、このときになんと答えますか?   今回のテーマは、「何故Macを使っているの?」と...

カテゴリ

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