Перетаcкивание (Drag and Drop)

Материал из Ren'Py Wiki
Перейти к навигации Перейти к поиску

Ren'Py включает перетаскивание отображаемых объектов, что позволяет перемещать объекты по экрану с помощью мыши. Ниже приведено несколько способов применения технологии перетаскивания:

  • Позволяет пользователю перемещать окна, сохраняя позиции окон.
  • Карточные игры, требующие перетаскивания карт по экрану (например, пасьянс).
  • Системы инвентаря.
  • Системы перегруппировки.


Перетаскивание отображаемых объектов позволяет реализовать вышеперечисленные и другие способы перетаскивания. Здесь участвуют два класса:

  • Класс Drag представляет собой либо что-то, что можно перетаскивать по экрану, либо то, на что можно перетащить объект, или что-то, что может выполнять оба действия.
  • Класс DragGroup представляет группу Drags - чтобы произошло перетаскивание, оба Drags должны быть частью одной группы перетаскивания.


Систему перетаскивания можно использовать либо через язык экрана, либо непосредственно как отображаемый объект. Имеет смысл использовать язык экрана в тех случаях, когда вам не нужно ссылаться на Drags, которые вы создаёте после их создания. Это может иметь место, если перетаскиваемый объект представляет собой окно, которое пользователь помещает на экран. Если вам необходимо обратиться к Drags после их создания, то часто проще напрямую создать Drags и добавить их в DragGroup.

Отображаемый объект (Displayables)[править | править код]

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, mouse_drop=False, **properties)
Отображаемый объект, представляющий объект, который можно перетаскивать с помощью мыши по его охватывающей области. Класс Drag также может представлять область, на которую можно перетаскивать другие Drags.
Drag можно перемещать внутри родительского элемента. Как правило, его родителем должен быть либо Fixed(), либо DragGroup.
Класс Drag имеет один дочерний элемент. Состояние дочернего элемента отражает состояние операции перетаскивания:
  • selected_hover - когда дочерний элемент перетаскивают.
  • selected_idle - когда элемент может быть сброшен в выбранной области.
  • hover - когда перетаскиваемый элемент будут перетаскивать, когда нажата кнопка мыши.
  • idle - в иных случаях.
"Ручка" перетаскивания – прямоугольник внутри дочернего элемента. Курсор мыши должен находиться над непрозрачным пикселем внутри "ручки" перетаскивания для перетаскивания или щелчка мышью.
Недавно созданный перетаскиваемый объект добавляется в DragGroup по умолчанию. Перетаскивать можно только в одном DragGroup - если объект добавляется во вторую группу, он удаляется из первой.
При первом отображении Drag, если его положение не может быть определено из DragGroup, в которой он находится, положение его верхнего левого угла вычисляется с помощью стандартного алгоритма компоновки.
d
Если присутствует, является дочерним элементом этого Drag. Drags использует дочерний стиль, отдавая ему предпочтение перед данным параметром, если значение этого параметра не None.
drag_name
Если принимает значение не None, имя этого перетаскивания. Это доступно как свойство name перетаскиваемых объектом. Если Drag с таким же именем есть или находился в DragGroup, начальная позиция этого Drag берётся из этого Draggable.
draggable
Если принимает значение True, Drag можно перемещать по экрану с помощью мыши.
droppable
Если принимает значение True, другие Drags могут быть сброшены в этом Drag.
drag_raise
Если принимает значение True, этот Drag выдвигается на первый план при перетаскивании. Если он присоединён к другим Drags, все присоединённые Drags поднимаются.
activated
Обратный вызов (или список обратных вызовов), вызываемый при нажатии мыши при перетаскивании. Вызывается с одним аргументом - списком перетаскиваемых Drags. Возвращаемое значение этого обратного вызова игнорируется.
dragged
Обратный вызов (или список обратных вызовов), вызываемый при перетаскивании этого Drag. Вызывается с двумя аргументами. Первым аргументом является список перетаскиваемых Drags. Второй - либо Drag, на который сбрасываются перетаскиваемые объекты, либо значение None, если сбрасывание не произошло. Если обратный вызов возвращает значение, отличное от None, это значение возвращается, как результат взаимодействия.
dropped
Обратный вызов (или список обратных вызовов), вызываемый при сбрасывании этого Drag в выбранную область. Вызывается с двумя аргументами. Первым аргументом является Drag, на который сбрасывают перетаскиваемые объекты. Второй - список перетаскиваемых Drags. Если обратный вызов возвращает значение, отличное от None, это значение возвращается, как результат взаимодействия.
Когда обратный вызов dragged и dropped запускаются для одного и того же события, обратный вызов dropped вызывается только, если обратный вызов dragged возвращает значение None.
clicked
Обратный вызов, который вызывается без аргументов, когда на Drag нажимают без перемещения. Droppable также может быть сфокусирован и нажат. Если обратный вызов возвращает значение, отличное от None, это значение возвращается, как результат взаимодействия.
alternate
Действие, которое выполняется при нажатии правой кнопкой мыши на Drag (на рабочем столе) или длительном нажатии без перемещения (на мобильном телефоне). Возможно, потребуется увеличить config.longpress_duration, если это приводит к раннему запуску на мобильных платформах.
drag_handle
Кортеж (x, y, ширина, высота), задающий положение "ручки" перетаскивания внутри дочернего элемента. В этом кортеже целые числа считаются точным количеством пикселей, а числа с плавающей точкой соответствуют размеру дочернего элемента.
drag_joined
Вызывается с текущим Drag в качестве аргумента. Ожидается, что он вернёт список кортежей [(drag, x, y)], давая возможность перетащить перетаскиваемые элементы как единое целое. x и y – это смещения перетаскиваемых объектов относительно друг друга, они не связаны с углом этого перетаскивания.
drag_offscreen
Если принимает значение True, этот перетаскиваемый объект можно перемещать за пределы экрана. Это может быть опасно использовать c drag_joined или перетаскиваемыми объектами, которые могут изменить размер, поскольку перетаскиваемые элементы могут полностью покинуть экран, без возможности вернуть их обратно на экран.
mouse_drop
Если принимает значение True, Drag сбрасывается на первый droppable, находящийся под курсором. Если принимает значение False, по умолчанию Drag сбрасывается на droppable с наибольшей степенью перекрытия.
drop_allowable
Обратный вызов, вызываемый, чтобы определить, допускает ли это сброс, чтобы текущие Drags сбрасывались в выбранную область. Вызывается с двумя аргументами. Первым аргументом является Drag, определяющий его чувствительность. Второй - список перетаскиваемых Drags.


