Pregunta

¿Cuál es la forma correcta de llamar la azulejos isométricos en un juego en 2D?

referencias

He leído (por ejemplo, éste ) que sugieren las baldosas se hizo en una manera que zig-zag cada columna en la matriz de representación 2D del mapa. Me imagino que deben extraerse más de una forma de diamante, donde lo que se ve arrastrado a la pantalla se relaciona más estrechamente con lo que la matriz 2D se vería así, simplemente girar un poco.

¿Hay ventajas o desventajas de ambos métodos?

¿Fue útil?

Solución

Actualización:. Corregido algoritmo de mapa de representación, añadido más ilustraciones, cambiado el formateo

Tal vez la ventaja de la técnica de "zig-zag" para la asignación de los azulejos a la pantalla se puede decir que x y y coordenadas del azulejo están en los ejes vertical y horizontal.

"El dibujo en un diamante" enfoque:

Al dibujar un mapa isométrica utilizando "dibujo en un diamante", que creo que se refiere a simplemente haciendo que el mapa utilizando un for-bucle anidado sobre la matriz de dos dimensiones, tales como este ejemplo:

tile_map[][] = [[...],...]

for (cellY = 0; cellY < tile_map.size; cellY++):
    for (cellX = 0; cellX < tile_map[cellY].size cellX++):
        draw(
            tile_map[cellX][cellY],
            screenX = (cellX * tile_width  / 2) + (cellY * tile_width  / 2)
            screenY = (cellY * tile_height / 2) - (cellX * tile_height / 2)
        )

Ventaja:

La ventaja de este enfoque es que se trata de un simple for-bucle anidado con la lógica bastante sencillo que funciona constantemente a través de todas las baldosas.

Desventaja:

Una desventaja de este enfoque es que los x y y coordenadas de los azulejos en el mapa aumentarán en líneas diagonales, lo que podría hacer más difícil para mapear visualmente la ubicación en la pantalla al mapa representado como una matriz:

 imagen de la baldosa del mapa

Sin embargo, no va a ser un escollo a la ejecución de lo anterior código de ejemplo - el orden de representación hará que los azulejos que se supone deben estar detrás de algunos azulejos que se extrae en la parte superior de las baldosas delante:

 resultante imagen de orden de procesamiento incorrecto

Con el fin de modificar este problema, para el interior de for-loop debe invertirse - a partir del valor más alto, y de la representación hacia el valor inferior:

tile_map[][] = [[...],...]

for (i = 0; i < tile_map.size; i++):
    for (j = tile_map[i].size; j >= 0; j--):  // Changed loop condition here.
        draw(
            tile_map[i][j],
            x = (j * tile_width / 2) + (i * tile_width / 2)
            y = (i * tile_height / 2) - (j * tile_height / 2)
        )

Con la corrección anterior, la prestación del mapa debe ser corregido:

 resultante imagen de orden de representación correcta

"zig-zag" enfoque:

Ventaja:

Tal vez la ventaja del enfoque de "zig-zag" es que el mapa generada podría parecer un poco más vertical compacto que el enfoque de "diamante":

 zig-zag a la representación parece compacta

Desventaja:

De tratando de implementar la técnica en zig-zag, la desventaja puede ser que sea un poco más difícil que escribir el código de representación, ya que no se puede escribir tan simple como un for-bucle anidado sobre cada elemento de una matriz:

tile_map[][] = [[...],...]

for (i = 0; i < tile_map.size; i++):
    if i is odd:
        offset_x = tile_width / 2
    else:
        offset_x = 0

    for (j = 0; j < tile_map[i].size; j++):
        draw(
            tile_map[i][j],
            x = (j * tile_width) + offset_x,
            y = i * tile_height / 2
        )

Además, puede ser un poco difícil de tratar de averiguar las coordenadas de una baldosa debido a la naturaleza escalonada del orden de representación:

 de coordenadas sobre una representación orden en zig-zag

Nota: Las ilustraciones incluidas en esta respuesta fueron creados con una aplicación de Java del código baldosas de representación presentada, con la siguiente matriz int como el mapa:

tileMap = new int[][] {
    {0, 1, 2, 3},
    {3, 2, 1, 0},
    {0, 0, 1, 1},
    {2, 2, 3, 3}
};

Las imágenes de mosaicos son:

  • tileImage[0] -> Una caja con una caja interior.
  • tileImage[1] -> un cuadro negro.
  • tileImage[2] -> un cuadro blanco.
  • tileImage[3] -> Una caja con un objeto gris de altura en ella.

Nota sobre anchos y alturas Azulejos

