リファクタリング、構成練り倒したい病が発症しました。
変数があっちこっちにちらばってるのはまだしも。
シーン管理が上手く出来ていないのでかなりスパゲッティになってきました。
状態遷移の中に状態遷移があるのが耐えられない。何か良い方法無いですか?
(フィールド画面内[nGameTransfer]でプレイヤーターン[nTransfer]であり、更に攻撃する敵を選択中[nPlayerTransfer]とそれぞれに状態遷移有り)
酷い状態のゲーム本体部分の関数を晒しておきます
► スポイラーを表示
//-----------------------------------------------------------------------------
// 名前 : UpData
// 引数 :
// 戻り値: 正常終了 = 0
// エラー = -1
// 説明 :
//-----------------------------------------------------------------------------
int CGame::UpData(){
static bool bRet = false;
bool bRet2;
static int nRet;
static int nCharFreeRet,nCharPikupRet,nCharDistRet,nCharMovedRet,CharMovedMenuRet;
static int nSysRet;
static MainTransfer nFeedTemp;//戦闘時の戻り値保存用
static EnumMoveTransfer ReturnTemp;//再移動等の戻り値保存用
//状態遷移処理
switch(nGameTransfer){
/************フィールド状態遷移******************/
case Field:
switch(nTransfer){
case FeedOut://画面のフィードアウト処理
if(this->FeedOutScr() == nResultOK){//フェードアウトが終わったら戦闘画面に映す
nGameTransfer = Battle;
}
break;
case AutoScroll:
//bRet = cm->AutoScrollTetra();
//if(bRet == true) nTransfer = DrawForceMenu;
nTransfer = DrawForceMenu;//debug中↑をコメントから外してこの行を削除すれば元に戻る
break;
case DrawForceMenu:/*出撃準備コマンドメニュー表示中*/
nRet = cmenu->Updata();
switch(nRet){
case no_transe://メニューからの返却値を無視しスルーする
break;
case Ready://出撃準備が選択されました
cwarready->Init();
nTransfer = WarReady;
break;
case GO://出撃が選択されました
nTransfer = Ready_Event;
break;
case Cursor: //マップが選択されました
cur->ChangeDrawFlag(true);//カーソル描写フラグを立てる
nTransfer = DrawCursor;//メイントランスファーを切り替える
break;
case ItemSelect://アイテム整理が選択されました
nTransfer = ItemOrder;
break;
case Save://セーブロードが選択されました
break;
}
break;
case WarReady://出撃準備画面表示中
cwarready->UpData(&nTransfer,csdraw);
break;
case DrawCursor://カーソル表示マップを見ている状態
cur->UpData();
cur->ScrollCalc(cm);
if(bRet2 = cur->MapLookTransfer() == true){
cur->ChangeDrawFlag(false);//カーソル描写フラグを折る
nTransfer = DrawForceMenu;//Zボタンを押したら出撃メニュー描写に戻る
}
csdraw->Updata(cur,force,enemyforce,&nTransfer,cm,MapSel);
break;
case ItemOrder://アイテム整理画面表示中
citarr->UpData(&nTransfer,csdraw);
break;
case DrawStatus://キャラクターのステータス画面表示中
csdraw->StatusCalc(cur,&nTransfer);
break;
case Ready_Event://出撃前のイベント状態
nTransfer = Player_TurnReady;
break;
case Player_TurnReady://自軍ターン準備状態
bool bRet;
/*デバッグ中コメントを外すと元に戻ります*/
//bRet = cdt->CalcTurnIndication(Player_TurnReady);//ターン表示
//if(bRet == true){
force->InitMovedFlag();//自軍のユニットをすべて移動可能にする
enemyforce->InitMovedFlag();//敵軍のユニットをすべて移動可能にする
nTransfer = AutoAcrollMainPlayer;//表示が終わったら状態遷移を主人公を探すモードに移す
//}
/*ここまで*/
break;
case Enemy_TurnReady://敵軍ターン準備状態
//bRet = cdt->CalcTurnIndication(Enemy_TurnReady);//ターン表示
//if(bRet == true){
force->InitMovedFlag();//自軍のユニットをすべて移動可能にする
enemyforce->InitMovedFlag();//敵軍のユニットをすべて移動可能にする
nTransfer = Enemy_Turn;//敵ターンに状態遷移を移す
//}
break;
case AutoAcrollMainPlayer://主人公へカーソルを移すモード
if(!cm->AutoScrollChar(force->MyForce[0])){//ランへオートスクロール
cur->ChangeDrawFlag(true);
//主人公への移動が終わったら状態遷移をプレイヤーターンに移す(ここで二つの状態遷移を初期化しているのに注意)
nPlayerTransfer = CharFree; nTransfer = Player_Turn;
}
break;
/*****************************************/
/******プレイヤーターンはここからです*****/
/*****************************************/
case Player_Turn://プレイヤーターンキャラクタ操作状態
switch(nPlayerTransfer){//プレイヤーターンの中で更に状態遷移を分岐させる
case SysMenu://システムメニュー表示中
nSysRet = csysmenu->Updata();
switch(nSysRet){
case Situation://状況メニューを選択した
break;
case TurnEnd://ターンエンドを選択した/*敵ターン準備状態に移す*/
csysmenu->Finalize();
cur->ChangeDrawFlag(false);//カーソル描写を折る
nTransfer = Enemy_TurnReady; nEnemyTransfer = SerchNomoveEnemy;//敵ターンに移行する(ここで状態遷移を二つ初期化しているのに注意)
break;
default:
break;
}
if(InputCheck::ReturnZtoResultOK() == nResultOK){
cur->ChangeDrawFlag(true);
nPlayerTransfer = CharFree;//状態遷移をキャラクタフリーに戻す
}
break;
case ReturnChar://カーソルをキャラクターに自動的に戻す状態遷移
if(movech->RetCurCharcter() == nResultOK){
nPlayerTransfer = ReturnTemp;//static変数に一時保存してある状態遷移に戻す
}
break;
case CharFree://キャラクタをピックアップしていないフリーな状態
cur->UpData();
cur->ScrollCalc(cm);
csdraw->Updata(cur,force,enemyforce,&nTransfer,cm,PlayTurn);
//ピックアップ処理
nCharFreeRet = movech->PickCharcter();
//キャラクタピックアップ処理
switch(nCharFreeRet){
case nResultOK:
nPlayerTransfer = CharPikup;//キャラクタのピックアップが成功したら状態遷移を次に移す
break;
case nResultSysMenu:
cur->ChangeDrawFlag(false);
nPlayerTransfer = SysMenu;//システムメニューに状態遷移を移す
break;
default:
break;
}
break;
case CharPikup://キャラクタピックアップ中
//キャラクタピックアップ処理解除
if(nCharPikupRet = movech->CancellPick() == nResultOK){
nPlayerTransfer = CharFree;//状態遷移をひとつ前に戻す
}
cur->UpData();
cur->ScrollCalc(cm);
movech->CalcDrawNumber(CharPikup);
//キャラクタ目的地決定
nCharDistRet = movech->SetDistnation();
switch(nCharDistRet){
case nResultDifferentPos://他のマスに移動する処理
nPlayerTransfer = CharMoving;//目的地が決定したら状態遷移をキャラクタ移動中に移す
break;
case nResultSamePos://他のマスに移動しない処理
if(movech->InitilizeMenu() == nResultOK){;//メニュー情報を初期化して
nPlayerTransfer = CharMovedMenu;//目的地までキャラクタを移動したら状態遷移を変更する
}
break;
default:
break;
}
break;
case CharMoving://キャラクタを動かしている途中
if(nCharMovedRet =movech->CalcMoveChar() == true){
if(movech->InitilizeMenu() == nResultOK){;//メニュー情報を初期化して
nPlayerTransfer = CharMovedMenu;//目的地までキャラクタを移動したら状態遷移を変更する
}
}
movech->CalcDrawNumber(CharMoving);
break;
case CharMovedMenu://キャラクタを動かした後のメニュー表示中
movech->CalcDrawNumber(CharMovedMenu);
movech->CalcMenuUpDown();
CharMovedMenuRet = movech->MenuDecision();//メニューの決定処理
switch(CharMovedMenuRet){//返却された数値に従って各項目へ状態遷移を移す
case 0://武器屋
break;
case 1://道具屋
break;
case 2://訪問
break;
case 3://会話メニューを選択した
break;
case 4://攻撃メニューを選択した
cur->ChangeDrawFlag(false);//カーソル表示フラグを折る
cfightselect->InitilizePickChar(movech->ReturnPickChar());//キャラクタの参照を得る
cfightselect->InitEnemyCount(movech->ReturnAttackResult());//周囲の敵の数を調べる
cfightselect->CreateEnemyArray(movech->ReturnAttackResult(),movech->ReturnAttackCheck(),force,enemyforce);//周囲の敵の情報を格納する
cfightselect->CalcWeponCount();
cfightselect->initlizeSelectNum();
cfightselect->GetOldEquip();
movech->debugarea();
nPlayerTransfer = NumFightSelItem;
break;
case 5://杖
break;
case 6://待機
nPlayerTransfer = NumStand;
break;
case 7://持ち物
break;
case 8://物交換
if(citemchange->CheckRectangleChar() == nResultOK){
nPlayerTransfer = NumItemChange;//物交換状態遷移に移す
}
break;
case 9://踊る
break;
default:
break;
}
if(CharMovedMenuRet = movech->MoveCancell() == nResultOK){
ReturnTemp = movech->CaseByReturnTransfer();//戻す状態遷移を保存しておく
nPlayerTransfer = ReturnChar;//自動的にキャラクタにカーソルを戻す状態遷移に変更する
}
//再移動処理に移る
if(movech->JudgeRemove() == nResultOK){
if(movech->InitRemove() == nResultOK){
nPlayerTransfer = RemovePickup;
}
}
break;
case RemovePickup://再移動のピックアップ中
movech->CalcDrawNumber(CharPikup);
cur->UpData();
cur->ScrollCalc(cm);
//キャラクタ目的地決定
nCharDistRet = movech->SetDistnation();
switch(nCharDistRet){
case nResultDifferentPos://他のマスに移動する処理
nPlayerTransfer = CharMoving;//目的地が決定したら状態遷移をキャラクタ移動中に移す
break;
case nResultSamePos://他のマスに移動しない処理
if(movech->InitilizeMenu() == nResultOK){;//メニュー情報を初期化して
nPlayerTransfer = CharMovedMenu;//目的地までキャラクタを移動したら状態遷移を変更する
}
break;
default:
break;
}
break;
case NumWeponShop://武器屋コマンド状態遷移
break;
case NumItemShop://道具屋コマンド状態遷移
break;
case NumSearchHouse://訪問コマンド状態遷移
break;
case NumTalk://会話コマンド状態遷移
break;
case NumRod://杖コマンド選択状態遷移
break;
case NumFightSelItem://戦うコマンド使用武器選択中
movech->CalcDrawNumber(CharMovedMenu);
cfightselect->CalcItemSelectNum();
if(InputCheck::ReturnZtoResultOK() == nResultOK){//キャンセル処理
cur->ChangeDrawFlag(true);
cfightselect->RetEquipItem();
cfightselect->DeleteEnemyArray();//最後まで戦い抜いた時もこの関数を読んでください
nPlayerTransfer = CharMovedMenu;
}
if(InputCheck::ReturnXtoResultOK() == nResultOK){//決定処理
movech->RepeatAttackCalcEnemySelect();
cfightselect->InitEnemyCountTarget(movech->ReturnAttackResult());
cfightselect->CreateEnemyArrayTarget(movech->ReturnAttackResult(),movech->ReturnAttackCheck(),force,enemyforce);//周囲の敵を検索する
cfightselect->SetstFightLastCalc(movech->ReturnAttackResult(),cm);//お互いの最終的な能力値の計算(一度だけ呼ぶ)
nPlayerTransfer = NumFightSelTarget;
}
break;
case NumFightSelTarget://戦うコマンド戦闘相手選択中
movech->CalcDrawNumber(CharMovedMenu);
if(cfightselect->CalcEmenySelectNum() == nResultOK){
cfightselect->SetstFightLastCalc(movech->ReturnAttackResult(),cm);//お互いの最終的な能力値の計算
}
if(InputCheck::ReturnZtoResultOK() == nResultOK){//キャンセル処理
cfightselect->InitSelectNum();
cfightselect->DeleteEnemyArrayTarget();
movech->RepeatAttackCalc();
movech->debugarea();
nPlayerTransfer = NumFightSelItem;
}
if(InputCheck::ReturnXtoResultOK() == nResultOK){//戦闘決定処理
//画面をフェードアウトさせて戦闘クラスを生成しnResultNGが返ってきたらクラスを破棄する
nFeedTemp = Player_Turn;
/*戦闘クラス生成*/
cbat = new CBattle(cfightselect->ReturnPickChar(),cfightselect->ReturnTargetChar(),cm);
nTransfer = FeedOut;
}
break;
case NumStand://待機コマンド状態遷移
if(nResultOK == movech->SetStand()){
nPlayerTransfer = CharFree;
}
break;
case NumPosItem://持ち物コマンド状遷移
break;
case NumItemChange://物交換コマンド状態遷移
movech->CalcDrawNumber(CharMovedMenu);//キャラクタの描写計算
if(citemchange->UpData() == nResultNG){
nPlayerTransfer = CharMovedMenu;
}
break;
case NumDance://踊るコマンド状態遷移
break;
default:
break;
}
break;
/*ここまで*/
/*****************************************/
/******敵ターンはここからです*****/
/*****************************************/
case Enemy_Turn:
int nEnemyRet;
//debug
//cur->ChangeDrawFlag(true);
switch(nEnemyTransfer){
case SerchNomoveEnemy://動かす敵の番号を割り出す
nEnemyRet = move_enemy->SetNomoveEnemyData();
if(nEnemyRet == nResultOK){
nEnemyTransfer = AutoScrollEnemy;//状態遷移を次に移す
}else{//動かす敵が居ないので敵ターン終了
nTransfer = Player_TurnReady;
}
break;
case AutoScrollEnemy://割り出した番号の敵ユニットまでオートスクロールする
if(move_enemy->AutoScroll_MoveChar() == nResultOK){
move_enemy->PickUpEnemy(NumPikup);//描写の関係で敵を立たせる
nEnemyTransfer = EnemyMoving;
}
break;
case EnemyMoving://敵キャラクタ移動処理
if(nCharMovedRet =move_enemy->CalcMoveChar() == true){
nEnemyTransfer = ThinkEnemyMovedAfter;//目的地までキャラクタを移動したら状態遷移を変更する
}
move_enemy->CalcDrawNumber(CharMoving);
break;
case ThinkEnemyMovedAfter:
move_enemy->EndFlag();
nEnemyTransfer = SerchNomoveEnemy;
break;
default:
break;
}
break;
/*ここまで*/
default:
break;
}
cm->UpData(cur);//キャラクタ情報ポップアップの表示
force->Updata(cm,cur,&nTransfer);
enemyforce->Updata(cm,cur);
CCharcterAction::CountUp();
break;
/*フィールド状態遷移ここまで*/
/*ここから戦闘状態状態遷移*/
case Battle:
if(cbat->UpData() == nResultNG){
delete cbat;
cbat = NULL;
movech->SetStand();
cur->ChangeDrawFlag(true);
cfightselect->DeleteEnemyArray();//最後まで戦い抜いた時もこの関数を呼んで
cfightselect->DeleteEnemyArrayTarget();
nPlayerTransfer = CharFree;
nGameTransfer = Field;
nTransfer = nFeedTemp;
}
break;
/*ここまで*/
default:
break;
}
return 0;
}
これから暫く見通しを良くするためにリファクタリングします。