可視組件是一類可以向用戶顯示的對象。Ren’Py可視組件具有多種用途。
當Ren’Py函數或者變數需要一個可視組件時,總共可用的東西有5種:
Image() 函數後被作為一個檔案名處理。Color,也可能是一個(r, g, b, a)格式的元組,元組中每個元素的值都位於0到255的閉區間內。顏色會被傳入 Solid() 函數。字串中允許存在一個或多個用方括號包含的帶替換內容,比如“eileen [mood]”和“eileen_[outfit]_[mood].png”這樣形式的。一旦出現了類似的字串,引擎就會創建出動態圖像。動態圖像在每次互動行為(比如say語句和菜單)開始階段,具有 文本內插 的行為表現。最終生成的字串會按照上文提到的規則處理。
When a string has “[prefix_]” in it, that substitution is replaced with each of the style prefixes associated with the current displayable.
如果某個字串含有一個子字串 “[prefix_”] ,就會使用當前可視組件關聯樣式的前綴替換該子字串。
最常見的可視組件是通過載入硬碟上的一個文件並顯示的圖像(image)。由於圖像是如此常用,所以每當某個上下文中某字串給出了一個檔案名,並需要將這個文件用作可視組件時,引擎就會自動創建一個圖像(image)對象。唯一需要直接使用圖像(image)對象的情況是,你想創建一個帶樣式特性的圖像。
Image(filename, **properties) link從文件中載入一個圖像。 filename 是檔案名的字串。
filename 應該是一個JPEG或PNG文件。
# 這兩行等價。
image logo = "logo.png"
image logo = Image("logo.png")
# 使用Image()允許我們指定一個默認位置截取某個圖像的一部分。
image logo right = Image("logo.png", xalign=1.0)
以下三種是推薦使用的圖片檔案格式:
沒有動畫的Gif文件和Bmp文件也是支持的,但已經不推薦用在本世代遊戲中。
從硬碟載入文件,解碼圖像並將圖像繪製到螢幕上,這一系列工作耗時比較長。因此載入過程需要幾十甚至上百毫秒的話,就無法提供一個可接受的幀率,並會讓用戶覺得惱怒。
因為圖像是一個固定尺寸,在大多數情況下都不會更改圖像的可視區域,所以可以在圖像真正使用之前提前載入,並放入記憶體的圖片快取中。圖片解碼並放入快取之後,就可以很高效地繪製在螢幕上了。
Ren’Py會預測未來使用的圖像,載入文件後先放入圖像快取備用。當圖像快取空間不足時,Ren’Py會先刪除不會再被使用到的那些圖像。
默認情況下,Ren’Py會預先快取相當於8個界面大小的圖像數據。(如果你的界面解析度是800×600,那一個界面大小相當於一張800×600的圖像,兩張400×600的圖像,以此類推。)這個值可以通過 :var:config.image_cache_size 配置項修改。
儘管精確的數值取決於規則細節,並且也存在一些明確的標準。一個最基礎的規則是,圖像快取中的每一個像素,都占用4個字長的主記憶體和4個字長的視訊記憶體。
我們將這些可視組件稱作“類圖像”,是因為他們占用界面中的一塊矩形區域但不會對輸入做任何反應。 有別於通常的圖像,這些“類圖像”可以調整尺寸填充某個區域(Frame、Tile、Solid),或者允許用戶指定尺寸(Composite、Crop、Null)。這些“類圖像”不是圖像處理器(Image Manipulator)。
類圖像可視組件使用 位置樣式特性。
AlphaMask(child, mask, **properties) link可視組件使用入參 child 作為自身的顏色,其alpha通道值使用 child 的alpha通道值與 mask 的乘積。因此,該可視組件具有 child 同樣的顏色,當 child 或 mask 之一是透明的情況下該組件也是透明,當 child 和 mask 都不透明的情況下該組件才不透明。
child 和 mask 可以是任意可視組件。AlphaMask的尺寸是 child 和 mask 的重疊區域尺寸。
需要注意,該函數與im.AlphaMask()使用不同的入參,im.AlphaMask()還使用入參mask的顏色通道。
Borders(left, top, right, bottom, pad_left=0, pad_top=0, pad_right=0, pad_bottom=0) linkborder對象提供邊界(border)尺寸和碼放(tile)給 Frame() 對象。其也可以提供填充( padding() )訊息,用於帶填充特性的窗口(window)或者框架(frame)。
填充(padding)訊息是一個欄位(field):
padding link這是一個4元素的元組,包含了矩形4條邊的填充(padding)訊息。
Composite(size, *args, **properties) link這個函數使用其他可視組件合成並創建一個新的可視組件。新可視組件的尺寸由 size 決定。 size 是一個(width, height)形式的元組,兩個元素分別表示寬度和高度。
保留的固定位置參數用於放置LiveComposite中的圖像。保留的固定位置參數應該是由兩個數據構成的組。組中的第一個元素是一個(x, y)形式的元組;第二個元素是合成用的可視組件,使用前一個元素表示的位置進行合成。
可視組件的合成順序為從後往前。
image eileen composite = Composite(
(300, 600),
(0, 0), "body.png",
(0, 0), "clothes.png",
(50, 50), "expression.png")
Crop(rect, child, **properties) link這個函數使用 rect 剪裁 child 並創建一個新的可視組件。 rect 是一個(x, y, width, height)形式的元組。
image eileen cropped = Crop((0, 0, 300, 300), "eileen happy")
DynamicImage(name) link動態圖像是一種可視組件,這個組件包含文本內插(text interpolation)字串。那些待內插的文本內容補完後就能生成一個新的可視組件對象。每一項互動行為開始後都會執行文本內插補完字串。
Flatten(child, **properties) link該對象將可能由多個紋理組成的入參 child ,壓成單個紋理。
某些操作,像alpha轉換特性,會應用到最終構成可視組件的每一個紋理上。最終的可視組件會剔除錯誤結果,比如界面上的紋理有重疊。Flatten對象根據多個紋理創建單個紋理的時,能避免這些問題。
Flatten是一個性能消耗高昂的操作,應該在必要的情況下才使用。
Frame(image, left=0, top=0, right=None, bottom=None, tile=False, **properties) linkFrame是一個可視組件,可以調整圖像尺寸使其匹配某個可用區域,同時也保存其邊界(border)的寬度和高度。Frame通常用於窗口(window)或按鈕(button)的背景。
使用框架(frame)將圖像增大為原尺寸的兩倍。
Border() 對象,這種情況下其他幾個參數也都被這個Border對象一塊代替。# 文本窗口過小時重新調整背景尺寸
init python:
style.window.background = Frame("frame.png", 10, 10)
Null(width=0, height=0, **properties) link在界面上創建一個空框(box)的可視組件。框的尺寸由 width 和 height 控制。這個對象用在某個可視組件需要一個子組件且找不到合適的子組件時,或者在box裡充當空白。
image logo spaced = HBox("logo.png", Null(width=100), "logo.png")
Solid(color, **properties) link將聲明的顏色 color 填滿自身所有區域的可視組件。
image white = Solid("#fff")
Tile(child, style='tile', **properties) link將 child 以碼放形式填充整個可視組件區域。
image bg tile = Tile("bg.png")
動態可視組件會基於遊戲狀態顯示一個子組件。這些組件不使用任何特性,布局則由各子組件返回的特性所決定。
需要注意,動態可視組件總是顯示它們的當前狀態。因此,動態可視組件參與轉場(transition)。(準確的說,轉場過程中動態可視組件總是顯示同樣的東西。)
根據設計,動態可視組件用於從定義到離開界面都很少改變的要素,而不是用於經常變化的內容,比如角色表情。
ConditionSwitch(*args, predict_all=None, **properties) link基於Python條件表達式,改變自身顯示內容的可視組件。固定位置入參應該是一組兩個值的形式,每組分別包含:
第一條為True的條件表達式會顯示自己的可視組件,所以需要保證至少一個條件表達式永遠為True。
這裡使用的條件表達式不應該有明顯的副作用。
config.conditionswitch_predict_all() 的配置。image jill = ConditionSwitch(
"jill_beers > 4", "jill_drunk.png",
"True", "jill_sober.png")
DynamicDisplayable(function, *args, **kwargs) link基於某個Python函數可以改變自身子組件的可視組件,作用範圍貫穿於某次互動行為。
使用入參調用的某個函數的名稱:
並返回一個(d, redraw)元組。這個元組中:
每次互動後, function 函數都會被調用。
有一個特殊情況, function 可能是一個Python字串並可以等效為一個可視組件。在那種情況下,每個互動行為中function都只能運行一次。
# 顯示一個從5到0的倒數計時,每十分之一秒更新直到計時結束。
init python:
def show_countdown(st, at):
if st > 5.0:
return Text("0.0"), None
else:
d = Text("{:.1f}".format(5.0 - st))
return d, 0.1
image countdown = DynamicDisplayable(show_countdown)
ShowingSwitch(*args, predict_all=None, **properties) link基於目前界面上正在顯示圖像,能更改自身顯示內容的可視組件。固定位置入參應該是一組兩個值的形式,每組分別包含:
默認圖像需要提前指定。
config.conditionswitch_predict_all() 的配置。ShowingSwitch的一個用途是,根據角色感情更改角色邊欄頭像。例如:
define e = Character("Eileen",
show_side_image=ShowingSwitch(
"eileen happy", Image("eileen_happy_side.png", xalign=1.0, yalign=1.0),
"eileen vhappy", Image("eileen_vhappy_side.png", xalign=1.0, yalign=1.0),
None, Image("eileen_happy_default.png", xalign=1.0, yalign=1.0),
)
)
At函數使用某個可視組件和若干個 變換(transform) 產生一個新的可視組件。
At(d, *args) link對給定的源可視組件 d ,將 args 中所有變換(transform)都應用於該組件。所有變換(transform)參數的應用順序是從左到右,所以最外層的變換(transform)效果是最右邊的入參。
transform birds_transform:
xpos -200
linear 10 xpos 800
pause 20
repeat
image birds = At("birds.png", birds_transform)
布局框是在界面上設置其子組件布局的可視組件。其可以使用水平布局或者垂直布局,也可以使用標準位置算法設置布局。
框式可視組件可以使用任意數量的固定位置參數和關鍵字參數。固定位置參數會被以子組件的形式加入框體中。關鍵字參數則是應用於框體的各種樣式特性。
框體使用 位置樣式特性 和 方框(box)樣式特性。
Fixed(*args, **properties) link充滿整個界面的框體。該框體成員的布局順序從後往前,使用自身的位置特性控制顯示位置。
HBox(*args, **properties) link框體內成員布局順序從左到右。
VBox(*args, **properties) link框體內成員布局順序從上到下。
# 顯示兩個logo,分別位於左邊和右邊。
image logo hbox = HBox("logo.png", "logo.png")
# 顯示兩個logo, 一個在另一個上方。
image logo vbox = VBox("logo.png", "logo.png")
# 顯示兩個logo。
# 由於默認情況下,其他位置顯示的圖像與界面左上方顯示的一致,
# 我們需要使用其他圖片替換那些不需要logo的地方。
image logo fixed = Fixed(
Image("logo.png", xalign=0.0, yalign=0.0),
Image("logo.png", xalign=1.0, yalign=1.0))
坐標布局會在界面上建立一個坐標系,並顯示其子組件。其使用
位置樣式特性 和 spacing 樣式特性。
Grid(*args, **properties) link在一個坐標繫中布局可視組件。前兩個固定位置參數分別對應坐標中的列號和行號。固定位置參數的 columns * rows 給定了坐標系中所能容納的可視組件總數。
這些可視組件通常用於創建某種視覺特效。
AlphaBlend(control, old, new, alpha=False) link這種過渡(transition)效果用於從一個可視組件(大多數使用某種動畫變化)過渡到另一個。當變換(transform)完全不透明時,新的可視組件會被啟用;當變化完全透明時,舊的可視組件會被啟用。
圖像處理器 本身是一個可視組件。它會接受一個圖像或者另一個圖像處理器對象,對原有對象進行某些處理。圖像處理器只接受圖像或其他圖像處理器作為輸入。
任何能放可視組件的地方也可以放圖像處理器,但反過來不一定可行。 Image() 對象是一種圖像處理器,所以任何需要使用圖像處理器的地方都可以使用image對象。
圖像處理的應用具有重大意義。過去的一些圖像處理器由於各種的問題不應再使用。
除了使用 im.Data() 的情況,可視組件 Transform() 提供了很多類似的功能,並同時修復了過去的問題,儘管使用這些需要啟用gl2配置項。
圖像處理器的詳情請參見 圖像處理器 。
占位組件(placeholder)用於正確顯示背景圖或者角色圖像。在開發者模式下,使用某個未定義的圖像時,占位組件會被自動使用。如果你覺得預設的顯示有問題,也可以手動指定占位組件的使用。
# 默認情況下,會使用girl占位組件。
image sue = Placeholder("boy")
label start:
show sue angry
"蘇" "你還好嗎?現在,受死吧!"
Placeholder(base=None, full=False, flip=None, **properties) link該可視組件可以用於顯示一個占位角色或背景。
顯示圖像的類型。應該是以下類型之一:
嘗試自動確認圖像用途。如果圖像名以“bg”、“cg”或者“event”開頭,則取值’bg’。
否則,引擎會連接一個web伺服器根據角色名字猜測性別並應用。(web伺服器也無法判斷的情況下,預設為’girl’占位組件。)
可視組件可以使製作者定義他們自己的可視組件,並且涉及到所有Ren’Py可以用到可視組件的地方。
一個帶前綴的可視組件名是一個帶有英文冒號的字串。前綴在冒號左邊,參數在冒號右邊。
config.displayable_prefix 變數將前綴對應到一個函數。函數接受此參數,並返回一個可視組件或None。
比如說,這個例子創建一個big前綴,返回一個原來兩倍大的圖像。
init -10 python:
def embiggen(s):
return Transform(s, zoom=2)
config.displayable_prefix["big"] = embiggen
init -10 確保前綴在任何圖像使用它之前被定義。
然後前綴可以用來定義圖像:
image eileen big = "big:eileen happy"
或者其他需要顯示可視組件的地方。