Ren'Py memo

Ren'Pyの個人的なメモ

フローチャートプラグインの紹介と簡単な説明

devilspider.itch.io

フローチャートプラグイン

・ライセンス:質問してみたところ"The license - if any - would simply state “feel free to use it in and modify for your game, just credit me”(もしライセンスがあるとすれば、簡単に言うと"あなたのゲームに使ったり改造したりするのはご自由に、ただ私のクレジットを入れてください "というものです)"とのこと

  • 通過した場所のボタンをセレクト→ジャンプが可能
  • 変数(現在地より前の質問の答えなど)を変更できる機能あり
  • 6~7つほど画像を用意する必要あり
  • 隠しチャートを後から表示させる機能あり
  • クレジットに制作者(Devil Spiδεr)の方の名前を載せることを推奨
  • 1つのセーブファイルからエンディングを参照する設計であるため、エンディング後タイトルに戻るなどの設計で使用することは非推奨

最初からスタンドアロン版を入れるより前に、デモ版のscript.rpyを合わせてflowchart.rpyを読んだほうが理解が深まると思います。

続きから

を載せます。


内容コメントの機械翻訳

・Original Comments by Devil Spiδεr
・この文章はDeepLで日本語に翻訳されました。

DEVIL SPIδεR'S FLOWCHART PLUGIN

# このプラグインは、多くのルートを持つビジュアルノベルによく見られるフローチャートの機能を実装したものです。
# ストーリーの異なるセグメントを表すフローチャートのボタンを "ノード "と

現在サポートされている機能

# - 拡張フローチャート - フローチャートは、より多くの進捗がアンロックされる ことによって大きくなる。
# - ノードへの条件付きアクセス - 既に訪問したノードを、独自の条件下でフローチャートからアクセスできなくする。
# - 画面上でのフラグ調整 - プレイヤーにフローチャートの画面内でストーリーの変数を変更させたい場合。

パラメーター

# パラメータの書式を列挙する場面は数多くある。もし引数が引用符で囲まれた書式("this "のような)の場合、引数も引用符で囲む。

画像

# game/flowchart/imageに少なくとも7つの画像があるはずです。
# crosshair.png以外の画像は全て同じサイズでなければなりません.

# ground.png
フローチャートのベースとなる「フレーム」。プレイヤーがフローチャートを見ることができるようになるとすぐに表示される。

# idle.png、hover.png、selected_idle.png、select_hover.png、insensitive.png
すべてのフローチャートのノードがとりうるさまざまな状態。

# crosshair.png
1つのノードのサイズである必要があります。(解像度はgui.flow_hotspot_sizeを参照)。

# オプションとして、拡張フローチャートが必要な場合に追加できる画像(イメージマップと同じサイズである必要があります)を提供することができます。
(extra_lines dictを参照)


このプラグインは、ゲームが1つのファイルで完結することを前提としています。もしトゥルーエンディング以外はプレイヤーをタイトル画面に投げ出すゲーム設計ならば、このフローチャートは意図したようには動作しません。

スタンドアロンアーカイブをダウンロードした場合、すべてのパラメータはデモの例と一致しており、ゲームに合わせて変更する必要があります。

ストーリー変数

# これらはゲーム内の進行状況を追跡するために使用されます。

default segment = ""
# 現在のセグメントを記録する

default segments =
# セーブファイル内で訪れたセグメントを記録する

default endings =
# セーブファイル内の完了したエンディングを記録する

default story_flags = {}
# ストーリー中の特別なフラグ(例えば、ストーリーに遅れて影響を与える選択肢)を追跡します。これはpythonのdictです。

default flowchart_accessible = False
# フローチャートを無効にしなければならない瞬間がある場合。


def new_node

#これはラベルの先頭に付けることを推奨する。これにより、古いラベルの名前が訪問先リストに追加され、現在のセグメント名が設定されます。
#スクリプト内でノードごとにラベルが複数ある場合は、最初のラベルにのみこれを記述してください。

def unlock_ending

これは、完成したエンディング(通常はそのラベルにちなんだ名前)をエンディングリストに追加する関数です。len(endings)を呼び出すことで、エンディングの数を追跡することができます。

def unrock_node

フローチャートからエンディングにアクセスできるようにするには、unlock_endingと一緒に使用する。

STORY NODES

# ゲーム内の全ノードの情報を記入します。

# フォーマットは "ラベル": (x座標, y座標), "name", "description", "condition"]

# 座標はイメージマップのボタンを正しくレンダリングするためのもので、イメージボタンのホットスポットの左上隅を示します。

# conditionはPython式かTrueを含む文字列で、式がfalseと評価された場合、そのノードはメニューから選択できません。

