목차

이전 항목

드래그 & 드롭

다음 항목

단축키 설정하기

링크


원문 보러 가기
오역 신고하기
Created using Sphinx.

스프라이트

렌파이에서는 여러 개의 이미지를 한 번에 표시할 때 사용할 수 있는 스프라이트 시스템을 지원합니다. 스프라이트 시스템으로 저마다 디스플레이어블을 하나씩 포함하고 있는 스프라이트를 대량생산할 수 있습니다. 그렇게 만들어진 스프라이트에는 화면 상에 표시될 위치값과 화면에 그려지는 순서값을 입력할 수 있습니다.

스프라이트 시스템은 Transform() 를 래핑한 Fixed() 와 비슷하다고 볼 수 있지만 두 디스플레이어블은 성능이 다릅니다. 우선 스프라이트는 트랜스폼보다 디스플레이어블 처리 속도가 빠릅니다. 스프라이트에 사용된 디스플레이어블은 사용된 스프라이트 갯수에 상관 없이 프레임 당 한 번만 렌더링되기 때문입니다. 그러나 스프라이트는 유연성이 부족합니다. Transform 에는 다양한 속성 사용할 수 있는 반면에 스프라이트에는 xoffset이나 yoffset 속성만 사용할 수 있습니다.

스프라이트 시스템을 사용하려면 우선 스프라이트매니저 객체를 생성한 다음, 생성 메소드를 호출해서 새 파티클을 만들어야 합니다. 필요에 따라 화면에서 어른거리는 스프라이트를 만드려면 각 스프라이트의 xoffset, yoffset, zorder 필드를 업데이트합시다. updateevent 인수를 스프라이트매니저에 입력하면 시시각각 변하거나 사용자의 입력에 반응하는 스프라이트를 만들 수 있습니다.

스프라이트 클래스

class Sprite

이 클래스는 스프라이트매니저가 관리하는 하나의 스프라이트를 나타낸다. 화면에 있는 스프라이트의 위치를 제어하는 필드를 포함한다. 스프라이트는 직접 생성하는 것이 아니라 SpriteManager.create() 를 호출해 생성해야 한다.

스프라이트 객체의 필드는 다음과 같다:

x, y
화면 좌측 상단 모서리를 원점으로 삼아 원점으로부터의 거리를 나타내는 나타내는 좌표값.
zorder
스트라이트매니저에서 사용하는 다른 스프라이트들과 비교했을 때 해당 스프라이트가 몇 번째 순서로 놓이는지를 나타내는 정수값. 숫자가 클 수록 보는 사람에게 더 가까이 놓이는 스프라이트이다.
events
True면 이벤트가 하위 디스플레이어블에 전달된다. 기본값인 False라면 하위 디스플레이어블은 이벤트를 무시한다(따라서 이벤트를 진행하는 데 시간을 들이지 않는다).

Sprite 객체에 사용할 수 있는 메소드는 다음과 같다.

destrody(self)

스프라이트를 제거한다. 화면에 표시되지 않도록 하며, SpriteManager에서 해당 스프라이트를 제거한다.

set_child(d)

해당 스프라이트와 관계된 디스플레이어블을 `d`로 교체한다.

class SpriteManager(update=None, event=None, predict=None, ignore_time=False, **properties)

스프라이트 묶음을 제어하며, 가능한 가장 빠른 속도로 표시하는 디스플레이어블이다.

update
None이 아니라면, 이 스프라이트 매니저가 스프라이트 하나를 렌더링할 때마다 호출되는 함수. 하나의 인수와 함께 호출되는데, 이 인수는 이 스프라이트매니저가 스프라이트를 처음으로 표시한 뒤 경과한 시간을 나타낸다. 이 함수는 함수가 다시 호출될 때까지, 스프라이트매니저가 다시 렌더링될 때까지 초 단위 시간을 반환해야 한다.
event
None이 아니라면 이벤트가 발생했을 때 호출되는 함수. 다음을 인수로 받는다. * pygame 이벤트 객체 * 이벤트의 x 좌표 * 이벤트의 y 좌표 * 스프라이트매니저가 처음 표시된 이후부터 경과한 시간 None이 아닌 값을 반환하는 때에는 인터렉션은 종료되며 None이 아닌 그 값이 반환된다.
predict
None이 아니라면 디스플레이어블의 리스트를 반환하는 함수. 디스플레이어블은 스프라이트매니저가 있을 때 예측된다.
ignore_time
True라면 디스플레이어블을 렌더링할 때 시간이 무시된다. 이 인수는 스프라이트매니저가 상대적으로 작은 이미지 덩어리를 사용하며, 그 이미지들이 시간이 지나도 그 모습을 바꾸지 않을 때 사용해야 한다. 이 인수는 적은 양의 디스플레이어블을 쓸 때 사용해야 한다. 모든 디스플레이어블이 스프라이트매니저에 존재하게 하려면 메모리를 사용하므로 다량의 디스플레이어블을 사용하는 경우에는 메모리 사용량을 증가시킬 수도 있기 때문이다.

