He escrito un juego de estrategia en tiempo real (una demostración para una especie de motor de juego, en realidad) en el que la interacción básica del usuario con el juego es seleccionar un grupo de soldados y luego hacer clic derecho en el mapa para moverlos a la ubicación especificada. Esto está en JavaScript y puedes jugar con él aquí ( código ).
Ignorando el problema de cómo se mueven los soldados desde su ubicación actual hasta su destino, mi pregunta es sobre determinar cuál es su destino real. Esto es lo que he probado hasta ahora:
- Intento 1: Indique a todos los soldados seleccionados que se muevan a las coordenadas en las que hizo clic el mouse. Esto tiene el extraño comportamiento de que todos los soldados se agruparán alrededor del objetivo de forma antinatural.
- Intento 2: Encuentre las coordenadas promedio de todos los soldados seleccionados, luego encuentre el desplazamiento desde ese punto central para cada soldado, y finalmente traduzca ese desplazamiento alrededor de las coordenadas del mouse. Esto funciona bien, excepto que si los soldados seleccionados están muy separados, no se acercarán al objetivo.
- Intento 3: Construya una cuadrícula alrededor de las coordenadas del mouse y coloque a cada soldado seleccionado en una celda de la cuadrícula. Si cada soldado llega a su celda asignada, esto funciona muy bien. Sin embargo, los soldados se asignan a las celdas de la cuadrícula en el orden en que se generaron los soldados, por lo que a veces chocan (es decir, todos los soldados en el lado derecho intentarán ir al lado izquierdo), lo que parece antinatural.
- Intento 4: use una cuadrícula como antes, pero primero ordene a los soldados por ubicación para que se alineen con sensatez, es decir, si hizo clic debajo del grupo, los soldados en la parte inferior del grupo terminarán en la parte inferior de la cuadrícula cuando llegar a su destino Esto funciona bastante bien, pero a veces hay fallas y no estoy seguro de por qué.
Aquí está la función que determina las coordenadas de destino:
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);
}
}
}
}
Puede pegar esta función en la consola de JavaScript de su navegador al ver la demostración y jugar con ella para cambiar el comportamiento de los soldados.
Mi pregunta es: ¿hay una mejor manera de determinar la ubicación del objetivo para que se mueva cada soldado?
fuente
Respuestas:
Aquí están mis sugerencias sobre sus ideas:
Intento 1: para solucionar esta situación, podría implementar la idea "lo suficientemente cercana" que planteó Spencer. Haría algo como dibujar una burbuja alrededor del punto final, que crece en función de una proporción del número y el tamaño de las unidades que ya están en él. Digamos que la burbuja comienza el tamaño de una unidad, luego, cuando llega la primera, el radio se duplica para las siguientes dos unidades, etc.
Intento 2: una solución para esto sería tomar la distancia promedio del grupo entre sí, luego reducir la distancia de los valores atípicos a eso, para que el grupo termine más agrupado de lo que originalmente eran (la métrica podría ser más corta / más largo que el promedio, lo que sea que lo haga parecer decente, o posiblemente establezca un tamaño de formulario máximo basado en el número / tamaño de tropas nuevamente) Lo único por lo que tendrá que preocuparse es cuando altera el camino de un valor atípico, usted ' tendría que verificar y asegurarse de que no interfiera con los otros caminos
Intento 3: Has mejorado este en el intento 4
Intento 4: Suena como si este funcionara bien si encuentras cualquier problema que lo esté descartando. Sin embargo, recomendaría jugar con spahes que no sean solo una formación de cuadrícula, para que el movimiento se vea un poco más natural, a menos que vaya por un realismo / estilo militar, en cuyo caso podría ser bueno tenerlos "formados "antes de moverse, pero eso podría ser molesto para el jugador después de un tiempo.
El intento 4 parece ser el más cercano a eliminar el comportamiento de fresado en su problema, pero en términos de mantener el movimiento fluyendo sin ningún ajuste que no sea necesario, mi favorito probablemente sería el intento 2.
Pero como una solución completamente diferente, puede tener dos tipos de objetos cuando se trata de encontrar rutas; cada unidad, así como un objeto invisible "escuadrón".
Escuadrón: construyes el objeto del escuadrón en el centro del grupo, como las otras soluciones, y usas tu búsqueda de ruta para dirigirlo hacia el objetivo.
Unidades: las unidades ignoran el objetivo por completo y, en su lugar, utilizan la búsqueda de ruta para mantenerse dentro de una cierta distancia (o formación, o cualquier otra métrica que haga que el movimiento se vea mejor) del objeto del escuadrón.
Esto separa los diferentes aspectos de la búsqueda de rutas y le permite ajustar cualquiera de los lados de forma aislada para tener más control sobre cómo se ve.
fuente
El intento 3 podría funcionar, pero necesita un poco de refinamiento.
Piensa en el concepto de formación (tu grilla es un comienzo). Una formación debe tener una ubicación (es decir, las coordenadas del clic o el soldado / edificio objetivo) y una rotación (esto podría ser fijo, aleatorio o determinista). La formación debe tener el mismo número de posiciones que el número de soldados seleccionados.
Un ejemplo simple de formación puede ser un círculo alrededor del objetivo. Espacie las posiciones equitativamente alrededor y aumente el radio del círculo para adaptarse a todos los soldados sin chocar.
El siguiente problema es decidir qué soldado camina a qué posición en la formación. Una solución simple podría ser hacer que cada soldado se mueva a la posición más cercana a él. Si ese ya está 'elegido' por otro soldado, toma la siguiente posición más cercana, etc.
Las formaciones pueden volverse bastante interesantes. A continuación se muestra una imagen de la 'formación de cuerno de toro' utilizada con gran éxito por Shaka the Zulu . (La imagen proviene de TotalWar Formation Mod )
fuente
Al hacer clic en el usuario, dibuje un vector de cada soldado en la ubicación en la que se hizo clic. Obtenga el ángulo de vector promedio de los vectores dibujados para cada soldado y mueva a cada soldado la longitud de su vector individual en esa dirección con el mismo ángulo. Esto debería dar la apariencia de que las unidades se mueven en formación hasta el punto y deben evitar que las unidades se agrupen.
Si desea que las unidades salgan de la formación, puede apuntar el ángulo de cada soldado directamente a la ubicación en la que se hizo clic. Sin embargo, sin colisión, las unidades comenzarán a converger. Para contrarrestar esto, agregue la colisión y obligue a las unidades a dejar de moverse una vez que estén "lo suficientemente cerca" del punto en el que se hizo clic. Las primeras unidades que lleguen estarán exactamente en el punto y las últimas en llegar deberán dirigirse a dejar de moverse una vez que estén lo suficientemente cerca o haya pasado un cierto tiempo.
Puede calcular la longitud de la ruta y la velocidad de la unidad para determinar cuándo debe llegar una sola unidad y luego forzar a la unidad a dejar de moverse si excede ese tiempo en una cierta cantidad. Tendrás que jugar un poco con ese número.
fuente