ひとの ものを とったら どろぼう!
ポケモンの中でも有名なセリフの1つです。モンスターボールを投げることでポケモンを捕まえることができますが、既に別トレーナーが所有しているポケモンを捕まえることはできません。
初代から、トレーナー戦でモンスターボールを投げると「ひとの ものを とったら どろぼう!」というセリフが表示されるので、PHPポケモンでも同じように処理していきましょう。
捕獲処理への制御
そもそも、トレーナー戦自体でモンスターボールを使えなくしてしまうという方法もありますが、それではノードを直接変更してしまうことで処理が動いてしまい、トレーナーが繰り出してきたポケモンを捕まえることが出来てしまいます。なので、サービスそのものに判定を追加し、トレーナー戦であれば捕獲処理をスキップさせるように制御していきましょう。
アイテム使用サービス(/App/Services/Battle/ItemService.php)
/**
* どうぐの使用
*/
class ItemService extends Service
{
--省略
/**
* どろぼうフラグ
* @var boolean
*/
protected $thief_flg = false;
/**
* @return void
*/
public function execute()
{
// アイテムの確認
if(!$this->validation()){
response()->setMessage('指定されたアイテムは使用できません');
return;
}
// アイテムの使用
$this->use();
if($this->capture_flg){
// 捕獲成功
// バトル終了判定用メッセージの格納
response()->setEmptyMessage('battle-end');
}else{
// 捕獲失敗・通常アイテムの使用
if($this->thief_flg){
// トレーナー戦でのボールの使用
response()->setMessage('人のものを取ったら、どろぼう!');
}else{
//相手のターン処理
$this->enemyTurn();
}
}
}
新たにthief_flgを追加し、サービス内で判定ができるようにしました。こちらを、ボール判定用のトレイトに入った際にチェック、フラグを有効化させます。
ボール使用時のトレイト(/Traits/Service/Item/ServiceItemCaptureTrait.php)
// ボール使用時のトレイト
trait ServiceItemCaptureTrait
{
--省略
/**
* 捕獲判定
* @param ball:string
* @return boolean
*/
protected function useItemCapture(string $ball): bool
{
// トレーナー戦の分岐
if(battle_state()->isMode('trainer')){
$this->thief_flg = true;
return false;
}
サービス内で全て処理してしまっても良かったのですが、別サービスからこのトレイトを使った際に通過してしまうことも懸念して、判定直前で処理を返却する構成にしました。
これで、トレーナー戦でモンスターボールを投げても捕獲処理へ入ることを防ぐことができましたね。
ゲームではボールを投げて弾かれるという演出があるので、ある程度システム部分が整えばこういった細かな部分も再現予定です。
賞金システム
PHPポケモンでは現在お金を稼ぐ手段が「ネコにこばん」しかありません。通常のポケモンでもメインとなる収益源は「トレーナー戦」なので、こちらも実装していきましょう。
賞金をもらった
トレーナー情報で賞金額は設定できるようにしているため、バトルに勝利すれば設定した金額を受け取れるように、勝負判定に処理を追加しましょう。
バトルコントローラー用トレイト(/App/Traits/Controller/BattleControllerTrait.php)
// judgmentWinメソッド内
// 勝利演出
response()->setMessage(trainer()->getPrefixName().'との勝負に勝った', $msg_id);
response()->setResponse([
'action' => 'show-trainer',
'target' => 'enemy',
], $msg_id);
// 勝利メッセージ
response()->setMessage(trainer()->getLine('lose'));
// 賞金
$money = trainer()->getMoney();
response()->setMessage(player()->getName().'は、賞金として'.$money.'円を受け取った!');
player()->addMoney($money);
// 勝利時の最終処理
$this->judgmentWinLast();
勝利メッセージの後に賞金を取得、受け取った金額のメッセージを表示させました。おこづかいを増やすためのメソッドは、プレイヤークラスに作成したaddMoneyを使用しています。
降参
負け判定の際にはお小遣いが半分になります。また、RPGのフィールド進行が無い関係上、戦闘から離脱するための「降参」という機能を実装しておいても不都合がないので、こちらも合わせて実装します。
バトルコントローラー(/App/Controllers/Battle/BattleController.php)
//branchメソッド内
/******************************************
* 降参(トレーナー戦のみ)
*/
case 'surrender':
if(battle_state()->isMode('trainer')){
// 持ち金を半分失う
player()->loseMoney();
// バトル終了
$this->battleEnd();
}
break;
トレーナー戦のみに限定したsurrenderというアクションを用意しました。おこづかいを半額失うという処理を、毎回書くのは面倒なので、プレイヤークラスにloseMoneyというメソッドを作成し、半額処理を行なっています。
プレイヤーおこづかい関係トレイト(/App/Traits/Class/Player/ClassPlayerMoneyTrait.php)
/**
* バトル敗北時のお小遣い消費
* @return void
*/
public function loseMoney(): void
{
// 半額を失う(切り捨て)
$this->money = (int)($this->money / 2);
}
失った金額を表示させたい場合は、返り値として割った金額を返却しておくようにすると便利です。現状は使用予定がないので、返り値無しのメソッドとしました。
最後に、敗北判定時にも同じメソッドを追記しておきましょう。
バトルコントローラー用トレイト(/App/Traits/Controller/BattleControllerTrait.php)
/**
* バトル結果(負け)
* @return void
*/
private function judgmentLose()
{
// トレーナー戦
if(battle_state()->isMode('trainer')){
response()->setMessage(trainer()->getLine('win'));
}
// お小遣いの半額を失う
player()->loseMoney();
// 全滅
response()->setMessage(player()->getName().'は、目の前が真っ暗になった...');
// バトル終了判定用メッセージの格納
response()->setEmptyMessage('battle-end');
}
おこづかいを失うという処理は、野生ポケモンとのバトルでも同じなので、分岐後の共通処理として行なっています。
では、実際にトレーナー戦の動きを見てみましょう。
勝利時には賞金が貰え、敗北時には半額が失われましたね。これでバトルシステムの大枠が完成です。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「トレーナー戦でのモンスターボール使用不可判定」と「賞金システム」の実装方法をご紹介しました。
ゲームづくりに興味がある方、プログラミングに興味がある方は、ぜひ参考にしてみてくださいね。