Пользователи · Новые посты · Правила форума · Поиск по форуму · · · Регистрация
Страница 31 из 31«12293031
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Помощь по Rep'Py (Вопрос\Ответ)
Помощь по Rep'Py (Вопрос\Ответ)

TERNOX
Дата: Вторник, 30 Сентября 2014, 21:50 | Сообщение # 1
Администратор
Сообщений: 409
Награды: 36
Репутация: 579
Сюда пользователи сайта могут писать вопросы о тех или иных функциях движка Ren'Py, а мы попытаемся на них ответить:)


Я у мамы ямаман.

AngelGrove
Дата: Вторник, 14 Ноября 2017, 14:01 | Сообщение # 451
Пользователь
Сообщений: 9
Награды: 0
Репутация: 0
Замечания: 0%
И вновь я и опять проблема... bad Мне надо сделать так, что бы при нажатии на кнопку (imagebuttom) отображался экран, но полностью скрывался интерфейс и оставался один лишь фон (ибо всплывающий экран на прозрачном фоне).

Попробовал сделать через action [Show ("name",_layer="name"), Hideinterface()] с переносом экрана на отдельный слой - всё получилось, но как закрыть экран и вернуть всё как было до нажатия? cry Пробовал [Hide ("name"), Return()] - не вышло...


Ты будешь моим братиком?

Сообщение отредактировал AngelGrove - Вторник, 14 Ноября 2017, 14:05

mrWebster
Дата: Вторник, 14 Ноября 2017, 16:45 | Сообщение # 452
Проверенный
Сообщений: 162
Награды: 0
Репутация: 23
Замечания: 20%
AngelGrove, думаю, это можно сделать через скрины. В блогах на этом сайте есть подробный разбор работы с ними.

Добро пожаловать во Мрак!

Ikuku
Дата: Вторник, 14 Ноября 2017, 17:44 | Сообщение # 453
Проверенный
Сообщений: 19
Награды: 1
Репутация: 49
Замечания: 0%
Увы, не все так просто -_- Тут сразу две проблемы. Одна - поменьше, легко решаемая: экшен Hide, очевидно, не умеет в экраны на слоях, отличных от слоя screen. Поэтому надо будет написать свою экшен-функцию, а в ней уже использовать скрытие с указанием слоя: renpy.hide_screen("name", layer = "mylayer") (да-да, без нижнего подчеркивания, в show_screen с ним, в hide - внезапно без него)
Код
python init:
    def MyHidey():
  renpy.hide_screen("name", layer="mylayer")

Вторая проблема в том, что HideInterface, судя по проведенным тестам, по окончанию user interaсtion восстановит не только интерфейс, но и свежескрытый экран тоже. То ли из-за того, что открыли мы экран в одном контексте, скрыли в другом, потом вернулись в прежний и HideInterface вернул все как было, то ли хз. Пока в голову не идет, как обойти эту проблему красиво, в общем, костыльное решение - прятать руками все открытые слои, поочередно, без HideInterface, и потом так же открывать обратно.


Сообщение отредактировал Ikuku - Вторник, 14 Ноября 2017, 17:46

AngelGrove
Дата: Среда, 15 Ноября 2017, 15:38 | Сообщение # 454
Пользователь
Сообщений: 9
Награды: 0
Репутация: 0
Замечания: 0%
mrWebster, Ikuku, это конечно многое не поменяло, но спасибо, будем пробовать. bad

Ты будешь моим братиком?

AngelGrove
Дата: Четверг, 16 Ноября 2017, 16:23 | Сообщение # 455
Пользователь
Сообщений: 9
Награды: 0
Репутация: 0
Замечания: 0%
Попытался я через функцию скрыть слой, но в итоге - ошибка cry





Ты будешь моим братиком?

