ATL のfunctionステートメントでプロパティーの値をオフセットするには

Ren’Py の ATL ブロックでは function ステートメントに任意の関数を指定して、関数からプロパティーの値を変更できます。これでATLだけでは難しい動作ができるのですが、それではプロパティーの値をオフセットさせる動作はどうすればよいかを考えます。位置に関しては x, yoffsetに値を代入するだけです。ここでは他のプロパティーにも利用できる汎用的な方法を扱います。

 まず次のように任意のプロパティーの値を関数から所得します。tran.xposで値を所得できるのは、そのATLブロック内で function ステートメントより前に xpos の値を指定したときのみです。この例ではxposを指定していないため、値を所得できません。そのような場合、inherited_<proparty名>から継承元のプロパティーの値を所得できます。

init python:
    def generate_func(proparty):
        def test_func(tran, st, at):
            current_value = getattr(tran, proparty)
            if current_value is None:
                current_value = getattr(tran, "inherited_"+proparty)
            return 0

label test:
    show test

    "AAA"

    show bg:
        function generate_func("xpos")

 次にその場でxposに正弦振動させてみましょう。関数を以下に変更します。

init python:
    def generate_func(proparty):
        from math import sin, pi
        def test_func(tran, st, at):
            current_value = getattr(tran, proparty, None)
            if current_value is None:
                current_value = getattr(tran, "inherited_"+proparty)
            setattr(tran, proparty, current_value + sin(st))
            return 0

 これでその場で正弦振動するかというと、そんなことにはなりません。というのもこの関数は呼び出されたときのプロパティーの値にその時間のsin(st)の値を足しているのですが、呼び出されたときのプロパティーの値はfunctionがなかったときの値ではなく、functionで変更した後の値になるため、変更が積み重なって期待した動作にならないのです。

これに対処するためには、関数呼び出し時の値が関数の処理に影響されないようにしなければなりません。さらに次のようにすると良さそうです。

    show bg:
        parallel:
            xpos 0.5
            0
            repeat
        parallel:
            function generate_func("xpos")

 このようにすると関数の実行前にxposの値が常に0.5になるのでその場で正弦振動できます。他にも以下のようにしても同じ事です。

    show bg:
        parallel:
            xpos 0.5
            linear 1 xpos 0.50001 #同じ値では動作しない
            repeat
        parallel:
            function generate_func("xpos")
    show bg:
        parallel:
            xpos 0.5
            linear 1. xpos 0.5 knot 0.5 #knotがあれば同じ値でも動作する
            repeat
        parallel:
            function generate_func("xpos")

x座標を移動しながら振動するには以下のようにします。

        parallel:
            xpos 0.5
            linear 1. xpos 0.7
            block:
                xpos 0.7
                0
                repeat
        parallel:
            function generate_func("xpos")

あまり美しい書き方は思いつきませんでした。ほとんどの用途ではx, yoffsetしか触らないでしょうから素直にoffsetに値を代入しましょう。

Pocket

コメントを残す

メールアドレスが公開されることはありません。