목차

이전 항목

파이썬에서의 트랜스폼과 트랜지션

다음 항목

모드

링크


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

스크린과 파이썬

렌파이는 렌파이 스크린 언어에서뿐만 아니라 파이썬 언어로 스크린을 정의하는 것을 지원합니다. 파이썬 스크린은 스크린 함수를 renpy.define_screen() 함수에 설정하는 것으로 만들어집니다. 그렇게 만들어진 스크린은 다른 스크린들처럼 사용할 수 있습니다.

스크린 함수는 유효 영역 변수에 상응하는 매개 변수를 받아야 하며, 다른 키워드 인수는 무시합니다(그말인 즉, 기타 키워드 인수 **kwargs 는 매개 변수 목록 마지막에 위치해야 한다는 것입니다). 그 뒤 디스플레이어블을 스크린에 표시하기 위해 UI함수를 불러냅니다. 스크린 함수는 인터렉션이 끝나거나 재시작 될 때 언제라도 호출됩니다.

재시작 과정이 유저에게 중간 과정이 없는 것처럼 보이고 재시작이 발생하지 않도록 하기 위해서는, 모든 UI 함수 호출은 id 인수를 제공해야 합니다. 스크린이 재생성되기 때문에, 렌파이는 같은 아이디를 가진 낡은 디스플레이어블의 내용물들과 각각의 디스플레이어블을 업데이트합니다. id는 스크린 언어에 의해 자동으로 생산되나, 스크린을 파이썬으로 만든다면 반드시 수동으로 설정해야할 것입니다.

아래는 간단한 파이썬 스크린 코드의 예입니다:

init python:
    def say_screen(who, what, **kwargs):
        ui.window(id="window")
        ui.vbox(id="say_vbox")

        ui.text(who, id="who")
        ui.text(what, id="what")

        ui.close()

    renpy.define_screen("say", say_screen)

스크린 함수

아래의 함수는 스크린 정의, 표시, 숨기기를 지원합니다.

renpy.call_screen(_screen_name, *args, **kwargs)

call screen 문과 프로그램적으로 동등하다.

이 함수는 _screen_name 을 스크린으로 표시하고, 인터렉션을 발생시킨다. 스크린은 마지막 인터렉션에서 사라지며 그 인터렉션의 결과물은 반환된다.

_ 으로 시작하지 않는 키워드 인수는 스크린 영역으로 전달된다.

키워드 인수 _with_none 가 거짓이라면 "with None"은 인터렉션이 종료한 시점에 실행되지 않는다.

renpy.define_screen(name, function, modal=True, zorder=0, tag=None)

name`으로 스크린을 정의한다. `name 은 문자열이어야 한다.

function 스크린을 표시하기 위해 호출되는 함수. 이 함수는 키워드 인수처럼 스크린 영역과 함께 호출된다. 추가 키워드 인수들은 무시한다.

ui를 스크린에 추가하기 위해 이 함수는 ui 함수를 호출해야 한다.

modal
계산 결과로 스크린이 모달 스크린이어야 하는지를 결정하는 문자열. 모달 스크린은 스크린이 입력 이벤트의 영향을 받는 것을 방지한다.
zorder
스크린이 표시될 위치 순서를 제어하는 정수. 더 큰 수로 zorder가 지정된 스크린은 작은 수로 zorder가 지정된 스크린보다 위에 올라오게 된다.
tag
이 화면과 관련된 태그. 스크린이 나타났을 때, 같은 태그가 지정된 다른 스크린을 대체한다. 기본적으로 태그는 스크린의 이름으로 설정된다.
predict
참이라면, 이미지 예측을 하기 위해 불러올 수 있는 스크린. 거짓이면 이미지 예측을 하기 위해 불러올 수 없다. 기본값은 참이다.
variant
문자열. 이 스크린을 사용할 스크린 종류를 지정한다.
renpy.get_screen(name, layer="screen")

지정한 tag 로 ScreenDisplayable의 값을 layer 에 반환한다. 태그가 있는 디스플레이어블이 없으면 스크린 이름으로 대체한다. 그래도 없는 경우 None이 반환된다.