dmit
Дата: Четверг, 16 Ноября 2017, 18:22 | Сообщение # 456
Проверенный
Сообщений: 101
Награды: 0
Репутация: 15
Замечания: 0%
Вы не правильно вызываете функцию MyHidey. ей нужен хотя бы 1 аргумент.
action [Hide("inventory_screen", MyHidey), Return()]
наверно:
action [MyHidey("inventory_screen", "mylayer"), Return()]


планета FOREVER!!!

Сообщение отредактировал dmit - Четверг, 16 Ноября 2017, 18:30

Ikuku
Дата: Четверг, 16 Ноября 2017, 20:16 | Сообщение # 457
Проверенный
Сообщений: 19
Награды: 1
Репутация: 49
Замечания: 0%
AngelGrove, первое, что вам нужно сделать - внести две правки в экшены кнопок:

Код
textbutton "Инвентарь" action [MyShown, HideInterface()]
textbutton "" action [MyHidey, Return()]


Пояснения по синтаксису:
1. Show("XXX") и Hide("XXX") - это экшены ренпи. Внутри их скобок - параметры, которые они принимают. Если вы пишете кастомную функцию, то не добавляете ее в скобки к Show, а либо заменяете Show на нее, либо просто добавляете в список после запятой. В вашем случае - заменяете.

2. Если Return() и, скажем, HideInterface() мы пишем со скобками, то кастомные экшены - без. Потому что (если вдаваться в детали) на самом деле наш кастомный экшен - не экшен, а функция. В свою очередь, цитируя доки: "экшен (кнопки) может быть функцией, которая не принимает аргументов". Т.е. функция без скобок (=не принимающая аргументы) - экшен.

MyHidey(tag, layer="...") - функция.
MyHidey - функция, которую можно использовать как экшен.

3. Код:
Код
def MyShown():
    renpy.show_screen("inventory_screen", _layer="mylayer")
def MyHidey(tag, layer=None):
    renpy.hide_screen("name", layer="mylayer")

правим на:
Код
def MyShown():
    renpy.show_screen("inventory_screen", _layer="mylayer")
def MyHidey():
    renpy.hide_screen("inventory_screen", layer="mylayer")

В вашем конкретном случае если слой и название экрана вы напрямую указываете внутри функции, то вам не нужно передавать их в нее в виде параметров.

В таком виде код должен перестать выбрасывать ошибку. При этом остается проблема с тем, что HideInterface вернет свежескрытый экран на место, и его придется еще раз скрывать кнопкой. Эту проблему надо решать дополнительно, я пока не знаю, как.

AngelGrove
Дата: Пятница, 17 Ноября 2017, 00:13 | Сообщение # 458
Пользователь
Сообщений: 9
Награды: 0
Репутация: 0
Замечания: 0%
Ikuku, спасибо за столь подробный разбор. Всё получилось! (Если не считать проблему с двойным кликом по кнопке). Пытался найти решение проблемы с двойным нажиманием, но так и не нашел (даже на японских сайтах нет ответа) и это печально...

Ты будешь моим братиком?

Ikuku
Дата: Пятница, 17 Ноября 2017, 01:59 | Сообщение # 459
Проверенный
Сообщений: 19
Награды: 1
Репутация: 49
Замечания: 0%
AngelGrove, дальнейшее включает мои догадки о причине проблем, я могу ошибаться.

Первая мысль была: отказаться от HideInterface() и вручную прятать все открытые экраны при показе инвентаря, и показывать их, когда его закрываем. Т.е. примерно так:
Код
def ShowInventory():
    renpy.show_screen("inventory_screen")

    renpy.hide_screen("inventory_button")
    _window_hide() # аналог оператора window hide
    renpy.restart_interaction() # для перерисовки окна игры

def HideInventory():
    renpy.hide_screen("inventory_screen")

    renpy.show_screen("inventory_button")
    _window_show() # аналог оператора window show
    renpy.restart_interaction() # для перерисовки окна игры

