プログラミング

経験値分配編 PHPポケモン 89

PHP PHPポケモン ポケモン
経験値分配編 PHPポケモン 89

経験値の分配とは

大型アップデート後、最初の追加機能は「経験値の分配」についてです。

ポケモンの入れ替えができるようになりましたが、経験値をもらえるのは現在フィニッシャーのみとなっており、レベルの低いポケモンを育てるのが困難な状態です。なので、ゲームバランスを整えるためにも、まず経験値周りの処理から見直しをしていきましょう。

 

 経験値の計算式

分配の計算式についてですが、世代によって微妙に異なっています。最新の第8世代ではポケモン全てに経験値が割り振られたり、世代によっては選出されたポケモンそれぞれに計算式が適用される場合もあります。

ですが、この点においては旧世代を参考にしながらオリジナルの計算式として、基本となる経験値量を選出されたポケモン数に分配、その後レベル補正をかけるという仕組みで実装していきます。

 

まずはPHPポケモンで現在使用している経験値の算出式を見てみましょう。

 

経験値の計算式(旧)

EXP × LM^2.5 + 1

  • EXP 倒されたポケモンのレベル × 倒されたポケモンの基礎経験値 ÷ 5
  • LM レベル補正 (2L + 10) / (L + Lp + 10)
  • L 倒されたポケモンのレベル
  • Lp 倒したポケモンのレベル

 

レベル補正が掛かる前のEXPが分配される基本の経験値となります。これを選出されたポケモン数で割るため、分配式は以下の通りです。

 

経験値の計算式(新)

EXP / count × LM^2.5 + 1

  • count 戦闘に参加したポケモンの数

 

これで、均等に経験値を分け合い且つ、レベル補正はそれぞれに依存させることができます。

 

選出ポケモン情報の保管

選出されたポケモンの記録は、バトル状態クラス(battle_state)を使って管理します。保管用のプロパティとしてfought_ordersを初期値配列で作成、ここに選出されたポケモン番号を格納していきます。

 