renpy.get_widget(screen, id, layer='screens')

layer 에 있는 screen 으로부터, id가 id 로 지정된 위젯을 반환한다. 스크린이 존재하지 않거나, 스크린에 id 로 지정된 위젯이 없는 경우에는 None을 반환한다.

renpy.get_widget_properties(id, screen=None, layer='screens')

layer 에 있는 screenid 로 지정된 위젯의 속성을 반환한다. screen 이 None 이면 현재 스크린의 속성을 반환한다.

스크린 코드 내부에서 사용할 수 있다.

이 함수는 위젯 속성이 적힌 딕셔너리를 반환하므로 개별 속성을 얻기 위해

renpy.hide_screen(tag, layer='screens')

hide screen문과 프로그램적으로 동등하다.

layer`tag`로 지정된 스크린을 숨긴다.

renpy.predicting()

렌파이가 현재 스크린을 예측한다면 참을 반환한다.

renpy.show_screen(_screen_name, *_args, **kwargs)

show screen문과 프로그램적으로 동등하다.

지정한 스크린을 표시한다. 아래와 같은 키워드 인수를 받는다.

_screen_name
표시할 스크린의 이름
_layer
스크린을 표시할 레이어
_tag
표시할 스크린에 붙을 태그. 지정되지 않으면 스크린과 관계된 태그가 기본으로 설정된다. 그것도 지정되지 않았다면 스크린의 이름이 기본으로 설정된다.
_widget_properties
위젯의 id부터 속성 이름 -> 속성값 맵까지의 맵. id의 위젯이 스크린에 나타나면 지정된 속성이 그에 추가된다.
_transient
값이 참이면, 스크린은 현재 인터렉션이 끝난 시점에 자동으로 숨겨질 것이다.

언더바(_)가 맨 앞에 붙지 않은 키워드 인수는 스크린 영역 초기화에 사용될 것이다.

renpy.start_predict_screen(_screen_name, *args, **kwargs)

렌파이가 지정한 인수와 함께 표시될 _screen_name`라는 이름의 스크린을 예측하기 시작하도록 한다. 이전에 예측한 `_screen_name 라는 스크린 대신에 예측한다. 스크린 예측을 중단하려면 renpy.stop_predict_screen() 를 호출하라.

renpy.stop_predict_screen(name)

앞으로 표시될 name 스크린에 대한 예측을 중단한다.

renpy.variant(name)

name 이 렌파이에서 사용할 수 있는 스크린 종류라면 True를 반환한다. 자세한 내용은 스크린 종류 를 참조하라. 이 함수는 선택된 스크린 종류에서 사용할 스타일을 설정하기 위해 파이썬의 if문을 사용할 때, 그 if문의 조건으로 사용할 수도 있다.

`name`은 스크린 종류의 리스트일 수 있다. 이 경우에 이 함수는 리스트 내에서 선택된 스크린 종류가 존재할 때 True를 반환한다.

UI 함수

UI 함수는 스크린 언어 명령문과 동등한 파이썬 함수입니다. 각 스크린 언어 명령문에는 그와 같은 이름을 가진 UI 함수가 있습니다. 예를 들어 ui.text는 스크린 언어의 text문과 동일하며 ui.add는 add문와 동일합니다.

파이썬 인수와 스크린 언어의 매개변수와 인수를 연관짓는 간단한 방법이 있습니다. 스크린 언어의 속성이 키워드 인수가 되면 매개 변수는 위치 인수가 됩니다. 예를 들어 스크린 언어 명령문이 아래와 같다면:

text "Hello, World" size 40 xalign 0.5

이렇게 된다는 얘기입니다:

ui.text("Hello, World", size=40, xalign=0.5)

(id 매개 변수가 필히 추가됐어야 하긴 합니다.)

UI 함수는 그들이 가질 수 있는 하위 디스플레이어블의 숫자의 종류에 따라, 세 그룹으로 나눌 수 있습니다.

아래의 UI함수는 하위 디스플레이어블을 받지 않습니다.

  • ui.add
  • ui.bar
  • ui.imagebutton
  • ui.input
  • ui.key
  • ui.label
  • ui.null
  • ui.text
  • ui.textbutton
  • ui.timer
  • ui.vbar
  • ui.hotspot
  • ui.hotbar
  • ui.spritemanager

