可視組件 link

可視組件是一類可以向用戶顯示的對象。Ren’Py可視組件具有多種用途。

  • 使用image語句聲明一個圖像名。

  • 使用screen language add語句添加至界面(screen)。

  • 聲明某個配置變數。

  • 聲明某個樣式特性。

當Ren’Py函數或者變數需要一個可視組件時,總共可用的東西有5種:

  • 典型的可視組件(displayable)對象,透過調用本章後面提到的某些函數創建。

  • 一個帶英文冒號 : 的字串。很少使用,詳見下面 可視組件前綴 部分。

  • 一個帶英文句號(.)的字串。該字串在傳入 Image() 函數後被作為一個檔案名處理。

  • 一種顏色。可能是十六進製表示的顏色字串格式——比如 “#rgb”、“#rgba”、“#rrggbb”或“#rrggbbaa”,可能是一個 Color,也可能是一個(r, g, b, a)格式的元組,元組中每個元素的值都位於0到255的閉區間內。顏色會被傳入 Solid() 函數。

  • 一個圖像名。所有字串拼接後,引用某個使用image語句定義的圖像。圖像名可以由image語句定義,或者從 images目錄 中自動定義。

  • 一個列表。如果提供的是一個列表,列表中的物件(item)會按後面描述的方式展開,並逐個檢查是否能匹配到某個檔案名或圖像名。如果匹配成功,列表物件展開會停止,匹配到的內容會按照剛才提到的幾種方式處理。

字串中允許存在一個或多個用方括號包含的帶替換內容,比如“eileen [mood]”和“eileen_[outfit]_[mood].png”這樣形式的。一旦出現了類似的字串,引擎就會創建出動態圖像。動態圖像在每次互動行為(比如say語句和菜單)開始階段,具有 文本內插 的行為表現。最終生成的字串會按照上文提到的規則處理。

如果某個字串含有一個子字串 “[prefix_”] ,就會使用當前可視組件關聯樣式的前綴替換該子字串。

圖像 link

最常見的可視組件是通過載入硬碟上的一個文件並顯示的圖像(image)。由於圖像是如此常用,所以每當某個上下文中某字串給出了一個檔案名,並需要將這個文件用作可視組件時,引擎就會自動創建一個圖像(image)對象。唯一需要直接使用圖像(image)對象的情況是,你想創建一個帶樣式特性的圖像。

Image(filename, *, optimize_bounds=True, oversample=1, dpi=96, **properties) link

從文件中載入一個圖像。 filename 是一個字串,表示載入的檔案名。

filename

應該是一個圖片檔案名,包括副檔名。

optimize_bounds

若為True,圖片在一個不透明像素構成的包圍框(bounding box)內的部分才會載入到視訊記憶體中。 (只有將圖片作為著色器輸入時,才可能需要將該項設置為False。)

oversample

若該參數大於1,表示圖像需要過採樣(oversample),實際像質數比邏輯尺寸大。 例如解析度為2048×2048,過採樣率為2的圖片文件,在各種布局計算時都當作1024×1024大小的圖片。

dpi

SVG圖片的DPI。預設值為96。增大該參數可以把SVG圖片渲染得更大,反之則渲染得更小。

# 這兩行等價。
image logo = "logo.png"
image logo = Image("logo.png")

# 使用Image()允許我們指定一個默認位置截取某個圖像的一部分。
image logo right = Image("logo.png", xalign=1.0)

以下四種是推薦使用的圖片檔案格式:

  • AVIF

  • Webp

  • Png

  • Jpg

推薦的向量圖檔案格式:

  • SVG

沒有動畫的Gif文件和Bmp文件也是支持的,但已經不推薦用在本世代遊戲中。

從硬碟載入文件,解碼圖像並將圖像繪製到螢幕上,這一系列工作耗時比較長。因此載入過程需要幾十甚至上百毫秒的話,就無法提供一個可接受的幀率,並會讓用戶覺得惱怒。

