레이어 이미지

스프라이트의 구성이 일정 수준 이상 복잡해지면 가능한 조합을 모두 정의하기 어려워집니다. 예를 들어 의상 4개, 머리 모양 4개, 감정 6개를 가진 캐릭터만 해도 조합이 96개나 됩니다. 각 조합을 정적인 이미지로 만들면 디스크 공간과 프로그래머의 작업 시간이 많이 필요합니다.

이를 해결하기 위해 Ren'Py는 여러 스프라이트를 레이어로 구성하여 하나의 이미지를 정의하는 방법을 제공합니다. 여기서 레이어는 Photoshop이나 GIMP 같은 그림 프로그램의 레이어를 뜻하며, Ren'Py의 다른 기능에서 사용하는 레이어와는 다릅니다. 각 레이어의 요소는 이미지에 지정한 속성이나 실행 중 평가하는 조건으로 선택할 수 있습니다.

이 이미지는 전용 언어를 사용하는 layeredimage 문으로 선언할 수 있습니다. Python에서는 LayeredImage() 객체를 사용합니다. 이 객체는 디스플레이어블은 아니지만 image 문에 할당하여 디스플레이어블처럼 사용할 수 있습니다.

이 페이지의 아래쪽에는 사용 팁과 예제가 있습니다.

레이어 이미지 정의

레이어 이미지를 정의하는 언어에는 레이어를 추가하는 몇 가지 문만 있습니다. 다음 예제는 실용적 의미는 크지 않지만 구문상 올바르며 layeredimage의 구문을 보여 줍니다.

layeredimage augustina:
    zoom 1.4
    at recolor_transform

    always:
        "augustina_base"

    attribute base2 default

    group outfit:
        attribute dress default:
            "augustina_dress"
        attribute uniform
        attribute psychedelic:
            image:
                "augustina_dress"
                matrixcolor TintMatrix("#f00")
                linear 1 matrixcolor TintMatrix("#0f0")
                linear 1 matrixcolor TintMatrix("#00f")
                repeat

    group face auto:
        pos (100, 100)
        attribute neutral default

label start:
    show augustina # displaying dress and neutral
    aug "이 원피스가 마음에 들어요."

    show augustina happy # auto-defined in the auto group
    aug "하지만 더 마음에 드는 건..."

    show augustina uniform -happy # uniform replaces dress, neutral replaces happy
    aug "바로 이 제복이에요!"

layeredimage

layeredimage 문으로 정의를 시작합니다. 이 문은 Ren'Py 스크립트 언어의 일부이며 초기화 시점에 실행됩니다. ATL 블록이 있는 image 문과 마찬가지로 이미지 이름을 받고 블록을 열지만, 블록의 내용은 크게 다릅니다. Ren'Py의 다른 이미지 이름처럼 공백을 포함할 수 있습니다.

블록 안에는 아래에서 설명하는 문과 다음 선택적 속성을 넣을 수 있습니다.

image_format

이미지가 문자열이고 이 속성을 지정했다면 이미지 이름을 image_format에 보간하여 이미지 파일 경로를 만듭니다. 예를 들어 "sprites/eileen/{image}.png"는 sprites의 하위 디렉터리에서 이미지를 찾습니다. auto 그룹은 이미지 파일이 아닌 정의된 이미지를 찾으므로 이 속성을 사용하지 않습니다.

format_function

초기화 시점의 이미지 정의 과정에서 이미지 정보를 디스플레이어블로 변환할 때 layeredimage.format_function() 대신 사용하는 함수입니다.

attribute_function

최종적으로 표시할 속성을 조정하는 함수 또는 호출 가능한 객체입니다. 이미지에 지정한 속성 집합을 인수로 받아 레이어 선택에 사용할 속성 집합을 반환해야 합니다. 속성 사이의 복잡한 의존 관계를 표현하거나 속성을 무작위로 선택하는 데 사용할 수 있습니다. 호출 시점과 방식은 표시할 속성 선택을 참조하세요.

at