バトル状態ポケモン関係トレイト(/App/Traits/Class/BattleState/ClassBattleStatePokemonTrait.php
/**
* 戦闘に参加しているポケモン番号の格納(private)
* @param order:integer
* @return void
*/
private function setOrder(int $order): void
{
    // 番号をプロパティへ格納
    $this->order = $order;
    // 戦闘に参加したポケモンリストに格納
    if(!in_array($order, $this->fought_orders, true)){
        $this->fought_orders[] = $order;
    }
}

 

選出されたポケモンが増えるタイミングは、オーダーセット時です。なので、オーダーをセットする処理をメソッド管理にして、このタイミングに選出リストへ加えていきます。

同じポケモンが再度選出される可能性も考慮して、in_arrayで重複回避をしています

 

選出されたとしても、そのポケモンが戦闘不能になっていれば経験値は貰えません。ですが、アイテムなどを使ってひんし状態が解除されれば経験値をもらうことができます。

なので、瀕死状態の確認はポケモン番号を取得する際にフィルターがけすることで判定します。

/**
* 経験値を貰える権利があるポケモン番号の取得
* @return array
*/
public function getEntitledExpOrders(): array
{
    /**
    * 現在戦闘中のポケモンを先頭にする
    */
    // 現在戦闘中のポケモン番号を削除(次のarray_unshiftが破壊的な関数のため変数へ格納)
    $fought_orders = array_diff($this->fought_orders, [$this->order]);
    // 先頭に現在のポケモン番号を追加
    array_unshift($fought_orders,  $this->order);
    // 戦闘可能状態でフィルターにかけて返却
    return array_filter(
        $fought_orders,
        function($order){
            return player()->getPartner($order)->isFight();
        }
    );
}

 

経験値取得の順番ですが、フィニッシャーが最初に来るように、一度array_diffを使って現在のポケモン番号を削除、array_unshiftで再度先頭へ追加しています。

 

※フィニッシャーが最後にならなくても不具合自体は発生しませんが、本作同様の手順で処理が行われるようにしています。

また、経験値バーの描画処理などは、現在のポケモン番号とフィニッシャーが一致していたときのみ生成されるように分岐させました。

 

それでは、実際の動きを進化処理まで含めて見てみましょう。

 

進化処理の作成段階では複数を想定して組んでいたため、問題なく処理されることが確認できました。

以上で経験値の分配機能は完成です。

 

技習得ポケモン複数発生時の対策

今まではポケモンが1匹のみを想定していたため、同時に技習得が発生した際に「バトル中のポケモン」を対象に処理を行なっていました。ですが、経験値の分配により同時に技習得が発生する可能性が出てきたため、どのポケモンの技を書き換えるかを判定する必要が出てきました。

 

例(現段階の処理)

ピカチュウ(フィニッシャー)

フシギダネ(選出:つるのムチを覚えたい)

ピカチュウが「つるのムチ」を覚えてしまう

 

これを回避するためにも、技習得のレスポンスに対してポケモンのIDを持たせ、習得時のポケモン選出をこのIDを使って検索したポケモンのオブジェクトに対して行います。

 

ポケモンクラスチェック用トレイト(/App/Traits/Class/Pokemon/ClassPokemonCheckTrait.php
// checkLevelMoveメソッド内
/**
* 技選択用モーダルの返却
*/
// メッセージIDを生成
$msg_id = response()->issueMsgId();
// レベルアップメッセージ
response()->setMessage($this->getNickName().'は'.$move->getName().'を覚えたい');
response()->setMessage('しかし技を4つ覚えるので精一杯だ');
response()->setMessage($move->getName().'の代わりに他の技を忘れさせますか?', $msg_id);
// レスポンスデータをセット
response()->setResponse([
    'toggle' => 'modal',
    'target' => '#'.$msg_id.'-modal',
    'move' => $move_class,
    'pokemon_id' => $this->id  #追加したポケモン判別用ID
], $msg_id);
// モーダル用のレスポンスをセット
response()->setModal([
    'id' => $msg_id,
    'modal' => 'acquire-move',
    'new_move' => $move,
    'pokemon_id' => $this->id
]);
// 諦めメッセージを事前に用意しておく
response()->setMessage($this->getNickName().'は'.$move->getName().'を覚えるのを諦めた');

 

技習得サービス(/App/Services/Battle/LearnMoveService.php
/**
* 技の置き換え
* @return void
*/
private function replaceMove()
{
    // 技を習得する対象のポケモンのIDを旧レスポンスから取得(交代したポケモンを想定)
    $pokemon = player()->getPartner(
        $this->before_responses[request('param.id')]['pokemon_id'], 'id'
    );
    // 忘れる技を取得
    $forget_move = $pokemon
    ->getMove(request('param.forget'));
    // 覚えさせる技を旧レスポンスから取得
    $new_move = new $this->before_responses[request('param.id')]['move'];
    // 技を覚えさせる
    $pokemon
    ->setMove($new_move, request('param.forget'));
    // メッセージの返却
    response()->setMessage('1 2の ……ポカン!');
    response()->setMessage($pokemon->getNickname().'は、'.$forget_move->getName().'の使い方をキレイに忘れた!そして......');
    response()->setMessage($pokemon->getNickname().'は新しく、'.$new_move->getName().'を覚えた!');
}

 

ユーザー入力によるバグ回避

ブラウザを使ったゲームにおいて気をつけて置かなければならないのが「ユーザー入力」による値の想定です。例えば、デベロッパーツールから値を直接変更すれば、インターフェースで制限を設けていたとしても「予期せぬ値」がPOSTされてきます

もちろん、無理な操作でデータが消失することに関してはプレイヤー側の責任として問題ありませんが、正常に処理が通ってしまうことが一番の問題となります。

 

例えば、今回のポケモンを判別するための値をinput hiddenで用意したとしましょう。これをノードの直接変更で別のポケモンが指定されてしまえば、本来覚えるはずのない技を覚えさせることが出来てしまいます。こういったバグを回避するためにも、できるだけPOSTする値にはクラス名や対象を特定するようなものは避けています。

オーダーを使った処理をしていれば、配列自体が変更されることがないため、最低でも選択肢が増えるということはありませんね。

 

様々なケースを想定していますが、場合によっては回避する手段があるかも知れません。此の辺りは見つけ次第対応予定ですので、ぜひ気づいた方はお問い合わせよりご連絡ください。

 

まとめ

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

今回のPHPポケモンでは「経験値の分配」についてご紹介しました。

WEBアプリケーション開発に興味がある方や、現在プログラミング学習に取り組んでいる方は、ぜひ参考にしてみてくださいね。

 

注目の記事

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

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

「数字を上げる」必勝マニュアル 〜再生回数・フォロワー・PV数〜
マーケティング
YouTuber,ブロガー,必勝マニュアル,自己啓発
「数字を上げる」必勝マニュアル 〜再生回数・フォロワー・PV数〜

  「継続は力なり」   色んな場面で言われます。何事も地道な努力が大事です。 しかし、地道な努力というのは成果が見えづらく、反応が得にくいことも確かです。   運良く勢いに乗れて、常に努力のし易い環境にいることで伸びていく人の確かにいます。 しかし、ほとんどの人がそうはいきません。...

プレイヤー情報作成編 PHPポケモン72
プログラミング
PHP,PHPポケモン,ポケモン
プレイヤー情報作成編 PHPポケモン72

プレイヤー情報の作成 少し前よりプレイヤーをホーム画面に表示させるようにしましたが、ただイメージとして配置しただけでプレイヤー情報自体は設定していませんでした。なので、今回はプレイヤーとして持たせる必要のある情報を作成していきましょう。   クラスの作成 初代ポケモンではプレイヤー情報として閲...

レベニューシェアとは?利益報酬・共同事業に潜む罠
フリーランス
レベニューシェアとは?利益報酬・共同事業に潜む罠

  レベニューシェアという言葉を聞いたことがありますか?   ビジネスの世界にいる人なら、意味は知らなくてもやったことがある方が意外と多いはずです。特にフリーランスの人や、プログラミングやデザインといったスキルを持っている人はレベニューシェアでは重宝されるため多い傾向があります。ここ最近...

【Laravel】1対1リレーションをわかりやすく解説(hasOne)
プログラミング
Laravel,PHP
【Laravel】1対1リレーションをわかりやすく解説(hasOne)

  Laravelの1対1リレーションのhasOneについて、公式マニュアルでは専用単語ばかりでどうしてもわかりにくいと感じてしまっている方へ向けて、わかりやすく解説しました。 ※例で紹介しているコードについては、一部英語を日本語表記で使用している部分もありますので、コピペで使用する方は必要に応じて置...

ブログ運営者のための「よくわかるSEO対策」フィード編
SEO対策
atom,feedly,rss,WebSub,WordPress,xml,フィード
ブログ運営者のための「よくわかるSEO対策」フィード編

  アメブロやFC2など優れたブログサービスが存在している中、好きなデザイン、こだわった機能を求めてWordPressを選択される方も多いですね。 また、コーポレートサイトにWordPressを用いる方もいるでしょう。ただしSEO対策がしっかりとされていなければ、提供されているサービスに太刀打ちできません。  もちろん...

【脱初心者向けプログラミング学習】処理を追え!「今、変数には何が入ってる?」
プログラミング
HTML,PHP,プログラミング学習
【脱初心者向けプログラミング学習】処理を追え!「今、変数には何が入ってる?」

  初心者から中々抜け出せない 1から処理をかけない   そんな悩みを抱えたプログラミング学習者に向けて、「脱初心者のためのプログラミング学習」についてPHPを例にまとめました。 やり方自体は同じですので、他の言語をメインとしている人は自分の環境に置き換えながら学習して、初心者から抜け出しましょ...

ポケモン図鑑編 PHPポケモン 88
プログラミング
PHP,PHPポケモン,ポケモン
ポケモン図鑑編 PHPポケモン 88

ポケモン図鑑とは ポケモンに出会ったり、仲間にしたりすると、ポケモン図鑑のデータがどんどんと埋まっていきます。PHPポケモンでもこの仕組みを実現させるために、ポケモン図鑑を作成していきましょう。   クラスによる管理 ポケモン図鑑はクラス管理をしていきます。プレイヤー1人に対して1つのポケモン図...

カテゴリ

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