因為圖像是一個固定尺寸,在大多數情況下都不會更改圖像的可視區域,所以可以在圖像真正使用之前提前載入,並放入記憶體的圖片快取中。圖片解碼並放入快取之後,就可以很高效地繪製在螢幕上了。

Ren’Py會預測未來使用的圖像,載入文件後先放入圖像快取備用。當圖像快取空間不足時,Ren’Py會先刪除不會再被使用到的那些圖像。

默認情況下,Ren’Py會預先快取相當於8個界面大小的圖像數據。(如果你的界面解析度是800×600,那一個界面大小相當於一張800×600的圖像,兩張400×600的圖像,以此類推。)這個值可以通過 :var:config.image_cache_size 配置項修改。

儘管精確的數值取決於規則細節,並且也存在一些明確的標準。一個最基礎的規則是,圖像快取中的每一個像素,都占用4個字長的主記憶體和4個字長的視訊記憶體。

SVG圖片 link

Ren’Py支持SVG 1.0標準的圖片,使用的是NanoSVG庫。一些 不支持 的功能特性如下:

  • 文本類元素直接忽略。如果文本已轉換為路徑(path),則可以渲染出來。

  • 內嵌的點陣圖(bitmap)直接忽略。

  • 內建腳本直接忽略。

  • 動畫直接忽略。

NanoSVG庫支持的功能特性詳見 這裡

推薦將所有SVG圖片中無法渲染的內容都轉換為路徑(path)。

Ren’Py渲染SVG圖片時假設虛擬界面的解析度為96dpi. 如果窗口拉大或縮小,SVG圖片將等比縮放,過採樣 會用於確保圖片能以正確的虛擬尺寸渲染。

SVG圖片在縮放後依然能保持銳度。

類圖像的可視組件 link

我們將這些可視組件稱作“類圖像”,是因為他們占用界面中的一塊矩形區域但不會對輸入做任何反應。 有別於通常的圖像,這些“類圖像”可以調整尺寸填充某個區域(Frame、Tile、Solid),或者允許用戶指定尺寸(Composite、Crop、Null)。這些“類圖像”不是圖像處理器(Image Manipulator)。

類圖像可視組件使用 位置樣式特性

AlphaMask(child, mask, **properties) link

可視組件使用入參 child 作為自身的顏色,其alpha通道值使用 child 的alpha通道值與 mask 的乘積。因此,該可視組件具有 child 同樣的顏色,當 childmask 之一是透明的情況下該組件也是透明,當 childmask 都不透明的情況下該組件才不透明。

childmask 可以是任意可視組件。AlphaMask的尺寸是 childmask 的重疊區域尺寸。

需要注意,該函數與im.AlphaMask()使用不同的入參,im.AlphaMask()還使用入參mask的顏色通道。

Borders(left, top, right, bottom, pad_left=0, pad_top=0, pad_right=0, pad_bottom=0) link

border對象提供邊界(border)尺寸和碼放(tile)給 Frame() 對象。其也可以提供填充( padding() )資訊,用於帶填充特性的窗口(window)或者框架(frame)。

left top right bottom

這些參數提供的某個框架(frame)需要使用的插入尺寸,以及各條邊的填充(padding)邊界。這些值應該是0或者正整數。

pad_left pad_top pad_right pad_bottom

這些參數會添加到各條邊填充(padding)的值,可以是正整數或負整數。(例如,如果 left 是5, pad_left 是-3,那麼最終的填充(padding)值就是2。)

填充(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) link

Frame是一個可視組件,可以調整圖像尺寸使其匹配某個可用區域,同時也保存其邊界(border)的寬度和高度。Frame通常用於窗口(window)或按鈕(button)的背景。

_images/frame_example.png

使用框架(frame)將圖像增大為原尺寸的兩倍。 link

image

一個可以被框架(frame)調整尺寸的圖像處理器。

left

左邊框的邊界(border)尺寸。此入參也可以是一個 Border() 對象,這種情況下其他幾個參數也都被這個Border對象一塊代替。

top

上面框的邊界(border)尺寸。

right

右邊框的邊界(border)尺寸。如果為None,則默認與 left 一樣。

bottom

