プログラミング

ポケモン預かりシステム編 ボックスの作成 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回 ド素人のためのネットワーク講座】
ネットワーク
Wi-Fi,インターネット
ネットワークとは【 第1回 ド素人のためのネットワーク講座】

  身近なもの、普段から触れているものであっても、詳しく知らないものや、正しい理解が出来ていないものは多いですね。 その中の一つに「ネットワーク」というものがあります。   この講座は、一般的に言われる「コンピューター・ネットワーク」についてを説明していきます。 これからシステム関係の...

HPバー色変更編(アニメーション) PHPポケモン53
プログラミング
PHP,PHPポケモン,ポケモン
HPバー色変更編(アニメーション) PHPポケモン53

HPバーの色変更 残りHPの割合に合わせて色クラスをセットしていましたが、ダメージを受けた際の判定処理(動的は変更)が未実装でしたので、今回はコチラを対応します。   残数(割合)の判定 HPの色判定は、HTMLの描画時とJSによるHP変動時に行います。animateメソッド前や後に行うと変更のズレが生じるため、a...

目先の利益に気をつけろ!貧乏ビジネスという落とし穴
フリーランス
目先の利益に気をつけろ!貧乏ビジネスという落とし穴

  目先の利益を求めてしまい、来たるべきビジネスチャンスに対応できないというケースは貧乏ビジネスに陥る大きな要因になります。また、相手が下す評価に左右されてしまうことも、自らの評価を下げてしまったり、見積もりを作る上でも大きく影響を及ぼしてしまいます。   今回は「目先の利益に気をつけろ!貧...

PHPポケモン「野生ポケモン遭遇編」18
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「野生ポケモン遭遇編」18

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

オブジェクト指向有効活用編 PHPポケモン 93
プログラミング
PHP,PHPポケモン,ポケモン
オブジェクト指向有効活用編 PHPポケモン 93

オブジェクト指向の有効活用 β版に向けたPHPポケモンの構成見直し、今回は「オブジェクト指向」の役割について、より理解を深めつつ、保守性も良くなるように整えていきます。   機能を持たせる 様々なプロパティを定数や静的変数へ以降していますが、今回は「静的メソッド」の活用範囲を増やしていきます。まず...

迷惑メールはなぜ届く?amazonや楽天を騙る悪質メールへの対処法とは
ネットワーク
amazon,スパム,メール,楽天
迷惑メールはなぜ届く?amazonや楽天を騙る悪質メールへの対処法とは

「いきなり迷惑メールが届くようになった」 「Amazonや楽天を装ったメールはどうやって見分ければいいの?」   知らない人からいきなり連絡が届いたり、登録もしていないようなサービスからメールが届けば、それは詐欺メールかも知れません。 スマホやパソコンが一般的に普及して、ネットでの買い物やサービスを利用...

PHPポケモン「引数メソッド実行編」デモ有り(御三家の追加)11
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「引数メソッド実行編」デモ有り(御三家の追加)11

  前回のPHPポケモンではメソッドを外部から実行できるようにコントローラー(インターフェース)を作成しました。なので、今回は引数が必要となるメソッドの実装に挑戦してみましょう。 最後にはデモページを準備しているので、気になった人はぜひ遊んでみてください。   第1回はコチラ     ...

英語できたらブログで稼げる 【ネオコピペ】
ライティング
ブログ,翻訳,英語
英語できたらブログで稼げる 【ネオコピペ】

  2010年に楽天が社内公用語の英語化を宣言したのは、多くの人が耳にしたことがあるでしょう。 私からすると、「英語ができることは強み」だという考えから、「これからは英語ができないと行きていけないのでは?」と考えを変えさせられるような、そんな出来事でした。   多言語できるデメリットを見つけるのは難...

カテゴリ

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