게임 루프

Pyxen은 고정 초당 30프레임으로 게임을 실행합니다. 메인 루프를 작성할 필요가 없습니다 — 두 개의 함수를 정의하면 Pyxen이 호출합니다.

start()와 update()

def start():
    # 시작 시 한 번 호출됩니다
    pass

def update():
    # 매 프레임, 초당 30회 호출됩니다
    pass

start()는 월드를 설정하는 곳입니다: 엔티티를 생성하고, 배치하고, 씬을 구성합니다.

update()는 게임 로직이 실행되는 곳입니다: 입력을 읽고, 엔티티를 이동하고, 조건을 확인하고, 상태를 업데이트합니다. 각 update() 호출 후 엔진이 프레임을 렌더링합니다.

고정 프레임 레이트

모든 프레임은 정확히 같은 시간을 차지합니다: 1/30초 (~33ms). 이것은 다음을 의미합니다:

시간 기반 움직임을 선호하면 time.dt(델타 타임)를 사용할 수도 있지만, 항상 1/30입니다.

프레임 순서

매 프레임 Pyxen은 이 단계를 순서대로 실행합니다:

  1. 입력 — 키보드, 마우스, 터치, 게임패드 상태 읽기
  2. update() — 코드 실행
  3. 충돌 — 엔진이 그리드 바디를 해결하고 충돌 콜백 호출
  4. 렌더 — 엔진이 모든 보이는 엔티티를 그림

이는 update()에서 입력을 읽을 때 값이 최신임을 의미합니다. 엔티티를 이동하면 충돌 해결이 바로 뒤에 일어납니다.

충돌 콜백

최상위에서 on_collision이나 on_tile_collision을 정의하면, 엔진이 충돌 단계에서 호출합니다:

def on_collision(entity, other):
    # 두 그리드 바디가 겹쳤습니다
    pass

def on_tile_collision(entity, tile):
    # 그리드 바디가 타일맵 타일에 부딪혔습니다
    pass

이것은 update() 이후, 렌더링 이전에 실행됩니다.

타이밍

pyxen.time 모듈이 제공하는 것:

속성용도
time.frame0, 1, 2, ...시작 이후 프레임 카운터
time.dt0.0333...델타 타임 (항상 1/30)
time.t0.0, 0.033, 0.066, ...경과 시간(초)
time.fps30초당 프레임

시간 기반 이벤트에는 두 가지 접근이 가능합니다:

# 프레임 기반: 60프레임(2초)마다 발사
if time.frame % 60 == 0:
    fire()

# 시간 기반: 같은 동작
if int(time.t * 30) % 60 == 0:
    fire()

프레임 카운팅이 일반적으로 더 간단하고 예측 가능합니다.