(update 함수가 호출되기 전에) 스프라이트매니저가 한 번 렌더링 되면 스프라이트매니저 클래스는 다음과 같은 필드를 갖게 된다.

width, height

스프라이트매니저의 너비와 높이. 픽셀 단위.

스프라이트매니저 객체에 사용할 수 있는 메소드는 다음과 같다.

create(d)

`d`를 이용하는 새로운 스프라이트를 생성하고 그 스프라이트를 스프라이트매니저에 추가한다.

redraw(delay=0)

스프라이트매니저를 delay 초가 경과한 뒤에 다시 그리도록 한다.

SnowBlossom(d, count=10, border=50, xspeed=(20, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False)

스노블러섬 이펙트는 다수의 스프라이트 객체를 화면의 위, 아래, 좌, 우로 움직인다. 스프라이트가 화면에서 사라지면 스프라이트는 다시 이펙트의 시작지점으로 돌아간다.

d
스프라이트에 사용할 디스플레이어블.
border
화면에 가상으로 그릴 테두리의 크기. border에 지정한 픽셀만큼 게임 화면 밖에 가상 테두리를 추가해 해당 테두리에서 스프라이트를 그려 스프라이트가 갑자기 나타나거나 사라지는 것처럼 보이지 않게 한다.
xspeed, yspeed
스프라이트가 가로, 세로 방향으로 움직이는 속도. 숫자를 하나만 적거나 숫자 두 개로 이루어진 튜플을 적을 수도 있다. 후자의 경우에는 두 숫자 범위 내에 있는 숫자가 파티클에 랜덤하게 배정된다. 두 번째 숫자가 첫 번째 숫자보다 크기만 하다면 음수를 적을 수도 있다.
start
각 파티클이 추가되기 전까지 걸리는 초 단위 시간. 파티클이 화면 위에서 떨어지는 모습이 "물결"처럼 보이지 않도록 할 수 있다.
fast
True면 파티클이 화면 가운데에서 막바로 시작한다.
horizontal
True면 파티클이 위나 아래가 아니라 왼쪽이나 오른쪽에서 나타난다.

스프라이트 예제

SnowBlossom 클래스를 사용해 화면 상단에서 무언가 떨어지는 이펙트를 쉽게 만들 수 있습니다.

image snow = SnowBlossom("snow.png", count=100)

아래 예제에서는 복잡한 동작을 만들 때 스프라이트매니저를 사용하는 방법을 확인할 수 있습니다. 이 스크립트는 마우스를 피해 움직이는 400개의 파티클을 생성하는 스크립트입니다.

init python:
    import math

    def repulsor_update(st):

        # 마우스 위치를 알아내지 못한다면 포기한다.
        if repulsor_pos is None:
            return .01

        px, py = repulsor_pos

        # 스프라이트...
        for i in repulsor_sprites:

            # 스프라이트와 마우스 간의 벡터를 계산한다.
            vx = i.x - px
            vy = i.y - py

            # 벡터 길이를 얻어서 그 벡터를 정상화한다.
            vl = math.hypot(vx, vy)
            if vl >= 150:
                continue

            # 이동할 거리를 계산.
            distance = 3.0 * (150 - vl) / 150

            # 이동한다.
            i.x += distance * vx / vl
            i.y += distance * vy / vl

            # 화면 밖으로 벗어나지 않도록 한다.
            if i.x < 2:
                i.x = 2

            if i.x > repulsor.width - 2:
                i.x = repulsor.width - 2

            if i.y < 2:
                i.y = 2

            if i.y > repulsor.height - 2:
                i.y = repulsor.height - 2

        return .01

    # 이벤트 상에서 마우스 위치를 기록.
    def repulsor_event(ev, x, y, st):
        store.repulsor_pos = (x, y)


label repulsor_demo:

    python:
        # 스프라이트 매니저를 생성.
        repulsor = SpriteManager(update=repulsor_update, event=repulsor_event)
        repulsor_sprites = [ ]
        repulsor_pos = None

        # 스마일 그림은 하나만 사용한다
        smile = Image("smile.png")

        # 400개의 스프라이트를 추가한다.
        for i in range(400):
            repulsor_sprites.append(repulsor.create(smile))

        # 400개의 스프라이트를 위치시킨다.
        for i in repulsor_sprites:
            i.x = renpy.random.randint(2, 798)
            i.y = renpy.random.randint(2, 598)

        del smile
        del i

    # 화면에 리펄서를 추가한다.
    show expression repulsor as repulsor

    "..."

    hide repulsor

    # 화면을 깨끗이 한다.
    python:
        del repulsor
        del repulsor_sprites
        del repulsor_pos