層疊式圖像 link

當某個精靈(sprite)集的複雜度到達某個等級後,分別定義出每種可能的組合就會變得非常不便。 例如,某個角色有4套服裝、4種髮型和6種表情,就總共有96種組合方式。 針對每種可能的組合創建靜態圖像會占用很多磁碟空間和編程時間。

為了應對這種使用場景,Ren’Py提供了一種辦法,可以定義多個圖層(layer)組成的圖像。 (此處的圖層跟Ren’Py中其他地方的“圖層”不太一樣,更類似於Photoshop或者GIMP等繪圖程序中圖層的概念。) 有兩種方法選擇圖層中需要顯示的元素,一直是通過圖像的 屬性 ,另一種是根據條件即時計算。

使用 layeredimage 語句和一些指定格式的腳本可以定義層疊式圖像。 LayeredImage() 對象是另一種 Python 形式的層疊式圖像。它不是 可視組件,但可以用 image 語句聲明,用法也與可視組件類似。

本頁結尾包含了使用層疊式圖像的建議和樣例。

定義層疊式圖像 link

腳本語言需要引入若干圖層,然後使用一些語句定義圖層上要顯示的圖像。 這裡是一個樣例,沒有什麼高超的靈感和技巧,只是在層疊式圖像上加上輪廓線。

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 # 顯示裙子和neutral狀態表情
    aug "我喜歡這件裙子。"

    show augustina happy # 在auto組中自定生成定義
    aug "但我更喜歡……"

    show augustina uniform -happy # 用校服替代裙子,neutral替代happy表情
    aug "這件制服!"

layeredimage語句 link

layeredimage 語句在Ren’Py用作某個層疊式圖像定義的開頭語句。 該語句是Ren’Py腳本語言的一部分,可以在 初始化階段 階段運行。 與 帶ATL語句塊的image語句 類似,layeredimage語句在開頭定義圖像名稱並開啟一個語句塊,後面的內容則大相徑庭。 圖像名稱中可以包含空格,類似於Ren’Py中的其他類型的圖像名稱。

定義layeredimage的語句塊中可能包含下列語句,以及一些特性(property)。

image_format

如果給定的圖像是一個字串,並且提供了image_format特性,就將 image_format 插入到圖像名,根據得到的名稱搜尋對應的圖片文件。 例如,“sprites/eileen/{image}.png”會在sprites子目錄下搜尋對應的png圖片文件。 (auto組不使用image_format特性,因為auto組自動搜尋已定義的圖像對象而不是圖片文件。)

format_function

這是一個函數,在初始化階段執行,用於代替 layeredimage.format_function 函數,將圖像資訊格式化並傳入某個可視組件。

attribute_function

這是一個函數或可調用對象,用於調整最終顯示的圖像屬性(attribute)。 在圖像上應用一些屬性時,該函數會被調用。函數會返回對應圖層調整後的屬性的集合。 該函數可以用於計算負責的屬性依賴關係,或者隨機選擇屬性。詳見 選擇顯示屬性

at

應用於層疊式圖像的一個變換(transform)或變換的列表。 其也可以用於 at transform: 形式的ATL語句塊,將ATL變換應用到層疊式圖像上。

transform properties

如果存在變換特性,都會用於構造一個應用於可視組件的 Transform

offer_screen

若為True,層疊式圖像將嘗試匹配整個界面,對其子組件調整位置和尺寸。 若為False,層疊式圖像將嘗試在更小的包圍矩形空間內放置各元素,每次顯示的層疊式圖像可能並不一樣。

若為None,即預設值,由配置項 config.layeredimage_offer_screen 決定。該配置項的預設值是True。

always語句 link

always 語句定義一個在層疊式圖像中始終顯示的圖像,該圖像不會與任何一個圖像屬性(attribute)做關聯。 always語句必須提供一個可視組件,當然也可以使用特性(property)。 這兩部分可以放在同一行,也可以放在一個語句塊(block)中。 此處的可視組件可以使用ATL語句塊中 image: 來定義,類似於 帶ATL語句塊的image語句

always語句使用下列特性:

when

when表達式 表達式需要放在圓括號中。若指定該項,對應圖層只在層疊式圖像滿足表達式時才會顯示設置的對應屬性。

transform properties

如果存在變換特性,都會用於構造一個應用於可視組件的 Transform()

at

應用於圖層的一個變換(transform)或變換的列表。 此處也可以使用一個 at transform: 開頭的ATL語句塊,定義的ATL變換將應用到對應可視組件上。