nodes = {(省略)

# ノードの X と Y のサイズ - ホットスポットのサイズが異なる場合は、これを変更してください。
gui.flow_hotspot_size = (100, 100)

画面上のフラグ調整

# ストーリーの中で、プレイヤーにフローチャートの中で直接変更させたい決定がある場合がある。このdictはそのような選択肢をフローチャートに表示させることができます。

# このdictの書式は以下の通り
"label_name": [選択肢の文字列", [("選択肢のテキスト", "選択肢のアクション")...]]、

# 選択肢の文字列はボタンの前に表示され、選択肢のテキストで適切な量のボタンを作成し、選択アクションを実行します。

flow_choices = {
"apples": ["What kind of apples do you like?", [("Red", "SetDict(story_flags, 'apple_kind', 'red')"),("Green", "SetDict(story_flags, 'apple_kind', 'green')")]],
}

フローチャートの拡張

# 特定の条件下で表示されるフローチャートを複数の部分に分割することができます. (隠しルート, ネタバレ防止など)。

# これらのフォーマットは以下の通りです:
# "image name": "Python expression",
# 画像名はgame/flowchart/imageにある画像ファイル名です.

extra_lines = {
"hidden_1": "'secret1' in segments",
}

ユーザーに表示される実際の画面

screen flowchart():

xysize (1025, 625) # これをフローチャートの画像サイズ+各軸の25に変更する。
child_size (1000, 600) # これをあなたのフローチャートの画像サイズに変更する。

(省略)

必要画像のサンプル


自分のゲームのために改造したコード


  • Original Code by Devil Spiδεr
  • 1つのセーブファイルを参照するのではなく、ゲーム全体で使用できる永続変数を使いたかったため内容をシンプルめの内容に削減、変更しました。推奨されていない目的のため改造をしているためだいぶ改悪ではあります。
  • (ラベルに飛ぶ前に区分用の変数を1個nodesから参照して変更していますが)このコード単体での処理ではなく、ジャンプ後のラベルで必要な背景変更や各変数を処理しています。

足した:永続変数の参照、現在地表示
削った:いくつかの関数・変数、フラグ調整機能、チャート拡張機能、condition機能

# Original Code by Devil Spiδεr
# https://devilspider.itch.io/flowchart-plug-in

init -3:
    default segment = "start"
    default persistent.segments = ["start"]

init python:

    def new_node(n):
        global segment
        segment = n
        if segment not in persistent.segments:
            persistent.segments.append(segment)

    nodes = {

        "start": [(0, 0), _("オープニング"),0],
        "erabi": [(0, 120), _("分岐1番目"),0],
        "sue0": [(128, 0), _("スーくん序盤"),1],
        "sane0": [(128, 120), _("サネちゃん序盤"),2],
        "mutsu0": [(128, 240), _("ムツ序盤"),3],
        "syudan1": [(262, 0), _("スーくん分岐"),1],
        "syudan2": [(262, 120), _("サネちゃん分岐"),2],
        "syudan3": [(262, 240), _("ムツ分岐"),3],
        "sue_end1": [(391, 0), _("スーくんEND1"),1],
        "sane_end1": [(391, 120), _("サネちゃんEND3"),2],
        "mutsu_end1": [(391, 240), _("ムツEND5"),3],
        "sue_end2": [(522, 0), _("スーくんEND2"),1],
        "sane_end2": [(522, 120), _("サネちゃんEND4"),2],
        "mutsu_end2": [(522, 240), _("ムツEND6"),3],
        "end1": [(649, 0), _("スーくんEND1後"),1],
        "end3": [(649, 120), _("サネちゃんEND3後"),2],
        "end5": [(649, 240), _("ムツEND5後"),3],
        "end2": [(779, 0), _("スーくんEND2後"),1],
        "end4": [(779, 120), _("サネちゃんEND4後"),2],
        "end6": [(779, 240), _("ムツEND5後"),3],

    }

    gui.flow_hotspot_size = (76, 76)

screen flowchart():

    tag menu

    default select_node = None

    use game_menu(_("Flowchart"), scroll="viewport"):
        vbox:
            style_prefix "flowchart"
            viewport:
                xpos 130
                ypos 30
                xysize (856, 337)
                child_size (856, 337)
                imagemap:
                    auto "images/chart/%s.png"
                    for i in persistent.segments:
                        hotspot nodes[i][0] + gui.flow_hotspot_size:
                            action SetScreenVariable("select_node", i)
                imagebutton:
                    idle "images/chart/crosshair.png"
                    xpos nodes[segment][0][0]
                    ypos nodes[segment][0][1]
                    action SetScreenVariable("select_node", None)

            if select_node:
                vbox:
                    xpos 340
                    ypos 45
                    text nodes[select_node][1]
                    text "▶▶" font "DejaVuSans.ttf" xpos 60 ypos 5
                hbox:
                    xpos 600
                    ypos -10
                    textbutton "Jump!" action [SetVariable("whois", nodes[select_node][2]), SetVariable("segment", select_node), Start(select_node)] xalign 0.5
            else:
                vbox:
                    xpos 440
                    ypos 65
                    text _("現在地:")+nodes[segment][1] xalign 0.5

style flowchart_text is gui_text
style flowchart_button is button
style flowchart_button_text is button_text

style flowchart_button:
    idle_background "color1"
    hover_background "color2"
    xsize 200
    ysize 55
    activate_sound gsound1

style flowchart_button_text:
    size 30
    bold True
    xalign 0.5
    yalign 0.5
    color gcolor1
    hover_color gcolor2
    insensitive_color gcolor4
    outlines [ (absolute(1), gcolor4, absolute(0), absolute(0)) ]