界面與Python link

Ren’Py支持使用Python定義界面(screen),與使用Ren’Py界面語言能實現一樣的效果。將一個界面函數傳入函數 renpy.define_screen() ,就可以創建一個Python界面。創建的Python界面可以跟其他任何界面一樣使用。

這個界面函數應該包含需求變數的對應參數,並忽略額外的關鍵字入參(也就是,函數的入參列表結尾是 **kwargs 。)。然後需要調用UI函數在界面上添加可視組件。界面函數需要能在任何互動行為開始後都能被調用。

為了確保函數重新運行時無縫的用戶體驗(並不導致某些東西重設),每次調用UI函數都提供 id 入參就很重要。如果重新創建了某個界面,Ren’Py會使用原可視組件內容的id更新每一個新的可視組件。id通過界面語言自動生成,但是手工處理界面時也許需要人工指定id。

Warning

不贊成也不推薦使用UI函數作為界面函數。

這是一個Python界面的樣例:

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)

界面函數 link

下定函數支持定義、顯示和隱藏界面。

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

在程序上等效於call screen語句。

該函數將 _screen_name 做為一個界面顯示,並觸發某個互動行為。互動結束後界面隱藏,並返回互動結果。

不以下劃線“_”開頭的關鍵字入參都會傳入界面的作用域。

如果關鍵字入參 _with_none 的值是False,互動結束後結尾的“with None”分句不會運行。

renpy.define_screen(name, function, modal="False", zorder="0", tag=None, variant=None) link

定義一個名為 name 的界面。

function

調用該函數可以顯示界面。調用該函數時,使用界面作用域(scope)作為需要的關鍵字入參。它會忽略其他的關鍵字入參。

這個函數需要調用ui函數將組件添加到界面上。

modal
一個字串,根據計算後的值決定創建的界面是否模態(modal)。一個模態(modal)界面會防止它的子界面接受輸入事件消息。
zorder
一個字串,最終計算後的值應該是一個整數。這個證書控制界面顯示順序。zorder值大的界面顯示在zorder值小的界面上方。
tag
界面關聯的圖像標籤(tag)。顯示界面時,所有帶有同樣標籤的其他界面都會被替換。標籤默認與界面名相同。
predict
若為True,界面啟用圖像預載入。若為False,不使用預載入。預設值是Trues,
variant
字串。表示使用的界面變種(variant)。
renpy.get_screen(name, layer=None) link

返回在圖層(layer)上名為 name 的界面可視組件。name 首先被看作是一個圖像標籤(tag)名,其次是一個界面名。如果那個界面不被顯示,就返回None。

根據 name 可能得到一個界面名的列表,第一正在顯示的界面作為最終結果返回。

該函數可以用於檢查某個界面是否正在顯示:

if renpy.get_screen("say"):
    text "The say screen is showing."
else:
    text "The say screen is hidden."
renpy.get_widget(screen, id, layer=None) link

返回圖層 layer 上的界面 screen 中帶有 id 的組件(widget)。如果界面不存在或界面中不存在帶有那個id的組件,則返回None。

renpy.get_widget_properties(id, screen=None, layer=None) link

返回圖層 layer 上界面 screen 中帶有 id 的組件(widget)的特性(property)。如果 screen 為None,返回當前界面的特性(property)。該函數可以用在某個界面的Python或特性(property)代碼中。

需要注意的是,這個函數返回結果是組件特性的字典。想要得到單個特性的值,就要進入字典取值。

renpy.hide_screen(tag, layer=None) link

等效於“hide screen”語句。

隱藏圖層 layer 上帶圖像標籤 tag 的界面。

renpy.predicting() link

Ren’Py正在預載入界面的情況下返回True。

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

等效於show screen語句。

這個函數使用下列關鍵字入參:

_screen_name
想要顯示的界面的名稱。
_layer
界面顯示使用的圖層名。
_zorder
界面顯示的zorder值。未賦值情況下,zorder值與關聯界面相同。預設值是0。
_tag
界面顯示使用的圖像標籤(tag)。如果沒有指定,就使用界面的圖像標籤關聯的默認標籤。如果那也沒有指定,預設使用界面的名稱做為標籤名。
_widget_properties
從組件(widget)的id到某個“特性名->特性值”映射的映射關係。當帶那個id的組件(widget)在界面上顯示時,就能為其添加指定的特性(property)。
_transient
若為True,界面會在當前互動結束後自動隱藏。

不以下劃線(_)開頭的關鍵字入參用於初始化界面的作用域。

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

觸發Ren’Py開始快取名為 _screen_name 的界面,那個界面之後會使用給定的入參顯示。這個函數會替換之前 _screen_name 的快取。需要停止快取某個界面的話,調用 renpy.stop_predict_screen()

