Reconnaître une boîte de clic hexagonale

17

Je travaille sur un jeu qui va impliquer des hexagones haletants .

À l'heure actuelle, j'ai une image hexagonale que j'utilise (tous les côtés sont de la même longueur ... elle s'inscrit dans une image de 50 pixels par 50 pixels).

Je suis un peu nouveau pour C # et vraiment nouveau pour XNA, mais y a-t-il une sorte de méthode facile que je peux appeler plutôt que de faire une instruction alambiquée si basée sur des points et des angles?

te
la source
Voir gamedev.stackexchange.com/questions/6382/… qui implémente la détection des clics hexadécimaux.
Tim Holt du
4
J'ai totalement googlé "hexagones haletants" je me disais, "quel genre d'hexagone est-ce?!" Je suppose que je passe une journée lente.
MichaelHouse
2
Hmm que se passe-t-il si vous cliquez dans le halètement plutôt que dans l'hexagone?
Tim Holt du
1
Selon vos besoins, un simple cercle suffirait si ce n'était que pour une zone de clic. Sinon, vous devrez utiliser un point sur la technique des polygones comme la somme des enroulements ou la somme.
PhilCK
À moins que la carte hexadécimale ne fasse l'objet d'une rotation arbitraire, le point sur le polygone est une surpuissance MAJEURE. Que faites-vous avec une carte de 1000x1000 hexs? Vérifiez tout le monde? RE: Cercles, ils ne fonctionneront pas. Près du sommet de jonction entre trois hexagones, vous aurez trois cercles qui se chevauchent. Les petits cercles qui se trouvent complètement dans les hexagones auront des espaces où les clics légitimes ne seront pas dans aucun cercle.
Tim Holt du

Réponses:

18

Un hexagone est un rectangle avec des coins coupés. La façon dont j'ai vu cela, et j'ai entendu dire que la série Civilization le faisait avec des cartes orthogonales, c'est de créer une bitmap avec un espace blanc (orthogonal ou hexagonal), et un rouge, vert, bleu et jaune coin. (Ou quelles que soient les couleurs que vous aimez.)

Hexagonal: Masque hexagonalouentrez la description de l'image ici

Orthogonal: entrez la description de l'image ici

Ensuite, déterminez simplement le rectangle sur lequel se trouve le curseur et testez la couleur du pixel à cet endroit. S'il est blanc, ils survolent cet espace. Chaque autre couleur est mappée à un décalage et survole cet hexagone à la place. Cette méthode est efficace, prend peu de géométrie et peut être utilisée pour tout espace de pavage arbitraire.

dlras2
la source
Juste une note: Un hexagone a 6 côtés de longueur égale. Aucune des images que vous avez présentées ne contient réellement d'hexagones. Au lieu de cela, ils contiennent des polygones à 6 côtés. En dehors de cela, cette méthode fonctionne. Il est probablement plus lent que de calculer les limites de l'hexagone, cependant pour les hexagones plus grands, car cette méthode nécessite plus d'espace pour les hexagones plus grands (si vous souhaitez conserver une précision par pixel). Pour les petits hexagones (et selon le matériel), cette méthode est probablement plus rapide que le calcul des limites.
Olhovsky
9
Un hexagone est un polygone à 6 faces. Ce à quoi vous pensez est un hexagone équilatéral (en fait, vous pensez probablement à un hexagone régulier , qui est un type d' hexagone équilatéral et équiangulaire)
Random832
Veuillez noter que je ne disais pas que votre réponse était mauvaise. Je pense que c'est une bonne réponse et une solution qui a sa place. Cela dit, je ne choisirais pas cette méthode plutôt que de calculer les limites de l'hexagone, car le calcul des limites de l'hexagone sur n'importe quelle plate-forme moderne, car le calcul des limites est une façon beaucoup plus extensible de le faire. Par exemple, disons que vous voulez changer la taille de l'hexagone - maintenant vous devez reconstruire l'image? Produire un masque hexagonal parfait pixel est une douleur. Le fait que vous n'en ayez pas produit ici en est un témoignage, je pense.
Olhovsky
2
@Olhovsky - Je n'ai pas produit un masque hexagonal parfait ici parce que je réponds aux questions en tant que service communautaire pendant mes quelques minutes de pause au travail, et que je n'écris pas réellement de jeu vidéo. L'OP cherchait une solution avec moins de mathématiques, et j'ai pensé que c'était bien, alors j'ai pensé partager, parce que c'est quelque chose auquel je n'aurais certainement pas pensé tout seul.
dlras2
18

Il n'y a pas de méthode XNA qui effectue un test de hit hexagonal.

Cet article explique comment écrire une fonction qui effectue le test et vous donne la fonction:

Comment vérifier si un point est à l'intérieur d'un hexagone

Voici un résumé de cet article: boîte de clic hexagone

Et la fonction qui fait le test se présente comme suit:

  1. Testez la boîte englobante autour de l'hexagone, tôt si elle ne l'intersecte pas.
  2. Transformez le point en un quadrant local comme indiqué ci-dessus.
  3. Effectuez le isInsidetest suivant pour le quadrant 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;
}

Voir l'article pour plus de détails.


Voici quelques autres sources utiles utiles:

Olhovsky
la source
1

Ici, j'ai une méthode qui peut être utilisée pour détecter les clics à l'intérieur de n'importe quel polygone:

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;
    }

Vous devez donner les coins de votre hexagone dans un tableau vector2 (poly) et la position cliquée (p) à la méthode.

chr1s1202
la source