ドラッグ&ドロップ link
Ren'Py にはマウスで画面上を移動できるドラッグドロップ displayable があります。ドラッグの使用法としては次があります :
ウィンドウの位置合わせ、ウィンドウ位置を記憶できるようにする。
カードを画面上でドラッグする必要のあるカードゲーム ( 例えばソリティア )。
アイテムシステム。
ドラッグで並び順を変えるシステム。
ドラッグドロップ displayable は、上記やその他の場面においてドラッグドロップを実装できるようにします。ここに関係する2つのクラスがあります。 Drag クラスは、スクリーン上をドラッグできるもの、またはその上にドロップされたドラッグ可能なものを受け取れるもの、その両方が出来るもののいずれかを表します。 DragGroup クラスは Drag のグループを表します。ドラッグドロップを実行するためには、両方の Drag が同じドラッググループに属していなければなりません。
ドラッグドロップシステムは スクリーン言語 を通してか、または直接 displayable として使用できます。作成後に作成した Drag を参照する必要がないときは、スクリーン言語を使用すると良いでしょう。これはドラッグ可能オブジェクトが、ユーザーがスクリーン上に配置したウィンドウである場合などです。作成後も作成した Drag を参照する必要がある場合は、直接 Drag を作成し、それらを DragGroup に追加すると良いでしょう。
ドロップ link
Ren'Py にはドロップを実施する 2 つの方法があります。
mouse_drop が True なら、 drag はマウスカーソルの直下にあるドロップ可能なものにドロップします。
mouse_drop はデフォルトで False であり、そうならドロップはその drag ともっとも重なっているドロップ可能なものに行われます。
focus_mask が使用されるドラッグの開始時とは異なり、ドロップでは、透明ピクセルを含む、 ドラッグ可能なものとドロップ可能なものの矩形領域全体が考慮されます。drap と drop displayable はこれを考慮して一般的に矩形にして設計する必要があるでしょう。
Displayable link
- class Drag(d=None, drag_name=None, draggable=True, droppable=True, drag_raise=True, dragging=None, dragged=None, dropped=None, drag_handle=(0.0, 0.0, 1.0, 1.0), drag_joined=..., clicked=None, hovered=None, unhovered=None, mouse_drop=False, **properties) link
それを囲んでいる領域上でドラッグ可能なオブジェクトを表わす displayable です。 Drag は他の Drag がドロップ可能な領域も表現できます。
その内側で Drag が移動可能なものを親と呼びます。一般的には親は
Fixed()
かDragGroup
であるはずです。Drag は子を一つ持ちます。子の状態はドラッグドロップ処理の状態を反映します。 :
selected_hover
ドラッグされている時。selected_idle
その上にドロップ可能な時。hover
- マウスをクリックすればドラッグ可能オブジェクトをドラッグできる時。idle
それ以外。
ドラッグで持てる部分はその子の内側の長方形です。ドラッグやクリックを実行するためにはマウスが Drag のその部分のピクセル上になければなりません。
focus_mask
プロパティーが True なら、さらにそのピクセルが不透明でなければなりません。新しく作成されたドラッグ可能なオブジェクトはデフォルトの DragGroup に追加されます。 ドラッグ可能オブジェクトは 一つの DragGroup にのみ所属できます。二つ目のグループに追加すると、最初のものからは削除されます。
Drag が最初にレンダリングされる時に、それが所属する DragGroup からその座標を決定できない場合その左上の座標が基本的なレイアウトアルゴリズムを使用して算出されます。いったん座標が算出されると、その Drag に保存された座標を優先し、レイアウトプロパティーは無視されます。
- 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 も持ち上げられます。
- activated
Drag 上でマウスが押されたとき呼び出されるコールバック ( またはコールバックのリスト ) です。ドラッグされている Drag のリストを引数に呼び出されます。このコールバックの返り値は無視されます。
- dragging
Drag がドラッグ中に呼び出されるコールバック ( またはコールバックのリスト ) です。それは1つの引数で呼び出され、ドラッグされている Drag のリストです。コールバックが None 以外の値を返すと、その値はインタラクションの結果として返されます。
- dragged
Drag がドラッグされた時に呼び出されるコールバック ( またはコールバックのリスト ) です。それは二つの引数で呼び出されます。一つ目はドラッグされている Drag のリストです。二つ目はその上にドロップされている Drag か、ドロップが起きていないなら None です。コールバックが None ではなく値を返すとその値はインタラクションの結果として返されます。
- dropped
Drag がドロップされた時に呼び出されるコールバック ( またはコールバックのリスト ) です。それは二つの引数で呼び出されます。一つ目はその上にドロップされている Drag 二つ目はドラッグされている Drag のリストです。コールバックが None 以外の値を返すと、その値はインタラクションの結果として返されます。
dragged と dropped のコールバックが同じイベントで起こされると、 dropped コールバックは dragged が None を返したときのみ呼び出されます。
- clicked
Drag が移動なしでクリックされたときに、クリックされた Drag を引数に呼び出されるコールバックです。ドロップ可能オブジェクトもフォーカスを持て、クリックすることも可能です。 コールバックが None ではなく値を返したら、その値がインタラクションの結果として返されます。
- alternate
Drag が(デスクトップの場合)右クリックされるか動かさないで長押し(モバイル)すると実行されるアクションです。このトリガーがモバイルプラットフォームで早すぎる場合は
config.longpress_duration
を大きくする必要があります。- hovered
Drag がフォーカスを所得すると実行するアクションです。
- unhovered
Drag がフォーカスを失うと実行するアクションです。
- tooltip
Drag がホバー状態で表示される tooltip です。
- drag_handle
子内部のドラッグ有効範囲の位置を与える (x, y, width, height) のタプルです。このタプルには、 positions を含めます。
- drag_joined
これは現在の Drag を引数として呼び出されます。ひとかたまりでドラッグしているドラッグ可能オブジェクトのタプル [ (drag, x, y) ] を返すことが期待されます。 x, y は Drag の互いに対するオフセットで、この drag に対するものではありません。 drag は組み合わされる Drag オブジェクトかそのような Drag の drag_name です。
- drag_offscreen
drag が画面外へ動かせるかの条件を判定します。 drag_joined やサイズを変更出来る drag に使用すると、その drag が完全に画面外に出て画面に戻す方法がなくなる可能性があるため危険になり得ます。
これは次のうちどれか1つであるべきです。 :
- False
画面外への drag の移動を禁止します(デフォルト)。
- True
どの方向にも画面外へのドラッグを許可します。
- "horizontal"
水平方向のみ画面外へのドラッグを許可します。
- "vertical"
垂直方向のみ画面外へのドラッグを許可します。
- (width, height)
width とheight は共に整数でなければなりません。 (width, height) のサイズ分が画面内にある限り、画面外へドラッグできます。例えば (100, 100) ならば、その displayable の他の部分が画面外にあっても、少なくとも 100x100 ピクセルの領域が画面内に残っていると保証します。これをドラッグされている displayable の幅と高さに設定すると、全く画面外へのドラッグを許可しないのと同じになります。
- (min_x, max_x, min_y, max_y)
min_x, max_x, min_y, max_y はそれぞれ整数であり、 min_x が左端からのピクセル数、 max_x が右端からのピクセル数です。 min_y と max_y の上端と下端との関係も同じです。ドラッグはその端が指定した端にぶつかるまで動かせます。 (0, 0, 0, 0) は全く画面外へのドラッグを許可しないのと同じになります。
例えば (-100, 200, 0, 0) ならば drag は 100 ピクセル画面の端から左へドラッグでき、 200 ピクセル画面の端から右へドラッグできます。上下の画面外へのドラッグは許可しません。
これを使用して、 drag を画面内の境界に制限できます。 (200, -200, 200, -200) なら画面の端から 200 ピクセル内でのみドラッグを許可します。
これは drag の周りの追加の "境界" を想像しください。これは画面外に境界を置き、その中に drag を制限します。
- callable
drag_offscreen には呼び出し可能オブジェクトも渡せます。引数は二つ必要となり、その drag のドラッグされた左上の座標を表す x と y 座標です。 drag の新しい (x, y) 座標となる (x, y) タプルを返さなければいけません。この呼び出し可能オブジェクトは drag の移動中頻繁に呼び出されます。例えば次の関数は drag を 300 ピクセル区切りにスナップします。
def drag_snap(x, y): if y < 300: y = 0 elif y < 600: y = 300 else: y = 600 return 200, y
- mouse_drop
True なら、 drag はカーソル下の最初のドロップ可能な物にドロップされます。デフォルトでは False で drag は重なりがもっとも大きい ドロップ可能なものにドロップされます。
- drop_allowable
現在ドラッグしているもののこれへのドロップを許可するか決定するコールバックです。二つの引数で呼び出され、一つ目はドロップを受け取る Drag, 二つ目はドラッグされている Drag のリストです。
- snapped
ドラッグがスナップを完了すると呼び出されるコールバック(またはコールバックのリスト)です。4つの引数で呼び出されます。1つ目はスナップアニメーションが処理された Drag です。2つ目と3つ目は Drag がスナップするよう設定された x と y 座標です。4つ目は真偽値で、 True ならスナップアニメーションは成功し、 False なら中断しました。例えば次の関数はスナップアニメーションが中断されると、その Drag の start_x と start_y 位置を意図したスナップ位置に設定します。
def snapped_callback(drag, x, y, completed): if not completed: drag.start_x = x drag.start_y = y
d を除いてパラメーターのすべてはその Drag オブジェクトでフィールドとして ( 同じ名前で ) 利用可能です。さらに Drag がレンダリングされた後は次のフィールドが利用可能になります。
- x, y
ピクセルでのその親に対する Drag の位置
- start_x, start_y
ピクセルでのその親に対するドラッグ開始時の Drag の位置
- grab_x, grab_y
ピクセルでのその Drag に対する捕まれた x, y 位置です。
- last_drop
離せば現在の Drag をドロップできる最後尾の Drag であり、妥当な Drag が現在なければ None になります。
- snapping
この Drag がスナップアニメーションの途中なら True になります。
- w, h
Drag の子のピクセルでの幅と高さです。
- bottom() link
この displayable をその DragGroup の最下端にします。
- set_child(d) link
この Drag の子を d に変更します。
- snap(x, y, delay=0, warper=None) link
Drag の位置を変更します。 Drag が表示されていないと位置の変更は瞬間です。そうでなければ、位置の変更は delay 秒かけて任意のワーパーで行われ、ワーパーが指定されていなければ等速で移動します。
- top() link
この displayable をその DragGroup のトップに持ち上げます。
- class DragGroup(*children, **properties) link
Drag のグループを表します。ドラッグはその DragGroup 内部に制限されます。ドロップは同じ DragGroup に所属する Drag 間でのみ働きます。 Drag はそれが DragGroup の内側にあるときのみ持ち上げられます。
Fixed()
と同様に DragGroup はレイアウトされます。DragGroup のコンストラクターに渡されるすべての位置パラメーターはその DragGroup に追加される Drag であるべきです。
- min_overlap
ドロップが受け入れられる最小のオーバーラップするピクセル数を表す整数です。
- add(child) link
ドラッグされなければならない child をこの DragGroup に追加します。 child はこの DragGroup の他の全ての子の上に追加されます。
- get_child_by_name(name) link
name の drag_name を持つ DragGroup の最初の子を返します。
- remove(child) link
DragGroup から child を除去します。
例 link
以下の say スクリーンの例では、スクリーン上をドラッグしてユーザーがウィンドウの位置を選べます。
screen say(who, what):
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"
droppable False
dragged detective_dragged
xpos 100 ypos 100
add "ivy.png"
drag:
drag_name "Zack"
droppable False
dragged detective_dragged
xpos 150 ypos 100
add "zack.png"
# The cities they can go to.
drag:
drag_name "London"
draggable False
xpos 450 ypos 140
add "london.png"
drag:
drag_name "Paris"
draggable False
xpos 500 ypos 280
add "paris.png"
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]."
より複雑なシステムを正しく構築するためには、かなりのプログラミング技術が必要です。
as
節を使用して drag と変数を結び付け、その Drag のメソッドを呼び出すのに使用出来るようにします。
screen snap():
drag:
as carmen
draggable True
xpos 100 ypos 100
frame:
style "empty"
background "carmen.png"
xysize (100, 100)
vbox:
textbutton "London" action Function(carmen.snap, 450, 140, 1.0)
textbutton "Paris" action Function(carmen.snap, 500, 280, 1.0)