私は、RTSゲーム(実際にはある種のゲームエンジンのデモ)を作成しました。このゲームでは、ユーザーがゲームで行う基本的な操作は、兵士の束を選択し、マップを右クリックして、指定された場所に移動します。これはJavaScriptであり、ここ(コード)で遊ぶことができます。
兵士が現在の場所から目的地にどのように移動するかという問題を無視して、私の質問は彼らの実際の目的地が何であるかを決定することについてです。これが私がこれまでに試したことです:
- 試行1:選択したすべての兵士に、マウスをクリックした座標に移動するように伝えます。これは奇妙な振る舞いで、すべての兵士が不自然にターゲットの周りに集まります。
- 試行2:選択されたすべての兵士の平均座標を見つけ、各兵士のその中心点からのオフセットを見つけ、最後にそのオフセットをマウス座標の周りに変換します。これは、選択した兵士が離れている場合、ターゲットに近づかないことを除いて、正常に機能します。
- 試行3:マウス座標の周りにグリッドを作成し、選択した各兵士をグリッドのセルに配置します。各兵士が割り当てられたセルに到達すると、これはうまく機能します。ただし、グリッドセルには兵士が生成された順序で割り当てられるため、衝突する場合があります(つまり、右側のすべての兵士が左側に移動しようとします)。これは不自然に見えます。
- 試行4:以前と同じようにグリッドを使用しますが、最初に兵士を場所別に並べ替えて、それらが適切に並ぶようにします。つまり、グループの下をクリックした場合、グループの最下部の兵士は、グリッドの最下部に配置されます。彼らの目的地に到達します。これはかなりうまく機能しますが、不具合が時々あり、その理由はわかりません。
次に、宛先座標を決定する関数を示します。
function moveSelectedSoldiersToMouse() {
var w = 0, h = 0, selected = [];
// Get information about the selected soldiers.
myTeam.soldiers.forEach(function(soldier) {
if (soldier.selected) {
selected.push(soldier);
w += soldier.width;
h += soldier.height;
}
});
var numSelected = selected.length, k = -1;
if (!numSelected) return;
// Build a grid of evenly spaced soldiers.
var sqrt = Math.sqrt(numSelected),
rows = Math.ceil(sqrt),
cols = Math.ceil(sqrt),
x = Mouse.Coords.worldX(),
y = Mouse.Coords.worldY(),
iw = Math.ceil(w / numSelected), // grid cell width
ih = Math.ceil(h / numSelected), // grid cell height
wg = iw*1.2, // width of gap between cells
hg = ih*1.2; // height of gap between cells
if ((rows-1)*cols >= numSelected) rows--;
w = iw * cols + wg * (cols-1); // total width of group
h = ih * rows + hg * (rows-1); // total height of group
// Sort by location to avoid soldiers getting in each others' way.
selected.sort(function(a, b) {
// Round to 10's digit; specific locations can be off by a pixel or so
var ax = a.x.round(-1), ay = a.y.round(-1), bx = b.x.round(-1), by = b.y.round(-1);
return ay - by || ax - bx;
});
// Place the grid over the mouse and send soldiers there.
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var s = selected[++k];
if (s) {
var mx = x + j * (iw+wg) - w * 0.5 + s.width * 0.5,
my = y + i * (ih+hg) - h * 0.5 + s.height * 0.5;
// Finally, move to the end destination coordinates
s.moveTo(mx, my);
}
}
}
}
デモを表示しているときにこの関数をブラウザーのJavaScriptコンソールに貼り付けて、兵士の行動を変更することができます。
私の質問は、次のとおりです。各兵士が移動するターゲットの場所を決定するより良い方法はありますか?