El tile_width las variables y tile_height que se utilizan en los ejemplos de código anteriores se refieren a la anchura y altura de la baldosa del suelo en la imagen que representa la baldosa:

Imagen que muestra la anchura del azulejo y la altura

El uso de las dimensiones de la imagen va a funcionar, siempre y cuando las dimensiones de imagen y el partido dimensiones de las baldosas. De lo contrario, el mapa del azulejo podría traducirse con espacios entre las baldosas.

Otros consejos

De cualquier manera hace el trabajo. Asumo que por zigzag que quiere decir algo como esto: (los números son el fin de la prestación)

..  ..  01  ..  ..
  ..  06  02  ..
..  11  07  03  ..
  16  12  08  04
21  17  13  09  05
  22  18  14  10
..  23  19  15  ..
  ..  24  20  ..
..  ..  25  ..  ..

Y por el diamante decir:

..  ..  ..  ..  ..
  01  02  03  04
..  05  06  07  ..
  08  09  10  11
..  12  13  14  ..
  15  16  17  18
..  19  20  21  ..
  22  23  24  25
..  ..  ..  ..  ..

El primer método necesita más fichas prestados de manera que la pantalla se dibuja, pero se puede hacer fácilmente una comprobación de límites y saltar todas las baldosas totalmente fuera de la pantalla. Ambos métodos requieren algún cálculo de números para averiguar cuál es la ubicación de la baldosa 01. Al final, ambos métodos son más o menos iguales en términos de matemáticas requerida para un cierto nivel de eficiencia.

Si usted tiene algunas baldosas que superan los límites de su diamante, recomiendo el dibujo con el fin de profundidad:

...1...
..234..
.56789.
..abc..
...d...

La respuesta de Coobird es la correcta, uno completo. Sin embargo, he combinado sus consejos con los de otro sitio para crear código que funciona en mi aplicación (iOS / Objective-C), que quería compartir con cualquier persona que viene aquí en busca de una cosa así. Por favor, si te gusta / up-voto esta respuesta, hacer lo mismo con los originales; todo lo que hice fue "A hombros de gigantes".

En cuanto a tipo de orden, mi técnica es el algoritmo de un pintor modificación: cada objeto tiene (a) una altitud de la base (I llamar "nivel") y (b) un X / Y para la "base" o " pie" de la imagen (ejemplos: la base del avatar es a sus pies; la base del árbol se encuentra en sus raíces; la base del avión es el centro de la imagen, etc.) entonces sólo una especie más bajo a más alto nivel, entonces bajo (más alto en la pantalla) a más alta de base-Y, a continuación, más bajo (más a la izquierda) a la más alta de base-X. Esto hace que las baldosas de la manera que uno esperaría.

El código para la pantalla (punto) para la baldosa (celular) convertir y atrás:

typedef struct ASIntCell {  // like CGPoint, but with int-s vice float-s
    int x;
    int y;
} ASIntCell;

// Cell-math helper here:
//      http://gamedevelopment.tutsplus.com/tutorials/creating-isometric-worlds-a-primer-for-game-developers--gamedev-6511
// Although we had to rotate the coordinates because...
// X increases NE (not SE)
// Y increases SE (not SW)
+ (ASIntCell) cellForPoint: (CGPoint) point
{
    const float halfHeight = rfcRowHeight / 2.;

    ASIntCell cell;
    cell.x = ((point.x / rfcColWidth) - ((point.y - halfHeight) / rfcRowHeight));
    cell.y = ((point.x / rfcColWidth) + ((point.y + halfHeight) / rfcRowHeight));

    return cell;
}


// Cell-math helper here:
//      http://stackoverflow.com/questions/892811/drawing-isometric-game-worlds/893063
// X increases NE,
// Y increases SE
+ (CGPoint) centerForCell: (ASIntCell) cell
{
    CGPoint result;

    result.x = (cell.x * rfcColWidth  / 2) + (cell.y * rfcColWidth  / 2);
    result.y = (cell.y * rfcRowHeight / 2) - (cell.x * rfcRowHeight / 2);

    return result;
}

El problema real es cuando se necesita sacar algunas baldosas / sprites intersección / que abarca dos o más piezas.

Después de 2 meses (duros) de analisis personales del problema que finalmente encontró e implementado una "correcta render dibujo" para mi nuevo juego cocos2d-js. Solución consiste en el mapeo, para cada baldosa (susceptible), que son los sprites "delante, detrás, arriba y atrás". Una vez que se puede hacer atraerlos a raíz de una "lógica recursiva".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top