Ich habe ein RTS-Spiel geschrieben (eigentlich eine Demo für eine Art Spiel-Engine), in dem der Benutzer in erster Linie mit dem Spiel interagiert und dann mit der rechten Maustaste auf die Karte klickt, um sie an den angegebenen Ort zu verschieben. Dies ist in JavaScript und man kann mit ihr spielen hier ( Code ).
Ich ignoriere das Problem, wie sich die Soldaten von ihrem aktuellen Standort zu ihrem Ziel bewegen, und frage mich, wie ihr tatsächliches Ziel lautet. Folgendes habe ich bisher versucht:
- Versuch 1: Weisen Sie alle ausgewählten Soldaten an, sich zu den Koordinaten zu bewegen, auf die die Maus geklickt hat. Dies hat das seltsame Verhalten, dass sich dann alle Soldaten unnatürlich um das Ziel sammeln.
- Versuch 2: Ermitteln Sie die Durchschnittskoordinaten aller ausgewählten Soldaten, ermitteln Sie dann den Versatz von diesem Mittelpunkt für jeden Soldaten und übersetzen Sie diesen Versatz schließlich um die Mauskoordinaten. Dies funktioniert gut, außer dass Ihre ausgewählten Soldaten, wenn sie weit voneinander entfernt sind, nicht in die Nähe des Ziels gelangen.
- Versuch 3: Erstellen Sie ein Raster um die Mauskoordinaten und platzieren Sie jeden ausgewählten Soldaten in einer Zelle des Rasters. Wenn jeder Soldat es in die ihm zugewiesene Zelle schafft, funktioniert dies hervorragend. Soldaten werden jedoch in der Reihenfolge, in der die Soldaten erzeugt wurden, Gitterzellen zugewiesen, sodass sie manchmal kollidieren (dh alle Soldaten auf der rechten Seite versuchen, auf die linke Seite zu gelangen), was unnatürlich aussieht.
- Versuch 4: Verwenden Sie ein Gitter wie zuvor, aber sortieren Sie die Soldaten zuerst nach Ort, so dass sie sich sinnvoll ausrichten. Wenn Sie also unter die Gruppe geklickt haben, landen die Soldaten am unteren Rand der Gruppe am unteren Rand des Gitters ihr Ziel erreichen. Das funktioniert ziemlich gut, aber manchmal gibt es Pannen und ich bin mir nicht sicher warum.
Hier ist die Funktion, die die Zielkoordinaten bestimmt:
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);
}
}
}
}
Sie können diese Funktion in die JavaScript-Konsole Ihres Browsers einfügen, wenn Sie die Demo anzeigen, und damit herumspielen, um das Verhalten der Soldaten zu ändern.
Meine Frage ist: Gibt es eine bessere Möglichkeit, den Zielort für jeden Soldaten zu bestimmen?