렌파이에서는 화면 상에서 마우스로 움직일 수 있는 드래그 & 드롭 디스플레이어블을 사용할 수 있습니다. 드래그는 다음과 같이 사용할 수 있습니다:
위에 열거한 것 외에도 드래그 & 드롭 디스플레이어블을 이용하면 다양한 기능을 만들 수 있습니다. 드래그 & 드롭과 관련된 클래스에는 두 가지가 있습니다. Drag 클래스는 드래그할 수 있는 디스플레이어블, 드래그할 수 있는 디스플레이어블을 드롭할 수 있는 디스플레이어블, 혹은 둘 다 할 수 있는 디스플레이어블을 나타냅니다. DragGroup 클래스는 드래그의 그룹을 나타냅니다 - 드래그 & 드롭이 발생하도록 하려면 두 드래그는 모두 같은 드래그그룹의 일부이어야 합니다.
드래그 & 드롭 시스템은 스크린 언어 에서 사용할 수도 있고 직접 디스플레이어블로 사용할 수도 있습니다. 드래그가 움직일 수 있는 대사창을 나타내는 경우처럼 생성된 드래그를 참조할 일이 없을 때에는 스크린 언어에서 사용하는 편이 좋습니다. 생성된 드래그를 참조해야 한다면 드래그를 직접 생성해 드래그그룹에 추가하는 것이 좋습니다.
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)¶드래그할 수 있는 영역을 가진 객체를 나타내는 디스플레이어블. Drag의 객체는 다른 드래그들이 드롭될 수 있는 영역을 나타낼 수도 있다.
드래그는 상위 디스플레이어블의 영역 안에서만 이동할 수 있다. 보통
드래그의 상위 디스플레이어블은 Fixed()
이거나 DragGroup
이어야 한다.
드래그는 하나의 하위 디스플레이어블을 받는다. 드래그 & 드롭의 상태에 따라 해당 하위 디스플레이어블의 상태를 바꿀 수도 있다:
selected_hover
- 드래그 중일 때.selected_idle
- 드래그를 얹을 수 있을 때.hover
- 사용자가 드래그를 클릭해서 드래그할 수있을 때.
idle
- 기타.
드래그 핸들은 하위 디스플레이어블 안에 있는 사각 영역이다. 드래그를 드래그하거나 클릭하려면 드래그 핸들 내부에 있는 픽셀 중에서 투명하지 않은 픽셀을 클릭해야 한다.
새로 생성된 드래거블은 기본 드래그그룹에 추가된다. 드래거블은 하나의 드래그그룹에만 속할 수 있다. 다른 드래그그룹에 드래그가 또 추가된다면, 드래그는 처음 속했던 드래그그룹에서는 제외된다.
드래그가 처음 렌더링되었을 때 속해 있는 드래그그룹에서 그 위치가 지정되지 않은 경우에는 기본 레이아웃 알고리즘을 사용하여 드래그의 왼쪽 위 모서리의 위치를 계산한다. 그 포지션이 한번
드래그 위에 무언가가 드롭될 때 호출되는 콜백 혹은 콜백의 리스트. 이 콜백은 두 개의 인수와 함께 호출된다. 첫 번째 인수는 어딘가에 드롭되는 드래그. 두 번째 인수는 드래그될 드래그의 목록. 콜백이 None 이 아닌 값을 반환한다면 None이 아닌 그 값이 인터렉션의 결과값으로써 반환된다.
dragged 와 dropped 콜백이 같은 이벤트에서 실행될 때 dragged 가 None을 반환하면 dropped 콜백만 호출된다.
d 를 제외한 모든 매개변수는 Drag 객체의 필드로 사용할 수 있다. 드래그가 렌더링된 후에는 아래의 필드를 설정할 수 있다:
set_child
(d)¶이 드래그의 하위 디스플레이어블을 d 로 변경한다.
snap
(x, y, delay=0)¶드래그의 위치를 변경한다. 드래그가 표시되지 않았다면, 위치를 변경할 때 시간이 걸리지 않는다. 그 외의 경우, 위치 변경은 delay 초 대기하며, 선형 이동처럼 움직인다.
top
(self)¶이 디스플레이어블이 속한 drag_group의 맨 위로 그 디스플레이어블을 올린다.
DragGroup
(*children, **properties)¶드래그의 그룹을 나타낸다. 드래그그룹은 해당 드래그그룹에 속한 드래그의 범위를 제한한다. 드롭은 오직 같은 드래그그룹 내에 있는 드래그 사이에서에만 작동된다. 드래그는 드래그그룹 내부에 있을 때만 발생한다.
드래그그룹은 Fixed()
처럼 배치된다.
드래그그룹의 생성자에 할당할 모든 위치 매개변수는 해당 드래그그룹에 추가될 드래그이어야 한다.
add
(child)¶해당 드래그그룹에 child 를 추가한다. child 는 반드시 드래그이어야 한다.
get_child_by_name
(name)¶drag_name을 가지는 드래그그룹의 첫 번째 하위 드래그를 반환한다.
remove
(child)¶이 드래그그룹에서 child 를 제거한다.
다음은 사용자가 게임 화면에서 대사창을 드래그해 그 대사창의 위치를 정하도록 하는 예제 스크립트입니다:
screen say:
drag:
drag_name "say"
yalign 1.0
drag_handle (0, 0, 1.0, 30)
xalign 0.5
window id "window":
# 대사창은 게임 화면보다 작아야한다.
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:
# 바탕그림용 지도
add "europe.jpg"
# 서로에게 드래그될 수 있는 탐정들과 도시를 포함시키는
# 드래그 그룹.
draggroup:
# 탐정들
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
# 탐정들이 갈 수 있는 도시
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:
"조사를 해봐야겠어! 누구를 어디로 보내야 할까?"
call screen send_detective_screen
"좋아, [detective] 는 [city]로 보내야겠군."
좀 더 복잡한 시스템은 제대로 사용하려면 상당한 프로그래밍 능력이 필요합니다. 렌파이 카드게임 프레임워크 는 드래그 & 드롭을 복잡한 시스템에서 사용하는 방법과, 카드 게임에 드래그 & 드롭을 유용하게 사용하는 방법을 모두 보여주는 예제입니다.