プログラミング

経験値分配編 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アプリケーション開発に興味がある方や、現在プログラミング学習に取り組んでいる方は、ぜひ参考にしてみてくださいね。

 

注目の記事

npm run watch-poll中にPCがフリーズした時の解決法
プログラミング
CSS,JavaScript,Laravel,Linux
npm run watch-poll中にPCがフリーズした時の解決法

  Laravelで開発中にPCが頻繁にフリーズするという問題にぶち辺り、原因がnpm run watch-pollだということが解ったので、その解決方法をまとめておきます。 複雑な原因でもなく大きな問題にもならなかったのですが、これが原因でデータ破損となれば困るので、同じような問題に直面した開発者向けです。    ...

PHPポケモン「状態異常+逃走編〜ねむり・こおり・やけど・どく〜」24
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「状態異常+逃走編〜ねむり・こおり・やけど・どく〜」24

状態異常の実装  今回は、前回作成した「まひ」を参考に、「ひんし」を除いた残りの状態異常も実装していきます。    クラスの作成  まずはそれぞれのクラスを作成します。前回解除時のメッセージを設定出来ていなかったので、まひと合わせて実装していきましょう。   状態異常:やけど(...

トークン認証とサニタイズ編 PHPポケモン 38 コード配布あり
プログラミング
PHP,PHPポケモン,ポケモン
トークン認証とサニタイズ編 PHPポケモン 38 コード配布あり

構成の見直し PHPポケモンも38回となり、大分作り込みが出来てきました。ここ最近はコードの説明ばかりでデモページなども準備出来ていませんでしたが、それには內部側の問題点が多かったためです。今回はその辺りをキレイに解決できるよう、本格的な構成の見直しをします。   ちなみにですが、どれぐらいの見直...

フィールド効果技編(しろいきり) PHPポケモン 50
プログラミング
PHP,PHPポケモン,ポケモン
フィールド効果技編(しろいきり) PHPポケモン 50

フィールド効果技とは ポケモンの技の中には、ポケモンに対して状態変化や異常を与えるもの以外に、フィールド自体に効果を持たせるものがいくつかあります。PHPポケモンでは未実装ですが、そういったフィールド効果技はポケモンを交代したとしても場に効果が残り続けます。  場の状態(ポケモンwiki) https:/...

動画編集で知っておくべき基本的な3工程
動画編集
Adobe,AfterEffects,Illustrator,Photoshop,PremierePro
動画編集で知っておくべき基本的な3工程

  YouTubeに動画を投稿したいけど、動画の基本的な作成手順がわからない・・・   動画作成をするためのソフトは色々ありますが、有料なものであればやはりAdobe製品に軍配が上がります。 しかし準備したは良いものの、いろんなソフトが合ってどれを使えばよいか分からないという悩みを抱えている方は非常...

忘れさせる技選択 後編(新しい技を習得) PHPポケモン 56
プログラミング
PHP,PHPポケモン,ポケモン
忘れさせる技選択 後編(新しい技を習得) PHPポケモン 56

新しい技を習得 前編に続き、技習得時の処理分岐を作成していきましょう。今回は「新しい技を習得する」です。 前回は覚えようとしている技を諦めるだけだったので、ポケモンのオブジェクトを書き換える必要がありませんでしたね。ですが、新しく覚えようとしている技を既に覚えている技と置き換える場合は、ポケモ...

ブログで生活するための7つの道のり 〜収益化と拡散の方法教えます〜
ライティング
Facebook,Google AdSense,Twitter,ノマドワーク
ブログで生活するための7つの道のり 〜収益化と拡散の方法教えます〜

  ブログで生活したい   毎日数時間、ブログを書くだけで生きていける、そんな夢のような生活を実現させたいと思い描く人は多いですが、簡単なことでは有りません。 ですが、やらなければいけないことがわかっていれば、収益化するのは簡単です。   今回は「ブログで生活するための7つの道のり」をテ...

【Youも明日からデザイナー】デザインセンスを磨くコツ3つ
デザイン
YouTube,サムネイル,バナー
【Youも明日からデザイナー】デザインセンスを磨くコツ3つ

  デザイナーにセンスは必要か?   この問いに、私は必ず「必要ない」と答えます。確かに、センスを磨くことは大切ですが、それがあたかも才能のように表現するのは間違っていると思っているからです。 デザインは誰にでもできます。そしてオリジナリティは各自が必ず持っています。だからこそ、なりたい...

カテゴリ

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