renpy.stop_predict_screen(name) link

觸發Ren’Py停止快取名為 name 的界面。

renpy.variant(name) link

如果 name 是Ren’Py中可用的某個界面變種(variant),就返回True。詳見:ref:界面變種 <screen-variants>。這個函數可以用做條件表達式,在Python的if語句中根據界面變種選擇使用對應的樣式(style)。

name 也可以是一個界面變種列表,只要列表中任何變種被選擇就返回True。

UI Functions link

Note

Ren’Py的執行機制已經改變過,創建可視組件的UI函數現在可能比它們的等效界面語言效率要慢得多。

UI函數是界面語言語句的等效Python語句。每條界面語言語言都有一個同名的UI函數。例如,ui.text函數對應text語句,而ui.add函數對應add語句。

這裡有一個界面語言的參數與Python入參之間的簡單映射關係。界面語言參數變成固定位置入參,特性(property)變成關鍵字入參。舉例,界面語言語句:

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=None, changed=None, adjustable=None, ranged=None) link

adjustment對象表示可以通過某個條(bar)或視口(viewport)調整的值。Adjustment對象包括值的訊息,值的範圍,以及修改這個對象使用的最小步長和最大頁面(page)。

下列參數分別對應Adjustment對象的欄位(field)或者特性(property)。

range
調整範圍,一個數值。
value
調整為這個值,一個數值。
step

調整的步長,一個數值。若為None,預設值是一個頁面(page)的1/10大小,前提是設置了頁面大小。否則預設為 range 大小的1/20。

使用滑鼠滾輪滾動一個視口(viewport)時會用到這個值。

page

Adjustment對象的頁面(page)大小。若為None,會通過視口(viewport)自動設置。如果沒有設置,預設值是 range 大小的1/10。

當點擊一個滾動條(scrollbar)時,這項值會被用到。

下列參數控制Adjustment對象的行為。

adjustable

若為True,條(bar)可以修改Adjustment對象。若為False,則不能修改。

如果給定了 changed 函數或者Adjustment對象有一個關聯的視口(viewport),那這項的預設值是True。否則預設值是False。

changed
當Adjustment的值發生改變時,會用新的值調用這個函數。
ranged
當通過一個視口(viewport)設置了Adjustment的範圍時,會用Adjustment對象調用這個函數。
ui.change(value) link

將Adjustment的值修改為 value ,並更新所有使用該Adjustment對象的條(bar)和視口(viewport)。

ui.at(transform) link

指定創建的下一個可視組件使用的變換(transform)。這個做法已經淘汰,現在所有UI函數都會使用一個at入參。

ui.close() link

關閉一個通過UI函數創建的可視組件。當可視組件關閉後,我們可以給它的父組件添加新的可視組件,如果沒有可用的父組件則為其所在圖層添加新的可視組件。

ui.detached() link

不在任何圖層或容器內添加下一個可視組件。如果你想要將某個UI函數的結果賦值給某個變數的話,就使用這個函數。

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

觸發某個與用戶的交互動作,並返回交互的結果。這個函數讓Ren’Py重繪界面並開始處理輸入事件。當某個可視組件對應某個事件返回了一個值,那個值會從ui.interact返回,然後互動結束。

這個函數極少被直接調用。通常會被Ren’Py的其他部分調用,包括say語句、menu語句、with語句、pause語句、call screen語句、 renpy.input() 等等。不過,必要的時候也可以直接調用。

當某個互動結束,transient圖層和所有“transient=True”的界面都會從場景(scene)列表中清除。

下列入參有文件說明。其他沒有文件說明的入參屬於Ren’Py內部使用。請都用關鍵字入參。

roll_forward
當前向滾動發生時,這個函數會返回相應的訊息。(若為None,前向滾動會被忽略。)這項應該總是傳入 renpy.roll_forward_info() 函數的結果。
mouse
這個函數中滑鼠指針使用的樣式。
ui.layer(name) link

為名為 name 的圖層添加可視組件。圖層的關閉必須使用 ui.close()

ui.screen_id(id_, d) link

如果使用了 id 和一個screen語句創建了界面組件(widget),則將可視組件 d 聲明為界面組件 id

行為(action) link

界面語言創建的許多可視組件都使用行為(action)作為入參。一個行為(action)是以下三種情況之一:

  • 一個可以被調用的Python對象(比如函數或綁定方法),不使用入參。
  • 父類為Action類的某個類的一個對象。
  • Action對象列表。

繼承Action類對象的好處是,允許你重寫類的方法(method),比如確認某個按鈕什麼情況下被選中的方法,以及判斷按鈕何時可用。

class Action link

要定義一個新的action,需要從這個類繼承。 重寫此類中的方法以更改action的行為。