레이어 이미지에 적용할 트랜스폼 또는 트랜스폼 리스트입니다. at transform: 뒤에 ATL 블록을 작성하여 layeredimage에 적용할 ATL 트랜스폼을 정의할 수도 있습니다.

트랜스폼 속성

지정하면 이 속성들로 트랜스폼을 만들어 디스플레이어블에 적용합니다.

offer_screen

True이면 layeredimage는 게임 화면 전체와 같은 영역을 받은 것으로 간주하여 자식을 배치하고 가변 크기 자식의 크기를 정합니다. False이면 사용 가능한 영역에 맞추어 처리합니다. 예를 들어 다른 요소가 있는 hbox에서는 영역이 작아지므로 layeredimage를 표시할 때마다 모양이 달라질 수 있습니다.

기본값인 None이면 config.layeredimage_offer_screen의 설정을 따릅니다. 이 설정의 기본값은 True입니다.

always

always 문은 layeredimage 안에서 항상 표시되고 어떤 속성에도 연결되지 않는 이미지를 선언합니다. 반드시 디스플레이어블을 지정해야 하며 속성도 받을 수 있습니다. 둘 다 같은 줄이나 블록 안에 작성할 수 있습니다. image: 뒤에 ATL 블록을 작성하여 디스플레이어블을 선언할 수도 있으며, 이는 ATL 블록이 있는 image 문과 비슷합니다.

always 문은 다음 속성을 받습니다.

when

괄호로 감싼 When 표현식입니다. 지정하면 layeredimage를 표시할 때 사용한 속성 집합이 when 표현식을 만족하는 경우에만 이 레이어를 표시합니다.

트랜스폼 속성

지정하면 이 속성들로 트랜스폼을 만들어 디스플레이어블에 적용합니다.

at

지정한 디스플레이어블에 적용할 트랜스폼 또는 트랜스폼 리스트입니다. at transform: 뒤에 ATL 블록을 작성하여 디스플레이어블에 적용할 ATL 트랜스폼을 정의할 수도 있습니다.

if

if 문(정확히는 if-elif-else 문)은 실행 중 평가할 조건을 하나 이상 지정할 수 있게 합니다. 각 조건에 디스플레이어블을 연결하며, 처음으로 참이 되는 조건의 디스플레이어블을 표시합니다. 참인 조건이 없으면 else 레이어가 있는 경우 이를 표시합니다.

if 문의 좀 더 완전한 예제는 다음과 같습니다.

if glasses == "evil":
    "augustina_glasses_evil"
elif glasses == "normal":
    "augustina_glasses"
elif glasses == "funky":
    "augustina_glasses_clown"
else:
    "augustina_nose_mark"

각 절에는 반드시 디스플레이어블을 지정해야 하며, 앞서 설명한 image: 구문을 사용할 수 있습니다. 다음 속성도 지정할 수 있습니다.

when

괄호로 감싼 When 표현식입니다. 지정하면 layeredimage를 표시할 때 사용한 속성 집합이 when 표현식을 만족하는 경우에만 이 조건의 디스플레이어블을 표시합니다.

트랜스폼 속성

지정하면 이 속성들로 트랜스폼을 만들어 디스플레이어블에 적용합니다.

at

디스플레이어블에 적용할 트랜스폼 또는 트랜스폼 리스트입니다. at transform: 뒤에 ATL 블록을 작성하여 디스플레이어블에 적용할 ATL 트랜스폼을 정의할 수도 있습니다.

layeredimage 문이 실행될 때 if 문은 ConditionSwitch()로 변환됩니다.

layeredimage.predict_all = None

layeredimage의 if 문으로 생성되는 ConditionSwitch의 predict_all 값을 설정합니다.

predict_all이 참이 아니면 레이어 이미지가 표시 중이거나 곧 표시될 때 if 문의 조건을 바꾸지 않도록 해야 합니다. 예측하지 못한 이미지 로딩이 발생하기 때문입니다. 이 설정은 자주 바뀌지 않는 캐릭터 꾸미기 옵션 등에 사용하도록 설계되었습니다.

attribute

