プログラミング

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

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

 

注目の記事

データ軽量化編 β版へ向けて  PHPポケモン 90
プログラミング
PHP,PHPポケモン,ポケモン
データ軽量化編 β版へ向けて PHPポケモン 90

β版の実装に向けて 大型アップデートにより、ある程度機能改善や実装箇所も増えてきましたが、それと同時に次の段階への移行が本格的に見えてきました。それがβ版です。   PHPポケモンは2020年12月現在α版となっており、完全な試作段階のWEBアプリケーションです。セーブ機能はなく、セッションの有効期...

Toastr(トースト)活用編 PHPポケモン 100
プログラミング
JavaScript,PHP,PHPポケモン,ポケモン
Toastr(トースト)活用編 PHPポケモン 100

記念すべき第100回目です!   色々考えましたが、100回目だからと言って特別な内容ではなく、いつもの流れの延長での開発進行となります。ご了承ください。 今回は、何人かのプレイユーザーの声も参考にしながら、ユーザビリティをあげるための機能追加を進めていきます。   Toastr(トースト)と...

Laravel7系でTraitのmakeコマンドを作成する方法
プログラミング
artisan,Laravel,Linux,PHP,Trait
Laravel7系でTraitのmakeコマンドを作成する方法

Laravel7がリリースされて、さっそくそれを使った開発の機会がやってきましたので、使用頻度の高いものをまとめていきたいと思います。 5系や6系の情報は多く出回っていますが、6系がLTSということもあって7系の情報は少なめですね。   今回は「Laravel7系でTraitのmakeコマンドを作成する方法」をご紹介します...

SEO対策で役立つ!ライティングスキルを向上させる3ステップ
ライティング
SEO,ブログ
SEO対策で役立つ!ライティングスキルを向上させる3ステップ

  ブログやメール、SNSなどライティングスキルが問われる場面が多く、それは質に直結しています。各プラットフォームによって特徴はありますが、基礎的な文章力自体がついていれば多様な場面で役立つことは間違いありません。 文章の質が高くなれば、ブログであればSEOに強い価値のあるサイトになりますし、SNS...

PHPポケモン(α)攻略wiki「最初のポケモン」
雑記
PHPポケモン,wiki,ポケモン
PHPポケモン(α)攻略wiki「最初のポケモン」

リリースから一ヶ月、遂にPHPポケモン(α)の攻略Wiki(仮)が公開です!   というのは大嘘で、内部の大幅変更の関係上、今回はPHPポケモンをプレイするにあたってのオススメなどをまとめて見た次第です。 ちなみに、バトルシステム自体は本家に沿って作成しているので、種族値や技性能に精通している人はブラウザ...

HTMLの基本設計「よくわかるSEO対策」構造化(マークアップ)編
SEO対策
HTML,SEO,マークアップ
HTMLの基本設計「よくわかるSEO対策」構造化(マークアップ)編

  HTML5がリリースされて随分経ちました。 それにより多くのタグが増え、それにより今までデザインを目的と使用されていたものが「構造化」という本来の役割を持たされるようになりました。    構造化は、目に見えにくい部分です   それぞれの役割を理解していなければ、せっかくきれいなサ...

進化の石編(構成) PHPポケモン 102
プログラミング
PHP,PHPポケモン,ポケモン
進化の石編(構成) PHPポケモン 102

進化の石 ピカチュウさんもそろそろ進化したがっているので、β版の公開に向けて進化の石を実装していきます。しかし、イーブイなど特別な進化先や条件を持ったポケモンを考慮すると、少し実装が手間取りそうだったので、今回は構成部分のみのまとめとなっておりますので、ご了承ください。   アイテムクラスの作...

パーティー実装編 戦闘に参加するポケモン PHPポケモン64
プログラミング
PHP,PHPポケモン,ポケモン
パーティー実装編 戦闘に参加するポケモン PHPポケモン64

先頭のポケモンを選出 前回パーティーのプロパティを準備して、複数(6匹)のポケモンを持ち歩けるようにすることを想定しました。 今回は、そこからバトル画面への連動をさせる部分までを作り込んでいきましょう。   複数のポケモンを所有している場合、戦闘が始まって繰り出されるのは「ひんし状態を除く一番上...

カテゴリ

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