__call__(self) link

當行為啟動狀態下,這個方法會被調用。在很多情況下,行為會返回一個非None值,並讓當前的互動結束。

繼承後的類必須重寫這個方法,使用預設方法會出現“未實現(NotImplemented)”錯誤(並被Ren’Py阻止直接報出這個錯誤)。

get_sensitive(self) link

調用這個方法判斷使用這個行為的按鈕是否可用。如果按鈕可用,則返回True。

注意,在這個方法返回False的情況下, __call__ 依然會被調用。

預設的實現會返回True。

get_selected(self) link

如果按鈕渲染為被選中的按鈕就返回True,否則返回False。

預設的實現會返回False。

get_tooltip(self) link

沒有指定提示框(tooltip)的情況下,將為按鈕獲取一個預設的提示框。返回值是提示框的值,或者提示框未知的情況下返回None。

默認返回None。

periodic(self, st) link

在每次互動的開頭這個方法都會被調用一次,之後週期性調用。如果方法返回一個數值,就會在這個數值(單位為秒)的時間後再次調用,但其間也可以被很快直接調用。

這個方法的主要用途是調用 renpy.restart_interaction() ,前提是需要改變get_selected或get_sensitive的值。

方法使用一個入參:

st
這個行為關聯的界面或可視組件首次顯示後經過的時間(單位為秒)。
unhovered(self):

如果某個按鈕(或類似對象)處於滑鼠懸垂(hovered)狀態下,當對象失去焦點時會調用這個方法。

想要在Python環境下運行某個行為(action),需要使用renpy.run。

renpy.is_selected(action) link

action 表示selected時返回True,否則返回False。

renpy.is_sensitive(action) link

action 表示sensitive時返回True,否則返回False。

renpy.run(action) link

運行一個行為或者行為列表。單個行為調用時不帶入參,行為列表按順序執行,None則忽略。

行為列表中第一個行為執行結果作為函數的返回值。

ui.is_selected(action) link

action 表示selected時返回True,否則返回False。

ui.is_sensitive(action) link

action 表示sensitive時返回True,否則返回False。

條值(barvalue) link

當創建一個bar、vbar或hotbar時,可以使用一個BarValue對象作為條(bar)的值特性(property)。調用BarValue對象的方法可以調整數值和樣式。

class BarValue link

定義一個新的BarValue時,可以繼承這個類並重寫一些方法。

get_adjustment(self) link

調用這個方法可以獲得一個針對條(bar)的adjustment對象。這個方法使用 ui.adjustment() 創建Adjustment對象,並返回創建的對象。

繼承後的類必須重寫這個方法,使用預設方法會出現“未實現(NotImplemented)”錯誤(並被Ren’Py阻止直接報出這個錯誤)。

get_style(self) link

這個方法用於判斷條(bar)使用的樣式。返回的是一個二元的元組,元素類型為樣式名稱或Style對象。第一個元素用於bar,第二個元素用於vbar。

預設值是(“bar”, “vbar”)。

get_tooltip(self) link

沒有指定提示框(tooltip)的情況下,將為按鈕獲取一個預設的提示框。返回值是提示框的值,或者提示框未知的情況下返回None。

默認返回None。

replaces(self, other) link

當某個界面更新,需要更換一個BarValue時,調用這個方法。它可以用於更新BarValue。調用順序在get_adjustment之前。

注意, other 不需要與 self 的類型相同。

periodic(self, st) link

在每次互動的開頭這個方法都會被調用一次,之後週期性調用。如果方法返回一個數值,就會在這個數值(單位為秒)的時間後再次調用,但其間也可以被很快直接調用。調用順序在get_adjustment之後。

它可以用於在某段時間內更新條(bar)的值,就像 AnimatedValue() 一樣。為了實現這點,get_adjustment應該存儲Adjustment對象,並週期性調用Adjustment的修改方法。

輸入值(inputvalue) link

當創建一項輸入時,一個InputValue對象可以用作輸入的 value 特性(property)。調用InputValue對象的方法可以實現:獲取和設置文本,判斷輸入是否可編輯,以及確認鍵按下後的處理。

class InputValue link

繼承這個類,並定義一個新的InputValue,需要重寫部分或全部方法,並設置默認欄位(field)的值。

default link

若為True,默認輸入是可以編輯的。(當其在界面上顯示時,可能會帶有插入記號。)

get_text(self) link

返回輸入的默認文本。這個方法必須實現。

set_text(self, s) link

當輸入文本改變時,調用這個方法修改為新的文本。這個方法必須實現。

enter(self) link

當用戶按下確認鍵時調用。如果其返回一個非None值,那個值會返回給交互行為。其也可以使用renpy.IgnoreEvent()忽略確認鍵的按下。否則,確認鍵按下的消息會廣播給其他可視組件。