아래의 UI 함수는 하위 디스플레이어블을 하나 받습니다. 반드시 받아야 하며, 하위 디스플레이어블을 잃는 경우에는 ui.null()을 받아야 합니다.

  • ui.button
  • ui.frame
  • ui.transform
  • ui.window
  • ui.drag

아래의 UI 함수는 하위 디스플레이어블을 여러 개 받습니다. ui.close() 가 호출될 때까지 하위 디스플레이어블을 받습니다.

  • ui.fixed
  • ui.grid
  • ui.hbox
  • ui.side
  • ui.vbox
  • ui.imagemap
  • ui.draggroup

스크린 언어 명령문과 상응하지 않는 몇 가지 UI 함수들이 있습니다. 그에 상응하는 개념들이 스크린 언어에는 존재하지 않기 때문입니다.

ui.adjustment(range=1, value=0, step=None, page=0, changed=None, adjustable=None, ranged=None)

바나 뷰포트에 의해 조정될 수 있는 값을 나타내는 조정 객체. 값, 값의 범위, 값을 조정할 단계 등의 정보를 포함한다.

다음은 조정 객체의 속성이나 필드에 해당하는 매개변수이다.

range
조정 객체의 범위. 사용되는 값은 숫자.
value
조정 객체가 가지는 값. 사용되는 값은 숫자.
step

몇 단계에 걸쳐 조정할지는 지를 결정할 때 쓰인다. 사용되는 값은 숫자. None 이라면 page 의 1/10. 그 외에는 range 의 1/20.

마우스 휠로 뷰포트를 스크롤할 때 사용된다.

page

조정 객체의 페이지 사이즈. None이라면 뷰포트에 의해 자동으로 설정된다. 설정되지 않으면 range 의 1/10이다.

스크롤바를 클릭할 때 사용된다.

다음은 조정 객체의 동작을 제어하는 매개 변수이다.

adjustable

True면 바로 이 조정 객체를 바꿀 수 있다. False라면 할 수 없다.

changed 함수가 지정되거나 조정 객체가 뷰포트에서 사용된다면 자동으로 True로 설정된다. 그 외의 경우에는 False값을 가진다.

changed
조정 객체의 값이 바뀔 때 새 값과 함께 호출되는 함수.
ranged
조정 객체의 범위가 뷰포트에 의해 설정되었을 때 조정 객체와 함께 호출되는 함수.
change(value)

조정 객체를 사용하는 뷰포트나 바를 업데이트하면 조정 객체의 값을 value 로 바꾼다.

ui.at(transform)

다음 디스플레이블이 생성될 때 적용할 변환 효과를 지정한다. 모든 UI함수가 at 인수를 받기 때문에 이 함수는 거의 쓸모 없다.

ui.close()

UI 함수에 의해 생성된 디스플레이어블을 닫는다. 디스플레이어블이 닫히면 새로운 디스플레이어블을 닫힌 UI 의 상위 UI 에 추가하거나, 아무 디스플레이어블도 열리지 않았다면 그냥 레이어에 추가한다.

ui.detached()

이 함수 다음에 적힌 디스플레이어블을 컨테이너나 레이어에 추가하지 않는다. UI 함수의 결과물을 변수에 배정하고 싶을 때 사용하면 된다.

ui.interact(roll_forward=None, mouse='default')

인터렉션을 발생시켜 인터렉션의 결과를 반환한다. 렌파이가 스크린을 다시 그리고 입력 받는 이벤트를 처리하도록 한다. 디스플레이어블이 이벤트에 반응한 결과로 값을 반환하면 이 값은 ui.interact 에서 반환하고 인터렉션을 종료시킨다.

이 함수는 직접 호출되는 경우가 드물다. 일반적으로 say문, menu 문, with 문, pause 문, call screen 문, renpy.input(), 기타 여러가지 기능들이 호출한다. 그러나 필요하다면 직접 호출할 수 있다.

