pyxen.draw

draw 모듈은 프레임마다 화면에 도형을 직접 그립니다. update() 안에서 호출하세요. 그린 내용은 그 프레임의 것이고 다음 프레임은 빈 상태로 시작하므로, 보여야 하는 동안 매 프레임 다시 그리세요.

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

아무것도 생성되지 않습니다. 붙잡아 둘 엔티티도, 파괴할 대상도 없습니다. 시간 여행 디버거는 각 프레임이 그린 내용을 보관하므로, 일시정지하고 프레임을 거슬러 가면 각 프레임이 플레이 중과 똑같은 도형을 보여 줍니다.


draw와 Shape 컴포넌트 중 무엇을 쓸까

Pyxen은 같은 기본 도형을 두 가지 방식으로 제공합니다. 화면에서는 똑같아 보이고, 차이는 수명뿐입니다.

Shape 컴포넌트draw
수명엔티티를 파괴할 때까지 유지매 프레임 다시 그림
위치엔티티의 위치·회전·크기직접 전달한 월드 좌표
비용완전한 엔티티(transform, 레이어, 컴포넌트 저장소)프레임 버퍼의 쿼드 몇 개
디버거엔티티로 목록에 나오고 검사됨거슬러 간 각 프레임에 표시
적합한 용도우주선·벽·고정 UI 같은 게임 객체게임 상태를 그린 그림: 잔상, 오버레이, HUD 막대

그것이 게임 속 존재라면 Shape를, 엔티티가 이미 가진 상태를 그림으로 표현한다면 draw를 쓰세요. 그 상태는 디버거와 인스펙터가 볼 수 있는 엔티티와 컴포넌트에 두고, 매 프레임 그것을 바탕으로 그립니다.


색

모든 색 인자는 각 성분이 0.0~1.0인 (r, g, b, a) 튜플 또는 Color를 받습니다.

draw.rect(10, 10, 40, 20, fill=(1, 0, 0, 1))        # 불투명한 빨강
draw.rect(10, 40, 40, 20, fill=(1, 0, 0, 0.35))     # 35% 빨강

채우는 도형은 기본값으로 아무것도 그리지 않습니다. draw.rect, draw.triangle, draw.circle은 fill과 stroke가 모두 완전히 투명한 상태로 시작하므로, 둘 다 넘기지 않은 호출은 보이지 않습니다. 이 모듈에서 가장 흔한 함정입니다. 반면 draw.line과 draw.polyline은 기본값이 불투명한 흰색이라 항상 보입니다.


함수

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

두 점을 잇는 직선.

인자타입설명
x1, y1float시작점(월드 좌표).
x2, y2float끝점.
color튜플선 색. 기본값은 불투명한 흰색.
widthfloat선 두께(픽셀). 기본값은 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)

이어진 선분들의 나열.

인자타입설명
points튜플 또는 FloatBuffer(x1, y1, x2, y2, …) 형태의 평탄한 나열. 좌표 쌍의 목록이 아닙니다.
color튜플선 색. 기본값은 불투명한 흰색.
widthfloat선 두께(픽셀).
closedboolTrue면 마지막 점을 첫 점과 잇습니다.
def update():
    draw.polyline((10, 10, 40, 60, 80, 20, 110, 70),
                  color=(1, 0.8, 0.2, 1), width=2)

평탄한 나열인 것은 의도된 설계입니다. FloatBuffer가 이미 이 형태이므로, 한 번 계산한 경로를 다시 만들지 않고 매 프레임 그대로 draw.polyline에 넘길 수 있습니다.


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

축에 정렬된 직사각형. x, y는 중심이 아니라 모서리입니다.

인자타입설명
x, yfloat모서리 위치.
width, heightfloat크기(픽셀).
fill튜플내부 색. 생략하면 채우지 않습니다.
stroke튜플외곽선 색. 생략하면 그리지 않습니다.
stroke_widthfloat외곽선 두께. 기본값은 1.
def update():
    # 체력 막대: 어두운 바탕, 밝은 채움, 얇은 외곽선.
    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)

세 점을 지나는 삼각형.

인자타입설명
x1, y1, x2, y2, x3, y3float세 꼭짓점.
fill튜플내부 색. 생략하면 채우지 않습니다.
stroke튜플외곽선 색. 생략하면 그리지 않습니다.
stroke_widthfloat외곽선 두께.
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)

중심점을 둘러싼 원.

인자타입설명
x, yfloat중심 위치.
radiusfloat반지름(픽셀).
fill튜플내부 색. 생략하면 채우지 않습니다.
stroke튜플외곽선 색. 생략하면 그리지 않습니다.
stroke_widthfloat외곽선 두께.
segmentsint곡선을 근사하는 직선 분할 수. 기본값은 12.

원은 사실 다각형입니다. 작은 크기에서는 12분할이면 둥글게 보입니다. 큰 원에서는 값을 올리고, 다각형 느낌을 일부러 보이고 싶다면 낮추세요.

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)

참고

  • draw 호출은 update()에 둡니다. start()에서 호출하면 한 프레임만 그려지고 사라집니다.
  • 그리기는 월드 좌표로 이뤄지므로 카메라가 움직이면 함께 움직입니다. 고정된 HUD가 필요하면 camera를 기준으로 그리거나 움직이지 않는 카메라 위에 두세요.
  • 한 프레임에 그린 것은 같은 프레임의 스프라이트 위에 놓입니다.