attribute 문은 지정한 속성으로 이미지를 표시할 때 결과 이미지의 일부가 될 디스플레이어블을 추가합니다. 앞의 예제에서 show augustina dress를 실행하면 "augustina" 이미지의 일부로 "augustina_dress"가 표시됩니다.

attribute 절은 단어 하나로 된 속성 이름을 받습니다. 정확히는 이미지 이름의 구성 요소 하나이며, 문의 구성 요소를 참조하세요. 키워드 두 개도 받을 수 있습니다. default는 같은 그룹의 다른 속성을 지정하지 않으면 이 속성을 기본으로 사용한다는 뜻입니다. null은 이 절에 디스플레이어블을 연결하지 않도록 합니다. 이는 상태 관리나 when, attribute_function, config.adjust_attributes, config.default_attribute_callbacks를 이용한 조건부 표시 설정에 유용합니다.

같은 속성 이름을 여러 attribute 절에서 사용할 수 있습니다. 뒤에서 설명하는 auto 그룹의 자동 정의 속성도 여기에 해당합니다. 이 경우 대응하는 모든 디스플레이어블을 동시에 표시합니다. when 속성으로 이 동작을 조정할 수 있습니다.

디스플레이어블을 지정할 수 있으며 앞서 설명한 image: 구문을 사용해도 됩니다. 명시적으로 지정하지 않으면 layeredimage 이름, 그룹(있는 경우), 그룹 또는 속성의 variant(있는 경우), 속성을 조합하여 구합니다. 자세한 내용은 패턴 절을 참조하세요.

attribute 문은 다음 속성을 받습니다.

when

괄호로 감싼 When 표현식입니다. 지정하면 layeredimage를 표시할 때 사용한 속성 집합이 when 표현식을 만족하는 경우에만 이 레이어를 표시합니다.

트랜스폼 속성

지정하면 이 속성들로 트랜스폼을 만들어 레이어에 적용합니다.

at

레이어에 적용할 트랜스폼 또는 트랜스폼 리스트입니다. at transform: 뒤에 ATL 블록을 작성하여 레이어에 적용할 ATL 트랜스폼을 정의할 수도 있습니다.

variant

속성의 디스플레이어블을 찾을 때 속성 이름 앞에 밑줄로 연결하여 붙이는 단어입니다. 디스플레이어블을 명시적으로 지정하지 않았고, variant가 지정된 그룹에도 속하지 않은 속성에만 사용할 수 있습니다.

when 절은 여기에서 설명하는 결과 이미지의 속성 목록을 기준으로 검사하지만, 그 목록 자체를 변경하지는 않습니다.

layeredimage eileen:
    attribute a
    attribute b default when not a
    attribute c default when not b

이 예제에서는 default 절 때문에 b와 c 속성이 속성 목록에 항상 포함됩니다. show eileen a를 호출하면 요청한 a 속성은 표시되지만 b 속성은 when 속성 때문에 표시되지 않습니다. 그래도 b는 속성 목록에 남아 있으므로 c 역시 표시되지 않습니다.

group

group 문은 속성들을 서로 배타적인 그룹으로 묶습니다. a와 b가 같은 그룹에 있으면 show eileen a b처럼 둘을 동시에 지정할 때 오류가 발생합니다. 단, multiple 그룹은 예외입니다. 같은 예에서 a를 지정하면 b가 숨겨지고 반대도 마찬가지입니다. 다만 여러 attribute 절에 같은 이름을 지정하는 것은 같은 그룹 안에서도 가능합니다. 이 경우 여러 스프라이트를 포함하는 하나의 속성으로 취급합니다. 자세한 내용은 이 절의 끝에서 설명합니다.

group 문은 이름을 받습니다. 이름은 주로 그룹 내 속성의 기본 이름을 생성하는 데 사용합니다.

