J'ai écrit un jeu RTS (une démo pour un moteur de jeu en quelque sorte) dans lequel l'interaction de base de l'utilisateur avec le jeu consiste à sélectionner un groupe de soldats, puis à cliquer avec le bouton droit sur la carte pour les déplacer vers l'emplacement spécifié. C'est en JavaScript et vous pouvez jouer avec ici ( code ).
Ignorant le problème de la façon dont les soldats se déplacent de leur emplacement actuel vers leur destination, ma question est de déterminer quelle est leur destination réelle. Voici ce que j'ai essayé jusqu'à présent:
- Tentative 1: dites à tous les soldats sélectionnés de se déplacer vers les coordonnées sur lesquelles la souris a cliqué. Cela a le comportement étrange que tous les soldats iront ensuite autour de la cible de manière anormale.
- Tentative 2: Trouvez les coordonnées moyennes de tous les soldats sélectionnés, puis trouvez le décalage à partir de ce point central pour chaque soldat, et enfin traduisez ce décalage autour des coordonnées de la souris. Cela fonctionne très bien, sauf que si vos soldats sélectionnés sont très éloignés, ils ne se rapprocheront pas de la cible.
- Tentative 3: Construisez une grille autour des coordonnées de la souris et placez chaque soldat sélectionné dans une cellule de la grille. Si chaque soldat arrive dans sa cellule assignée, cela fonctionne très bien. Cependant, les soldats sont affectés à des cellules de la grille dans l'ordre de leur apparition, donc parfois ils entrent en collision (c'est-à-dire que tous les soldats du côté droit essaieront d'aller vers le côté gauche), ce qui ne semble pas naturel.
- Tentative 4: utilisez une grille comme précédemment, mais triez d'abord les soldats par emplacement de manière à ce qu'ils s'alignent de manière sensible, c'est-à-dire que si vous avez cliqué en dessous du groupe, les soldats en bas du groupe se retrouveront au bas de la grille lorsqu'ils atteindre leur destination. Cela fonctionne plutôt bien, mais il y a parfois des problèmes et je ne sais pas pourquoi.
Voici la fonction qui détermine les coordonnées de destination:
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);
}
}
}
}
Vous pouvez coller cette fonction dans la console JavaScript de votre navigateur lors de la visualisation de la démo et jouer avec elle pour changer le comportement des soldats.
Ma question est la suivante: existe-t-il une meilleure façon de déterminer l'emplacement cible de chaque soldat vers lequel se déplacer?