對話(dialogue)和旁白(narration) link
文本是視覺系小說的根本,對以故事情節為主的遊戲來說更是重中之重。這裡說的文本可能包括使用人物名字作為標籤(label)的對話,以及不存在任何主體的旁白。(為了偷懶,我們把對話和旁白統稱為對話,除非某些場合下兩者有重大區別。)由於對話如此重要,創作者需要能夠訂製化對話的某些特性使其符合製作遊戲的特色。
在Ren’Py中,大多數對話使用say語句編寫。透過使用角色(character)對象,對話外觀可以針對每一個角色實行訂製化。
say語句 link
say語句被用在對話和旁白場景中。由於在Ren’Py腳本中say語句出現如此之頻繁,所以在編寫say語句的語法是一個最小化後的語法結構。這是一些樣例:
"這是一句旁白。"
"艾琳" "這是一句對話,用了完整的角色名。"
e "這是一句對話,使用了角色對象。"
"嘭!!" with vpunch
say語句的第一種形式是一個其自身組成的整個字串。這種形式用於陳述,陳述內容就是字串內容。
say語句的第二種形式是由兩個字串組成。第一個字串是發言角色的名字,第二個字串是該角色正在說的內容。
say語句的第三種形式是一個簡單表達式後接一個字串。簡單表達式應該等同於一個角色名字或者一個角色(character)對象。在後面的例子中,角色對象被用於控制對話展現。
say語句的最後一種形式是一個字串及with分句的一個轉場(transition)效果。在上面的例子中,字串會顯示為對話內容,螢幕會同步抖動。
儘管say語句所處理對話的具體細節實際是由角色(character)對象所控制,say語句的通常用處是在界面上展現一個對話,直到用戶點擊滑鼠後取消對話,並在界面上移除對話內容。
某些字元對Ren’Py有特殊含義,所以不能用在對話字串中。左花括號 {
開啟一個文本標籤(tag),左方括號 [
開啟一個替換(substitution)。若需要在對話中使用這些字元,需要連續出現兩次。而轉移雙引號則需要使用反斜槓符號,不然字串會在那個引號處截斷。應用舉例
"I walked past a sign saying, \"Let's give it 100%!\""
也可以使用代理函數代替角色對象。詳見 此章節。
定義角色(character)對象 link
透過創建一個角色對象並在say語句中使用該角色對象,你可以訂製化對話窗口外觀(甚至行為)。角色對象透過使用define語句,將角色(character)聲明為一個變數。舉例:
define e = Character("艾琳", who_color="#c8ffc8")
完成了這步工作後,定義的角色就可以使用在say語句中。例如:
e "Hello, world."
角色(Character)是一個python函數,該函數包含一大串的關鍵字參數。這些關鍵字參數控制著角色行為。
define語句會計算其自身的表達式,並聲明為一個給定的變數名。若 define
語句不在 init
語句塊(block)中,其會自動以與初始化相同的最高優先度(0)運行。
- Character(name, kind=adv, **args) link
創建並返回了一個角色對象,其控制了對話和旁白的觀感。
- name
如果該參數是一個字串,則成為對話中角色的名字。如果 name 參數是
None
,名字不會顯示,用於旁白。- kind
新建角色的基底角色。當使用該參數時,新建角色沒有顯示賦值的參數,均使用對應基底角色的屬性作為預設值。這個設計常用來定義模板(template)角色,然後繼承模板角色屬性並修改。
連結圖片 與某個角色關聯的圖像標籤(tag)名。這種設計,允許一個包含角色的say語句使用標籤(tag)名來展現角色圖片,也同時允許角色說話時Ren’Py自動選擇並展現一個頭像。
- image
與角色關聯的圖像標籤(tag)名的字串。
語音標籤(tag) 若某個聲音標籤(tag)被指定為某個角色所有,標籤下對應的聲音文件將會與該角色關聯,這些聲音文件可以在自訂設置界面被靜音或者被播放。
- voice_tag
voice_tag是一個字串,在“voice”頻道內可以voice_tag可以控制關聯角色聲音文件的靜音或者播放。
前綴和後綴 這個設計允許在角色名字或者展現文本上添加前綴和後綴。前綴和後綴可以用在每一行對話的前後添加引用內容。
- what_prefix
顯示對話內容之前,添加的前綴字串。
- what_suffix
顯示對話內容之前,添加的後綴字串。
- who_prefix
顯示角色名字之前,添加的前綴字串。
- who_suffix
顯示角色名字之前,添加的後綴字串。
改變角色顯示名 該可選項用於控制顯示角色名。
- dynamic
該參數若為True,角色名 name 應是一個包含python表達式的字串。該字串會在每行對話執行前先演算,將演算結果用作角色名。
互動控制 這些可選項在“對話展示、發生互動、模式輸入”情況下控制顯示效果。
- condition
若給定,該參數應是一個包含python表達式的字串。若表達式結果為False,對話不會發生,即say語句不會執行。
- interact
若該值為True,默認情況下無論對話何時被展現,都會發生一項互動。若該值為False,則互動不會發生,而一些額外元素可以被添加到界面上。
- advance
若該值為True,默認情況下用戶可以快進語句執行,還有一些其他的快進方式(比如跳過skip和auto-forward mode自動前進模式)也將生效。若該值為False,用戶不能跳過say語句,除非腳本中出現某些替換方法(比如跳轉超連結)。
- mode
該參數是一個字串,給定了角色發言時進入的模式(mode)。詳見 模式(mode) 章節。
- callback
角色發言時,若有事件(event)發生則會被調用的函數。詳見 角色(character)回調(callback) 章節。
點擊繼續 “點擊繼續”提示是在(一段內容)所有文本均已展示完的情況下,通常出現一次,提醒用戶進入下一部分內容。
- ctc
一個用做“點擊繼續”提示的可展現部件,若有其他特殊提示被使用時可能不會展現。
- ctc_pause
當文本顯示被{p}或{w}標籤(tag)暫停時,用作“點擊繼續”提示的一個可視組件。
- ctc_timedpause
當文本顯示被{p=}或{w=}標籤(tag)暫停時,用作“點擊繼續”提示的一個可視組件。當該值為None時,會使用 ctc_pause 的值作為預設值。若你想要使用 ctc_pause 而不是 ctc_timedpause ,請使用
Null()
。- ctc_position
該參數控制“點擊繼續”提示的位置。若值為
"nestled"
,該提示會作為目前展示文本的一部分出現,在最後一個字元顯示後立即出現相應提示。若值為"fixed"
,提示會被直接添加到界面上,其在界面上的位置由位置樣式屬性控制。
界面 顯示對話使用到一個 界面 。該入參允許你選擇界面(screen),並傳入參數。
- screen
顯示對話時使用的界面名。
關鍵字參數以前綴
show_
開頭,去掉前綴後傳參給界面(screen)。例如,show_myflag
的值會改為變數myflag
並傳參給界面(screen)。(myflag變數並不是預設會用參數,但可以被一個訂製對話界面使用。)鑑於某些歷史原因,show系列變數由Ren’Py引擎處理:
- show_layer
若給定了這個參數,其應該是一個字串,這個字串給定了展現“說話”界面所在圖層的名字。
樣式化文本和窗口 以
who_
、what_
和window_
開頭的關鍵字參數,會去掉前綴後分別用於 樣式 <styles> 角色名、對話文本和窗口內容。例如,若一個角色被給定了關鍵字參數
who_color="#c8ffc8"
,角色名的顏色就被改變,這裡的例子中會被改成綠色。window_background="frame.png"
是把包含該角色的對話窗口背景設置為圖片frame.png。應用於角色名、對話文本和窗口的樣式化,也可以使用這種方式進行設置:分別對應使用
who_style
,what_style
和window_style
參數。設置
config.character_id_prefixes
後,就可以樣式化其他可視組件了。例如,如果使用了預設的GUI配置,帶有前綴 namebox_ 的樣式將會應用在發言角色名上。
帶有圖像屬性(attribute)的say語句 link
當一個角色與一個圖像標籤(tab)關聯,包含對應角色的say語句將在角色名和第二個字串之間就可以插入圖像屬性(attribute)。
在這中情況下,如果帶有給定標籤(tag)的某個圖片需要顯示,Ren’Py會定位一條包含角色標籤(tag)和屬性(attribute)的show命令。如果圖片未顯示,Ren’Py會保存屬性(attribute)並用於頭像,但依然不會顯示圖片。
舉例:
define e = Character("艾琳", image="eileen")
label start:
show eileen mad
e "我對你有點失望。"
e happy "不過這都是過去的事了。"
等價於:
define e = Character("艾琳")
label start:
show eileen mad
e "我對你有點失望。"
show eileen happy
e "不過這都是過去的事了。"
在上面的例子中,mad
和 happy
會互相替換。
不過也可以可以直接從 happy
恢復而不用指定 mad
屬性。
辦法是使用減號(-),具體請參考 show語句。
舉例:
define e = Character("艾琳")
label start:
show eileen
e mad "我對你有點失望。"
e happy "雖然還挺有趣的。"
e -happy "我不清楚現在該怎麼看了。"
如果在圖像屬性前面加一個 @
符號,圖像屬性的改變將是臨時性的,在執行完這行對話腳本後會恢復成上一個圖像屬性。
舉例:
define e = Character(“艾琳”, image=“eileen”)
label start:
show eileen mad e “我對你有點失望。”
e @ happy “雖然還挺有趣的。”
e “我不清楚現在該怎麼看了。”
兩種語法可以混用,在 @
符號之前表示永久改變,符號後面表示臨時改變一次。
e happy @ vhappy "真的!一切都改變了。"
減號也可以與 @
符號混用:
e @ right -mad "我的怒火暫時得到了平息……"
e "但是!"
使用這個方式,若需要在圖片改變時觸發一個轉場(transition)效果的話,將config.say_attribute_transition設置為一種轉場(transition)即可。
若要設置更多控制項,可以使用 config.say_attribute_transition_callback
。
樣例角色 link
這是一些樣例角色:
# 角色的對話內容包含在一對圓括號中。
define e = Character("艾琳", what_prefix='(', what_suffix=')')
# 從一個變數中獲取角色名稱。
define p = Character("player_name", dynamic=True)
特殊角色 link
一些角色名是系統預定義的,並會在某些場合自動啟動。有意地重定義這些角色可以改變Ren’Py引擎的行為,但意外使用的話很可能會引發問題。
adv
使用角色(character)定義生成的默認角色類型。這種類型的角色在界面上同一時間只能顯示一行文本。
nvl
在 NVL模式教學 下可以引發對話的角色類型。這種類型的角色可以在界面上一次顯示多行文本。
narrator
旁白角色,不需要角色名的say語句中使用。
name_only
給定一個字串,該字串用作對話中顯示角色名。這種角色可以被複製為一個給定名字的新角色,而新角色在顯示的對話中使用同樣的名字。
centered
該類型角色的台詞會顯示在界面正中間,在所有窗口外面。
vcentered
該類型角色的台詞會豎直顯示在界面正中間,在所有窗口外面。
extend
使用最近一個發言角色,在原有對話內容後追加一行台詞。快速擴展對話。這可以用於界面變更後的對話內容延續。
擴展(extend)能識別NVL模式,並正確處理該模式下的內容。 但在NVL模式下修改語言設定,則extend內容將無法正確顯示。
舉例:
# 展現對話的第一行台詞,等待一個點擊事件,變更角色表情,然後展示其餘台詞。
show eileen concerned
e "有時候,我會感到憂傷。"
show eileen happy
extend " 但是我通常很快就能恢復過來!"
# 與上面類似,不同之處在於,當第一行台詞結束後自動變更角色表情。
# 只有當用戶始終沒有自己設置文本顯示速度的情況下,這種設計才是合理的。
show eileen concerned
e "有時候,我會感到憂傷。{nw}"
show eileen happy
extend " 但是我通常很快就能恢復過來!"
對話窗口管理 link
Ren’Py中包括幾種語句,允許管理對話窗口。由於對話窗口在對話中一直是展現的,這些窗口控制語句在非對話互動的情況下控制窗口的出現或者消失。
window show
window show語句觸發窗口展現。該語句接受一個可選入參,入參為transition,用於窗口出現的轉場效果。如果transition參數為空,將使用定義在
config.window_show_transition
的值。window hide
window hide語句觸發窗口隱藏。該語句接受一個可選入參,入參為transition,用於窗口隱藏的轉場效果。如果transition參數為空,將使用定義在
config.window_hide_transition
的值。window auto
window auto語句啟用了窗口自動管理。在
config.window_auto_show
中列出的語句——預設是say語句前,窗口會自動展現。在config.window_auto_hide
中列出的語句——預設是scene
和call screen
以及帶標題的menu
語句前,窗口會自動隱藏。(只有直接顯式使用該語句才有效,而函數返回該語句內容相同的字串不生效。)
window auto
語句分別使用 config.window_show_transition
和 config.window_hide_transition
作為顯示和隱藏窗口的轉場效果。 window auto
啟用的自動化管理可以被 window show
或者 window hide
語句關閉。
舉例:
window show # 使用默認轉場效果顯示窗口
pause # 在暫停中依然顯示窗口
window hide # 隱藏窗口
pause # 在暫停中依然隱藏窗口
window show dissolve # 使用融化(dissolve)效果顯示窗口
pause # 在暫停中依然顯示窗口
window hide dissolve # 使用融化(dissolve)效果隱藏窗口
pause # 在暫停中依然隱藏窗口
window auto
"The window is automatically shown before this line of dialogue."
pause # 在暫停中依然顯示窗口
scene bg washington # 在場景(scene)切換前隱藏窗口
with dissolve
對話窗口管理是
Preference()
特性構造器“show empty window”一項的主題。若“show empty window”特性被關閉,以上語句均不會產生任何效果。
帶有參數的say語句 link
使用語句後面圓括號包含的入參值可以傳給say語句。舉例:
e "Hello, world." (what_color="#8c8")
傳入say語句的參數首先會被 var:config.say_arguments_callback 回調函數處理,前提是入參不是None。若有回調函數無法處理的參數,將會被傳給角色(character),因為這些參數會被看作定義角色所需。上面的樣例會將對話顯示為綠色。
特殊關鍵字 _mode 和 _with_node 將在本次互動中覆蓋原設置的字元。
interact 參數是個特殊情況:當定義角色對象時就把該參數設置為False後,即使後面再次傳入 interact=True
也依然不能覆蓋原設置,也就是說角色依然不會對互動有反應。
注意,config.say_arguments_callback
配置的回調函數並不會在傳入參時調用,而且也並不是每條say語句執行時都被調用。
該配置項可以用來實現角色面對不同情況時的不同反應。例如:
init python:
def say_arguments_callback(char, *args, **kwargs):
if colorblind_mode:
kwargs["what_color"] = "#000"
return args, kwargs
define config.say_arguments_callback = say_arguments_callback
獨白模式 link
某些視覺小說會有大段連續的旁白,或者同一個角色的多段會話內容。這種情況下,腳本裡反覆寫入角色名稱和引號就顯得很累贅。
為了應對這些情況,Ren’Py提供了獨白模式。將對話內容放入成對的3個雙引號中,Ren’Py會根據對話內容中的空行自動分段。 分段後的每一段內容,都會創建自身的say語句。這裡的一個樣例,包含3段旁白,將分為3段對話。
"""
這是第一行旁白。第一行比其他兩行都長,所以它將換行
(補足字數補足字數補足字數補足字數)。
這是第二行旁白。
這是第三行旁白。
"""
e """
這是對話的第一行。第一行比其他兩行都長,所以它將換行
(補足字數補足字數補足字數補足字數)。
這是對話的第二行。
這是對話的第三行。
"""
say語句後面可能會有分句,並帶上入參或者屬性(attribute)。這些入參或者屬相將在獨白中分配給每一行。
如果創作者想要忽略段落之間的空行,可以在腳本文件最外層,並且第一行獨白之前寫一條 rpy monologue single
。
(譯者註:即,不使用空行自動分段。)
如果想要禁用該設置,或者混用三重雙引號與單條對話的形式,可以使用 rpy monologue none
標記獨白模式的結尾位置。
character
儲存區 link
主要內容在 其他的命名儲存區 。
say語句會在默認儲存區之前先搜索 character
命名儲存區。
如果你想要默認儲存區中保存一個與角色名字相同的變數,需要這樣定義:
define character.e = Character("Eileen")
該角色就可以在默認儲存區中像一般變數一樣使用了:
default e = 0
label start:
# 這依然是一個糟糕的變數名。
$ e = 100
e "我們現在還有 [e] 個單位的能量。"
這在管理某個角色相關的變數資訊方面很有用,不會跟say語句發生衝突。
define character.naomi = Character("Naomi Nagata", who_color="#8c8")
default naomi = PersonClass(engineering=5, max_g_force=.7) # 可以是一個對象
define character.fred = Character("Fred Johnson", who_color="#72f")
default fred.money = 1000 # 可以是一個自訂命名空間中的變數
default fred.rank = "Colonel"
label traded:
fred "這個給你。"
$ fred.money -= 50
$ naomi.money += 50
naomi "Thanks ! I knew you would value my class-[naomi.engineering] engineering skills."
naomi "感謝!我就知道你會意識到我 [naomi.engineering] 級工程技能的價值。"
其他表現形式 link
NVL模式教學 :在整個螢幕顯示對話內容的模式。
氣泡式台詞 :使用台詞氣泡來顯示對話內容,並且使用可互動的方式調整氣泡位置。
其他參考 link
等效語句 :如何在Python中使用本章節描述的大多數功能特性,雖然有一些制約條件。
renpy.last_say()
:提供最後一條say語句的資訊。