그룹 이름 multiple은 예약되어 있으며 그룹을 multiple 그룹으로 만듭니다. 이 경우 블록 안에서 선언한 속성끼리 배타성을 적용하지 않습니다. 서로 배타적이지 않은 여러 속성을 그룹에서 자동으로 정의하거나 여러 속성에 같은 속성값을 한꺼번에 적용할 때 유용합니다. 다만 그룹 내 속성에 default 키워드를 지정하는 것과 충돌합니다. multiple 그룹은 일반 그룹과 크게 다르며, 그룹에 대한 설명 대부분이 적용되지 않습니다. 특히 이름이 없는 것으로 간주합니다.

이름 뒤에는 auto 키워드를 붙일 수 있습니다. 키워드가 있으면 그룹 내 속성을 선언한 뒤 Ren'Py가 이미지 목록에서 그룹 패턴(아래 참조)에 맞는 이미지를 찾습니다. 이 경우 layeredimage에 지정한 format_function은 무시합니다. 명시적으로 선언한 속성에 해당하는 이미지를 제외하고, 발견한 이미지들을 그룹 블록 안에서 attribute 문으로 선언한 것처럼 그룹에 추가합니다. 실제 사용 예는 예제 절을 참조하세요.

선택적인 키워드 다음에는 그룹의 첫 줄에 속성들을 선언할 수 있으며, 속성과 attribute 문을 담는 블록도 받을 수 있습니다.

group 문은 when, at 등 attribute 문과 같은 속성을 받습니다. 그룹에 지정한 속성은 그룹 내 속성들에 전달됩니다. 단, 개별 속성에 같은 속성값을 지정하면 이를 덮어씁니다. 다음 두 속성은 그룹과 더 밀접하게 관련됩니다.

variant

attribute가 받는 속성과 비슷하지만 그룹과 그 안의 속성 양쪽에 동시에 지정할 수는 없습니다. 지정할 경우 단어 하나여야 합니다. 디스플레이어블을 명시적으로 지정하지 않은 속성의 이미지 이름을 자동으로 생성할 때 variant로 사용합니다(패턴 절 참조). 또한 auto 그룹에서 속성을 자동으로 정의할 때 이미지를 찾는 패턴에도 사용합니다(위 참조).

prefix

수동 또는 자동으로 정의한 속성 이름 앞에 밑줄로 연결하여 붙이는 접두사입니다. 예를 들어 prefix가 leftarm이고 attribute hip이 있으면 show eileen leftarm_hip로 표시합니다.

하나의 속성이 여러 그룹에 속할 수도 있습니다. 이 경우 그 속성은 자신이 속한 모든 그룹의 다른 모든 속성과 배타적입니다. 예를 들어 dress 속성을 표시할 때 현재 표시된 상의와 바지를 모두 숨기도록 할 수 있습니다.

layeredimage eileen:
    attribute base default
    group bottom:
        attribute jeans default
        attribute dress null
    group top:
        attribute shirt default
        attribute dress

같은 layeredimage 안에서 같은 이름의 group 블록을 여러 개 정의하면 하나의 그룹을 이루는 여러 부분으로 간주합니다. 예를 들면 다음과 같습니다.

layeredimage eileen sitting:
    attribute base default
    group arms variant behind:
        attribute on_hips
        attribute on_knees
        attribute mixed
    attribute table default
    group arms variant infront:
        attribute on_table default
        attribute holding_margarita
        attribute mixed

이 예제에서 eileen_sitting_arms_behind_mixed.png에는 탁자 뒤에 있는 왼팔이, eileen_sitting_arms_infront_mixed.png에는 탁자 위에 있는 오른팔이 들어 있습니다. show eileen sitting mixed를 호출하면 두 이미지를 각각 탁자 뒤와 앞에 동시에 표시합니다. on_hips와 on_table 속성은 서로 다른 블록에서 선언되었어도 같은 그룹에 속하므로 배타적입니다.

when

when 표현식은 layeredimage에서 현재 활성화된 속성 집합에 따라 결정되는 불리언 조건을 나타냅니다.

하나 이상의 속성 이름을 "and" 및 "or" 키워드로 연결하며 "not"으로 부정할 수 있습니다. 괄호로 우선순위를 지정할 수도 있습니다.

예제:

always:
    "eileen_red_dress"
    when b and not c
    # the image will be shown when attribute b is active and attribute c is not