下面框的邊界(border)尺寸。如果為None,則默認與 top 一樣。

tile

若該值為True,使用碼放(tile)形式重新調整圖像區域尺寸,否則使用縮放(scale)形式。

# 文本窗口過小時重新調整背景尺寸
init python:
    style.window.background = Frame("frame.png", 10, 10)
Null(width=0, height=0, **properties) link

在界面上創建一個空框(box)的可視組件。框的尺寸由 widthheight 控制。這個對象用在某個可視組件需要一個子組件且找不到合適的子組件時,或者在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")

文本組件 link

參見 文本組件

動態可視組件 link

動態可視組件會基於遊戲狀態顯示一個子組件。

需要注意,動態可視組件總是顯示它們的當前狀態。因此,動態可視組件參與轉場(transition)。(準確的說,轉場過程中動態可視組件總是顯示同樣的東西。)

根據設計,動態可視組件用於從定義到離開界面都很少改變的要素(比如自訂角色系統),而不是用於經常變化的內容,比如角色表情。

ConditionSwitch(*args, predict_all=None, **properties) link

基於Python條件表達式,改變自身顯示內容的可視組件。固定位置入參應該是一組兩個值的形式,每組分別包含:

  • 包含Python表達式語句的字串。

  • 當條件表達式為True時顯示的組件。

第一條為True的條件表達式會顯示自己的可視組件,所以需要保證至少一個條件表達式永遠為True。

這裡使用的條件表達式不應該有明顯的副作用。

predict_all

若為True,當顯示可視組件時,所有可能的可視組件都會提前快取。若為False,只載入當前條件表達式的可視組件。若為None,使用 config.conditionswitch_predict_all() 的配置。

image jill = ConditionSwitch(
    "jill_beers > 4", "jill_drunk.png",
    "True", "jill_sober.png")
class DynamicDisplayable(function, *args, **kwargs) link

基於某個Python函數可以改變自身子組件的可視組件,作用範圍貫穿於某次互動行為。 此類對象不能使用任何特性,因為其布局是由子組件的特性所決定。

function

該入參是一個函數,調用時可使用以下參數:

  • 可視組件的顯示時間。

  • 具有相同標籤(tag)的任意可視組件的顯示時間。

  • 任何固定位置的或關鍵字入參用於DynamicDisplayable類對象。

並返回一個(d, redraw)元組。這個元組中:

  • d 是需要顯示的可視組件。

  • redraw 是再次調用該函數的間隔等待時間,如果是空值(None)的話就不會再次調用函數直到下次互動行為。

每次互動後,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

基於目前界面上正在顯示圖像,能更改自身顯示內容的可視組件。固定位置入參應該是一組兩個值的形式,每組分別包含:

  • 一個指定圖像名的字串,或者用None表示默認圖像。

  • 在條件表達式為True時使用的可視組件。

默認圖像需要提前指定。

predict_all

若為True,當顯示可視組件時,所有可能的可視組件都會提前快取。若為False,只載入當前條件表達式的可視組件。若為None,使用 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),
        )
    )

圖層可視組件 link

圖層可視組件會基於遊戲的某些狀態值在某個圖層上顯示內容。 圖層可視組件設計為與 config.detached_layers 協同使用。

圖層可視組件與動態可視組件類似,圖層顯示的內容由當前狀態值決定。 因此,圖層可視組件不受轉場效果的影響。除非某個轉場指定目標就是圖層可視組件對應的圖層。

class Layer(layer, **properties) link

該類可以讓某個圖層像可視組件一樣覆蓋在其他圖層上。設計為與獨立圖層(detached layer)協同使用。

不能把圖層覆蓋在自身上。

layer

需要顯示的圖層。

clipping

若為False,圖層內容可以超過自身範圍的部分依然顯示。否則超出範圍的部分將被剪裁。

配置項config.layer_clipping的值會覆蓋此參數的值。

# 定義一個新的名為broadcast的獨立圖層
define config.detached_layers += [ "broadcast" ]

# 定義一個新的名為tv的圖層可視組件,用於顯示圖層broadcast的內容
image tv = Window(Layer("broadcast"), background='#000', padding=(10, 10))