인터렉션이 종료할 때 임시 레이어 및 transient=True 로 설정한 모든 스크린은 scene 리스트에서 지워진다.

매뉴얼에 기록한 인수는 아래에 적힌 두 가지이다. 다른 인수들은 렌파이 내부에서 사용하는 인수이기 때문에 매뉴얼에 기록하지 않았으며, 모든 인수를 키워드 인수로 전달해야 한다.

roll_forward
롤포워드가 발생했을 때 이 함수가 반환할 정보. (None이라면 롤포워드를 무시한다.) 일반적으로는 renpy.roll_forward_info() 함수의 결과값을 전달받아야 한다.
mouse
이 함수가 실행되는 동안 사용할 마우스 커서 스타일.
ui.layer(name)

디스플레이어블을 name 레이어에 추가한다. 나중에 ui.close() 를 사용하여 닫아야 한다.

ui.screen_id(id_, d)

마치 디스플레이어블 d`가 id가 `id_ 인 스크린에 스크린 언어를 사용해 생성된 것처럼 `d`를 id가 `id_`인 위젯에 배정한다.

Action 클래스

스크린 언어로 만들어지는 디스플레이어블은 대부분 액션을 인수로 받습니다. 액션은 아래 셋 가운데한 가지입니다:

  • (함수나 바운드 메소드처럼) 아무 인수도 받지 않는 콜러블 파이썬 객체
  • Action 클래스를 승계하는 클래스의 객체
  • 다른 액션들 목록

Action 클래스를 상속할 때의 장점은 버튼이 작동 가능한 상태를 결정하거나 버튼이 선택된 때를 결정하는 메소드를 재정의하는 것이 가능하다는 점입니다.

class Action

새 액션을 정의하려면, 이 클래스를 상속하라. 이 클래스에 있는 메소드를 재정의하면 액션의 동작을 변경할 수 있다.

__call__(self)

액션이 작동할 때 호출되는 메소드. 대부분의 경우, 액션에서 None이 아닌 값을 반환되면 현재 인터렉션을 종료시킨다.

이 메소드는 반드시 재정의해야한다. 기본 메소드는 "구현되지 않았음Not Implemented" 에러를 발생시키기 때문이다(따라서 렌파이는 오류를 보고하게 된다.).

get_sensitive(self)

이 메소드는 이 액션이 있는 버튼이 작동 가능한 상태이어야 하는지를 정하기 위해 호출된다. 버튼이 작동가능하다면 참값을 반환해야 한다.

이 메소드가 거짓값을 반환하더라도 __call__ 호출될 수 있다는 점을 기억해둘 것.

기본적으로 구현된 메소드는 참값을 반환한다.

get_selected(self)

이 메소드는 버튼이 선택된 버튼으로 렌더되어야 하는 경우 참값을 반환한다. 그 외의 경우 거짓값을 반환한다.

기본적으로 구현된 메소드는 False를 반환한다.

periodic(self, st)

이 메소드는 인터렉션의 시작지점마다 한 번씩 호출되고, 그 후 정기적으로 호출된다. 숫자를 반환하는 경우, 그만큼의 시간이 경과한 후에 호출될 것이다. 그보다 일찍 호출될 수도 있다.

이 메소드의 주된 사용법은 get_selected나 get_sensitive의 값이 변경되어야 할 경우 renpy.restart_interaction() 을 호출하기 위한 것이다.

이 메소드는 하나의 인수를 받는다:

st
이 액션과 관련된 스크린이나 디스플레이어블이 처음으로 나타난 후부터 경과한 시간 (초 단위 숫자)
unhovered(self):

이 액션이 버튼이나 그와 유사한 객체의 hovered 매개변수에서 사용될 때 그 객체가 포커스를 잃은 경우 이 메소드가 호출된다.

BarValue 클래스

bar, vbar, hotbar를 생성할 때 Barvalue 객체는 value 인수를 받을 수 있습니다. BarValue 객체의 메소드들은 adjustment 객체나 스타일을 얻을 때 호출됩니다.

class BarValue

새로운 BarValue를 정의하기 위해서 이 클래스를 상속하고 몇 가지 메소드를 재정의해야 한다.