if var:
    "eileen_blue_ribbon"
    when not (a or b)
    # the image will be shown when the var variable is true
    # and neither attributes a nor b are active

attribute a:
    "eileen_a"
    when b or e
    # the image will be shown when attribute "a" is active
    # and either attribute "b" or "e" are active

사용을 권장하지 않는 속성

always, if, attribute 문의 다음 속성은 더 이상 권장하지 않지만, when 절이 추가되기 전에 작성한 게임에 있을 수 있습니다. 여전히 동작하지만 when 사용을 권장합니다.

if_all

속성 이름을 나타내는 문자열 또는 문자열 리스트입니다. 지정하면 해당 속성들이 모두 있는 경우에만 이 레이어를 표시합니다.

if_any

속성 이름을 나타내는 문자열 또는 문자열 리스트입니다. 지정하면 해당 속성이 하나라도 있는 경우에만 이 레이어를 표시합니다.

if_not

속성 이름을 나타내는 문자열 또는 문자열 리스트입니다. 지정하면 해당 속성이 하나도 없는 경우에만 이 레이어를 표시합니다.

when 구문으로 변환하려면 다음을:

if_any ["a", "b"]
if_all ["c", "d"]
if_not ["e", "f"]

더 간결한 다음 형식으로 바꿀 수 있습니다.

when (a or b) and c and d and not (e or f).

패턴과 서식 함수

디스플레이어블이 명시적으로 지정되지 않은 속성의 이미지를 찾는 패턴은 다음 요소로 구성됩니다.

  • 공백을 밑줄로 바꾼 layeredimage 이름.

  • multiple이 아닌 그룹에 속한 경우 그룹 이름.

  • variant가 있는 경우 variant 이름.

  • 속성 이름.

위 요소들을 모두 밑줄로 연결합니다. 예를 들어 레이어 이미지 이름이 "augustina work"이고 그룹이 "eyes"이면 augustina_work_eyes_attribute 패턴과 일치하는 이미지를 찾습니다. variant가 blue이면 augustina_work_eyes_blue_attribute 패턴을 사용합니다. 다음 예제를 보세요.

layeredimage augustina work:
    group eyes variant blue:
        attribute closed

속성은 "augustina_work_eyes_blue_closed" 이미지에 연결됩니다. 이는 augustina_work_eyes_blue_closed.png라는 이미지 파일로 해석될 수도 있고, image 문 등으로 명시적으로 정의된 이미지일 수도 있습니다.

패턴의 동작은 format_function으로 모두 변경할 수 있습니다. 위 동작을 내부적으로 구현하는 함수는 layeredimage.format_function()입니다. 직접 만든 format_function으로 대체하려면 이 함수가 받는 인수를 확인하세요.

layeredimage.format_function(what, name, group, variant, attribute, image, image_format, **kwargs)

속성이나 조건에 관한 정보를 디스플레이어블로 변환하기 위해 호출합니다. 제작자가 대체할 수 있지만, 새 함수는 알 수 없는 키워드 인수를 무시해야 합니다.

what

변환할 대상을 설명하는 문자열로, 더 이해하기 쉬운 오류 메시지를 만드는 데 사용합니다.

name

layeredimage의 이름입니다.

group

속성이 속한 그룹입니다. 지정하지 않았거나 조건의 일부이면 None입니다.

variant

그룹에 지정한 variant 인수입니다. 지정하지 않았으면 None입니다.

attribute

속성 자체입니다.

image

디스플레이어블 또는 문자열입니다.

image_format

LayeredImage의 image_format 인수입니다.

image가 None이면 name, group(None이 아닌 경우), variant(None이 아닌 경우), attribute를 밑줄로 연결하여 문자열 image를 만듭니다.

images가 문자열이고 image_format이 None이 아니면, image를 해당 문자열에 서식 적용하여 최종 디스플레이어블을 얻습니다.