image living_room = Placeholder('bg', text='living_room')
image studio = Solid('7c7')
image eileen = Placeholder('girl')

label example:
    pause

    # 設置broadcast圖層的場景
    scene studio onlayer broadcast
    with None

    # 開啟新場景living_room
    scene living_room

    # 在螢幕右下角顯示圖層可視組件tv
    show tv:
      align (.75, .75) zoom .3

    # 在broadcast圖層顯示Eileen
    show eileen onlayer broadcast

    # 以dissolve轉場進入living room場景,同時Eillen從畫面右側進入。
    with {'master': dissolve, 'broadcast': moveinright}
    pause

應用於可視組件的變換(transform) link

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)

布局框和坐標系 link

布局框是在界面上設置其子組件布局的可視組件。其可以使用水平布局或者垂直布局,也可以使用標準位置算法設置布局。

框式可視組件可以使用任意數量的固定位置參數和關鍵字參數。固定位置參數會被以子組件的形式加入框體中。關鍵字參數則是應用於框體的各種樣式特性。

框體使用 位置樣式特性方框(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 給定了坐標系中所能容納的可視組件總數。

特效 link

這些可視組件通常用於創建某種視覺特效。

AlphaBlend(control, old, new, alpha=False) link

這種過渡(transition)效果用於從一個可視組件(大多數使用某種動畫變化)過渡到另一個。當變換(transform)完全不透明時,新的可視組件會被啟用;當變化完全透明時,舊的可視組件會被啟用。

alpha

若該值為True,前後圖像會相互混合。若該值為False,也就是預設值,前面的圖像會顯示半透明,覆蓋在後面的圖像上。

圖像處理器 link

圖像處理器 本身是一個可視組件。它會接受一個圖像或者另一個圖像處理器對象,對原有對象進行某些處理。圖像處理器只接受圖像或其他圖像處理器作為輸入。

任何能放可視組件的地方也可以放圖像處理器,但反過來不一定可行。 Image() 對象是一種圖像處理器,所以任何需要使用圖像處理器的地方都可以使用image對象。

圖像處理的應用具有重大意義。過去的一些圖像處理器由於各種的問題不應再使用。 除了使用 im.Data() 的情況,可視組件 Transform() 提供了很多類似的功能,並同時修復了過去的問題。

圖像處理器的詳情請參見 圖像處理器

占位組件 link

占位組件(placeholder)用於正確顯示背景圖或者角色圖像。在開發者模式下,使用某個未定義的圖像時,占位組件會被自動使用。如果你覺得預設的顯示有問題,也可以手動指定占位組件的使用。

# 默認情況下,會使用girl占位組件。
image sue = Placeholder("boy")

label start:
     show sue angry
     "蘇" "你還好嗎?現在,受死吧!"
Placeholder(base=None, full=False, flip=None, text=None, **properties) link

該可視組件可以用於顯示一個占位角色或背景。

base

顯示圖像的類型。應該是以下類型之一:

‘bg’

顯示一個背景占位組件。這個組件會以淺灰填滿整個界面,並在界面上方顯示圖像名。

‘boy’

顯示一個“記為男性”的占位組件,胸口位置顯示圖片名。

‘girl’

顯示一個“記為女性”的占位組件,胸口位置顯示圖片名。

None

嘗試自動確認圖像用途。如果圖像名以“bg”、“cg”或者“event”開頭,則取值’bg’。

否則,使用’girl’占位組件。

full

若該值為True,使用全身像的精靈(sprite)。否則,使用3/4像的精靈(sprite)。

flip

若該值為True,精靈(sprite)會水平翻轉。

text

若指定了該項,顯示占位符時會使用此項文本。若沒有指定,則會使用對應占位符自帶的文本。

可視組件前綴 link

可視組件可以使製作者定義他們自己的可視組件,並且涉及到所有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"

或者其他需要顯示可視組件的地方。

其他參考 link

顯示圖像 :這頁介紹了如果製作以上可視組件並在界面上顯示。