get_adjustment(self)

이 메소드는 바가 adjustment 객체를 얻기 위해 호출된다. ui.adjustment() 로 adjustment를 생성해야 하며, 그 후에는 이렇게 만들어진 객체를 반환해야 한다.

이 메소드는 반드시 재정의되어야한다. 기본 메소드는 "구현되지 않았음Not Implemented" 에러를 발생시키기 때문이다 (따라서 렌파이는 오류를 보고하게 된다.).

get_style(self)

이 값을 이용하는 바의 스타일을 정의하기 위해 사용한다. 이 메소드는 두 개의 스타일 이름이나 스타일 객체의 튜플을 반환해야 한다. 첫 번째 것은 바, 두번째 것은 vbar에 사용된다.

기본 설정은 ("bar", "vbar") 이다.

replaces(self, other)

BarValue 가 다른 BarValue로 대체되었을 때, 예를 들면 스크린이 업데이트되었거나 하는 경우에 호출 된다. 다른 곳에서 이 BarValue를 업데이트하기 위해 사용할 수도 있다. 이 메소드는 get_adjustment 이전에 호출된다.

otherself 와 같은 타입일 필요는 없다.

periodic(self, st)

이 메소드는 각 인터렉션의 시작지점에서 호출된다. 초 단위 숫자를 반환하면, 그 이상의 초 단위 시간이 경과하기 전에 호출될 것이다. 혹은 더 일찍 호출될 수도 있다. get_adjustment 이후에 호출된다.

이 메소드는 AnimatedValue() 처럼 시간이 경과함에 따라 값을 업데이트하는 경우에 사용할 수 있다. 그렇게 하기 위해서는 get_adjustment가 adjustment를 저장해야 하며, periodic는 adjustment의 변경된 메소드를 호출해야 한다.

제작자 정의 스크린 언어 명령문

렌파이에서는 제작자가 임의로 스크린 언어 명령문을 정의할 수 있습니다. 제작자 정의 스크린 언어 명령문은 스크린 언어의 :ref:`use문 <sl-use>`용 래퍼입니다. 위치 인수는 그대로 위치 인수이며, 속성은 키워드 인수가 되고 명령문이 블럭을 받는다면 use문도 그렇게 됩니다. 예를 들어 다음과 같은 스크린 언어 명령문이 있다면:

titledwindow "Test Window":
    icon "icon.png"

    text "테스트입니다."

이 명령문은 아래처럼 됩니다.:

use titledwindow("Test Window", icon="icon.png"):
    text "테스트입니다."

제작자 정의 스크린 언어 명령문은 반드시 python early 블럭에 등록되어야 합니다. 더불어, 제작자 정의 명령문을 포함한 파일이름은 그 파일이름이 사용되는 파일보다 먼저 불려와야 합니다. 렌파이는 유니코드 순서대로 파일을 불러오므로, 일반적으로 제작자 정의 명령문을 등록한 파일 이름에 01이나 그보다 작은 숫자를 접두사처럼 붙이는 것이 바람직할 것입니다.

제작자 정의 스크린 언어 명령문은 renpy.register_sl_statement 함수로 등록할 수 있습니다.:

class renpy.register_sl_displayable(name, displayable, style, nchildren=0, scope=False, replaces=False, default_keywords={})

디스플레이어블을 생성하는 스크린 언어 명령문을 등록한다.

name
스크린 언어 명령문의 이름. 렌파이 키워드가 적힌 문자열. 이 키워드는 새 명령문을 이끌 때 사용된다.
displayable

호출되었을 때 디스플레이어블 객체를 반환하는 함수. 모든 위치 인수, 속성, 스타일 속성은 이 함수에 인수로 전달된다. 다른 키워드 인수 역시 아래에 설명한 대로 함수에 전달된다.

이 함수는 반드시 Displayable 을 반환해야 한다. 여러 디스플레이어블을 반환하면 가장 외부에 있는 디스플레이어블의 _main 속성이 하위 디스플레이어블을 추가할 수 있는 "main" 디스플레이어블로 설정된다.

