pyxen.draw

Le module draw dessine des formes directement à l’écran, pour une seule frame. Appelez-le depuis update() ; ce que vous dessinez est effacé à la fin de la frame, donc vous le redessinez à la frame suivante ou il disparaît.

from pyxen import *

def update():
    draw.circle(64, 64, 20, fill=(1, 0.2, 0.3, 1))
    draw.line(0, 0, 128, 128, color=(1, 1, 1, 1))

Rien n’est créé et rien ne persiste — il n’y a aucune entité à conserver ni rien à détruire.


draw ou un composant Shape ?

Pyxen propose les mêmes primitives deux fois. Elles sont identiques à l’écran et ne diffèrent que par leur durée de vie.

Composant Shapedraw
Durée de vieExiste jusqu’à la destruction de l’entitéUne frame
PositionPosition, rotation et échelle de l’entitéCoordonnées monde que vous passez
CoûtUne entité complète : transform, calque, stockage de composantsQuelques quads dans le tampon de frame
Utile pourLes objets du jeu — vaisseaux, murs, interface fixeGéométrie procédurale, affichage de débogage, barres d’interface, traînées

Choisissez Shape quand la chose est un élément de votre jeu. Choisissez draw quand vous peignez l’image de quelque chose que vous suivez déjà vous-même.


Couleurs

Chaque argument de couleur accepte un tuple (r, g, b, a) dont les composantes vont de 0.0 à 1.0, ou un Color.

draw.rect(10, 10, 40, 20, fill=(1, 0, 0, 1))        # rouge opaque
draw.rect(10, 40, 40, 20, fill=(1, 0, 0, 0.35))     # rouge à 35 %

Les formes pleines ne dessinent rien par défaut. draw.rect, draw.triangle et draw.circle démarrent avec fill et stroke entièrement transparents : un appel qui n’en passe aucun est donc invisible — c’est la surprise la plus fréquente avec ce module. draw.line et draw.polyline utilisent au contraire un blanc opaque par défaut et apparaissent toujours.


Fonctions

draw.line(x1, y1, x2, y2, color=(1,1,1,1), width=1)

Une ligne droite entre deux points.

ArgumentTypeDescription
x1, y1floatPoint de départ, en coordonnées monde.
x2, y2floatPoint d’arrivée.
colortupleCouleur du trait. Blanc opaque par défaut.
widthfloatÉpaisseur du trait en pixels. Vaut 1 par défaut.
def update():
    draw.line(0, 64, 128, 64, color=(0.3, 1, 0.5, 1), width=2)

draw.polyline(points, color=(1,1,1,1), width=1, closed=False)

Une suite de segments reliés entre eux.

ArgumentTypeDescription
pointstuple ou FloatBufferSéquence à plat (x1, y1, x2, y2, …) — pas une liste de paires.
colortupleCouleur du trait. Blanc opaque par défaut.
widthfloatÉpaisseur du trait en pixels.
closedboolSi True, relie le dernier point au premier.
def update():
    draw.polyline((10, 10, 40, 60, 80, 20, 110, 70),
                  color=(1, 0.8, 0.2, 1), width=2)

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 à draw.polyline à chaque frame, sans le reconstruire.


draw.rect(x, y, width, height, fill=None, stroke=None, stroke_width=1)

Un rectangle aligné sur les axes. x, y est son coin, pas son centre.

ArgumentTypeDescription
x, yfloatPosition du coin.
width, heightfloatTaille en pixels.
filltupleCouleur intérieure. Omettez pour ne pas remplir.
stroketupleCouleur du contour. Omettez pour ne pas en tracer.
stroke_widthfloatÉpaisseur du contour. Vaut 1 par défaut.
def update():
    # Une barre de vie : fond sombre, remplissage vif, fin contour.
    draw.rect(4, 4, 60, 6, fill=(0.1, 0.1, 0.1, 1))
    draw.rect(4, 4, 60 * health / max_health, 6, fill=(0.2, 1, 0.4, 1))
    draw.rect(4, 4, 60, 6, stroke=(1, 1, 1, 0.5))

draw.triangle(x1, y1, x2, y2, x3, y3, fill=None, stroke=None, stroke_width=1)

Un triangle passant par trois points.

ArgumentTypeDescription
x1, y1, x2, y2, x3, y3floatLes trois sommets.
filltupleCouleur intérieure. Omettez pour ne pas remplir.
stroketupleCouleur du contour. Omettez pour ne pas en tracer.
stroke_widthfloatÉpaisseur du contour.
def update():
    draw.triangle(64, 20, 84, 60, 44, 60, fill=(1, 1, 0.3, 1))

draw.circle(x, y, radius, fill=None, stroke=None, stroke_width=1, segments=12)

Un cercle autour d’un point central.

ArgumentTypeDescription
x, yfloatPosition du centre.
radiusfloatRayon en pixels.
filltupleCouleur intérieure. Omettez pour ne pas remplir.
stroketupleCouleur du contour. Omettez pour ne pas en tracer.
stroke_widthfloatÉpaisseur du contour.
segmentsintNombre 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 quand vous voulez un polygone visible.

def update():
    draw.circle(64, 64, 24, fill=(0.2, 0.4, 1, 1), segments=32)
    draw.circle(64, 64, 30, stroke=(1, 1, 1, 0.4), segments=32)

Remarques

  • Les appels à draw ont leur place dans update(). Depuis start(), ils dessinent une seule frame puis disparaissent.
  • Le dessin se fait en coordonnées monde : la caméra le déplace donc. Pour une interface qui reste en place, dessinez relativement à camera ou gardez l’interface sur une caméra fixe.
  • Tout ce qui est dessiné dans une frame passe au-dessus des sprites dessinés cette frame-là.