コマンドプロンプトには移動範囲を格納した構造体と攻撃範囲を格納した構造体を表示しております。
結果をみて、じっくり考えれば出来るものですね。
エイッ 試験的にキャラクタの攻撃範囲はベタで10に固定しています。
ただね、再帰を使っているので、計算するのに3秒かかるんです。計算が終わるまでDXライブラリが3秒止まるw
同時にこんなに重い関数を書いたのは初めてでした。
無駄な計算を減らすために、そのマスをチェックしたかの配列を作って
チェック済みのところは飛ばすようにしないと、実用に耐えずだめかもしれないです。
また更に改良が必要でした。がんばろう俺。
► スポイラーを表示
//-----------------------------------------------------------------------------
// 名前 : MoveReflexCalc
// 引数 :キャラクタの位置情報 X,Y,キャラクタの移動力 ,方向フラグ di ,移動経路情報 str
// 戻り値:
// 説明 :移動範囲を計算して移動経路を確立する
//-----------------------------------------------------------------------------
void CMoveChar::MoveReflexCalc(int ax,int ay,int MovePower,int di,string str){
//バッファオーバーチェック
if(ax cm->md.Width - 1|| ay cm->md.Height - 1)return;//地形を回り込んでしまうバグを回避するため-1
//コストチェック
int nDown = 1;//コストを1で初期化
int index = cm->MapBlock[0][ay][ax];//index番号の取得
int nTipAttribute = cm->lpCostTabel[index].TipAttribute;//チップ属性の取得
int nUnitAttribute = lpPickChar->ud.nMoveCost;//ユニット移動属性の取得
//printf("nTipAttribute = %d,nUnitAttribute = %d\n",nTipAttribute,nUnitAttribute);
//配列からコストの検索
for(int i = 0;i MoveCostTableRow;++i){
//ユニット移動属性が一致したらコストを引っ張り出す
if(nUnitAttribute == cm->lpMoveCostTable[i].nJobCode){
nDown = cm->lpMoveCostTable[i].nMoveCostTable[nTipAttribute - 1];//構造体の行数とそろえるために-1する
}
}
//敵キャラ味方キャラの場所をチェックする、まずは自信が何者なのか調べる
int nBelong;
if(lpPickChar->ud.UniqueNo ud.UniqueNo >= 50 && lpPickChar->ud.UniqueNo str_Belong[ay][ax].BelongFlag == 1)nDown = 100;
break;
case 1://敵ユニットの場合
if(cm->str_Belong[ay][ax].BelongFlag == 0)nDown = 100;
break;
case 2://NPCの場合
if(cm->str_Belong[ay][ax].BelongFlag == 1)nDown = 100;
break;
default:
break;
}
//移動量を引いて処理を続けるか判定する
if(MovePower - nDown MovePower){return;}
//フラグを立てる
MoveResult[ay][ax] = 0;//移動可能にする
BlockCheck[ay][ax] = MovePower;//コストの記録
//経路情報を記録する
if(MoveDirection[ay][ax].length() > str.length() || MoveDirection[ay][ax].length() == 0){
MoveDirection[ay][ax] = str;
}
///最後の文字列が経路情報
if(di != 3)MoveReflexCalc(ax,ay - 1,MovePower-nDown,1,str + "U");//上
if(di != 4)MoveReflexCalc(ax + 1,ay,MovePower-nDown,2,str + "R");//右
if(di != 1)MoveReflexCalc(ax,ay + 1,MovePower-nDown,3,str + "D");//下
if(di != 2)MoveReflexCalc(ax - 1,ay,MovePower-nDown,4,str + "L");//左
//攻撃範囲の計算
AttackReflexCalc(ax,ay,10,1);
AttackReflexCalc(ax,ay,10,2);
AttackReflexCalc(ax,ay,10,3);
AttackReflexCalc(ax,ay,10,4);
return;
}
//-----------------------------------------------------------------------------
// 名前 : AttackReflexCalc
// 引数 :キャラクタの位置情報 X,Y,キャラクタの移動力 ,方向フラグ di ,移動経路情報 str
// 戻り値:
// 説明 :攻撃範囲を計算する
//-----------------------------------------------------------------------------
void CMoveChar::AttackReflexCalc(int ax,int ay,int MovePower,int di){
//バッファオーバーチェック
if(ax cm->md.Width - 1|| ay cm->md.Height - 1)return;//地形を回り込んでしまうバグを回避するため-1
//コストチェック
int nDown = 1;//コストを1で初期化
//移動量を引いて処理を続けるか判定する
if(MovePower - nDown < 0){
return;//コストがマイナスならば進めないので処理を抜ける
}else{
AttackResult[ay][ax] = 0;/*アタック構造体に攻撃可能数字を代入*/
}
///最後の文字列が経路情報
if(di != 3)AttackReflexCalc(ax,ay - 1,MovePower-nDown,1);//上
if(di != 4)AttackReflexCalc(ax + 1,ay,MovePower-nDown,2);//右
if(di != 1)AttackReflexCalc(ax,ay + 1,MovePower-nDown,3);//下
if(di != 2)AttackReflexCalc(ax - 1,ay,MovePower-nDown,4);//左
return;
}