DXライブラリの掲示板で質問をしたら、そこからライブラリの調整をしていただけました。
今まで何度か掲示板とかで質問をしてきましたが、なんというかこう、自分の単純な理解不足でない質問が出来たのは初めてです。
きっとこれが成長というやつなんでしょう。
ゲームの製作のほうは順調に進んではいるんですが、見た目があまり変わらないので特に記事にすることもなく。
ひとまず時間が流れるようにするところまで行きたいんですが、それが一段楽するのは今月の終わりころかもしれません。
現時点での描画に6ミリ秒かかってるのがちょっと心配。ここからもう少し描画が増えた場合に、果たしてどの程度1フレームに猶予が生まれるだろうかと。16ミリ秒のうち10ミリ秒を描画で使うとしたら、COMの思考に使えるのが6ミリ秒しか残らない・・・。いっそ、30FPSで固定させてしまおうかとも考え中です。
HEXであれスクエアであれ、SLGタイプのゲームを作るとき、ある点を中心とした範囲を求めたくなることがあります。あるユニットの周辺nHexだとか、あるユニットの移動可能範囲だとか。
今回はそれについて。
void HexCalculator::RegisterWithInHex(Hex* p_hex, int distance, std::set< Hex* >* p_hexlist){
std::vector< Hex* > checklist;
checklist.push_back(p_hex);
Hex* p_checkhex;
Hex* p_adjoinhex[6];
mp_hexlist->ClearHexTmpPoint(99999999);
p_hex->tmp_point = 0;
while (!checklist.empty()){
p_checkhex = checklist.back();
p_checkhex->ReturnAdjoinHex(p_adjoinhex);
for (int n = 0; n < 6; n++){
if (p_adjoinhex[n] == NULL) continue;
if (p_checkhex->tmp_point >= p_adjoinhex[n]->tmp_point) continue;
p_adjoinhex[n]->tmp_point = p_checkhex->tmp_point + 1;
if (p_checkhex->tmp_point < distance){
p_hexlist->insert(p_adjoinhex[n]);
checklist.push_back(p_adjoinhex[n]);
}
}
RemoveFactorOnVector(&checklist, p_checkhex);
}
}
範囲を求めるプログラムをアレンジすれば、移動経路も求められそうな書き方をしていましたが、誤解を与えるといけないので移動経路探査も書いておきます
void HexCalculator::RegisterRoute(Hex* p_hexstart, Hex* p_end, std::vector< Hex* >* p_hexlist,Unit* p_unit){
std::vector< Hex* > checklist;
checklist.push_back(p_hexstart);
Hex* p_checkhex;
Hex* p_adjoinhex[6];
mp_hexlist->ClearHexTmpPoint(99999999);
p_hexstart->tmp_point = 0;
double needmove;
double maxpoint = 99999999;
while (!checklist.empty()){
p_checkhex = checklist.front();
p_checkhex->ReturnAdjoinHex(p_adjoinhex);
for (int n = 0; n < 6; n++){
if (p_adjoinhex[n] == NULL) continue;
needmove = CalcNeedMove(p_adjoinhex[n], p_unit);
if (p_adjoinhex[n]->tmp_point > p_checkhex->tmp_point + needmove && p_checkhex->tmp_point + needmove <= maxpoint){
checklist.push_back(p_adjoinhex[n]);
p_adjoinhex[n]->tmp_point = p_checkhex->tmp_point + needmove;
p_adjoinhex[n]->tmp_route = p_adjoinhex[n];
}
if (p_adjoinhex[n] == p_end){
if(maxpoint > p_adjoinhex[n]->tmp_point){
maxpoint = p_adjoinhex[n]->tmp_point;
}
}
}
RemoveFactorOnVector(&checklist, p_checkhex);
}
p_checkhex = p_end;
while(p_hexstart != p_checkhex) {
p_hexlist->insert(p_hexlist->begin(), p_checkhex);
p_checkhex = p_checkhex->tmp_route;
}
p_hexlist->insert(p_hexlist->begin(), sp_checkhex));
}
さて困りました。
重い。移動経路探査がどうやら重いようです。
これは複数のユニットを選択した状態で、選択したHexへの移動経路を表示している画像です。
1ユニットであればマウスを小刻みに動かしても問題ないのですが、多くのユニットを選択していると移動経路の計算で数十ミリ秒かかります。経路探査は違うHexを選択したときにしか実行しないので、カーソルを小刻みに動かさなければ実害はないと思いますが。
たくさんのユニットを選択した状態でかなり遠距離のHexを探そうとした時とかは、処理落ちしちゃいそうです。
困ったなぁ。
どういうルートを通るのかを移動命令を出す前に見せるようにしないなら問題ないんですが。でもそれだと、思わぬルートを通ってしまうかもしれないし。パラドゲーっぽく移動命令を出した後で移動ルートを決定するのでもいいかなぁ。
処理速度で詰まるのは大変なんですよね。今まであんまりそういう問題抱えてこなかったから対処法が分かりません。
今時のCPUでも重い処理なのかこれ・・・。
画像がおかしくてラインがちゃんと繋がっていないのはおいておくとして、これはユニットに移動目的地を与えた後、移動経路を表示している状態です。
この状態での描画に20ミリ秒程度かかったりします。60FPSだと処理落ち確定。
移動経路画像もHEX画像なんかと同じサイズの画像を用意して、条件に合わせて表示する形なんですが、こういうやり方はよくないのかもしれません。
ただ、そういえば、数十*数十規模のノードを持つゲームで、同時に複数のユニットの移動経路を表示するゲームって見かけないんですよね。
HOIはそこまで遠くのプロヴィンスを選択することがあまりないし、そもそもあれは各ユニットの最短経路を求めていないように思います。あれ、こっち通った方が早く着くんじゃないの? って、個別に選択しなおすことがあるくらいです。
Civ4では同一座標の複数ユニットを選択してる状態で、選択箇所への移動経路を表示することはありますが、各地に散らばっている複数のユニット全部の移動経路を表示する場面はありません。
さらに言えばターン制のゲームならこれらの情報はプレイヤーのターンのときにだけ表示すればいいだけですので、COMのターンになったら重い処理をやめることができます。しかしシムシティみたいに時間が流れている中でプレイヤーが操作をするタイプだと、各フレームでの余り時間でCOMの行動も計算させないといけません。
このゲームの仕様だと、60*60HEXというのは大きすぎるんじゃないかという気がしてきました。
単純なサイズの縮小や、そもそもHEXから離れる事も含めて、いったんゲームデザインを見直そうかと思います。
HEXから離れるとなると戦闘システムを全部考え直さないといけないので、ひとまず製作中断です。
まさか処理速度の壁に阻まれる日が来るとは思ってませんでした。
ゲームの仕様を考え直さないといけないんですが、すぐにはまとまらないので、ちょっとWOTの話でも。
グラボを詰んでいないうちのPCでも特に不自由なく遊べるので、結構長くプレイしています。たぶんアクティブプレイヤー全体の中で、私はちょうど真ん中くらいのプレイヤーじゃないかなぁと思います。
そういうレベルのプレイヤーから、初心者向けにあんまり難しくない意識すべき事柄をまとめてみました。
一応、大部分を流用した形での新しいゲームシステムを考えてはいます。いるんですが、もう一工夫足りない感じで躓いています。
で、タイトルどおりなんですが、今回はWOTのプレイ動画をあげて見ます。昨日、なんかたまたまうまくいった戦闘があったのです。大活躍! ていうのとは違うんですが、敵も味方もNoob過ぎた結果、自分が無双したとかいう戦いよりこういう方が好きだったりします。
前半死にそうな場面がありましたが、あそこで死んでたら負けたと思います。あの状況でよく生き残れたなと。
ちなみに車両の名前に色が着いてますが、これはそのプレイヤーのだいたいの技量を示しています。
赤<橙<黄<緑<青<紫 という感じです。
え? 音がおかしい? 気のせいじゃないですか?
キルミーベイベーは死んだんだ。いくら呼んでも帰ってはこないんだ。
もうあの時間は終わって、君も人生と向き合うときなんだ。
どうしてもうまい具合にまとまらないのがこの部分。
パラドゲー的戦略部分はだいたい据わりのいい形になってるんですが、戦闘処理をどうするかで迷っています。迷いすぎて、別なゲームをちらほら考えてみたりします。
戦略要素と戦闘要素を持つゲームは多々あります。というよりも、戦略要素があれば普通は戦闘要素もあります。
戦闘要素がどういう風になってるかもいろいろあって、
パラドゲー
同一地域にいる戦力同士が勝手に数値処理される。
プレイヤーが介在できるのは、どういう兵科の兵力をいつどこに移動させるか程度。
古い信長の野望(天翔記辺りまで)
部隊をある領地に侵入させると、HEXタイプ(とは限らない)のマップに切り替わり、ユニットを移動させて戦闘させる。
プレイヤーはパラドゲー的要素のほかに、どういう武将を用いるか、駒をどう動かすかを考えることを求められる。
新しい信長の野望(革新辺り)
進軍ルートは決まっているので、だいたい同一地域に敵対勢力が存在すれば、勝手に戦闘が発生する。
プレイヤーは野戦か篭城かの選択と、どんな武将を用いるかを選べる以外は、パラドゲーに近い。
ただし、戦闘に影響する施設を作れるため、タワーディフェンス的要素が追加されている。
天下統一、戦国夢幻
極度に抽象化された会戦場において、単純な指示を出す。
武将の選択は可能だが、駒を動かすという要素はなきに等しい。
TotalWar:Rome
いくつものユニットにリアルタイムで命令を出す。ユニットは原則矩形で表せるが、ユニットに属す各兵士の駒が別個に存在するため、矩形同士の戦闘ではないように見える。
プレイヤーは古い信長の野望的要素のほかに、駒の向きや、包囲攻撃、遠距離攻撃や騎兵突撃などの細かい戦術も求められる。
Mount&Blade
兵士一人ひとりがパラメーターを持ち、別個に命令を出すことが出来る。戦闘自体は3Dアクションであり、超集団戦のSkyrimみたいに見えないこともない。
プレイヤーが出す命令は基本的には集団に対してのものであり、普通は歩兵、弓兵、騎兵毎に分類して命令を出す。陣形を整えたまま戦うという要素にかけているため、SLGとして考える余地はあまりない。
なんかいろいろ出来そうに見えるが、実際のところ天下統一と同じ位にしかプレイヤーの戦術は介入できない(プレイヤー自身が最強の兵士であるため、プレイヤーが敵を殺しまくることはできるが、今回はそういう要素は問題にしていない)。
Author:ウィア
とても地味でマニアックな同人ゲームを作っています