За исключением d, все параметры доступны в виде полей (с одинаковыми именами) в объекте Drag. Кроме того, после того, как перетаскивание было отображено, становятся доступными следующие поля:
x, y
Положение Drag относительно его родительского элемента, в пикселях.
w, h
Ширина и высота дочернего элемента Drag, в пикселях.


bottom(self)
Опускает отображаемый элемент в самый низ его drag_group.


set_child(d)
Изменяет дочерний элемент этого перетаскивания на d.


snap(x, y, delay=0)
Изменяет положение перетаскивания. Если перетаскивание элемента не отображается, изменение положения происходит мгновенно. Иначе, изменение положения осуществляется с задержкой в несколько секунд и анимируется, как линейное движение.


top(self)
Поднимает отображаемый элемент до самого верха его drag_group.


class DragGroup(*children, **properties)

Представляет собой группу Drags. Drag ограничен границей своего класса DragGroup. Сбрасывание работает только между Drags, которые находятся в одной DragGroup. Drags может быть поднято только тогда, когда они находятся внутри DragGroup.
DragGroup размечается, как Fixed().
Все позиционные параметры в конструкторе DragGroup должны быть Drags, которые добавляются в DragGroup.


min_overlap
Целое число, которое означает минимальное количество пикселей в перекрытии, чтобы был разрешен сброс.


add(child)
Добавляет child, который должен быть Drag в этом DragGroup.


get_child_by_name(name)
Вычисляет первый дочерний элемент этого DragGroup, где есть drag_name список.


remove(child)
Удаляет child из этого DragGroup.

Примеры (Examples)[править | править код]

Ниже приведен пример экрана say, позволяющий игроку выбирать расположение окна, перетаскивая его по экрану:

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"

    # Группа drag гарантирует, что детективов и города можно перетащить друг на друга.
    draggroup:

        # Наши детективы.
        drag:
            drag_name "Ева"
            child "ivy.png"
            droppable False
            dragged detective_dragged
            xpos 100 ypos 100
        drag:
            drag_name "Зак"
            child "zack.png"
            droppable False
            dragged detective_dragged
            xpos 150 ypos 100

        # Города, куда можно направить детективов.
        drag:
            drag_name "Лондон"
            child "london.png"
            draggable False
            xpos 450 ypos 140
        drag:
            drag_name "Париж"
            draggable False
            child "paris.png"
            xpos 500 ypos 280

label send_detective:
    "Нужно продолжить расследование! Кого нам отправить и куда?"

    call screen send_detective_screen

    "Хорошо, мы пошлём [detective] в [city]."


Спецификатор as можно использовать для привязки перетаскивания к переменной, которая затем может использоваться для вызова методов перетаскивания.

screen snap():

    drag:
        as carmen
        draggable True
        xpos 100 ypos 100
        frame:
            style "empty"
            background "carmen.png"
            xysize (100, 100)

            vbox:
                textbutton "Лондон" action Function(carmen.snap, 450, 140, 1.0)
                textbutton "Париж" action Function(carmen.snap, 500, 280, 1.0)


Для создания более сложных систем требуется значительный навык программирования, чтобы правильно всё настроить. Фреймворк Cardgame в Ren'Py является примером того, как использовать перетаскивание в сложной системе, и полезен для создания карточных игр сам по себе.

Источник[править | править код]

Статья "Drag and Drop" на английском языке.


На главную страницу Официальная документация движка Вернуться к началу статьи