ターン制(厳密には若干違いますが)のゲームを作ろうと思い以下のようなコードを書きました。
(関係ない場所は省略しました
//以下バトルモードのプログラム
extern int money;
extern int clear;
extern int miss;
void BATTLE() //戦闘モードクラス
{
#define START 0
#define JUGHGE 1
#define MY_TURN 2
#define ENEMY_TURN 3
const int DIREY_ATK = 3000;
const int DIREY_ITEM = 2000;
const int DIREY_SCF = 3500;
int CheckHitKey( int KeyCode );
int Turn;
int Hero;
int Ats[2];
int Cr;
HeroModel hero;
hero.hp = 10000;//主人公体力
hero.str = 1300;//攻撃力
hero.ats = 1000;//アーツ(魔法攻撃力)
hero.def = 2200;//防御力
hero.atd = 2000;//アーツ防御力
hero.sp = 200;//スピード
hero.direy = 0;//ディレイ
EnemyModel enemy;
enemy.hp = 11000;//敵体力
enemy.str = 300;//攻撃力
enemy.ats = 1000;//アーツ
enemy.def = 2100;//防御力
enemy.fad = 200;//火耐性
enemy.aad = 100;//水耐性
enemy.ead = 50;//風耐性
enemy.tad = 500;//地耐性
enemy.atd = 1000;//アーツ防御力
enemy.sp = 180;//スピード
enemy.direy = 0;//ディレイ
Turn = START;
Hero = 0; //0=通常 1=アーツ駆動状態
Ats[0] = 0;//クリムゾンレイ(攻撃アーツ
Ats[1] = 0;//ティアラ(回復アーツ
while( ProcessMessage() == 0 )
{
// 画面を初期化(真っ黒にする)
ClearDrawScreen() ;
// もしもZキーが押されていたらSクラフト発動
if( CheckHitKey( KEY_INPUT_Z ) ){
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "必殺技発動!" ,GetColor(255,0,0));
hero.direy += DIREY_SCF / hero.sp; //ディレイ算出
int dm_a,dm_b,dm_c,dm;
int iryoku;
iryoku = 700;
dm_a = hero.str * ( iryoku / 100 ); //攻撃値を求める
dm_b = ( dm_a * 5 - enemy.def * 2.5) / 2; //基本ダメージ
if( dm_b < 0 ){ //基本ダメージがマイナスの場合ダメージを0に
dm_b = 0;
}
dm_c = ( dm_b ) / 15; //ランダム値
dm = dm_b + dm_c; //最終ダメージ
enemy.hp -= dm;
if( enemy.hp < 0){ //残りHPが0以下になったら0に修正
enemy.hp = 0;
}
DrawFormatString( 250, 240 - 32, Cr, "敵に %5d のダメージ!!", dm);
DrawFormatString( 250, 260 - 32, Cr, "敵の残りHP %5d", enemy.hp);
if( enemy.hp > 0 ){
Turn = JUGHGE;
}
else {
DrawString( 250 , 280 - 32 , "敵を倒した!!!" , Cr );
money += 100;
clear++;
WaitKey() ;
return;
}
WaitKey();
break;
}
switch(Turn) {
case START : //戦闘開始処理
DrawString(260,100,"敵が現れた!",GetColor(255,0,0)) ;//戦闘開始時のメッセージの表示など
if(hero.sp >= enemy.sp) {
Turn = MY_TURN;
} else {
Turn = ENEMY_TURN;
}
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break ;
case JUGHGE:
if(hero.direy <= enemy.direy) {
Turn = MY_TURN;
} else {
Turn = ENEMY_TURN;
}
break;
case MY_TURN:
if( Hero == 0){
// 白色の値を取得
Cr = GetColor( 255 , 255 , 255 ) ;
// 文字列の描画
DrawString( 250 , 240 - 32 , "主人公のターン!!" , Cr );
DrawString( 50 , 100 - 32 , "A:攻撃 S:逃げる D:回復アイテム F:アーツ" , Cr );
WaitKey();
if( CheckHitKey (KEY_INPUT_S) == 1 ){
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "にげます。" , Cr );
miss++;
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
return;
}
if( CheckHitKey (KEY_INPUT_A) == 1 ){
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "主人公の攻撃!" , Cr );
hero.direy += DIREY_ATK / hero.sp; //ディレイ算出
int dm_a,dm_b,dm_c,dm;
int iryoku;
iryoku = 100;
dm_a = hero.str * ( iryoku / 100 ); //攻撃値を求める
dm_b = ( dm_a * 5 - enemy.def * 2.5) / 2; //基本ダメージ
if( dm_b < 0 ){ //基本ダメージがマイナスの場合ダメージを0に
dm_b = 0;
}
dm_c = ( dm_b ) / 15; //ランダム値
dm = dm_b + dm_c; //最終ダメージ
enemy.hp -= dm;
if( enemy.hp < 0){ //残りHPが0以下になったら0に修正
enemy.hp = 0;
}
DrawFormatString( 250, 240 - 32, Cr, "敵の残りHP %d", enemy.hp);
if( enemy.hp > 0 ){
Turn = JUGHGE;
}
else {
DrawString( 250 , 260 - 32 , "敵を倒した!!!" , Cr );
money += 100;
clear++;
WaitKey() ;
return;
}
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
if( CheckHitKey (KEY_INPUT_F) == 1 ){
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "K:クリムゾンレイ T:ティアラ" , Cr );
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
if( CheckHitKey (KEY_INPUT_K) == 1 ){
DrawString( 250 , 240 - 32 , "アーツ駆動…" , Cr );
hero.direy += 3500 / hero.sp; //ディレイ算出
Turn = JUGHGE;
Hero = 1; //アーツ遷移
Ats[0] = 1;
}
if( CheckHitKey (KEY_INPUT_T) == 1 ){
DrawString( 250 , 240 - 32 , "アーツ駆動…" , Cr );
hero.direy += 1000 / hero.sp; //ディレイ算出
Turn = JUGHGE;
Hero = 1; //アーツ遷移
Ats[1] = 1;
}
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
if( CheckHitKey (KEY_INPUT_D) == 1 ){
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "回復アイテム!!" , Cr );
hero.direy += DIREY_ITEM / hero.sp;
hero.hp += 500;
DrawFormatString( 250, 240 - 32, Cr, "残りHP %d", hero.hp );
Turn = JUGHGE;
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
DrawString( 250 , 260 - 32 , "ターン終了" , Cr );
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
else{//アーツ駆動状態の場合
if( Ats[0] == 1){
DrawString( 250 , 220 - 32 , "アーツ発動「クリムゾンレイ」" , Cr );
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
hero.direy += 1500 / hero.sp; //ディレイ(硬直時間
int dm_a,dm_b,dm_c,dm;
int iryoku;
iryoku = 800;
dm_a = hero.ats * ( enemy.fad / 100 ) * ( iryoku / 100 );//攻撃値を求める
dm_b = ( dm_a * 5 - enemy.atd * 2.5) / 2; //基本ダメージ
if( dm_b < 0 ){ //基本ダメージがマイナスの場合ダメージを0に
dm_b = 0;
}
dm_c = ( dm_b ) / 15; //ランダム値
dm = dm_b + dm_c; //最終ダメージ
enemy.hp -= dm;
if( enemy.hp < 0){ //残りHPが0以下になったら0に修正
enemy.hp = 0;
}
DrawFormatString( 250, 220 - 32, Cr, "%d のダメージ!!", dm);
DrawFormatString( 250, 240 - 32, Cr, "敵の残りHP %d", enemy.hp);
if( enemy.hp > 0 ){
Turn = JUGHGE;
Hero = 0;
Ats[0] = 0;
}
else {
DrawString( 250 , 260 - 32 , "敵を倒した!!!" , Cr );
money += 100;
clear++;
WaitKey() ;
return;
}
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
if( Ats[1] == 1 ){
DrawString( 250 , 220 - 32 , "アーツ発動「ティアラ」" , Cr );
// 画面に描かれているものを一回全部消す
ClsDrawScreen();
hero.direy += 1000 / hero.sp; //ディレイ(硬直時間
hero.hp += 2000;
DrawString( 250 , 220 - 32 , "HP回復" , Cr );
DrawFormatString( 250, 240 - 32, Cr, "HP %d", hero.hp);
Hero = 0;
Ats[1] = 0;
WaitKey();
break;
}
}
case ENEMY_TURN:
ClsDrawScreen();
// 白色の値を取得
Cr = GetColor( 255 , 255 , 255 ) ;
// 文字列の描画
DrawString( 250 , 240 - 32 , "敵のターン!!" , Cr );
ClsDrawScreen();
DrawString( 250 , 220 - 32 , "敵の攻撃!" , Cr );
enemy.direy += DIREY_ATK / enemy.sp;
int dm_a,dm_b,dm_c,dm;
int iryoku;
iryoku = 100;
dm_a = hero.str * ( iryoku / 100 ); //攻撃値を求める
dm_b = ( dm_a * 5 - hero.def * 2.5) / 2; //基本ダメージ
if( dm_b < 0 ){ //基本ダメージがマイナスの場合ダメージを0に
dm_b = 0;
}
dm_c = ( dm_b ) / 15; //ランダム値
dm = dm_b + dm_c; //最終ダメージ
hero.hp -= dm;
DrawFormatString( 250, 240 - 32, Cr, "自分の残りHP %d", hero.hp );
if( hero.hp > 0){
Turn = JUGHGE;
}
else {
DrawString( 250, 260 - 32 , "力尽きた…" , Cr);
money -= 50;
miss ++;
WaitKey();
return;
}
DrawString( 250 , 260 - 32 , "ターン終了" , Cr );
WaitKey() ; // キーの入力待ち(『WaitKey』を使用)
break;
}
}
// Windows 特有の面倒な処理をDXライブラリにやらせる -1 が返ってきたらループを抜ける
if( ProcessMessage() < 0 ) return ;
// もしESCキーが押されていたらループから抜ける
if( CheckHitKey( KEY_INPUT_ESCAPE ) ) return ;
return;
}
//ここまで
このプログラム自体は問題無く動きました(うえの状態だと見た目に難がありますがw)
しかし、見ての通り1対1にしか対応できないんです。
私は初心者なので行き詰ってしまいました。どうすればいいのでしょうか?プログラムを全て書き直す羽目になってもかまいません。
複数の敵、複数の味方を戦わせるにはどうすればいいのか、アドバイスだけでも頂けるとありがたいです。
(とくに分からない点は、複数のキャラの戦闘順をどう処理したらいいのか)
*一応環境*
VisualC++2010 ExpressEdition
*システムについて*
このゲームの戦闘順ですが念のため説明しときます。念のため。
まず最初は自分も敵もディレイは”0”で、スピードで行動順を決めます。
その後、起こす行動によって”ディレイ値(ディレイ÷スピードで算出)”を加算していきます。(強力な技やアーツはディレイが高く、アイテム使用などはディレイが低い)。
このとき、ディレイ値の低い者から行動します。
(ちなみにこれもコードを見れば分かりますが、アーツは発動するまでにもディレイがあります。
アーツ駆動→主人公アーツ使用状態に遷移→駆動までのディレイ→発動→ダメージ計算等→主人公通常モード遷移→アーツ使用後の硬直時間ディレイ)