## Пользовательские классы

Разработчик игры (т. е. пользователь Ren-Engine) может использовать свои классы для rpg-объектов со своим поведением, специфическим для его игры.

Для этого такие классы должны удовлетворять некоторым требованиям:

1. Конструктор (`__init__`) помимо `self` принимает ещё и параметры `xpos, ypos, xsize, ysize, **kwargs` (позицию, размеры и словарь параметров), разумеется, любые эти параметры можно запомнить, проигнорировать или использовать для каких-то своих вычислений,
2. Опционально может присутствовать метод `free`, возвращающий полный путь (или результат `im`-функции) к карте непроходимости, составленной по принципам обычных объектов локаций,
3. Метод `update`, вызываемый для обновления объекта перед отрисовкой,
4. Метод `get_draw_data(self)`, возвращающий данные для отрисовки. Результатом должен быть словарь (`dict`) или список из нескольких словарей со свойствами:
   - `image` - путь к изображению или результат `im`-функции,
   - `pos` - кортёж или список из `x`- и `y`-координат; дальнейшие параметры не являются обязательными,
   - `size` - кортёж или список из ширины и высоты (по умолчанию - размеры `image`),
   - `crop` - как и в ATL или ScreenLang, это часть из отрисовываемого изображения: `x, y, xsize, ysize`, по умолчанию `(0.0, 0.0, 1.0, 1.0)`,
   - `anchor` - как и в ATL или ScreenLang, это отступ, по умолчанию `(0, 0)`,
   - `alpha` - непрозрачность от `0.0` до `1.0`, по умолчанию `1.0`,
   - `rotate` - поворот по часовой стрелке, в градусах, по умолчанию `0`,
   - `zorder` - значение для сортировки по глубине:
     - Если меньше `0`, то объект будет отрисовываться позади локации (может быть использовано, когда локация имеет прозрачные участки),
     - Если больше `1e6` (миллион), то будет отрисовываться после изображения `over` локации (может быть использовано для тумана),
     - В ином случае объект будет отрисовываться после объектов с меньшим `zorder` и до тех, что имеют `zorder` больше (у обычных объектов `zorder` обычно равен `y`-координате точки, на которой он стоит).

Используется пользовательский класс rpg-объектов в той же функции, что и обычные rpg-объекты, но вместо зарегистрированного типа объекта (т. е. строки с именем типа) передаётся ваш класс и именованные параметры, попадающие в `kwargs` конструктора.

Например:

    my_obj = add_location_object('location_name', 'place_name', MySuperObject, param1=123, param2=234)
    my_obj.your_class_method()

Или, если параметров будет много и создавать объект нужно будет не 1 раз:

    my_obj_params = {
        'param1': 123,
        'param2': 234,
    }
    my_obj = add_location_object('location_name', 'place_name', MySuperObject, **my_obj_params)

## Пользовательские функции

Стандартным rpg-объектам можно устанавливать свои функции, которые будут выполняться после стандартной функции обновления перед отрисовкой.
Пользовательские функции должны принимать объект в качестве аргумента и могут менять некоторые его свойства:
`x`, `y`, `xanchor`, `yanchor`, `xsize`, `ysize`, `alpha`.

Примеры:

Плавно удаляем (сначала добавляя прозрачности) 3 уже существующих мячика:

    # функция для плавного сокрытия мячика
    def ball_hiding(ball):
        dtime = get_game_time() - ball.start_hiding
        hiding_time = 3

        ball.alpha = 1 - dtime / hiding_time
        if ball.alpha < 0:
            remove_location_object(ball.location.name, ball, ball.type)

    # ...

    # получаем список всех мячиков (объектов с типом 'ball')
    # в локации location_name, отсортированых по расстоянию до места place_name
    balls = get_location_objects('location_name', 'place_name', 'ball')

    # для 3 ближайших мячиков
    for ball in balls[:3]:
        # запоминаем текущее время и запускаем плавное удаление
        ball.start_hiding = get_game_time()
        ball.user_function = ball_hiding

Передвижение для добавляемой машины:

    def car_moving(car):
        dist = car.location.xsize
        moving_time = 10

        car.x = ((get_game_time() / moving_time) % 1) * dist

    car = add_location_object('location_name', 'place_name', 'car')
    car.user_function = car_moving

Далее ->
<- Назад