畫廊、音樂空間和場景重播 link
畫廊 link
畫廊是一個專門的界面,允許用戶解鎖並查看圖片。該界面有一個或多個相關聯的按鈕,每個按鈕都有對應的圖片。按鈕和圖片的狀態取決於是否已被解鎖。
Gallery類實例管理畫廊。同一個gallery類的實例可能會被多個畫廊界面共同使用。
畫廊有一個或多個相關聯的按鈕,每個按鈕都有對應的圖片,每個圖片對應一個或多個可視組件。當某個按鈕對應的條件全部滿足並與該按鈕關聯的圖片至少解鎖一張時,這個按鈕也就被解鎖了。所有關聯條件全部滿足時,圖片就能解鎖。
創建畫廊需要下面四步。
創建一個Gallery實例。
在Gallery實例中添加按鈕和圖片,以及解鎖按鈕和圖片需要的條件。這也是一個多步過程。
調用
Gallery.button()
定義一個新的按鈕。可選,調用
Gallery.unlock()
或Gallery.condition()
添加一個或多個解鎖條件至按鈕。使用一個或多個可視組件作為參數,調用
Gallery.image()
定義一個圖像(image)。或者直接調用Gallery.unlock_image()
。可選,調用
Gallery.transform()
將可視組件與變換(transform)相關聯。可選,調用
Gallery.unlock()
、Gallery.condition()
或Gallery.allprior()
給圖像添加一個或多個解鎖條件。
重複步驟3至5就可以再次添加按鈕,重複所有5個步驟就可以再次添加圖片。
創建一個畫廊界面。界面應該顯示一個背景,並且包含導航,允許用戶轉到其他畫廊或者返回主選單及額外菜單(extras menu)。
在主選單和額外菜單上添加進入畫廊界面的入口。
這是一個樣例:
init python:
# 步驟1,創建Gallery對象。
g = Gallery()
# 步驟2,在畫廊中添加按鈕和圖像。
# 一個圖像一直解鎖狀態的按鈕。
g.button("title")
g.image("title")
# 添加一個包含自動解鎖圖像的按鈕。
g.button("dawn")
g.image("dawn1")
g.unlock("dawn1")
# 該按鈕有多個關聯圖像。
# 我們使用unlock_image函數,這樣就不需要同時調用“.image”和“.unlock”了。
# 我們也在第一張圖像上添加了一個變換效果。
g.button("dark")
g.unlock_image("bigbeach1")
g.transform(slowpan)
g.unlock_image("beach1 mary")
g.unlock_image("beach2")
g.unlock_image("beach3")
# 該按鈕有一個關聯的條件,允許遊戲選擇是否解鎖圖片。
g.button("end1")
g.condition("persistent.unlock_1")
g.image("transfer")
g.image("moonpic")
g.image("girlpic")
g.image("nogirlpic")
g.image("bad_ending")
g.button("end2")
g.condition("persistent.unlock_2")
g.image("library")
g.image("beach1 nomoon")
g.image("bad_ending")
# 該按鈕的最後一張圖像有一個關聯條件,只有只有達到兩種結局才會解鎖。
g.button("end3")
g.condition("persistent.unlock_3")
g.image("littlemary2")
g.image("littlemary")
g.image("good_ending")
g.condition("persistent.unlock_3 and persistent.unlock_4")
g.button("end4")
g.condition("persistent.unlock_4")
g.image("hospital1")
g.image("hospital2")
g.image("hospital3")
g.image("heaven")
g.image("white")
g.image("good_ending")
g.condition("persistent.unlock_3 and persistent.unlock_4")
# 後面兩個按鈕包含會同時顯示的多個圖片。
# 這可能會用於在背景上顯示人物立繪。
g.button("dawn mary")
g.unlock_image("dawn1", "mary dawn wistful")
g.unlock_image("dawn1", "mary dawn smiling")
g.unlock_image("dawn1", "mary dawn vhappy")
g.button("dark mary")
g.unlock_image("beach2", "mary dark wistful")
g.unlock_image("beach2", "mary dark smiling")
g.unlock_image("beach2", "mary dark vhappy")
# 用於圖像切換使用的轉場(transition)。
g.transition = dissolve
# Step 3. 我們使用的畫廊界面。
screen gallery:
# 確保畫廊界面替換主選單。
tag menu
# 背景圖。
add "beach2"
# 按鈕網格(grid)。
grid 3 3:
xfill True
yfill True
# 調用make_button顯示具體的按鈕。
add g.make_button("dark", "gal-dark.png", xalign=0.5, yalign=0.5)
add g.make_button("dawn", "gal-dawn.png", xalign=0.5, yalign=0.5)
add g.make_button("end1", "gal-end1.png", xalign=0.5, yalign=0.5)
add g.make_button("end2", "gal-end2.png", xalign=0.5, yalign=0.5)
add g.make_button("end3", "gal-end3.png", xalign=0.5, yalign=0.5)
add g.make_button("end4", "gal-end4.png", xalign=0.5, yalign=0.5)
add g.make_button("dark mary", "gal-dark_mary.png", xalign=0.5, yalign=0.5)
add g.make_button("dawn mary", "gal-dawn_mary.png", xalign=0.5, yalign=0.5)
add g.make_button("title", "title.png", xalign=0.5, yalign=0.5)
# 用於響應後返回主選單的界面。
# 也能用於導航到其他畫廊界面。
textbutton "Return" action Return() xalign 0.5 yalign 0.5
步驟4會由於遊戲結構的不同而大相徑庭,不過一種通用辦法是添加下面這行:
textbutton "Gallery" action ShowMenu("gallery")
主選單界面添加畫廊選項。
- class Gallery(self) link
該類支持畫廊實例的創建。該類提供的處理鎖定圖片的函數、顯示一個或者多個圖片的行為,以及創建按鈕使用那個行為的方法。
- transition link
改變圖像時使用的轉場(transition)。
- locked_button link
make_button用於某個被鎖定按鈕的默認可視組件。
- hover_border link
make_button使用的默認滑鼠懸垂(hover)邊界(border)。
- idle_border link
make_button使用的默認空閒(idle)邊界(border)。
- unlocked_advance link
若為True,畫廊只會在解鎖的圖片中advance through。
若為True,畫廊會在圖片的上方顯示導航和幻燈片按鈕。
若要訂製導航外觀,你可以重寫gallery_navigation界面。預設的界面定義在common/00gallery.rpy中。
- span_buttons link
若為True,添加span按鈕。
- slideshow_delay link
使用幻燈片模式時,畫廊中每張圖片的播放時間。
- image_screen = "_gallery"
該界面用於顯示畫廊中的獨立圖片。 可以使用下列關鍵字參數:
- locked
圖片鎖定狀態則為True。
- displayables
一個經過變換的可視組件組成的列表,用於向用戶展示。
- index
顯示圖片序號,從1開始計。
- count
當前按鈕對應的圖片數量。
- gallery
Gallery對象。
調用
Gallery.image()
和Gallery.unlock_image()
時,帶前綴 show_ 的將作為額外參數傳入。 界面的默認定義在 renpy/common/00gallery.rpy 文件底部。
- Action(name) link
一個行為(action),顯示與給定的按鈕名name相關聯的圖像。
- Next(unlocked=False) link
前進至畫廊的下一個圖片。
- unlocked
若為True,只使用已解鎖的圖片。
- Previous(unlocked=False) link
後退至畫廊的上一個圖片。
- unlocked
若為True,只使用已解鎖的圖片。
- Return(self) link
停止顯示畫廊圖片。
- ToggleSlideshow(self) link
切換幻燈片模式。
- allprior(self) link
一個條件函數,當前按鈕關聯的所有主要圖片都解鎖的情況下為True。
- button(name) link
創建一個名為 name 的按鈕。
- name
創建的按鈕名稱。
- condition(expression) link
一個條件函數,expression為真時表示條件滿足。
- expression
一個Python表達式字串。
- display(*displayables) link
將一個新的圖像添加至當前按鈕。該圖像由一個或多個可視組件構成。
- get_fraction(name, format='{seen}/{total}') link
返回一個文本字串,表示名為 name 的按鈕的已解鎖圖片數和圖片總數。
- format
一個Python格式字串,用於格式化數值。有三種可以被替換的值:
- {seen}
已經看過的圖片的數值。
- {total}
按鈕中圖片總數。
- {locked}
依然鎖定的圖片數量。
- image(*displayables) link
將一個新的圖像添加至當前按鈕。該圖像由一個或多個可視組件構成。
前綴 show_ 會被剔除,然後作為額外關鍵字參數傳入gallery.image_screen界面。
- make_button(name, unlocked, locked=None, hover_border=None, idle_border=None, **properties) link
該函數創建一個按鈕,顯示與給定按鈕名相關聯的圖像。
- name
需要創建的按鈕名稱。
- unlocked
當按鈕解鎖時顯示的可視組件。
- locked
當按鈕鎖定時顯示的可視組件。若為None,將使用畫廊對象的locked_button欄位(field)值。
- hover_border
當按鈕解鎖並得到焦點時,覆蓋在按鈕上的可視組件。若為None,將使用畫廊對象的hover_border欄位(field)值。
- idle_border
當按鈕解鎖未得到焦點是,覆蓋在按鈕上的可視組件。若為None,將使用畫廊對象的idle_border欄位(field)值。
更多的關鍵字入參會成為所創建按鈕對象的樣式特性(sytle property)。
- transform(*transforms) link
將變換(transform)應用於註冊的最後一張圖片。該函數被調用時應該包含與圖片中可視組件數量相同的變換(transform)數量。每個變換分別對應一個可視組件。
如果某個變換為None,就使用預設的變換。
- unlock(*images) link
一個條件函數,使用一個或多個圖片名作為入參,當所有入參的圖像都被用戶看過時表示條件滿足。圖片名稱應該是字串。
- unlock_image(*images) link
一個簡便的函數,等效於使用相同的參數調用圖片對象並解鎖。 (前綴為
show_
的關鍵字入參會傳給對應圖片對象。) 這個函數會觸發某個圖片的顯示,前提是這個圖片之前被看過。指定的圖片名應該是字串。
音樂空間 link
音樂空間是允許用於選擇和播放遊戲內音軌的界面。這些音軌可能在用戶剛開始玩時是鎖定的,隨著遊戲進度的推進逐步解鎖。
音樂空間通過MusicRoom類的實例進行管理。遊戲中允許存在多個MusicRoom實例,允許存在多個音樂空間。創建一個音樂空間包含以下四個步驟:
創建一個MusicRoom實例。MusicRoom構造器使用的參數控制音樂播放使用的通道(channel),以及音樂的淡入淡出效果時長。
將音樂文件添加至實例。
創建一個使用MusicRoom實例的界面,界面中包含按鈕、圖片按鈕和熱點(hotspot)。界面中還包含能拾取音軌、進入下一個或上一個音軌、暫停或開始播放音樂的行為(action)。
需要注意,行為(action)用作某個MusicRoom實例的成員函數,所以如果MusicRoom實例名為mr,那麼mr.Play(“track1.ogg”)就是播放行為的正確用法。
將音樂空間界面添加到主選單或者額外菜單。
這是一個前三步的樣例:
init python:
# 步驟1,創建一個MusicRoom實例。
mr = MusicRoom(fadeout=1.0)
# Step 2. 添加音樂文件。
mr.add("track1.ogg", always_unlocked=True)
mr.add("track2.ogg")
mr.add("track3.ogg")
# Step 3. 創建音樂空間界面。
screen music_room:
tag menu
frame:
has vbox
# 每條音軌的播放按鈕。
textbutton "Track 1" action mr.Play("track1.ogg")
textbutton "Track 2" action mr.Play("track2.ogg")
textbutton "Track 3" action mr.Play("track3.ogg")
null height 20
# 切換音軌按鈕。
textbutton "Next" action mr.Next()
textbutton "Previous" action mr.Previous()
null height 20
# 用戶退出音樂空間的按鈕。
textbutton "Main Menu" action ShowMenu("main_menu")
# 音樂空間的音樂播放入口。
on "replace" action mr.Play()
# 離開時恢復主選單的音樂。
on "replaced" action Play("music", "track1.ogg")
步驟4會由於遊戲結構的不同而大相徑庭,不過一種通用辦法是添加下面這行:
textbutton "Music Room" action ShowMenu("music_room")
主選單界面添加音樂空間選項。
使用 Preferences()
函數,特別是
Preferences("music volume")
,就可以在音樂界面添加一個音量滑塊。
- class MusicRoom(channel='music', fadeout=0.0, fadein=0.0, loop=True, single_track=False, shuffle=False, stop_action=None) link
一個音樂空間類,包含一系列可由用戶解鎖的曲子,以及順序播放音訊列表的行為。
- channel
音樂空間使用的音訊通道。
- fadeout
改變音軌時,漸出效果時長,單位為秒。
- fadein
改變音軌時,漸入效果時長,單位為秒。
- loop
當播放列表到達結尾時,決定循環播放還是停止播放。
- single_track
若為True,每次只播放一條音軌。若 loop 為True,則循環播放這條音軌。否則在音軌結束時結束播放。
- shuffle
若為True,所有音軌亂序播放。若為False,根據音軌加入到音樂空間的順序播放。
- stop_action
當音樂停止時執行的行為(action)。
single_track 和 shuffle 兩項是衝突的,二者最多只有一項能設置為True。(設置 single_track 和 shuffle 的行為會有這樣的強制要求)。
- Next(self) link
觸發音樂空間播放列表中下一個已解鎖音樂的行為。
- Play(filename=None) link
這個行為觸發音樂空間開始播放音樂。如果給定了 filename ,就開始播放對應的音訊檔案。否則,當前播放文件重新開始(前提是已經解鎖),或者播放第一個音訊檔案。
如果給定了 filename ,但對應的音訊依然被鎖定,那對應的按鈕是不可用狀態,正在播放的 filename 會被設為被選中狀態。
- Previous(self) link
讓音樂空間播放列表中上一個解鎖文件的行為。
- RandomPlay(self) link
讓音樂空間播放隨機選擇的一個解鎖音軌的行為。
- SetLoop(value) link
這個行為設置loop特性的值。
- SetShuffle(value) link
這個行為設置shuffle特性的值。
- SetSingleTrack(value) link
這個行為設置single_track特性的值。
- Stop(self) link
這個行為停止音樂播放。
- ToggleLoop(self) link
這個行為切換loop特性的值。
- TogglePlay(self) link
如果當前沒有任何音樂在播放,這個行為會開始播放第一個解鎖的音軌。否則,停止當前音樂的播放。
任何音樂播放時,這個按鈕都是可用狀態。
- ToggleShuffle(self) link
這個行為切換shuffle特性的值。
- ToggleSingleTrack(self) link
這個行為切換single_track特性的值。
- add(filename, always_unlocked=False, action=None) link
將音樂文件 filename 添加到音樂空間。音樂空間中文件被添加的順序就是音樂播放的默認順序。
- always_unlocked
若為True,音樂文件始終是解鎖狀態。這個設置允許音樂文件在遊戲播放過之前,就可以在音樂空間中使用。
- action
這是一個行為或者行為列表。當文件播放時,這個行為或行為列表會被調用。
例如,這些行為可以用於播放音樂文件時改變界面或者背景。
- is_unlocked(filename) link
如果 filename 已被解鎖(或一直是解鎖)則返回True,否則返回False。
重播 link
Ren’Py也提供了從主選單或遊戲菜單重播某個場景的能力。這可以用來創建一個“場景畫廊”或者“回憶畫廊”,允許用戶重複重要的場景。在對應的場景結束後,Ren’Py會返回到啟動重播前的菜單界面。
場景重播也可以使用 Start()
行為。這兩種模式的差別如下:
重播可以從任何界面啟動,而Start只能使用在主選單或者主選單顯示的界面。
當重播結束,主控流程會回到重播啟動的點。那個點可能是在主選單或者遊戲菜單中。如果某個遊戲運行過程中調用了重播,遊戲狀態是會被保留。
在重播模式下禁用存檔。重新載入由於需要存檔,也是禁用的。
在重播模式下,調用
renpy.end_replay()
會結束重播。在普通模式下,renpy.end_replay()不產生任何效果。
需要使用重播模式的優勢,需要在場景開始添加一個文本標籤(label),在結尾添加一個renpy.end_replay的調用。界面不應該假設在普通模式和重播模式下圖層(layer)或變數的狀態不同。(在重播開頭,標籤會被一個黑屏界面喚起。)
舉例:
"最後,我終於見到了魔導士本尊。"
label meaning_of_life:
scene revelation
"魔術師" "你問我,生命的意義?"
"魔術師" "我曾經苦思冥想,並為獲取這個問題的答案耗費了大量時光。"
"魔術師" "而現在我會這樣回答這個問題——生命的意義是……"
"魔術師" "是43。"
$ renpy.end_replay()
"魔術師" "總之就是類似的東西。"
(譯者註:這個梗比較冷僻,稍作解釋。道格拉斯·亞當斯的小說《銀河便車指南》中提到,42是“生命、宇宙以及任何事情的終極答案”。 此後,42經常被用來表示致敬。援引維基百科上對 42 的解釋,幾個最著名的致敬梗有:
若在Google輸入the answer to life, the universe, and everything,Google會直接回答42——而且還是用Google計算器算出來的。
若在Wolfram Alpha中輸入Answer to the Ultimate Question of Life, the Universe, and Everything,Wolfram Alpha也會回答42。
若在Siri中問“What’s the meaning of life?”,Siri也會回答42。
此處魔術師回答“43”也是對此的惡搞。)
這樣定義的場景(scene),就可以使用重播行為喚起重播了。
textbutton "生命的意義" action Replay("meaning_of_life")
重播模式有一個專用的儲存變數:
- _in_replay link
在重播模式下,這個變數就是重播開始的文本標籤(label)。非重播模式下,這個變數值是None。
除此之外,config.enter_replay_transition
和
config.exit_replay_transition
會分別使用在進入和離開重播模式時。在進入重播時, config.replay_scope
會向清理後的儲存區添加變數,默認情況下會設置
_game_menu_screen
以觸發“右鍵點擊行為”默認顯示環境設定界面。
重播模式下一下變數和行為會被使用:
- EndReplay(confirm=True) link
結束當前重播。
- confirm
若為True,結束重播前提示用戶確認。
- Replay(label, scope={}, locked=None) link
從 label 處開始重播的行為。
- scope
一個字典,表示從變數名與變數值的映射關係。進入重播時,所有變數會設置該字典的值。
- locked
若為True,該重播鎖定。若為False,該重播解鎖。若為None,如果遊戲進度未進展到對應標籤則鎖定重播。
- renpy.call_replay(label, scope={}) link
將腳本標籤(label)視為一個回憶。
關鍵字入參用於設置回憶場景的變數初始值。
- renpy.end_replay() link
處在重播時,立刻結束重播。否則,不做任何事。