if語句 link

if 語句(或者更完整的if-elif-else語句)允許創作者設置一個或多個條件表達式。這些條件表達式會運行時進行計算。 每個條件表達式與某個可視組件關聯,第一個結果為True的條件表達式對應的圖像會被顯示。如果沒有條件表達式為True,else 語句對應的圖像就會顯示。

一個稍微複雜的 if 語句樣例如下:

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

每個分句必須指定一個可視組件。此處的可視組件可以是前面使用 image: 定義的圖像。 if語句還可以使用下列特性(property):

when

when表達式 表達式需要放在圓括號中。若指定該項,對應圖層只在層疊式圖像滿足表達式時才會顯示設置的對應屬性。

transform properties

如果存在變換特性,都會用於構造一個應用於可視組件的 Transform()

at

應用於圖層的一個變換(transform)或變換的列表。 此處也可以使用一個 at transform: 開頭的ATL語句塊,定義的ATL變換將應用到對應可視組件上。

layeredimage 語句運行時,if 語句就會轉換為 ConditionSwitch()

predict_all 不為True時,應該避免修改if語句的條件表達式。因為層疊式圖像要嘛顯示要嘛即將顯示,修改if語句條件表達式會導致沒有預載入的圖像就被使用。 這種設計主要用於很少變化的角色自訂選項。

attribute語句 link

attribute 語句添加了一個可視組件,當使用給定的屬性(attribute)時顯示對應的圖像(image)。 比如,在前一個樣例中,調用 show augustina dress 會導致“augustina_dress”作為整個“augustina”的一部分並顯示。

attribute語句使用一個屬性(attribute)名稱,這種情況下是一個詞(更準確的說,是一個圖像名稱,詳見 語句元素)。 其也可以使用兩個關鍵字。 default 關鍵字表示,在沒有明確使用同組其他屬性的情況下作為預設的屬性。 null 關鍵字防止Ren’Py自動搜索對應屬性的可視組件, 對某些有使用條件 :ref:`elements-of-statements`attribute_functionconfig.adjust_attributesconfig.default_attributes 的屬性時很有用。

相同的屬性名可以同時用在多個 attribute 分句中(auto 組自動定義的屬性會在後續另行說明), 在滿足條件時都顯示相應的可視組件(when 特性可以調整最終結果)。

此處可指定的可視組件可以是前面使用 image: 定義的圖像。 如果沒有直接給定可視組件(displayable),Ren’Py會根據層疊式圖像名稱、組(group)、組變種(group variant)和屬性(attribute),算出一個可視組件的名稱。 詳見 pattern 章節。

attribute語句使用下列特性(property):

when

when表達式 表達式需要放在圓括號中。若指定該項,對應圖層只在層疊式圖像滿足表達式時才會顯示設置的對應屬性。

transform properties

如果存在變換特性,都會用於構造一個應用於可視組件的 Transform()

at

應用於圖層的一個變換(transform)或變換的列表。 此處也可以使用一個 at transform: 開頭的ATL語句塊,定義的ATL變換將應用到對應可視組件上。

variant

此項是一個關鍵字,會作為屬性名(帶一個下劃線符號)搜索可視組件。 該特性僅在未指定屬性且group帶變種的可視組件時使用才是合法的。

when 從句會基於最終圖像的屬性列表進行嘗試,具體方式詳見 這裡, 但它 不會修改 屬性列表。

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

在上面的例子中,屬性 bc 總是 屬性列表的一部分(原因是他們的 default 從句)。 調用 show eileen a 時,屬性 a 根據腳本中寫的需求決定是否顯示,而屬性 b 不同,因為有 when 特性的約束。 但是,儘管對顯示結果不起作用,屬性 b 始終處於屬性列表中,即意味著屬性 c 始終對顯示結果不起作用。

group語句 link

group 語句可以將幾種屬性組成一個組(group),同組內各屬性互斥。 除非該組聲明為 multiple,否則同組內的屬性 ab 用在諸如 show eileen a b 之類地方會出現報錯。 正確的用法是,只使用屬性 a 自動隱藏 b,反之亦然。 另外,多個 attribute 從句傳入同一個屬性名是合法的。一般出現這種情況的原因是同一個屬性包含多個精靈(sprite),詳見本節結尾內容。

group 語句使用一個名稱(name)。該名稱並不常用,但可以用於生成組內屬性的默認名稱。

