ドラッグドロップ link

Ren'Py にはマウスで画面上を移動できるドラッグドロップ displayable があります。ドラッグの使用法としては :

  • ウィンドウの位置合わせ、ウィンドウ位置を記憶できるようにする。

  • カードを画面上でドラッグする必要のあるカードゲーム ( 例えばソリティア )。

  • アイテムシステム。

  • ドラッグで並び順を変えるシステム。

ドラッグドロップ displayable は、上記やその他の場面においてドラッグドロップを実装できるようにします。ここで関係する2つのクラスがあります。 Drag クラスは、スクリーン上をドラッグできるもの、またはその上にドロップされたドラッグ可能なものを受け取れるもの、その両方が出来るもののいずれかを表します。 DragGroup クラスは Drag のグループを表します。ドラッグドロップを実行するためには、両方の Drag が同じドラッググループに属していなければなりません。

ドラッグドロップシステムは スクリーン言語 を通してか、または直接 displayable として使用できます。作成後に作成した Drag を参照する必要がないときは、スクリーン言語を使用すると良いでしょう。これはドラッグ可能オブジェクトが、ユーザーがスクリーン上に配置したウィンドウである場合などです。作成後も作成した Drag を参照する必要がある場合は、直接 Drag を作成し、それらを DragGroup に追加すると良いでしょう。

Displayable link

class Drag(d=None, drag_name=None, draggable=True, droppable=True, drag_raise=True, dragged=None, dropped=None, drag_handle=(0.0, 0.0, 1.0, 1.0), drag_joined=..., clicked=None, hovered=None, unhovered=None, **properties) link

それを囲んでいる領域上でドラッグ可能なオブジェクトを表わす displayable です。 Drag は他の Drag がドロップ可能な領域も表現できます。

Drag がその内側で移動可能なものを親と呼びます。一般的には親は Fixed()DragGroup であるはずです。

Dorag は子を一つ持ちます。子の状態はドラッグドロップ処理の状態を反映します。 :

  • selected_hover ドラッグされている時。

  • selected_idle その上にドロップ可能な時。

  • hover - マウスがクリックされるとドラッグ可能オブジェクトがドラッグされる時。

  • idle それ以外。

ドラッグで持てるのはその子の内側の長方形です。ドラッグやクリックを実行するためにマウスは Drag の不透明なピクセル上になければなりません。

新しく作成されたドラッグ可能なオブジェクトはデフォルトの DragGroup に追加されます。 ドラッグ可能オブジェクトは 一つの DragGroup にのみ所属できます。二つ目のグループに追加すると、最初のものからは削除されます。

Drag が最初にレンダリングされる時に、それが所属する DragGroup からその座標を決定できない場合その左上の座標が基本的なレイアウトアルゴリズムを使用して算出されます。

d

与えられると、この Drag の子になります。 None でなければ Drag はこれに優先して child スタイルを使用します。

drag_name

None を指定するかこのドラッグ可能オブジェクトの名前を指定します。これはドラッグ可能オブジェクトの name プロパティーとして利用できます。もし同じ名前の Drag がその DragGroup に所属しているまたはしていたならこの Drag の最初の座標はそのドラッグ可能オブジェクトから受け取ります。

draggable

True の場合、Drag はスクリーン上をマウスでドラッグできます。

droppable

True なら他の Drag がこの Drag 上にドロップ可能です。

drag_raise

True ならこの Drag がドラッグされたときにトップまで持ち上げられます。他の Drag と接続されていたら、すべての接続された Drag も持ち上げられます。

dragged

Drag がドラッグされた時に呼び出されるコールバック ( またはコールバックのリスト ) です。それは二つの引数で呼び出されます。一つ目はドラッグされている Drag のリストです。二つ目はその上にドロップされている Drag か、ドロップが起きていないなら None です。コールバックが None ではなく値を返すとその値はインタラクションの結果として返されます。

dropped

Drag がドロップされた時に呼び出されるコールバック ( またはコールバックのリスト ) です。それは二つの引数で呼び出されます。一つ目はその上にドロップされている Drag 二つ目はドラッグされている Drag のリストです。コールバックが None 以外の値を返すと、その値はインタラクションの結果として返されます。

dragged と dropped のコールバックが同じイベントで起こされると、 dropped コールバックは dragged が None を返したときのみ呼び出されます。

