스프라이트 및 렌더링
Pyxen은 Metal 기반 2D 렌더러를 사용하여 게임을 렌더링합니다. 화면에 보이는 모든 것은 Sprite 컴포넌트를 가진 엔티티입니다.
스프라이트
스프라이트는 엔진에 엔티티를 위해 무엇을 그릴지 알려줍니다. 프로젝트의 이미지를 참조하여 생성합니다:
player = world.spawn(sprite=Sprite("hero"))
문자열 "hero"는 프로젝트 에셋에 있는 hero라는 이미지를 참조합니다.
타일 시트
대부분의 게임은 타일 시트 — 그리드에 배열된 여러 프레임이나 타일을 포함하는 단일 이미지 — 를 사용합니다. tile 매개변수로 이미지의 영역을 선택합니다:
Sprite("characters", tile=(0, 0, 16, 16)) # 첫 번째 타일
Sprite("characters", tile=(16, 0, 16, 16)) # 두 번째 타일
Sprite("characters", tile=(0, 16, 16, 16)) # 두 번째 행의 타일
네 값은 이미지의 좌상단에서 측정한 (x, y, width, height) 픽셀 단위입니다.
스프라이트 애니메이션
스프라이트 에디터에서 이름 있는 애니메이션을 만들면 직접 재생할 수 있습니다:
player = world.spawn(
sprite=Sprite("hero", animation="walk"),
x=100, y=50
)
엔진이 스프라이트 메타데이터에서 애니메이션의 프레임 시퀀스와 FPS를 읽고 프레임을 자동으로 진행합니다. 애니메이션을 전환하려면 새 스프라이트를 할당합니다:
player.sprite = Sprite("hero", animation="jump")
한 번만 재생되는 애니메이션(공격이나 사망 등)은 loop=False로 설정하고 완료를 확인합니다:
player.sprite = Sprite("hero", animation="attack", loop=False)
def update():
if player.animation and player.animation.finished:
player.sprite = Sprite("hero", animation="idle")
e.animation 컴포넌트를 통해 현재 상태에 읽기 전용으로 접근할 수 있습니다: .name, .frame, .playing, .finished. 자세한 내용은 Entity 레퍼런스를 참조하세요.
매 프레임 타일을 변경하여 수동으로 애니메이션할 수도 있습니다:
def update():
frame = time.frame % 4
player.sprite = Sprite("hero", tile=(frame * 16, 0, 16, 16))
피벗 포인트
기본적으로 스프라이트는 좌상단 모서리에서 그려집니다. 피벗 포인트를 변경하여 스프라이트가 고정되는 위치를 제어할 수 있습니다:
Sprite("hero", tile=(0, 0, 16, 16), pivot=(8, 8))
이렇게 하면 스프라이트가 엔티티 위치의 중심에 배치됩니다. 피벗은 타일에 상대적인 픽셀 좌표입니다. 타일의 중심에 피벗을 설정하는 것이 가장 일반적인 선택입니다 — 회전과 스케일링이 직관적으로 동작합니다.
색상 틴팅
엔티티의 스프라이트에 색상을 설정하여 틴팅할 수 있습니다:
player.color = (1.0, 0.5, 0.5, 1.0) # 붉은 틴트
색상은 0.0에서 1.0 사이의 RGBA 튜플입니다. 흰색 (1, 1, 1, 1)은 틴팅 없음을 의미합니다. 알파 채널로 투명도를 사용할 수 있습니다:
ghost.color = (1, 1, 1, 0.5) # 50% 투명
트윈을 사용하여 색상과 알파를 부드럽게 애니메이션할 수도 있습니다:
ghost.tween("alpha", to=0, duration=0.5, ease="out_quad") # 페이드 아웃
펄스나 깜빡임 같은 지속적인 효과에는 애니메이션을 사용합니다:
ghost.animate("alpha", by=0.3, center=0.7, speed=4.0) # 깜빡임
카메라
카메라는 월드의 어느 부분이 보이는지를 제어합니다. Camera 컴포넌트를 가진 엔티티를 생성하여 만듭니다:
cam = world.spawn(camera=Camera(), x=160, y=90)
플레이어를 따라가도록 카메라를 이동합니다:
def update():
cam.x = player.x
cam.y = player.y
카메라는 줌을 지원합니다:
cam.camera.zoom = 2.0 # 2배 확대
트윈으로 줌을 부드럽게 애니메이션할 수 있습니다:
cam.tween("zoom", to=2.0, duration=0.5, ease="out_quad")
해상도
Pyxen 게임은 기본 해상도 320x180 픽셀로 실행됩니다. 이는 의도적인 선택입니다 — 낮은 해상도는 픽셀 아트를 선명하게 보이게 하고 렌더링을 빠르게 유지합니다. 엔진이 출력을 화면에 맞게 스케일링합니다.
텍스트
Text 컴포넌트는 비트맵 텍스트를 렌더링합니다. 텍스트 엔티티는 다음과 같이 만듭니다:
label = world.spawn(text=Text("Hello, world!"))
기본적으로 텍스트는 내장 픽셀 폰트를 사용합니다. 폰트 에디터로 만든 커스텀 폰트를 사용하려면:
title = world.spawn(text=Text("Game Over", font="myfont"))
런타임에 text 속성을 수정하여 텍스트를 업데이트합니다:
def update():
score_label.text = Text(f"Score: {score}")
전체 API는 Text 레퍼런스를 참조하세요.
그리기 순서
엔티티는 다음 순서로 그려집니다:
- 레이어 — 낮은 레이어가 먼저 그려짐 (레이어 0이 레이어 1 뒤에)
- 깊이 — 레이어 내에서, 씬 그래프 위치에 의해 결정
- 스프라이트가 없는 엔티티는 그려지지 않지만 월드에는 존재
레이어와 깊이에 대한 자세한 내용은 씬 그래프를 참조하세요.