質問: ### 前提・実現したいこと RPGをつくっています。装備品によってプレーヤーをパワーアップさせようかなと考えています。具体的には攻撃力や防御力などが該当します。 その実装方法について友達と相談して、意見が分かれたので意見をください。1が友人、2が私です。また、2つの意見のいいとこ取りをするいい意見がある場合はそれがベストです。 以上、よろしくお願いいたします。 1. プレイヤー側に`powerup(アイテム)`関数を作り、その中でアイテムの種類によってパワーアップする値を変える方法 2. アイテム側に`powerup(プレイヤー)`関数を作り、プレイヤーのメソッド(`powerupAtack()`,`powerupDefense()`)を実行する方法 ### メリット 1. 攻撃力や防御力といった変数が外部から隠ぺいされる 2. アイテム側に実装(どんな効果か)を隠ぺいできる。つまり、プレイヤー側はアイテムの存在を意識しなくてよい。 ### デメリット 1. アイテムが増えたとき、プレイヤー側の`powerup(アイテム)`関数に処理を追加しなてはならない。アイテムの数が200,300に増えたときに、その関数もデカくなる 2. 外から値をいじり放題
回答: 追記:ここで前提にしているアイテムは、装備品だけに限定した話で、消耗品は含んでいません。 いろいろな考え方があり、正解はないのですが、ゲームの仕様に合わせて都合よく作るのが良いと思います。 自分が前に作ったゲームでは、ステータスにはデフォルト値と現在の値の2つを用意し、 アイテムには、全ステータスの増加分(パーセント)を返すメソッドを用意しました。 ``` // 攻撃力が10%アップするアイテムの例 // 全ステータス分のメソッドを用意し、効果がないステータスは0を返す // マイナス効果があるなら、単に-5などとすれば良い。 item.getAttack(); // 10 item.getDefense(); // 0 item.getCritical(); // 0 ``` ステージの効果とか、敵の魔法などにより、プレイヤーのステータスへマイナス効果を与えるような仕様もあるため、いったんパーセントに直して最終的なステータス値を決める必要がありました。 デフォルト値は、アイテム効果を除いた素の値を返します。 レベルアップによって変化するのであれば、メンバ変数をreturnする事になります。 これはあくまでも例で、だいたいこんな事をやっていたという事を思い出しながら書いています。 アイテム効果の増加分については、固定となるためバトル前に計算してメンバ変数に持っておいても良いと思います。 ただ、戦闘中にアイテムが壊れるとか、敵から受ける状態異常などの都合もあり、必ず毎回計算する部分は出てきます。 ``` // 防御力(デフォルト値) int Player::getDefaultDefense() const { return mDefaultDefense; } // 防御力(アイテム効果を含めた現在の値) // バトルではこの値を使用 int Player::getDefense() { int base = getDefaultDefense(); // 現在装備しているアイテム std::vector items = getItems(); // アイテム効果(増加分のパーセント)を計算 int addPercent = 0; for(auto item: items) { // 防御力を返すメソッドなので、アイテムの防御力のところだけ考えればいい addPercent += item->getDefense(); } // バトル中の敵の魔法などにより防御力が下がるような仕様があるなら // ここで、その分だけaddPercentから引いておく // 最終的な割合を計算 // 80, 90, 100, 105などの値になる float percent = 100 + addPercent; // 割合が0以下となったら、計算するまでもないので0を返す if(percent <= 0.0f) { return 0; } // デフォルト値を元に最終的な値を計算 float value = (float)base * (percent / 100.0f); // ここでは整数にしたいので、四捨五入して値を決定 return (int)(value + 0.5f); } ```