下列行為也是InputValue對象的可用方法:

Enable() link

返回一個行為,啟用輸入的文本編輯。

Disable() link

返回一個行為,禁用輸入的文本編輯。

Toggle() link

返回一個行為,切換文本的可編輯狀態。

創作者定義的界面語言語句 link

Ren’Py支持定義訂製化界面語言語句。創作者定義的界面語言語句本質上是變相使用了界面語言中的 use語句 。固定位置入參不變,特性(property)變成了關鍵字參數。如果自訂的語句後面有一個語句塊(block),use語句也支持。例如,下面的訂製化界面語言語句:

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

    text "This is a test."

可以變成:

use titledwindow("Test Window", icon="icon.png"):
    text "This is a test."

創作者定義的界面語言語句必須在python early語句塊(block)中註冊。還有,包含創作者定義的界面語言語句的文件必須在使用這個語句的文件之前載入。由於Ren’Py按照unicode順序載入文件,通常合理的做法是,在註冊創作者自訂語句的文件加上前綴“01”之類一個不大的數字。

創作者定義的界面語言語句使用renpy.register_sl_statement函數進行註冊:

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

註冊一個界面語言語句,用於創建一個可視組件。

name
註冊的界面語言語句名稱,一個包含自訂Ren’Py關鍵字的字串。這個關鍵字用於標識進入了新的語句。
displayable

這是一個函數,被調用後返回一個可視組件對象。所有固定位置入參、特性(property)和樣式特性都可以作為入參傳入這個函數。其他關鍵字入參請看後面部分。

這個函數的返回值必須是一個可視組件。如果它返回了多個可視組件,最外層可視組件的“_main”屬性(attribute)應該被設置成那個“主”可視組件——子組件添加在“主”組件上。

style
可視組件樣式的基礎名稱。如果風格特性(property)沒有指定,這項會添加風格前綴。處理後的樣式名會以 style 關鍵字傳入可視組件的處理函數。
nchildren

可視組件的子組件數量。可能是:

0
沒有子組件。
1
有1個子組件。如果多於1個,則所有子組件放在一個固定布局(Fixed)中。
“many”
有多個子組件。

下列入參應該使用作為關鍵字入參傳入:

replaces
若為True,且需要該可視組件替換之前的可視組件,就把新的可視組件作為參數傳入。
default_keywords
可視組件的關鍵字入參默認集合。

返回一個對象,並可以透過調用下列方法為這個對象添加固定位置入參和特性(property)。每個方法都會返回調用方法的對象自身,並允許方法連結起來用。

add_positional(name) link

添加一個名為 name 的固定位置入參。

add_property(name) link

添加一個名為 name 的特性(property)。特性會作為關鍵字入參傳入。

add_style_property(name) link

添加一個特性的族(family),以 name 結尾,沿用樣式特性的前綴。例如,調用時使用(“size”),這個方法就定了size、idle_size、hover_size等。

add_prefix_style_property(prefix, name) link

添加一個特性的族(family),名字由 prefix (樣式特性前綴)和 name 構成。例如,調用時使用了前綴 text_ 和名稱 size ,這個方法就創建了text_size、text_idle_size、text_hover_size等。

add_property_group(group, prefix='') link

添加一組特性,前綴為 prefixgroup 可能是下列字串之一:

  • “bar”
  • “box”
  • “button”
  • “position”
  • “text”
  • “window”

這些分別對應 樣式特性 中的各個組。組名也可以是“ui”,添加的就是 通用UI特性

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

使用Ren’Py註冊一個訂製化界面語言語句。

name
這項必須是一個word型數據。它是訂製化界面語言語句的名稱。
positional
語句使用的固定位置參數的個數。
children
界面使用的子組件。如果沒有指定,預設為 name
screen
使用的界面名。如果沒有指定,預設是 name

返回的對象可以被添加固定位置入參和特性(property)。這個對象有一個與 renpy.register_sl_displayable() 返回對象相同的“.add_”方法。

做一個創作者定義界面語言語句的例子,這裡是 titledwindow 語句的實現。首先,在早期載入的文件——像名為“01custom.rpy”就載入足夠早——中 python early 語句塊中註冊訂製化語句。註冊的腳本如下:

python early:
    renpy.register_sl_statement("titledwindow", children=1).add_positional("title").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

需要大量傳遞特性(property)值時,更合理的方法是使用 **properties 參數,例如:

screen titledwindow(title, icon=None, **properties):
    frame:
        # 如果properties參數中不包含background,則會使用預設值。
        background "#00000080"

        properties properties

        has vbox

        hbox:
            if icon is not None:
                add icon

            text title

        null height 15

        transclude