Reconociendo un clickbox hexagonal

17

Estoy trabajando en un juego que involucrará hexágonos de jadeo .

En este momento, tengo una imagen hexagonal que estoy usando (todos los lados tienen la misma longitud ... encaja en una imagen de 50 px por 50 px).

Soy algo nuevo en C # y realmente nuevo en XNA, pero ¿hay algún tipo de método fácil al que pueda llamar en lugar de hacer una declaración enrevesada basada en puntos y ángulos?

El e
fuente
Vea gamedev.stackexchange.com/questions/6382/… que implementa la detección de clics hexadecimales.
Tim Holt
44
Busqué en Google "hexágonos jadeantes", pensé, "¿qué tipo de hexágono es ese?" Supongo que estoy teniendo un día lento.
MichaelHouse
2
¿Qué pasa si haces clic en el jadeo en lugar de en el hexágono?
Tim Holt
1
Dependiendo de sus necesidades, un círculo simple sería suficiente para un área de clic. De lo contrario, tendrá que usar un punto en la técnica de polígono, como la suma de bobinado o la suma.
PhilCK
A menos que el mapa hexadecimal se rote arbitrariamente, el punto en el polígono es MAYOR exageración. ¿Qué haces con un mapa que tiene 1000x1000 hexes? ¿Verifica cada uno? RE: Círculos, no funcionarán. Cerca del vértice de la unión entre tres hexes, tendrás tres círculos superpuestos. Los círculos más pequeños que se encuentran completamente dentro de los hexes tendrán huecos donde los clics legítimos no estarán en ningún círculo.
Tim Holt

Respuestas:

18

Un hexágono es un rectángulo con esquinas recortadas. La forma en que he visto esto, y he escuchado que la serie Civilization lo hace de esta manera con mapas ortogonales, es crear un mapa de bits con un espacio en blanco (ortogonal o hexagonal) y rojo, verde, azul y amarillo. esquina. (O los colores que quieras)

Hexagonal: Máscara hexagonaloingrese la descripción de la imagen aquí

Ortogonal: ingrese la descripción de la imagen aquí

Luego, solo determina en qué rectángulo está el cursor y prueba el color del píxel en esa ubicación. Si es blanco, están flotando sobre ese espacio. Cada otro color se asigna a un desplazamiento, y en su lugar se ciernen sobre ese hexágono. Esta manera es eficiente, requiere poca geometría y puede usarse para cualquier espacio de teselado arbitrario.

dlras2
fuente
Solo una nota: un hexágono tiene 6 lados de igual longitud. Ninguna de las imágenes que presentó contiene hexágonos. En cambio, contienen polígonos de 6 lados. Aparte de eso, este método funciona. Sin embargo, es probable que sea más lento que calcular los límites del hexágono para hexágonos más grandes, ya que este método requiere más espacio para hexágonos más grandes (si desea mantener la precisión por píxel). Para hexágonos pequeños (y dependiendo del hardware), este método es probablemente más rápido que calcular los límites.
Olhovsky
9
Un hexágono es cualquier polígono de 6 lados. Lo que usted está pensando en una equilátero hexagonal (de hecho, es probable que pensar en una regular de hexágono, que es un tipo de equilátero y el hexágono equiangular)
Random832
Tenga en cuenta que no estaba diciendo que su respuesta fuera mala. Creo que es una buena respuesta y una solución que tiene su lugar. Dicho esto, no elegiría este método en lugar de calcular los límites del hexágono, ya que calcular los límites del hexágono en cualquier plataforma moderna, ya que calcular los límites es una forma mucho más extensible de hacerlo. Por ejemplo, supongamos que desea cambiar el tamaño del hexágono, ¿ahora tiene que reconstruir la imagen? Producir una máscara hexagonal perfecta de píxeles es un dolor. El hecho de que no hayas producido uno aquí es un testimonio de eso, creo.
Olhovsky
2
@Olhovsky: no he producido una máscara hexagonal perfecta aquí porque estoy respondiendo preguntas como un servicio comunitario durante mis pocos minutos de descanso en el trabajo, y en realidad no estoy escribiendo un videojuego. El OP estaba buscando una solución con menos matemáticas, y pensé que esto estaba bien, así que pensé en compartir, porque es algo que ciertamente no habría pensado por mi cuenta.
dlras2
18

No hay un método XNA que haga una prueba de golpe hexagonal

Este artículo explica cómo escribir una función que realiza la prueba y le brinda la función:

Cómo verificar si un punto está dentro de un hexágono

Aquí hay un resumen de ese artículo: cuadro de clic hexagonal

Y la función que realiza la prueba es la siguiente:

  1. Pruebe el cuadro delimitador alrededor del hexágono, temprano si no se cruza.
  2. Transforme el punto en un cuadrante local como se muestra arriba.
  3. Realice la siguiente isInsideprueba para el cuadrante local.

public function isInside(pos:Vec2Const):Boolean
{
    const q2x:Number = Math.abs(pos.x - _center.x);       
    const q2y:Number = Math.abs(pos.y - _center.y);
    if (q2x > _hori || q2y > _vert*2) 
        return false;
    return 2 * _vert * _hori - _vert * q2x - _hori * q2y >= 0;
}

Vea el artículo para más detalles.


Aquí hay algunas otras fuentes relacionadas útiles:

Olhovsky
fuente
1

Aquí obtuve un método que puede usarse para detectar clics dentro de cualquier polígono:

public bool PointInPolygon( Vector2 p, Vector2[] poly )
    {
        Vector2 p1, p2;
        bool inside = false;

        if( poly.Length < 3 )
        {
            return inside;
        }

        Vector2 oldPoint = new Vector2( poly[poly.Length - 1].X, poly[poly.Length - 1].Y );

        for( int i = 0; i < poly.Length; i++ )
        {
            Vector2 newPoint = new Vector2( poly[i].X, poly[i].Y );

            if( newPoint.X > oldPoint.X )
            {
                p1 = oldPoint;
                p2 = newPoint;
            }
            else
            {
                p1 = newPoint;
                p2 = oldPoint;
            }

            if( ( newPoint.X < p.X ) == ( p.X <= oldPoint.X )
                && ( (long)p.Y - (long)p1.Y ) * (long)( p2.X - p1.X )
                 < ( (long)p2.Y - (long)p1.Y ) * (long)( p.X - p1.X ) )
            {
                inside = !inside;
            }

            oldPoint = newPoint;
        }

        return inside;
    }

Debe dar las esquinas de su hexágono en una matriz vector2 (poli) y la posición en la que se hizo clic (p) para el método.

chr1s1202
fuente