Clone PyGame QIX, zones de remplissage


8

Je joue avec PyGame.

Maintenant, j'essaie d'implémenter un clone QIX .

J'ai ma boucle de jeu et je peux déplacer le joueur (curseur) sur l'écran.

Dans QIX, le mouvement du joueur laisse une trace (queue) sur l'écran, créant une polyligne.

Si la polyligne avec les limites de l'écran crée un polygone, la zone est remplie.

Comment puis-je accomplir ce comportement?

Comment stocker la queue en mémoire?

Comment détecter quand il construit une forme fermée qui doit être remplie?

Je n'ai pas besoin d'une solution de travail exacte, certains pointeurs, les noms d'algo seraient cool.

entrez la description de l'image ici

Au début, il n'y a que la bordure grise, où le joueur peut déplacer son curseur.

  • Premier scénario:

L'utilisateur déplace son curseur du point A au point B, en traçant la multiligne rouge jusqu'au point C.À ce stade, en raison du franchissement de la frontière, le point A doit être automatiquement connecté au point C, créant un polygone, qui doit être rempli ( ce truc orange sur mon dessin). Remplir le polygone est sacrément simple dans PyGame, car je fournis la séquence de points, et PyGame se soucie du reste.

  • Deuxième scénario:

L'utilisateur se déplace sur la bordure jusqu'au point D, d'où il trace une ligne vers le point E. Parce qu'il traverse la ligne du polygone précédent, et avec ses lignes et la bordure, un autre polygone peut être créé, il doit également être rempli. (le vert).

  • Troisième scénario:

Le joueur se déplace plus loin sur le polygone (il peut se déplacer sur les lignes de polygones existantes) et trace une ligne du point G au point F. Là encore, en raison de la bordure et des lignes existantes, un autre polygone doit être rempli (le bleu) .


Peut-être qu'il y a des réponses ici (question similaire): gamedev.stackexchange.com/questions/26377/…
tigrou

Merci, mais le lien montre des cas d'utilisation primitifs. J'ai mis à jour ma question, alors peut-être que c'est plus clair ce que j'essaie d'accomplir
astropanic

Réponses:


5

Voici comment je l'aborderais:

  1. Il y a toujours une seule zone ouverte, représentée par un polygone. Tous les autres domaines ne sont pas pertinents.
  2. Une ligne commence lorsque vous vous déplacez du périmètre du polygone vers l'intérieur du polygone.
  3. Une ligne s'arrête lorsque vous revenez de l'intérieur du polygone sur le périmètre.
  4. Lorsque vous arrêtez la ligne, vous avez divisé le polygone en deux polygones.
  5. Vous décidez ensuite lequel des deux polygones remplir et lequel conserver comme zone ouverte. À Qix, le côté où se trouvait le Qix (ennemi) est resté ouvert et l'autre côté a été rempli.

Comment subdivisez-vous le polygone? Vous utilisez les extrémités de votre ligne pour diviser le périmètre du polygone en deux sections, puis utilisez la nouvelle ligne pour terminer ces deux sections en nouveaux polygones.

Par exemple, supposons que votre zone ouverte soit un polygone avec des points [p0, p1, p2, p3, p4, p5]. Votre point de départ se Aproduit entre p1et p2, et votre point de fin se Bproduit entre p3et p4. La nouvelle ligne qui a été tracée est [A, s, t, u, v, B]. Nous avons d'abord divisé le polygone en deux segments [A, p2, p3, B]et [B, p4, p5, p0, p1, A]. Ces deux segments forment ensemble le polygone d'origine. Ensuite, nous collons la nouvelle ligne dans chacun (une fois en avant, une fois en arrière), formant [A, p2, p3, B, v, u, t, s]et [B, p4, p5, p0, p1, A, s, t, u, v]. Vous remplissez l'un de ces polygones et conservez l'autre comme nouvelle zone ouverte.

Je n'ai pas implémenté cela et je ne sais pas avec certitude si cela fonctionnera, mais c'est l'approche que j'utiliserais: la subdivision des polygones au lieu du remplissage des polygones.


1

Il s'agit d'un problème impliquant plusieurs sous-étapes discrètes. Voici un aperçu de ce que je suggérerais:

  • Attendez que le joueur forme une intersection de plusieurs lignes
  • Obtenez un pixel de chaque côté de l'intersection
  • Pathfind pour voir s'ils peuvent se connecter les uns aux autres
  • Les pixels qui ne peuvent pas se connecter les uns aux autres sont des zones distinctes
  • Effectuez un remplissage pour obtenir tous les pixels de la zone

Je stockerais l'état des pixels du jeu dans un tableau Numpy (numpy dot scipy dot org). La couleur peut être trois tableaux distincts pour RVB, mais le tableau sur lequel je vais me concentrer est le tableau ligne / pas de ligne. Il suffit de l'initialiser avec des zéros et de le définir à la taille de votre terrain de jeu, et chaque fois que le joueur passe à travers un pixel, définissez l'élément correspondant dans le tableau sur 1. Vous voudrez les afficher à l'écran dans une couleur différente , car ils sont votre ligne!

Chaque fois que le pixel du joueur se déplace, je vérifie s'il passe (et trace une ligne à côté) d'une ligne existante. Si oui, j'obtiendrais un pixel de chaque division possible:

. . . | . 
. . . | . 
. . . | x 
. . x < -

Les points sont des pixels vides, les lignes sont (évidemment) des lignes et les X sont les pixels vides que nous voulons sélectionner. Nous pouvons le faire de la manière suivante:

  • Ajoutez tous les pixels vides adjacents au lecteur / intersection à une liste.
  • Parcourez la liste en supprimant les pixels si l'élément suivant de la liste est adjacent (dans le champ de jeu) à celui sur lequel vous vous trouvez.

Une fois que vous avez des pixels de tous les côtés possibles de l'intersection, exécutez A * sur chaque paire possible. (Voir http://www-cs-students.stanford.edu/~amitp/gameprog.html#paths ou Google a-star pour plus d'informations.) Si un chemin peut être trouvé entre une paire, supprimez l'un des pixels connectés de la liste.

Après avoir bouclé et patché pour toutes les paires, les pixels restants doivent chacun être dans une zone fermée séparée! Pour obtenir tous les pixels de chaque zone, effectuez un remplissage à partir du pixel de cette zone. Voir http://en.wikipedia.org/wiki/Flood_fill .

Bonne chance!


0

Vos domaines ne sont que des séries de points. Le travail acharné consiste à prendre la série de points formant (généralement) un polygone concave et à les trianguler afin que vous puissiez les rendre et probablement leur projeter une texture. Voir http://en.wikipedia.org/wiki/Polygon_triangulation pour plus de détails


1
ce n'est pas un problème avec la triangulation, PyGame s'en occupe. J'ai mis à jour ma question avec une image, et dans certains cas d'utilisation, jetez un coup d'œil pour que vous compreniez le point. Merci quand même
astropanic
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.