###前提・実現したいこと
RPGをつくっています。装備品によってプレーヤーをパワーアップさせようかなと考えています。具体的には攻撃力や防御力などが該当します。
その実装方法について友達と相談して、意見が分かれたので意見をください。1が友人、2が私です。また、2つの意見のいいとこ取りをするいい意見がある場合はそれがベストです。
以上、よろしくお願いいたします。
- プレイヤー側に
powerup(アイテム)
関数を作り、その中でアイテムの種類によってパワーアップする値を変える方法 - アイテム側に
powerup(プレイヤー)
関数を作り、プレイヤーのメソッド(powerupAtack()
,powerupDefense()
)を実行する方法
###メリット
- 攻撃力や防御力といった変数が外部から隠ぺいされる
- アイテム側に実装(どんな効果か)を隠ぺいできる。つまり、プレイヤー側はアイテムの存在を意識しなくてよい。
###デメリット
- アイテムが増えたとき、プレイヤー側の
powerup(アイテム)
関数に処理を追加しなてはならない。アイテムの数が200,300に増えたときに、その関数もデカくなる - 外から値をいじり放題
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
追記:ここで前提にしているアイテムは、装備品だけに限定した話で、消耗品は含んでいません。
いろいろな考え方があり、正解はないのですが、ゲームの仕様に合わせて都合よく作るのが良いと思います。
自分が前に作ったゲームでは、ステータスにはデフォルト値と現在の値の2つを用意し、
アイテムには、全ステータスの増加分(パーセント)を返すメソッドを用意しました。
cpp
1// 攻撃力が10%アップするアイテムの例 2// 全ステータス分のメソッドを用意し、効果がないステータスは0を返す 3// マイナス効果があるなら、単に-5などとすれば良い。 4item.getAttack(); // 10 5item.getDefense(); // 0 6item.getCritical(); // 0
ステージの効果とか、敵の魔法などにより、プレイヤーのステータスへマイナス効果を与えるような仕様もあるため、いったんパーセントに直して最終的なステータス値を決める必要がありました。
デフォルト値は、アイテム効果を除いた素の値を返します。
レベルアップによって変化するのであれば、メンバ変数をreturnする事になります。
これはあくまでも例で、だいたいこんな事をやっていたという事を思い出しながら書いています。
アイテム効果の増加分については、固定となるためバトル前に計算してメンバ変数に持っておいても良いと思います。
ただ、戦闘中にアイテムが壊れるとか、敵から受ける状態異常などの都合もあり、必ず毎回計算する部分は出てきます。
cpp
1// 防御力(デフォルト値) 2int Player::getDefaultDefense() const { 3 return mDefaultDefense; 4} 5 6// 防御力(アイテム効果を含めた現在の値) 7// バトルではこの値を使用 8int Player::getDefense() { 9 int base = getDefaultDefense(); 10 11 // 現在装備しているアイテム 12 std::vector<Item*> items = getItems(); 13 14 // アイテム効果(増加分のパーセント)を計算 15 int addPercent = 0; 16 for(auto item: items) { 17 // 防御力を返すメソッドなので、アイテムの防御力のところだけ考えればいい 18 addPercent += item->getDefense(); 19 } 20 21 // バトル中の敵の魔法などにより防御力が下がるような仕様があるなら 22 // ここで、その分だけaddPercentから引いておく 23 24 // 最終的な割合を計算 25 // 80, 90, 100, 105などの値になる 26 float percent = 100 + addPercent; 27 28 // 割合が0以下となったら、計算するまでもないので0を返す 29 if(percent <= 0.0f) { 30 return 0; 31 } 32 33 // デフォルト値を元に最終的な値を計算 34 float value = (float)base * (percent / 100.0f); 35 36 // ここでは整数にしたいので、四捨五入して値を決定 37 return (int)(value + 0.5f); 38}
投稿2017/07/01 15:07
編集2017/07/01 15:09総合スコア4025
0
既にベストアンサーでクローズですが、
残念ながら退会されたユーザの回答にコメントさせてもらったので具体を示しておきます。
mingosさんとchankaneさんのやり取りのJava実装と言えるものになってます。
ちなみに、2017/07/02 08:25のchankaneさんの発想はGoodでした。
GitHubにソースをアップしたので見てみてください。
以下にMainのソースだけ抜粋しておきます。
※当然ながらこの抜粋ソースだけでは動きません。
Java
1package org.pygmy.rpg; 2 3import org.pygmy.rpg.character.Character; 4import org.pygmy.rpg.item.Item; 5import org.pygmy.rpg.item.armor.concrete.IronArmor; 6import org.pygmy.rpg.item.concrete.Portion; 7import org.pygmy.rpg.item.weapon.concrete.IronSword; 8import org.pygmy.rpg.item.weapon.concrete.SteelAxe; 9 10public class Main { 11 12 public static void main(String[] args) { 13 14 // プレーヤーと敵を作成 15 Character player = new Character("player", 100, 10, 10); 16 Character enemy = new Character("enemy", 100, 10, 10); 17 18 // プレーヤーにポーションを持たせる 19 System.out.println("アイテム:ポーションを持たせる"); 20 dumpCountOfItems(player); 21 player.giveItem(Portion.create()); 22 dumpCountOfItems(player); 23 24 // 攻撃 25 System.out.println("攻撃"); 26 dumpPointOfLife(player); 27 enemy.attackTo(player); 28 dumpPointOfLife(player); 29 30 // 武器と防具を装備 31 player.equip(IronSword.create()); 32 player.equip(IronArmor.create()); 33 34 enemy.equip(SteelAxe.create()); 35 36 // 攻撃(装備後) 37 System.out.println("攻撃(装備後)"); 38 dumpPointOfLife(player); 39 enemy.attackTo(player); 40 dumpPointOfLife(player); 41 42 // プレーヤーのポーションを使う 43 // 1) ポーションを取り出して… 44 System.out.println("アイテム:ポーションを取り出して…"); 45 dumpCountOfItems(player); 46 Item item = player.takeItem(Portion.class); 47 dumpCountOfItems(player); 48 // 2) 使う 49 System.out.println("アイテム:使って…"); 50 dumpPointOfLife(player); 51 item.useTo(player); 52 dumpPointOfLife(player); 53 // 3)使い切った? 54 if (item.isUsedup()) { 55 System.out.println("アイテム:捨てる"); 56 } else { 57 System.out.println("アイテム:戻す"); 58 dumpCountOfItems(player); 59 player.giveItem(item); 60 dumpCountOfItems(player); 61 } 62 } 63 64 private static void dumpPointOfLife(Character character) { 65 System.out.println(character.getName() + " -> Point of Life = " + character.getPointOfLife()); 66 } 67 68 private static void dumpCountOfItems(Character character) { 69 System.out.println(character.getName() + " -> Count of Items = " + character.getCountOfItems()); 70 } 71}
アイテムの取り回し方がポイントです。
GitHubにアップしたソースには設計や実装上のエッセンスも少し入れてみました。
ゲームの仕様によってメリット・デメリットはあると思いますが、
気付いてもらえれば発想の幅が広がったり、実装スキル向上になると思います。
マップの件以来の回答です。
着々と進められているようで良かったです。
是非、完成させてくださいね。
投稿2017/07/03 18:46
編集2017/07/03 18:48総合スコア804
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
これはどのように設計するか、という問題ですね。正解は無いと思います。ですが指針になるものはあります。
オブジェクト指向で考えます。
オブジェクト指向であれば、プレイヤー、アイテムは別々のオブジェクトとして存在することになります。
プレイヤーが属性として持っているのは、HP,MP,力,素早さなどになります。
アイテムが属性として持っているのはHP+5,MP+5,力+1,素早さ-1などになります。
この時にオブジェクトとしての振る舞いを考えると、アイテムとプレイヤーの関係はプレイヤーがアイテムを使用する(装備する)という関係です。ですので、プレイヤー.equip(アイテム)のようなメソッドによりパワーアップ(またはダウン)をするのが自然です。装備を外した場合はプレイヤー.remove(アイテム)ということになります。
いまいち投稿者の方とご友人の想定されているメリットデメリットがわかりませんが、デメリット1はオブジェクト指向で考えることで解消されるはずです。また、メリット1,2とも言える事ですが隠ぺいする事が目的では無く、隠ぺいすることでどのようなメリットがあるかを考えた方が良いように思います。メリットがないのであれば隠ぺいすることに意味はありません。
他の方のご意見も聞きたいですが、ぜひベストな設計目指して試行錯誤して見てください。
投稿2017/07/01 14:30
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/01 14:48
退会済みユーザー
2017/07/01 14:51
2017/07/01 14:52
退会済みユーザー
2017/07/01 15:06
2017/07/01 15:16
2017/07/01 15:16
退会済みユーザー
2017/07/01 15:59
2017/07/01 16:13
退会済みユーザー
2017/07/01 16:21
2017/07/01 17:11
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/01 15:29
2017/07/01 15:39
2017/07/01 15:42
2017/07/01 15:45
2017/07/01 15:53
2017/07/01 16:24 編集
2017/07/01 17:18
2017/07/01 23:25
2017/07/02 00:10
2017/07/02 00:27
2017/07/02 00:32
2017/07/02 00:38
2017/07/02 00:46