style
이 디스플레이어블에 적용할 스타일의 기본 이름. 스타일 속성을 지정하지 않으면 스타일 접두사가 붙는다. 계산된 스타일은 style 키워드 인수로서 displayable 하무에 전달된다.
nchildren

이 디스플레이어블이 받을 하위 디스플레이어블 수. 다음 중 하나이어야 한다.:

0
하위 디스플레이어블을 받지 않는다.
1
하위 디스플레이어블을 하나 받는다. 하나 이상을 받으면 하위 디스플레이어블은 Fixed 에 배치된다.
"many"
하나 이상의 디스플레이어블을 받는다.

아래에 나열된 인수는 키워드 인수를 사용해 전달되어야 한다.:

replaces
이 값이 참이고 이 디스플레이어블이 이전 디스플레이어블을 대체하면, 대체된 디스플레이어블은 새로 나타난 이 디스플레이어블에 매개변수로 전달된다.
default_keywords
디스플레이어블에 지정할 키워드 인수의 기본 셋.

아래 메소드를 호출하면 위치 인수와 속성 인수를 받을 수 있는 객체를 반환한다. 각각의 메소드는 호출한 객체를 다시 반환하므로, 메소드가 서로 연속적으로 계산할 수 있다.

add_positional(name)

name 이라는 위치 인수를 추가한다.

add_property(name):

name 이라는 속성을 추가한다. 속성은 키워드 인수로서 전달된다.

add_style_property(name):

name 이 접미사로 붙고 다양한 스타일 속성이 접두사로 붙는 속성 계열을 추가한다. 예를 들어 ("size") 와 함께 호출되면, 이것은 size, idle_size, hover_size 등을 정의할 것이다.

add_prefix_style_property(prefix, name):

스토어 속성 접두사인 prefixname 로 구성된 속성 계열을 추가한다. 예를 들어 prefix에 text_, name에 size 를 입력하고 호출하면 이 메소드는 text_size, text_idle_size, text_hover_size 등을 만들 것이다.

add_property_group(group, prefix=''):

prefix 가 접두사로 붙는 속성 그룹을 추가한다. group 에 입력할 문자열은 다음 중 하나이어야 한다.:

  • "bar"
  • "box"
  • "button"
  • "position"
  • "text"
  • "window"

이 속성들은 스타일 속성 그룹과 상응한다. 그룹에 "ui" 를 입력하면 일반 ui 속성 을 추가한다.

class renpy.register_sl_statement(name, positional=0, children='many', screen=None)

맞춤 스크린 언어 명령문을 렌파이에 등록한다.

name
반드시 단어이어야 한다. 맞춤 스크린 언어 명령문의 이름으로 사용된다.
positional
이 명령문이 입력 받을 위치 매개변수의 개수.
children
이 맞춤 명령문이 받을 하위 디스플레이어블의 개수. 0, 1, 또는 0 이상을 의미하는 "many" 를 입력해야 한다.
screen
사용할 스크린. 입력하지 않으면 name 이 기본값이 된다.

위치 인수와 속성을 가질 수 있는 객체를 반환한다. 이 객체는 class:renpy.register_sl_displayable 가 반환하는 객체와 동일하게 .add_ 메소드를 가지고 있다.

제작자 정의 스크린 언어 명령문의 예제로, 위에서 사용했던 titledwindow 라는 명령문을 구현한 스크립트를 준비했습니다. 제일 먼저 이 명령문은 01custom.rpy 같은 파일처럼 렌파이가 구동될 때 일찍 불려오는 파일의 python early 블럭에 등록되어야 합니다. 명령문을 등록하는 방식은 다음과 같습니다.

python early:
    renpy.register_sl_statement("titledwindow", positional=1, children=1).add_property("icon").add_property("pos")

그 다음, 직접 만든 명령문을 구현하는 스크린을 정의해야 합니다. 이 스크린은 아무 파일에 정의해도 됩니다. 스크린은 다음과 같습니다.

screen titledwindow(title, icon=None, pos=(0, 0)):
    drag:
        pos pos

        frame:
            background "#00000080"

            has vbox

            hbox:
                if icon is not None:
                    add icon

                text title

            null height 15

            transclude