clicked

Drag が移動せずにクリックされると、引数なしで呼び出されるコールバックです。ドロップ可能オブジェクトはフォーカスを持ち、クリックすることも可能です。 コールバックが None ではなく値を返したら、その値はインタラクションの結果として返されます。

drag_handle

子内部のドラッグ有効範囲の位置を与える (x, y, width, height) のタプルです。このタプルでは、整数はピクセルの定数になるように配慮され、一方少数は子のサイズに対する割合です。

drag_joined

これは現在の Drag を引数として呼び出されます。ひとかたまりでドラッグしているドラッグ可能オブジェクトのタプル [ (drag, x, y) ] を返すことが期待されます。 x, y は Drag の互いに対するオフセットで、この drag に対するものではありません。

drag_offscreen

True なら ドラッグ可能オブジェクトは画面外へ動かせます。これは drag_joined やサイズを変更出来る Drag に使用すると、Drag が完全に画面外に出て画面に戻す方法がなくなるため危険でしょう。

d を除いて引数のすべてはその Drag オブジェクトでフィールドとして ( 同じ名前で ) 利用可能です。さらに Drag がレンダリングされた後は次のフィールドが利用可能になります。

x, y

ピクセルでのその親に対する Drag の位置

w, h

Drag の子のピクセルでの幅と高さです。

set_child(d) link

この Drag の子を d に変更します。

snap(x, y, delay=0) link

Drag の位置を変更します。 Drag が表示されていないと位置の変更は瞬間です。そうでなければ、位置の変更は delay 秒かかり、等速で移動するアニメーションが表示されます。

top(self) link

この displayable をその DragGroup のトップに持ち上げます。

class DragGroup(*children, **properties) link

Drag のグループを表します。ドラッグはその DragGroup 内部に制限されます。ドロップは同じ DragGroup に所得する Drag 間でのみ働きます。 Drag はそれが DragGroup の内側にあるときのみ持ち上げられます。

Fixed() と同様に DragGroup はレイアウトされます。

DragGroup のコンストラクターに渡されるすべての位置引数はその DragGroup に追加される Drag であるべきです。

add(child) link

child をこの DragGroup に追加します。 child は Drag でなければいけません。

get_child_by_name(name) link

drag_name の名前を持つこの DragGroup の最初の子を返します。

remove(child) link

DragGroup から child を除去します。

link

以下の say スクリーンの例では、スクリーン上をドラッグしてユーザーがウィンドウの位置を選べます。

screen say:

    drag:
        drag_name "say"
        yalign 1.0
        drag_handle (0, 0, 1.0, 30)

        xalign 0.5

        window id "window":
            # Ensure that the window is smaller than the screen.
            xmaximum 600

            has vbox

            if who:
                text who id "who"

            text what id "what"

こちらはより複雑な例で、ゲームプレイに影響を与えるためにどのようにドラッグを使用できるかを表示します。これはどのようにキャラクターをある場所に送るためにドラッグが使用できるかを表示します。

init python:

    def detective_dragged(drags, drop):

        if not drop:
            return

        store.detective = drags[0].drag_name
        store.city = drop.drag_name

        return True

screen send_detective_screen:

    # A map as background.
    add "europe.jpg"

    # A drag group ensures that the detectives and the cities can be
    # dragged to each other.
    draggroup:

        # Our detectives.
        drag:
            drag_name "Ivy"
            child "ivy.png"
            droppable False
            dragged detective_dragged
            xpos 100 ypos 100
        drag:
            drag_name "Zack"
            child "zack.png"
            droppable False
            dragged detective_dragged
            xpos 150 ypos 100

        # The cities they can go to.
        drag:
            drag_name "London"
            child "london.png"
            draggable False
            xpos 450 ypos 140
        drag:
            drag_name "Paris"
            draggable False
            child "paris.png"
            xpos 500 ypos 280

label send_detective:
    "We need to investigate! Who should we send, and where should they go?"

    call screen send_detective_screen

    "Okay, we'll send [detective] to [city]."

さらに複雑なシステムを作るには、高度なプログラミングスキルが必要です。 Ren'Py cardgame framework は、複雑なゲームにおけるドラッグドロップの例を示すとともに、カードゲームの作成を容易にします。