Python語句 link

Ren’Py使用Python程序語言編寫,並且支持在Ren’Py腳本中包含Python語句。對Python的支持可以用在很多方面,從立一個flag到創建新的可視組件等。本節內容主要涵蓋Ren’Py腳本如何透過各種python語句直接調用Python的方法。

Ren’Py現在支持Python 2.7。不過我們還是強烈推薦寫可以同時在Python2和Python3兩個版本正常運行的Python語句。

Python link

python語句包含一個Python的語句塊(block),當主控流程達到該語句時就會執行對應的語句塊。一條基本的python語句非常簡練:

python:
    flag = True

在必要時,python語句可以更複雜:

python:
    player_health = max(player_health - damage, 0)
    if enemy_vampire:
        enemy_health = min(enemy_health + damage, enemy_max_health)

這裡有兩個標識符可以改變python語句的表現:

hide

若出現了 hide 標識符,python語句將會以匿名者視角運行Python語句塊。在該python語句塊執行完畢後,匿名者視角就會遺失。

hide標識符允許Python使用不能保存的臨時變數——但也意味著存儲(store)對象不能直接接入存儲區(store),而必須以欄位(field)的形式接入。

in
in 標識符包含一個變數名。Python會使用那個變數名所代表的存儲區(store),而非默認存儲區。

單行Python語句 link

最常見的情況就是只有一行Python語句,運行在默認存儲區內。例如,一行Python可以用來初始化或者更新一個flag。為了讓編寫只有一行的Python更精煉,這裡提供了單行Python語句。

單行Python語句以美元符號($)開頭,一行語句內容可以包羅萬象。這是一些單行Python語句樣例:

# 立一個flag。
$ flag = True

# 初始化一個變數。
$ romance_points = 0

# 變數自增。
$ romance_points += 1

# 調用Ren'Py函數。
$ renpy.movie_cutscene("opening.ogv")

單行Python通常運行在預設的存儲區。

init python語句 link

init python 語句在初始化階段運行,早於其他遊戲資源載入。在其他方面,這種功能可以用於定義類(class)和函數(function),或者初始化樣式(style)、配置變數、持久化數據。

init python:

    def auto_voice_function(ident):
        return "voice/" + ident + ".ogg"

    config.auto_voice = auto_voice_function

    if persistent.endings is None:
        persistent.endings = set()

init 1 python:

    # 解鎖bad ending。
    persistent.endings.add("bad_ending")

initpython 之間可以放一個運行優先度數值。如果沒有指定優先度,預設使用0。init語句按照優先度數值從低到高的順序運行。優先度相同的情況下,按照檔案名的unicode字元順序。文件內,從頭到尾順序運行。

為了避免與Ren’Py引擎產生衝突,創作者最好選用-999到999範圍內作為優先度。負整數的優先度主要用在庫(library)和主題設置。普通的init語句應該使用0或者正整數作為優先度。

init python語句也可以使用 hidein 分句。

在init python語句中被賦值的變數不會用於存檔、讀檔,且不接受回滾。因此,在初始化完成後,這些變數值就不該改動。

define語句 link

define語句在初始化時將一個變數賦值。例如:

define e = Character("艾琳")

等價於

init python:
    e = Character("艾琳")

define語句可以選擇使用一個命名存儲區(詳見下面的例子),將存儲區名放在變數前面,用英文句號(.)連接。舉例:

define character.e = Character("艾琳")

define語句可選擇帶一個索引值,使其可以在一個字典中設置元素:

define config.tag_layer["eileen"] = "master"

除了使用等號 = ,define語句還可以使用另外兩個運算符。 += 運算符用於添加元素,還主要用於列表合併。 |= 運算符主要用於集合合併。例如:

define config.keymap["dismiss"] += [ "K_KP_PLUS" ]
define endings |= { "best_ending }

使用define語句的一個優點是,在聲明時它會記錄下檔案名和該行腳本編號,供啟動器(launcher)的導航(navigation)特性使用。

通過define語句定義的變數會被當作一個常數,不會保存或讀取,也不該被修改。(Ren’Py不做強制要求,但修改那些參數會導致不可預見的情況出現。)

default語句 link

default語句給一個變數賦值,前提是該變數在遊戲啟動或者新遊戲載入時未定義。舉例:

default points = 0

如果變數 points 在遊戲啟動時未定義,這條default語句等價於:

label start:
    $ points = 0

如果變數 points 在遊戲載入時未定義,這條default語句等價於:

label after_load:
    $ points = 0

default語句可以選擇使用一個命名存儲區(詳見下面的例子),將存儲區名放在變數前面,用英文句號(.)連接。舉例:

default schedule.day = 0

init offset語句 link

init offset語句為所有在初始化階段運行的語句設置了優先度偏移量(offset)。(init、init python、define、default、screen、transform、style等語句。)init offset語句中給定的偏移量(offset)對之後同一個語句塊(block)及其子語句塊的所有語句均生效,除非期間出現一個init priority語句。下面這條語句:

init offset = 42

將優先度偏移量(offset)設置為42。而在下面段腳本中:

init offset = 2
define foo = 2

init offset = 1
define foo = 1

init offset = 0

第一條define語句運行在優先度2,這意味著其會在第二條define語句後運行,因此變數 foo 的最終值為2。

存儲區變數名 link

Ren’Py存儲Python變數的地方稱作存儲區(store)。請務必保證你使用的存儲區名沒有衝突。

define語句將一個值聲明為一個變數,也可用作定義一個角色對象。這也意味著角色和flag不能同名。

下面這段有問題的腳本:

define e = Character("艾琳")

label start:

    $ e = 0

    e "你好,世界。"

    $ e += 1
    e "你得了一分!"

無法運行,因為變數 e 同時用作角色和flag。

其他也常常需要放入存儲區的對象是轉場(transition)和變換(transform)。

以下劃線 (_) 開頭的變數名是預留給Ren’Py內部使用。詳情可以查看 預留變數名目錄

其他的命名存儲區 link

命名存儲區提供了一種將Python函數和變數有效組織成模組(module)的方法。利用Python的模組化功能,你可以將命名衝突的可能性降到最小。

命名存儲區可以可以通過 pythoninit python 語句中的 in 分句接入。python和init python語句都在命名存儲區內運行Python。每個存儲區相當於一個Python模組(module)。默認存儲區就是 store ,接入該存儲區內的變數名格式為 store.name 。這些python模組可以透過使用Python import語句導入(import),模組中的變數和函數名可以使用Python from 語句導入(import)。

舉例:

init python in mystore:

    serial_number = 0

    def serial():

        global serial_number
        serial_number += 1
        return serial_number

init python:
    import store.mystore as mystore

label start:
    $ serial = mystore.serial()

命名存儲區與默認存儲區在存檔、讀檔和回滾方面的情況一樣。define語句也可以在命名存儲區內定義變數或函數名。

第一方和第三方Python模組(module)和包(package) link

Ren’Py可以導入(import)純python的模組和包。創作者需要用在遊戲中的第一方的模組和包,可以直接放置在game文件夾裡。第三方的包可以放在game/python-packages文件夾裡。

例如,如果要安裝requests包,創作者可以用命令行進入遊戲所在目錄,然後運行如下命令:

pip install --target game/python-packages requests

無論何種情況,模組和包都可以導入(import)一個init python語句塊(block)中:

init python:
    import requests

Warning

在.rpy文件裡定義的Python語句會格式轉換,使其允許回滾。從.py文件導入(import)的文件則不會發生這種格式轉換。因此,在Python中創建的對象無法使用回滾(rollback)操作,且在創建之後就最好不要更改。