Вроде все должно было работать, но всплыли нюансы, касающиеся окна say. Во-первых, в скрипте надо было где-то в самом начале сделать window show, чтобы то, что выше, начало работать, во-вторых, у окна say тоже оказались проблемы с контекстом - вышеописанные функции его (окно) прячут - но почему-то не показывают. причем сама по себе структура (внутри старого скрипта):
Код
"test 123"
$ _window_hide()
pause
$ _window_show()
pause
"test 123"

точно так же как и
Код
"test 123"
$ ShowInventory()
pause
$ HideInventory()
pause
"test 123"

отрабатывает нормально (т.е. когда окно say прячется и вызывается из одного и того же контекста).

На этом этапе задача свелась к тому, чтобы не нарушать контекст, в котором работает инвентарь. И чисто технически можно сделать ужасно хитрый трюк: вынести работу с инвентарем в отдельный лэйбл, который мы будем вызывать по необходимости с помощью call inventory_label, и в нем - в одном и том же контексте! - и прятать/открывать окна.

Не могу сказать, что это прямо чистенько-аккуратно, но это работает. Вот базовый код, дополняйте/режьте/переназывайте переменные под свои нужды как угодно:
Код
init -1 python:
    # Показывает инвентарь
    def ShowInventory():
        renpy.show_screen("inventory_screen")

        renpy.hide_screen("inventory_button")
        _window_hide() # аналог оператора window hide
        renpy.restart_interaction() # для перерисовки окна игры

    # Прячет инвентарь
    def HideInventory():
        renpy.hide_screen("inventory_screen")

        renpy.show_screen("inventory_button")
        _window_show() # аналог оператора window show
        renpy.restart_interaction() # для перерисовки окна игры

    # нет прямого способа экшеном вызвать call на метку, поэтому пилим кастомный
    def CustomCall():
        renpy.call("inventory_label")

screen inventory_button:
    frame:
        xalign .5
        textbutton "Инвентарь" action CustomCall

#Экран инвентаря
screen inventory_screen:
    modal True
    frame:
        xalign .3
        textbutton "Закрыть" action Return()

label start:
    window show # эта строка нужна, чтобы _window_hide и _window_show работали
    show screen inventory_button

    "Testing inventory."
    "Lalala."

    return

label inventory_label:
    "Hi! You're inside the inventory label!"
    $ ShowInventory()
    pause
    $ HideInventory()

    return

Как он работает, пошагово:

1. При нажатии кнопки "Инвентарь" кастомный экшен вызывает служебную метку, создавая для нее новый контекст.
2. В этом контексте прямо из самой метки запускается функция "ShowInventory", которая прячет ненужные окна и показывает нужные. Лэйбл ставится на паузу (ожидаем ввод), чтобы следующая функция не закрыла инвентарь раньше времени. Окно инвентаря модальное, т.е. любые действия вне его блокируются.
3. По нажатию кнопки "закрыть", мы просто имитируем user interaction, "прожимая" паузу внутри лэйбла, скрипт идет на следующий шаг, встречает на нем функцию HideInventory, закрывает ненужные окна и открывает нужные.
4. return возвращает нас из служебной метки ровно на то место в предыдущем контексте, откуда мы ушли в инвентарь (это дает нам воможность открывать инвентарь когда вздумается, не заботясь тем, что мы забудем, куда возвращаться).

(P.S. служебная метка для работы с инвентарем одна-единственная на любое его открытие в любой момент времени, создавать по метке на каждое открытие не нужно.)


Сообщение отредактировал Ikuku - Пятница, 17 Ноября 2017, 02:04

AngelGrove
Дата: Пятница, 17 Ноября 2017, 17:10 | Сообщение # 460
Пользователь
Сообщений: 9
Награды: 0
Репутация: 0
Замечания: 0%
Ikuku, вы мой спаситель. Обязательно попробую! ( ~'ω')~

Ты будешь моим братиком?
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Помощь по Rep'Py (Вопрос\Ответ)
Страница 31 из 31«12293031
Поиск: