pyxen.draw

Das Modul draw zeichnet Formen für genau ein Frame direkt auf den Bildschirm. Rufe es aus update() auf; was du zeichnest, wird am Ende des Frames gelöscht — du zeichnest es im nächsten Frame erneut, sonst verschwindet es.

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))

Es entsteht nichts und nichts bleibt bestehen — es gibt keine Entität, die du behalten, und nichts, das du zerstören müsstest.


draw oder eine Shape-Komponente?

Pyxen bietet dieselben Primitive zweimal an. Auf dem Bildschirm sind sie identisch und unterscheiden sich nur in ihrer Lebensdauer.

Shape-Komponentedraw
LebensdauerLebt, bis du die Entität zerstörstEin Frame
PositionPosition, Rotation und Skalierung der EntitätWeltkoordinaten, die du übergibst
KostenEine vollständige Entität: Transform, Ebene, KomponentenspeicherEin paar Quads im Frame-Puffer
Gut fürSpielobjekte — Schiffe, Wände, feste OberflächeProzedurale Geometrie, Debug-Anzeigen, Balken, Spuren

Nimm Shape, wenn das Ding etwas in deinem Spiel ist. Nimm draw, wenn du ein Bild von etwas malst, das du ohnehin schon selbst verwaltest.


Farben

Jedes Farbargument nimmt ein (r, g, b, a)-Tupel mit Komponenten von 0.0 bis 1.0 oder ein Color.

draw.rect(10, 10, 40, 20, fill=(1, 0, 0, 1))        # deckendes Rot
draw.rect(10, 40, 40, 20, fill=(1, 0, 0, 0.35))     # Rot mit 35 %

Die gefüllten Formen zeichnen standardmäßig nichts. draw.rect, draw.triangle und draw.circle starten mit vollständig transparentem fill und stroke, ein Aufruf ohne beides ist also unsichtbar — das ist die häufigste Überraschung bei diesem Modul. draw.line und draw.polyline verwenden dagegen deckendes Weiß und sind immer zu sehen.


Funktionen

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

Eine gerade Linie zwischen zwei Punkten.

ArgumentTypBeschreibung
x1, y1floatStartpunkt, in Weltkoordinaten.
x2, y2floatEndpunkt.
colorTupelLinienfarbe. Standard ist deckendes Weiß.
widthfloatLinienstärke in Pixeln. Standard ist 1.
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)

Eine Folge verbundener Liniensegmente.

ArgumentTypBeschreibung
pointsTupel oder FloatBufferFlache Folge (x1, y1, x2, y2, …) — keine Liste von Paaren.
colorTupelLinienfarbe. Standard ist deckendes Weiß.
widthfloatLinienstärke in Pixeln.
closedboolBei True wird der letzte Punkt mit dem ersten verbunden.
def update():
    draw.polyline((10, 10, 40, 60, 80, 20, 110, 70),
                  color=(1, 0.8, 0.2, 1), width=2)

Die Punkte liegen bewusst flach: genau diese Form hat ein FloatBuffer bereits, sodass ein einmal berechneter Pfad in jedem Frame unverändert an draw.polyline übergeben werden kann, ohne ihn neu aufzubauen.


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

Ein achsenparalleles Rechteck. x, y ist seine Ecke, nicht sein Mittelpunkt.

ArgumentTypBeschreibung
x, yfloatPosition der Ecke.
width, heightfloatGröße in Pixeln.
fillTupelInnenfarbe. Weglassen für keine Füllung.
strokeTupelUmrissfarbe. Weglassen für keinen Umriss.
stroke_widthfloatStärke des Umrisses. Standard ist 1.
def update():
    # Eine Lebensleiste: dunkler Hintergrund, kräftige Füllung, dünner Umriss.
    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)

Ein Dreieck durch drei Punkte.

ArgumentTypBeschreibung
x1, y1, x2, y2, x3, y3floatDie drei Ecken.
fillTupelInnenfarbe. Weglassen für keine Füllung.
strokeTupelUmrissfarbe. Weglassen für keinen Umriss.
stroke_widthfloatStärke des Umrisses.
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)

Ein Kreis um einen Mittelpunkt.

ArgumentTypBeschreibung
x, yfloatPosition des Mittelpunkts.
radiusfloatRadius in Pixeln.
fillTupelInnenfarbe. Weglassen für keine Füllung.
strokeTupelUmrissfarbe. Weglassen für keinen Umriss.
stroke_widthfloatStärke des Umrisses.
segmentsintGerade Segmente, die die Kurve annähern. Standard ist 12.

Ein Kreis ist in Wahrheit ein Vieleck. Zwölf Segmente wirken bei kleinen Größen rund; erhöhe den Wert für große Kreise und senke ihn, wenn du ein sichtbares Vieleck willst.

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)

Hinweise

  • draw-Aufrufe gehören in update(). Aus start() zeichnen sie ein einziges Frame und sind dann weg.
  • Gezeichnet wird in Weltkoordinaten, die Kamera bewegt das Gezeichnete also mit. Für eine Oberfläche, die stehen bleibt, zeichne relativ zu camera oder lass sie auf einer unbewegten Kamera.
  • Alles, was in einem Frame gezeichnet wird, liegt über den Sprites dieses Frames.