group名稱 multiple` 是預置的,可以將group設置為特殊的multiple類型。 如此設置後,定義在同語句塊中的屬性可以不會衝突。 可使同一個group內的圖像屬性不再互斥,並同時設置層疊式圖像的多個屬性。 group與 default 關鍵字有衝突。 注意 multiple 類型的group與其他普通group有很大區別,大多數時候並不適用普通group的設計思路。 可以將 multiple 類型的group視為根本沒有名稱(name)。

group名稱後面可能跟著關鍵字 auto 。 如果在組內的任意屬性後面的確存在auto,且定義了組內的任意屬性後,Ren’Py會掃描自己的圖像列表以匹配組的正則表達式(詳見 pattern)。 有個例外情況,傳入層疊式圖像的 format_function` 會被忽略。

找到的所有圖像,如果匹配不到已定義的屬性,就會自動在組內添加屬性,就像使用 attribute 語句定義group一樣。 詳見 樣例 章節的實際樣例。

在以上這些可選的關鍵字後面,group語句第一行就可以聲明相應的特性(property),也能以包含特性和屬性的語句塊形式跟著group後面。

group語句可以使用 attribute 語句中設置的特性——即 whenat 等等。 應用到整個組的特性會分別應用到組內的各個屬性(attribute),但會被組內屬性自帶的特性所覆蓋。 此外,有兩個特性是專門用於組的:

variant

該特性類似於 attribute,差別在於其不能傳給group中的_and_屬性。 若指定該特性,其應該是一個字串,用於自動生成圖像名稱的屬性變種(詳見 pattern), 如果存在這項特性,它會作為圖像名範式的一部分,前提是對應屬性定義在 auto 組中。

prefix

給定的prefix前綴會加一個下劃線,並添加到手動或自動定義的屬性名稱前面。 如果 prefixleftarm,遇到的屬性名為 attribute hip,顯示圖像的完整腳本為 show eileen leftarm_hip