예를 들어 name이 "eileen", group이 "expression", attribute가 "happy"이면 image는 "eileen_expression_happy"가 됩니다. image_format이 "images/{image}.png"이면 Ren'Py는 최종적으로 "images/eileen_expression_happy.png"를 찾습니다. 다만 format 인수가 없어도 같은 이미지를 찾는다는 점에 유의하세요.

전달한 format_function은 auto 그룹의 이미지 검색 방식을 바꾸지 않습니다. auto 그룹은 항상 위에서 설명한 패턴을 그대로 사용합니다.

레이어 이미지 프록시

같은 레이어 이미지를 여러 곳에서 사용하려면 프록시가 유용하며 때로는 꼭 필요합니다. 특정 layeredimage에 트랜스폼을 적용한 버전을 만들거나 사이드 이미지로 사용하려는 경우가 이에 해당합니다.

LayeredImageProxy() 객체는 레이어 이미지 하나를 다른 곳에서 복제하여 이 기능을 제공합니다. 예를 들면 다음과 같습니다.

image dupe = LayeredImageProxy("augustina")

독립적으로 표시할 수 있는 이미지 복제본을 만듭니다. 트랜스폼 인수도 받으므로 다음과 같이 사이드 이미지의 위치를 정하는 데 유용합니다.

image side augustina = LayeredImageProxy("augustina", Transform(crop=(0, 0, 362, 362), xoffset=-80))

차이를 살펴보세요.

image sepia_augustina_one = Transform("augustina", matrixcolor=SepiaMatrix())
image sepia_augustina_two = LayeredImageProxy("augustina", Transform(matrixcolor=SepiaMatrix()))

sepia_augustina_one은 "augustina" layeredimage의 원래 버전, 즉 아무 속성도 지정하지 않았을 때 표시되는 이미지에 세피아 효과를 적용합니다. 반면 sepia_augustina_two는 "augustina"가 받는 모든 속성을 받은 뒤 그 결과에 세피아 효과를 적용합니다. 다음과 같이 사용할 수 있다면:

show augustina happy eyes_blue dress

다음과 같이 사용할 수 있습니다.

show sepia_augustina_one happy eyes_blue dress
# won't work, because Transform doesn't take attributes

show sepia_augustina_two happy eyes_blue dress
# will work, and show "augustina happy eyes_blue dress" in sepia effect
class LayeredImageProxy(name, transform=None)

전달받은 속성을 다른 레이어 이미지에 전달하는, 이미지처럼 사용할 수 있는 프록시 객체입니다.

name

프록시 대상 layeredimage의 이름을 나타내는 문자열입니다.

transform

지정하면 프록시 처리 후 이미지에 적용할 트랜스폼 또는 트랜스폼 리스트입니다.

표시할 속성 선택

show 문 뒤에 무엇이 표시되는지는 여러 요인의 영향을 받습니다. 처리 순서를 명확히 설명하기 위해 이 절에서는 show 문부터 화면 표시까지 속성 집합이 거치는 과정을 살펴봅니다.

  • show 문은 이미지 태그 뒤에 초기 속성 집합을 지정합니다.

  • 이미지 태그에 대응하는 config.adjust_attributes 함수가 있으면 이를 호출합니다. 다른 속성 집합을 반환할 수 있으며, 이 경우 기존 집합을 대체하고 기존 집합은 버립니다.

  • config.default_attribute_callbacks 함수가 있고 호출 조건을 만족하면 이를 호출하여 집합에 속성을 추가할 수 있습니다.

