Formes
Rect, Triangle, Circle, Line et Polyline sont des composants de forme. Vous en donnez un à une entité au moment de la créer, et l’entité dessine cette forme à chaque frame jusqu’à ce que vous la détruisiez.
from pyxen import *
def start():
world.spawn(x=110, y=90, shape=Rect(48, 32, fill=(0.4, 0.7, 1.0, 1.0)))
world.spawn(x=210, y=90, shape=Circle(24, stroke=(1.0, 0.6, 0.3, 1.0), stroke_width=2))
Une forme est une véritable entité : tout ce que les entités savent faire s’applique. Déplacez-la
avec entity.x et entity.y, faites-la tourner avec entity.rotation, donnez-lui un parent,
animez-la avec un tween, placez-la sur un calque, masquez-la avec entity.visible.
Formes ou draw ?
Pyxen propose les mêmes cinq primitives deux fois. Elles sont identiques à l’écran et ne diffèrent que par leur durée de vie. Voir draw pour l’autre moitié.
| Composant de forme | draw | |
|---|---|---|
| Durée de vie | Existe jusqu’à la destruction de l’entité | Chaque frame le redessine |
| Position | Position, rotation et échelle de l’entité | Coordonnées monde que vous passez |
| Coût | Une entité complète : transform, calque, stockage de composants | Quelques quads dans le tampon de frame |
| Débogueur | Listée et inspectée comme une entité | Montré dans chaque frame où vous revenez |
| Utile pour | Les objets du jeu — vaisseaux, murs, interface fixe | L’image de l’état de votre jeu : traînées, superpositions, barres d’interface |
Choisissez une forme quand la chose est un élément de votre jeu. Choisissez draw quand vous
peignez l’image d’un état que vos entités portent déjà. Les deux s’affichent tels qu’ils étaient
quand vous remontez les frames dans le débogueur.
Trois pièges classiques
Une forme est définie à la création et ne peut plus changer ensuite. Il n’existe pas de
entity.shape — le lire lève ValueError: component schema does not exist. C’est différent de
sprite et text, qui, eux, sont modifiables. Pour changer une forme, détruisez l’entité et
créez-en une nouvelle.
entity.color ne teinte pas une forme. Cela fonctionne pour les sprites ; une forme se
dessine avec ses propres fill et stroke et l’ignore. Définissez la couleur sur la forme
elle-même.
L’épaisseur du contour porte deux noms. Rect, Triangle et Circle prennent
stroke_width ; Line et Polyline prennent width. Les deux désignent la même chose.
Couleurs
Chaque argument de couleur accepte un tuple (r, g, b, a) dont les composantes vont de 0.0 à
1.0, ou un Color.
Rect(40, 20, fill=(1, 0, 0, 1)) # rouge opaque
Rect(40, 20, fill=(1, 0, 0, 0.35)) # rouge à 35 %
Une forme sans fill ni stroke ne dessine rien. Les deux démarrent entièrement
transparents : Rect(40, 40) est donc une entité valide et invisible — c’est la surprise la plus
fréquente ici. Vous pouvez passer les deux pour obtenir une forme pleine avec un contour.
Types
Rect(width, height, fill=None, stroke=None, stroke_width=1, pivot=None)
Un rectangle.
| Argument | Type | Description |
|---|---|---|
width, height | float | Taille en pixels. |
fill | tuple | Couleur intérieure. Omettez pour ne pas remplir. |
stroke | tuple | Couleur du contour. Omettez pour ne pas en tracer. |
stroke_width | float | Épaisseur du contour. Vaut 1 par défaut. |
pivot | tuple | Le point auquel se rapporte la position de l’entité, en pixels de la forme. Par défaut le coin ; (width/2, height/2) le centre. |
Rect est la seule forme dotée d’un pivot — c’est aussi le point autour duquel la rotation
s’effectue.
def start():
world.spawn(x=110, y=90, shape=Rect(48, 32, fill=(0.4, 0.7, 1.0, 1.0)))
# Centré sur sa propre position : la rotation se fait sur place.
world.spawn(name="spinner", x=210, y=90,
shape=Rect(48, 32, stroke=(1.0, 0.6, 0.3, 1.0), stroke_width=2,
pivot=(24, 16)))
def update():
world.get(name="spinner").rotation += 0.02
Triangle(x1, y1, x2, y2, x3, y3, fill=None, stroke=None, stroke_width=1)
Un triangle passant par trois points, donnés relativement à la position de l’entité.
| Argument | Type | Description |
|---|---|---|
x1, y1, x2, y2, x3, y3 | float | Les trois sommets, en décalage par rapport à l’entité. |
fill | tuple | Couleur intérieure. Omettez pour ne pas remplir. |
stroke | tuple | Couleur du contour. Omettez pour ne pas en tracer. |
stroke_width | float | Épaisseur du contour. |
world.spawn(x=160, y=90, shape=Triangle(0, -20, 18, 14, -18, 14, fill=(1, 1, 0.3, 1)))
Circle(radius, fill=None, stroke=None, stroke_width=1, segments=12)
Un cercle centré sur l’entité.
| Argument | Type | Description |
|---|---|---|
radius | float | Rayon en pixels. |
fill | tuple | Couleur intérieure. Omettez pour ne pas remplir. |
stroke | tuple | Couleur du contour. Omettez pour ne pas en tracer. |
stroke_width | float | Épaisseur du contour. |
segments | int | Nombre de segments droits approximant la courbe. Vaut 12 par défaut. |
Un cercle est en réalité un polygone. Douze segments suffisent à paraître rond en petite taille ;
augmentez la valeur pour les grands cercles, et baissez-la volontairement quand vous voulez un
polygone visible — segments=6 donne un hexagone.
world.spawn(x=110, y=90, shape=Circle(28, fill=(0.5, 1.0, 0.7, 1.0), segments=6))
world.spawn(x=210, y=90, shape=Circle(28, fill=(1.0, 0.5, 0.7, 1.0), segments=32))
Line(x1, y1, x2, y2, stroke=None, width=1)
Une ligne droite entre deux points, relativement à l’entité.
| Argument | Type | Description |
|---|---|---|
x1, y1 | float | Départ, en décalage par rapport à l’entité. |
x2, y2 | float | Arrivée. |
stroke | tuple | Couleur du trait. |
width | float | Épaisseur du trait. Attention : width, et non stroke_width. |
world.spawn(x=60, y=90, shape=Line(0, 0, 80, -40, stroke=(0.3, 1, 0.5, 1), width=2))
Polyline(points, stroke=None, width=1, closed=False, fill=None)
Une suite de segments reliés entre eux.
| Argument | Type | Description |
|---|---|---|
points | tuple ou FloatBuffer | Séquence à plat (x1, y1, x2, y2, …) — pas une liste de paires. |
stroke | tuple | Couleur du trait. |
width | float | Épaisseur du trait. Attention : width, et non stroke_width. |
closed | bool | Si True, relie le dernier point au premier. |
fill | tuple | Remplit la zone délimitée. Surtout utile avec closed=True. |
Les points sont à plat volontairement : c’est déjà la forme d’un FloatBuffer, si bien qu’un
tracé calculé une fois peut être passé tel quel à Polyline sans le reconstruire.
world.spawn(x=250, y=90,
shape=Polyline((0, 0, 30, -25, 60, 0), stroke=(1, 0.9, 0.2, 1), width=3))