一項屬性可以用於多個group。但這樣用會讓所有包含該屬性的group中的其他互斥屬性同時失效。 這種機制可以用於服裝類,例如 dress` 屬性可以讓角色的上裝與下裝同時顯示或隱藏。

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

定義在同一個層疊式圖像中一些同名的 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表達式 link

一個when表達式可以根據層疊式圖像屬性集得到一個布爾型結果,啟動圖像的對應屬性。

when表達式包含一個或多個屬性名,使用and或or關鍵字分隔,也可以使用not關鍵字表示邏輯“非”。 創作者可以在表達式中使用圓括號定義運算優先度。

樣例:

always:
    "eileen_red_dress"
    when b and not c
    # 當屬性b啟用而屬性c未啟用時,顯示該圖像

if var:
    "eileen_blue_ribbon"
    when not (a or b)
    # 只有屬性a和b都未啟用時,顯示該圖像

attribute a:
    "eileen_a"
    when b or e
    # 當屬性b或c之一啟用時,顯示該圖像

已棄用特性 link

alwaysifattribute 特性已棄用(deprecated)。在添加 when 之前的Ren’Py項目中可能用到這些特性。 目前這些特性還可以生效,但後續都推薦使用 when

if_all

屬性名稱的字串或字串列表。如果出現了這項特性,只有所有特定的屬性都出現時,才顯示圖層。

if_any

屬性名稱的字串或字串列表。如果出現了這項特性,只要有任意特定的屬性出現時,就顯示圖層。

if_not

屬性名稱的字串或字串列表。如果出現了這項特性,只有所有特定的屬性都不出現時,才顯示圖層。

To convert to the when syntax, you can replace 若要轉換為等效 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).

範式和格式函數 link

不明確指定圖像屬性的範式,由下列部分構成:

  • 層疊式圖像名稱,空格使用下劃線替換。

  • 組(group)名稱,前提該組不是 multiple 類型。

  • 變種(variant)名稱。

  • 屬性(attribute)名稱。

各部分都使用下劃線連接。例如,我們有一個名為“augustina work”的圖層圖像,名為“eyes”的組, 那麼根據範式 augustina_work_eyes_attribute 匹配圖像。 如果帶一個 bluevariant ,就會根據範式 augustina_work_eyes_blue_attribute 進行匹配。 在下例中:

layeredimage augustina work:
    group eyes variant blue:
        attribute closed

圖像屬性(attribute)連結的圖像為 "augustina_work_eyes_blue_closed"。 處理時對應的圖片檔案名為 augustina_work_eyes_blue_closed.png。 當然,這個例子中也可以使用 image語句 顯式定義。

可以使用 format_function 修改所有範式的結果:layeredimage.format_function() 就是一種格式函數的實現。 請參考入參列表,需要的情況下可以用自己實現的 格式函數 替換它。

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

調用該函數可以將各種屬性和情況的資訊串聯起來,並返回一個可視組件名。可以被創作者定義的函數替換,但增加的其他未知入參會被忽略。

what

一個字串,描述格式內容,可用於各類報錯資訊中。

name

層疊式圖像的名稱。

group

某個屬性的組(group)。未指定或其屬於某種情況的一部分時,可以為None。

variant

組(group)的變種入參,可以是None。

attribute

屬性自身。

image

一個可視組件或一個字串。

image_format

LayeredImage對象的 image_format 參數。

如果 image 為None,那麼 namegroup (若不是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 組搜索圖像的結果。

層疊式圖像代理 link

有時候,為了在多個地方使用同一個層疊式圖像,需要給層疊式圖像生成一個代理對象(proxy)。 這樣設計的原因之一是,各處可能使用同一個精靈(sprite)的不同圖像尺寸;另一個原因則是,可以使用層疊式圖像作為對話框頭像(side image)。

LayeredImagePorxy() 對象實現了這個功能,為層疊式圖像創建出可以在各處使用的副本。例如:

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” 原生版本 一個舊照片風格版本,也就是說不需要提供任何屬性(attribute)就可以顯示。 而 sepia_augustina_two 則跟“augustina”一樣可以帶入各種屬性,並同時保持舊照片的風格。 實現方法如下:

show augustina happy eyes_blue dress

然後:

show sepia_augustina_one happy eyes_blue dress
# 無效。因為Transform對象不接受屬性(attribute)

show sepia_augustina_two happy eyes_blue dress
# 有效。顯示“augustina happy eyes_blue dress”的舊照片風格。
class LayeredImageProxy(name, transform=None) link

該類是一個類圖像對象,生成向某個層疊式圖像傳遞屬性的代理。

name

一個字串,表示需要代理的層疊式圖像名稱。

transform

一個變換或變換列表,會應用到代理的圖像上。

選擇顯示屬性 link

有多個因素會影響 show語句 最終顯示結果。 為了明確說明各因素的作用順序,本段內容詳細說明了從 show 指令開始到螢幕最終顯示的完整流程。

  • show 語句根據後面跟隨的圖像標籤(image tag),初始化屬性(attribute)的集合。

  • 如果 config.adjust_attributes 成功匹配到圖像標籤並調用了相關函數,函數將返回一個處理後的屬性集合。 此集合將替代上一步的屬性集合。

  • 如果配置項 config.default_attribute_callbacks 中定義了回調函數,當該函數的觸發條件達成時, 調用函數並將執行結果的屬性加入到上一步的集合中。

上述步驟並不僅限適用於層疊式圖像,Ren’Py對所有需要顯示的圖像和層疊式圖像都要經過前置處理。 因此,圖像屬性集使用下面的步驟必須能找到一個並且只有一個有明確定義的圖像(或層疊式圖像,或Live2D)。 詳見 show語句章節

  • show語句中包含的屬性會與層疊式圖像定義時的屬性合併,通過上述前兩步提出一些並保留剩下的。 如果發現無法識別的屬性則會報錯。無報錯的情況下,Ren’Py根據存在的屬性與圖像標籤做匹配關聯。 這步計算會考察部分屬性與圖像標籤的不相容限制。某些實際的不相容是由非multiple類型的組中的同名屬性引起,使用 when 分句就不會出現這種問題。 這也是為什麼明明在從句中沒有某個屬性,Ren’Py卻認為該屬性應該啟用並顯示出來的原因,往往在 when 從句條件不滿足的情況下容易出現類似問題。 (譯者註:這段原文使用了很多複雜長句,可能翻譯有誤。)

  • 如果某個 attribute_function 函數應用到層疊式圖像,將使用經過前述步驟篩選後的屬性作為入參調用該函數。 該函數可能會返回一個略有差別的屬性集。

  • 再來一次不相容檢查,此次是全量檢查。 這是最後一步處理,剩餘的屬性決定最終顯示效果。

幾點建議 link

在圖像名稱中使用下劃線。

默認情況下,Ren’Py中的層疊式圖像使用下劃線作為圖像名各段的分隔符號。 可以在圖像中臨時使用空格,不過後面很可能會導致問題和故障。

Ren’Py的一條規則是,如果創作者想要顯示一個圖像,那個圖像有一個同名圖像正在顯示,那麼就顯示那個同名圖像。 這個規則也貫徹在層疊式圖像中。創作者可以直接定義並顯示圖層,不過也會導致奇怪的問題,比如一雙眼睛懸浮在空中。

每個圖像使用的圖像標籤(tag)都與主圖像不同的話,就不存在這個問題了。

不需要剪裁圖層。

Ren’Py讀取圖像並載入到RAM之前會進行最佳化,將所有圖像剪裁到非透明像素的包圍框(bounding box)。 因此,在圖像被正確預載入的前提下,創作者剪裁圖像並不會提升性能或減少圖像尺寸。

層疊式圖像不應使用運行過程中會發生變化的數據

注意,定義層疊式圖像之後,在 layeredimage 語句塊中的所有表達式都會在初始化階段計算,因此需要提前考慮各個 if 語句中的異常情況。 這與ATL的變換不同,也與 config.adjust_attributesconfig.default_attribute_callbacksattribute_function 配置不同。 但與 format_function 類似,都只在層疊式圖像定義後調用。

選擇合適的語法

如果創作者想要一個總是可見的精靈(sprite),可以使用 always 從句或 attribute x default 語法。 always 語句要求創作者顯式提供可視組件(使用 範式 自動生成的屬性不行), 而 attribute 語句會要求“x”對應的屬性名在層疊式圖像中總是處於啟用狀態。

如果創作者想要在使用 show 語句時向層疊式圖像傳入圖像屬性來決定具體顯示的內容, 例如使用 show eileen happy 更換 show eileen jeans,則要在 group 語句塊中使用 attribute 語句(或在 auto 組中隱式)將兩個標籤設置為互斥關係。

如果創作者想要根據某個Python變數或條件表達式決定顯示內容,則使用 if 語句。

如果創作者“即要又要”(比如:使用 show eileen ribbon 顯示藍色或紅色緞帶,緞帶顏色由某個變數決定;是否顯示緞帶又由 ribbon 屬性控制),可以將各種屬性組織為不同“版本”,然後使用 config.adjust_attributes 配置的函數處理。

樣例 link

範式和自動分組

假設下列文件已經存在,並放置到 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 會定義一個(預設的) base 屬性(attribute),並使用 範式 與(自動定義的)圖像“francis_base”做關聯: 使用下劃線將圖像名(“francis”)、組名稱(此例中沒有)、變種命中(此例中沒有)和屬性名按順序連接構成圖像名。

接著,包含“face”並且符合範式的屬性都歸入到 face 組,即 neutral 屬性會與“francis_face_neutral”圖像關聯,“neutral”是該組中的一個屬性。

在所有顯式出現的屬性都對照對應的圖像後,face 組就成了一個 auto 類型的組,所有存在的圖像(無論是否自動定義)都會通過範式進行匹配搜索。 此例中,使用範式搜索後會找到3個圖像:“francis_face_angry”、“francis_face_happy”和“francis_face_very_happy”。 分別對應 angryhappyvery_happy 三種屬性。 但是不存在 anoyed 屬性,因為“francis_face annoyed”中有一個空格,不符合使用下劃線連接屬性的範式。

最後定義了 supersad 屬性,因為可視組件是顯式聲明的,不需要通過範式搜索。 roup, so they end up not being used in the francis layeredimage. 圖像“francis_supersad”和“francis_face annoyed”會使用Ren’Py原本的 規則 根據圖片檔案名生成圖像名, 並且無法匹配任何一個屬性或auto組,因為無法用於 francis 層疊式圖像。

可見使用範式關聯圖像與屬性,然後使用auto組能有效減少代碼量。 同一個層疊式圖像值需要13行程式碼就可以定義完成。 這種語法可以有效應對sprite圖集數量的幾何式增長——比如此例中添加任何關於face屬性的圖片不需要修改任何代碼。

Dynamism in attributes 屬性的動態機制

下面的例子中,定義一些屬性,會根據某些變數發生變化:

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特性中包含group

when 特性不能指定group名稱,只能透過group內的某些屬性或完全不指定屬性來控制層疊式圖像的顯示。 但是,依然有辦法可以實現,使用層疊式圖像語法控制內部組件的顯示。

假設group沒有default屬性,可以添加一個默認的 null 屬性,實際用什麼做屬性雖個人喜好。 之後,如果group內沒有啟用任何屬性,則啟用之前定義的屬性(實際上不會顯示內容),並且當group隱藏時該屬性會再次啟用。

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的頭髮(也包括肩膀部分的頭髮)。