이전 단계들은 layeredimage에만 해당하는 과정이 아닙니다. 이 단계가 끝난 뒤에야 Ren'Py가 표시할 이미지나 layeredimage를 결정하기 때문입니다. 따라서 지정한 속성 집합은 show 문 절에서 설명하는 동작에 따라 정의된 이미지 하나(또는 layeredimage, Live2D 등)와 정확히 일치해야 합니다.

  • 그런 다음 지정한 속성을 layeredimage에 정의된 속성들과 조합하면서 이전에 표시한 속성 중 일부는 버리고 나머지는 유지합니다. 인식할 수 없는 속성도 이 시점에 감지하여 관련 오류를 발생시킵니다. 오류가 없으면 새 속성과 유지된 속성을 합친 집합을 Ren'Py가 해당 이미지 태그의 속성 집합으로 인식합니다. 이 계산은 일부 배타성 제약을 반영하지만 전부는 아닙니다. 예를 들어 같은 일반 그룹에 속해서 생기는 배타성은 이때 적용되지만 when 절은 적용되지 않습니다. 따라서 해당 절 때문에 표시되지 않는 속성도 Ren'Py에서는 활성 상태로 간주합니다. 예를 들어 이후 if_x 절의 조건이 더 이상 충족되지 않으면 다시 지정하지 않아도 표시됩니다.

  • layeredimage에 attribute_function을 지정했다면 남은 속성 집합을 인수로 호출합니다. 이 함수는 다른 속성 집합을 반환할 수 있습니다.

  • 이 집합에 layeredimage의 배타성 제약을 다시 적용하며, 이번에는 모든 제약을 적용합니다. 이 마지막 단계에서 남은 속성들을 표시합니다.

사용 팁

이미지 파일명에 밑줄을 사용하세요.

Ren'Py의 레이어 이미지는 기본적으로 이미지 이름의 각 부분을 밑줄로 구분합니다. 공백으로 구분한 이미지를 사용하고 싶을 수도 있지만 나중에 문제가 생길 수 있습니다.

Ren'Py에는 이미 표시 중인 이미지와 이름이 정확히 같은 이미지를 지정하면 그 이미지를 대신 표시하는 규칙이 있습니다. 이 때문에 정의한 레이어 이미지를 거치지 않고 스프라이트가 단독으로 표시되어, 눈만 허공에 떠 있는 등의 이상한 문제가 생길 수 있습니다.

각 스프라이트에 전체 이미지와 다른 태그를 부여하면 이 문제가 발생하지 않습니다.

레이어를 직접 잘라낼 필요는 없습니다.

Ren'Py는 이미지를 RAM에 로드하기 전에 불투명 픽셀의 경계 상자로 잘라 최적화합니다. 따라서 이미지가 올바르게 예측 로딩되고 있다면 직접 이미지를 잘라도 성능이나 이미지 크기에 큰 개선이 없는 것이 일반적입니다.

레이어 이미지에 실행 중 바뀌는 데이터를 사용하지 마세요.

if 문의 조건을 제외하면 layeredimage 블록에 작성한 모든 표현식은 초기화 시점, 즉 레이어 이미지를 처음 정의할 때 평가됩니다. ATL 트랜스폼이나 config.adjust_attributes, config.default_attribute_callbacks, attribute_function 내부의 처리는 다르지만, format_function은 layeredimage를 정의할 때만 호출되므로 이에 해당합니다.

적합한 구문 선택

스프라이트를 항상 표시하려면 always 절이나 attribute x default 구문을 사용합니다. always는 디스플레이어블을 명시적으로 지정해야 하며 패턴을 이용한 자동 연결을 사용할 수 없습니다. attribute는 "x"라는 속성 이름을 사용하며 이 layeredimage에서 항상 활성 상태가 됩니다.

show 문에서 layeredimage에 전달한 속성에 따라 표시하려면, 예를 들어 show eileen jeans 대신 show eileen happy로 선택하려면 attribute 문을 사용합니다. group 블록 안이나 밖에 둘 수 있고 auto 그룹에서 암시적으로 정의할 수도 있습니다.

Python 변수나 조건에 따라 표시하려면 if 문을 사용합니다.

둘 다에 따라 표시하려면 모든 버전을 속성으로 선언하고 전용 config.adjust_attributes 함수를 사용합니다. 예를 들어 show eileen ribbon으로 변숫값에 따라 파란 리본이나 빨간 리본을 표시하되, ribbon 속성을 지정하지 않으면 리본을 표시하지 않도록 할 수 있습니다.

예제

패턴과 auto 그룹

images/ 디렉터리 또는 그 하위 폴더의 다음 파일과 작성된 코드를 살펴보세요.

