なんとなくだらだらと。方向性はまだ決まってない。
当方のプログラムでは、山田巧さん作成のDXライブラリを利用させていただいてます。
本サイト http://homepage2.nifty.com/natupaji/DxLib/index.html
DX Library Copyright (C) 2001-2008 Takumi Yamada.
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
さて、このへんから手探りになってくるぞ。
攻撃、防御メソッドをUnitクラスに追加してみる。 まずは乱数取得の準備。 テストプログラムのクソースごときに、そんなに精度の高い乱数が必要なわけがない。 ここは標準のランダム関数を使うことにする。 #include <iostream> #include <string> #include <stdlib.h> // 乱数取得に必要 #include <time.h> // rand()の初期化に必要 using namespace std; 準備その2 乱数の初期化。srandで初期化しないと、毎回同じ結果になるんだよね(笑) で、初期化のパラメーターに int main() { srand(time(NULL)); Unit player,enemy; コンパイルしたら、うだうだ警告出してくるんで、警告を抑え込む。 .\main.cpp(40) : warning C4244: '引数' : 'time_t' から 'unsigned int' への変換です。データが失われる可能性があります。 time_t型って、intだったっけ? まあ、目的はなんか適当な数字を拾ってくるだけなんで、どうでもいい。 unsigned int型に型変換する。 int main() { srand(static_cast<unsigned int>(time(NULL))); Unit player,enemy; 型変換は結構危険なんで、昔からの(unsigned int)time(NULL); みたいな書き方よりは こうやってきちんとキャスト書いたほうがいい。 実数から小数点以下を取り去る目的の double → int 変換とか、自分で理由が分かってたら問題に ならないんだけど、 よくわかってないけどワーニングを抑え込むためとか、「型変換したら動きました (コンパイル通りました)」とかは、後で深刻な原因不明バグになりやすい。 後者はあるあるすぎて困る。 で、どこで型変換してるか探しやすくするために、型変換の関数(?) ~_cast を使うのが俺ジャスティス。 乱数の初期化の話だけでだいぶ盛り上がってしまったぞ。 攻撃ルーチンの概要を、こんな感じで設計してみる。 1.攻撃側から攻撃力を算出 2.防御側から防御力を以下略 3.攻撃力 - 防御力 がダメージ。0以下になったらダメージ=1として、最低1ダメージは通る 4.防御側の体力を減らす。0以下なら死亡。 クラスUnit の定義 public: void Init(string Name, int HP,int Atp,int Dfp); void ShowStatus(); int Attack(); int Defence(); }; 攻撃力は、Atpの半分+Atpまでの乱数 Atpが8なら、4+(0~7) で4~11のダメージ期待。 防御力は、Dfpの半分+Dfpの半分までの乱数 こんな感じで設定してみる。 // 攻撃・アタックポイント int Unit::Attack() { int res; res = Atp/2 + rand()%Atp; return res; } // 防御・ディフェンスポイント int Unit::Defence() { int res; res = (Dfp + rand()%Dfp)/2; return(res); } 書いてみると、予想以上にしょぼい。 計算が1行でまとまるなら1行にまとめる。 // 攻撃・アタックポイント int Unit::Attack() { return(Atp/2 + rand()%Atp); } // 防御・ディフェンスポイント int Unit::Defence() { return((Dfp + rand()%Dfp)/2); } 使ってみる。 int NormalAttack(Unit &lst, Unit &rst) { int dmg; dmg = (lst.Attack() - rst.Defence()); if(dmg <= 0) dmg = 1; cout << lst.Name << "のこうげき!\n"; cout << rst.Name << "に " << dmg << "のダメージを与えた。\n"; return(0); } int main() { srand(static_cast<unsigned int>(time(NULL))); Unit player,enemy; player.Init("ゆうしゃ", 30, 8, 5); enemy.Init("ゴブリン", 12, 6, 3); player.ShowStatus(); enemy.ShowStatus(); NormalAttack(player,enemy); NormalAttack(enemy,player); // 確認 player.ShowStatus(); enemy.ShowStatus(); cout << "\n\n終了。" << endl; return 0; } \(^o^)/ .\main.cpp(78) : error C2248: 'Unit::Name' : private メンバ (クラス 'Unit' で宣言されている) に アクセスできません。 今まで何も感じなかったのが不思議。慣れって怖い。 俺はゲトセト関数作るのが嫌いだ。Get()Set()作るぐらいなら全public宣言する! ってわけにもいかないんだろうな。お行儀よく、クラス定義に書き足す。 void ShowStatus(); int Attack(); int Defence(); string getName(){return(Name);} }; そうすると、さっき作ったNormalAttack()関数の修正も? int NormalAttack(Unit &lst, Unit &rst) { int dmg; dmg = (lst.Attack() - rst.Defence()); if(dmg <= 0) dmg = 1; cout << lst.getName() << "のこうげき!\n"; cout << rst.getName() << "に " << dmg << "のダメージを与えた。\n"; return(0); } ダメージ計算も追加する。 まずはクラスに定義を追加 int Defence(); string getName(){return(Name);} int Hit(int dmg); }; 実体 int Unit::Hit(int dmg) { HP -= dmg; if(HP <= 0) return -1; return 0; } で、ノーマル攻撃関数にダメージ計算を追加。 cout << rst.getName() << "に " << dmg << "のダメージを与えた。\n"; if(rst.Hit(dmg)){ cout << lst.getName() << "は、" << rst.getName() << "にとどめをさした!\n"; return(-1); } return(0); } よし、これで動くかな? だいたい想定どおりに動いてるっぽい。 ちゃんととどめ刺せてるかどうか、ゴブリンの体力減らして確認してみる。 /(^o^)\ まあ、そうだよな。そうだよな。 HPマイナスは気になる。 int Unit::Hit(int dmg) { HP -= dmg; if(HP <= 0) { HP = 0; return -1; } return 0; } 死んでるはずの敵に殴られるのは、今は何もやってないからな。ご愛敬ってところ。 次。 PR |
カレンダー
カテゴリー
フリーエリア
最新記事
(01/29)
(01/28)
(01/26)
(12/28)
(12/27)
(12/25)
(12/20)
(09/09)
(09/09)
(09/09)
(09/08)
(09/08)
(09/08)
(09/06)
(09/05)
(08/27)
(08/27)
(08/27)
(08/25)
(08/23)
ブログ内検索
P R
アクセス解析
カウンター
|