Ren’Py改造メモ(2)

Ren’Pyでマウスを自動移動する

最近のいたれりつくせりのシステムに慣れてしまって筆者はもうマウスに自動移動してくれないと我慢できなくなりました。

Yes/NoダイアログがひらいたらYesボタンにマウスが自動移動してくれないとだめなんです。
選択肢が出たら一番目の選択肢に自動移動してくれないとだめなんです。
セーブ画面を開いたら、空きスロットに自動移動してくれないとだめなんです。
ロード画面を開いたら、最新のセーブに自動移動してくれないとだめなんです。

それをRen’Pyで実行しようとしましたが、マニュアルを読む限りRen’Py自体にはマウスを移動させる機能がないっぽい。
なのでRen’Pyのもとになっているpygameを使用したプラグインを作ってみました。
(筆者がプラグインと呼んでいるだけで、実際はライブラリの方が正確だと思いますが、この方がわかりやすいと思うので)
まずはここからautomouse.zipをダウンロードしてください。
v6.17で本家に同等の機能をマージしてもらいました。なのでもうプラグインをダウンロードする必要はありません。ただし、MouseJump アクションは廃止されていますので、かわりにMouseMove(x,y,0)を使用してください。

あとは自動移動したい場所(主にscreens.rpy)でActionを実行してください。
MouseMove(x,y,time_ms)でx,y座標にtime_ms秒かけて自動移動します。
MouseJump(x,y)でx,y座標に瞬間移動します。
ただしここでのx,yは画面左上からのピクセルでの相対位置です。
割合とかでは指定できません。
また、自動移動は嫌という人のために変数persistent.automouseが偽の時、これらのActionはなにもしないようにしてあるので、設定項目で変数の真偽を変更出来るようにしてください。

たとえばすべてのYes/Noダイアログでマウスを(300,160)の座標に100秒かけて移動するなら、screens.rpyの471行目辺りに以下のように追加します。


##############################################################################
# Yes/No Prompt
#
# Screen that asks the user a yes or no question.
# http://www.renpy.org/doc/html/screen_special.html#yesno-prompt

screen yesno_prompt:

    #追加部分↓
    on "show" action MouseMove(300, 160, 100)
    #追加部分↑
    modal True

on “show” action でこのスクリーンが表示されると常に指定したActionを実行するようになります。

これでたいていの場合問題ないと思うのですが、ダイアル内が二行以上になってたりするとずれてしまいます。そういう場合は個別に座標を指定します。

例えばタイトル画面で終了を選択したときにマウスを自動移動するにはscreens.rpyの197行目を以下のように編集します。
Before


        textbutton _("Quit") action Quit(confirm=False)

After


        textbutton _("Quit") action [MouseMove(300, 160, 100), Quit(confirm=False)]

Actionを複数同時に実行したいときはこのようにリストにします。

また、右上の閉じるボタンを押した時はラベルconfirm_quitがある場合はそこにジャンプしますので、適当な場所に以下のコードを記述します。(v6.16からはconfirm_quitは使用出来ません。一つ目の方法を使用してください。)


label confirm_quit:
    $ automouse_move(300, 160, 100)
    $ renpy.loadsave.force_autosave()

    if layout.yesno_prompt(None, layout.QUIT):
        jump _quit
    else:
        return

 

ただこの方法だと処理毎にコードを書かなければならないので、最初の方法をお勧めします。

次に、選択肢で自動移動するようにします。
screens.rpyで71行目のscreen choiceを書き換えてください。


# Choice
#
# Screen that's used to display in-game menus.
# http://www.renpy.org/doc/html/screen_special.html#choice

screen choice:

    # 追加部分↓
    on "replace" action MouseMove(400, 300, 100)
    # 追加部分↑

これで選択肢が表示されると、自動移動するようになります。
但し、NVLモードのメニューを使用している場合はどこに選択肢が表示されるか分からないので、移動出来ません。

次に最新のセーブスロットにマウスを移動しましょう。
これはちょっと面倒です。
先ず最後にセーブされたデータのページとそのページ内での番号が次の変数に以下の形式で記録されています。
persistent._file_newest=”1-3″   (1ページ目の三番目)
よって次のようにするとページと番号を分けられます。
page = persistent._file_newest.split(“-“)[0]
name = persistent._file_newest.split(“-“)[1]
ここから座標を計算する式を作りましょう。

v6.16ではpersistent._file_newestが削除されました。代わりにrenpy.newest_slot(r’\d+’)を使用します。persistent._file_newestと同じ形式の文字列を返します。

v6.16以前ではこうします。

    def calculate_x():
        # ページが違ったりセーブがなかったときは現在地へ移動
        if not persistent._file_newest or persistent._file_newest.split("-")[0] != persistent._file_page:
            return automouse_get_pos()[0]
        name = int(persistent._file_newest.split("-")[1])
        if name > 5:
            x = 500
        else:
            x = 100
        return x

    def calculate_y():
        # ページが違ったりセーブがなかったときは現在地へ移動
        if not persistent._file_newest or persistent._file_newest.split("-")[0] != persistent._file_page:
            return automouse_get_pos()[1]
        name = int(persistent._file_newest.split("-")[1])
        if name > 5:
            name = name - 5
        return 42 + (name - 1)*56

    on "show" action MouseMove(calculate_x(), calculate_y(), 100)

6.16だとこうなります。

    def calculate_x():
        # ページが違ったりセーブがなかったときは現在地へ移動
        if renpy.newest_slot(r'\d+') is None or renpy.newest_slot(r'\d+').split("-")[0] != persistent._file_page:
            return automouse_get_pos()[0]
        name = int(renpy.newest_slot(r'\d+').split("-")[1])
        if name > 5:
            x = 500
        else:
            x = 100
        return x

    def calculate_y():
        # ページが違ったりセーブがなかったときは現在地へ移動
        if renpy.newest_slot(r'\d+') is None or renpy.newest_slot(r'\d+').split("-")[0] != persistent._file_page:
            return automouse_get_pos()[1]
        name = int(renpy.newest_slot(r'\d+').split("-")[1])
        if name > 5:
            name = name - 5
        return 42 + (name - 1)*56

    on "show" action MouseMove(calculate_x(), calculate_y(), 100)

コメントを残す

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