francis_base.png
francis_face_neutral.png
francis_face_angry.png
francis_face_happy.png
francis_face_very_happy.png
francis_face annoyed.png
francis_supersad.png
layeredimage francis:
    attribute base default
    group face auto:
        attribute neutral default
    attribute supersad image:
        "#00c3"
        xysize (100, 100)

francis layeredimage는 기본 속성인 base를 선언하고 패턴으로 자동 정의된 "francis_base" 이미지와 연결합니다. 패턴은 layeredimage 이름("francis"), 그룹 이름(여기서는 없음), variant 이름(여기서는 없음), 속성 이름("base")을 밑줄로 연결합니다.

이어서 face 그룹에서 명시적인 neutral 속성을 "francis_face_neutral" 이미지에 연결합니다. 같은 패턴을 사용하되 그룹 이름은 "face", 속성 이름은 "neutral"입니다.

명시적 속성에 모두 이미지를 연결한 뒤에는 face가 auto 그룹이므로 자동 정의 여부와 관계없이 기존 이미지에서 패턴과 일치하는 항목을 찾습니다. 여기서는 "francis_face_angry", "francis_face_happy", "francis_face_very_happy"를 찾습니다. 앞과 같은 패턴으로 각각 angry, happy, very_happy 속성에 연결합니다. 다만 "francis_face annoyed" 이미지는 패턴이 밑줄을 요구하는 곳에 공백이 있으므로 annoyed 속성은 정의되지 않습니다.

마지막으로 supersad 속성을 선언합니다. 디스플레이어블을 명시적으로 지정했으므로 패턴으로 이미지를 찾지 않습니다.

"francis_supersad"와 "francis_face annoyed" 이미지는 Ren'Py의 일반적인 규칙에 따라 파일명에서 자동 정의되지만, 어떤 속성이나 auto 그룹과도 일치하지 않아 francis layeredimage에서는 사용하지 않습니다.

이처럼 패턴으로 이미지와 속성을 연결하고 auto 그룹을 사용하면 코드가 크게 줄어듭니다. 모두 명시적으로 선언하면 같은 layeredimage에 13줄이 필요합니다. 직접 확인해 보세요. 또한 이 구문은 스프라이트 조합이 기하급수적으로 늘어나는 경우에도 유연하게 대응합니다. 예를 들어 얼굴을 아무리 추가해도 코드를 바꿀 필요가 없습니다.

속성의 동적 처리

사용 팁 절에서 언급한 것처럼 변수에 따라 속성을 정의하는 예제입니다.

layeredimage eileen:
    attribute base default
    group outfit auto
    group ribbon prefix ribbon:
        attribute red
        attribute blue

default eileen_ribbon_color = "red"

init python:
    def eileen_adjuster(names):
        atts = set(names[1:])
        if "ribbon" in atts:
            atts.remove("ribbon")
            atts.add("ribbon_" + eileen_ribbon_color)
        return names[0], *atts

define config.adjust_attributes["eileen"] = eileen_adjuster

when에서 그룹 사용

when 속성에는 그룹 이름을 지정하여 해당 그룹의 속성이 하나라도 표시될 때만, 또는 하나도 표시되지 않을 때만 레이어를 표시하도록 할 수 없습니다. 다만 layeredimage 구문의 다른 기능을 조합하면 구현할 수 있습니다.

그룹에 기본 속성이 없다면 원하는 이름의 기본 null 속성을 추가할 수 있습니다. 그러면 그룹의 속성이 아무것도 표시되지 않을 때 이 속성이 활성화됩니다. 실제로 표시되는 내용은 없습니다. 그룹의 속성을 숨기면 이 기본 속성이 다시 활성화됩니다.

layeredimage eliza:
    attribute head_and_hair default
    group top auto
    group headtop prefix headtop:
        attribute notop null default
        attribute hat
        attribute cap
    attribute hair_patch when notop

여기서 hair_patch 속성은 이를 가릴 모자가 없을 때만 Eliza의 맨 위 레이어 위에 머리카락을 더 표시합니다. 예를 들어 어깨 위에 표시할 수 있습니다.