В Renpy есть неприятная особенность. Если высота инвентаря больше высоты экрана, то клик по нижним предметам не срабатывает. Можно вместо бегунка сделать кнопки для пролистывания инвентаря. Заодно добавим возможность группировки предметов с одинаковыми изображениями. Для этого удобно пользоваться словарями. Количество рядов и колонок настраивается переменными columns и rows.
init python: # окно игры в центре экрана import os os.environ['SDL_VIDEO_CENTERED'] = '1' # автоматическое объявление изображений config.automatic_images_minimum_components = 1 config.automatic_images = [' ', '_', '/'] config.automatic_images_strip = ['images'] # размеры сетки с инвентарем настраиваются columns = 3 rows = 3 # размеры иконок в инвентаре side = 64 # сам инвентарь inventory = {} # текущее положение скролла инвентаря from_i = 0 # получить количество предметов def get_count(str): s = str.split(":") if len(s) > 0: return int(s[0]) return 0 # получить подсказку по предмету def get_hint(str): s = str.split(":") if len(s) > 1: return s[1] return "" # получить описание предмета def get_about(str): s = str.split(":") if len(s) > 2: return s[2] return "Описание отсутствует." # изменение количества предметов в ячейке на plus единиц # если не было, то будут созданы # если количество < 1, то удалены вовсе def iplus(item_name, plus = 1, hint = None, about = None): if plus: global inventory i = get_count(inventory.get(item_name, "0")) if hint == None: hint = get_hint(inventory.get(item_name, "0")) if about == None: about = get_about(inventory.get(item_name, "0")) i += plus if i < 1: # предметы количеством < 1 удаляются из инвентаря i = 0 if item_name in inventory: inventory.pop(item_name) else: inventory[item_name] = str(i) + ":" + hint + ":" + about else: # если plus == None, то уничтожаем все единицы предмета if item_name in inventory: inventory.pop(item_name) # изменения на экран renpy.restart_interaction() # вручную сохраняем измененные данные инвентаря # так как renpy сохраняет данные только # при смене текста в текстбоксе renpy.retain_after_load() # скролл вверх class iUp(Action, DictEquality): def __call__(self): global from_i from_i -= columns if from_i < 0: from_i = 0 from_i = (from_i / columns) * columns renpy.restart_interaction() # кликабельность кнопки def get_sensitive(self): return from_i >= columns # скролл вниз class iDn(Action, DictEquality): def __call__(self): global from_i from_i += columns if from_i < 0: from_i = 0 from_i = (from_i / columns) * columns renpy.restart_interaction() # кликабельность кнопки def get_sensitive(self): return from_i + columns * rows < len(inventory) # обработчик кликов, # чтобы не пихать гору кода в action кнопок def iclick(i): # например, вызовем окно применения предмета renpy.show_screen("scr_use", i) renpy.restart_interaction() # кнопка применения предмета def accept(i): # уменьшаем количество предметов на 1 iplus(inventory.keys()[i], -1) # превращаем функции в action iClick = renpy.curry(iclick) Accept = renpy.curry(accept) init: image empty = Null(side, side) # необязательное окно прменения предмета screen scr_use(i): modal True frame: background "#100b" align(.5, .5) xminimum 500 has vbox: xalign .5 text " " add inventory.keys()[i] xalign .5 text get_hint(inventory.values()[i]) xalign .5 text get_about(inventory.values()[i]) xalign .5 text " " hbox: xminimum 500 textbutton "Применить" xalign .5 xminimum 150 action [Hide("scr_use"), Accept(i)] textbutton "Отмена" xalign .5 xminimum 150 action Hide("scr_use") text " " # сам экран инвентаря screen scr_inventory: zorder 111 default tt = Tooltip(" ") button: align (.95, .05) background "#0018" # фон инвентаря action NullAction() # заполняем ячейки vbox: text "Инвентарь" xalign .5 textbutton _("↑") xminimum side*columns action iUp() # скролл вверх for y in range(0, rows): hbox: for x in range(0, columns): # индекс ячейки $ i = from_i + x + y * columns # если не за грницами списка предметов if i < len(inventory): button: # размеры предмета minimum (side, side) maximum (side, side) background inventory.keys()[i] # картинка предмета hovered tt.Action(get_hint(inventory.values()[i])) # количество text "{size=16}" + str(get_count(inventory.values()[i])) align(1.0, 1.0) action iClick(i) # действе по клику else: # пустые ячейки button: minimum (side, side) background "empty" text " " action NullAction() textbutton _("↓") xminimum side*columns action iDn() # скролл вниз text tt.value xalign .5 # чтобы использовать инвентарь нужно только # доработать под себя фунцию для обработки клика по предмету в инвентаре iclick label start: # если сначала объявить переменную прямо в скрипте, # то renpy будет сам сохранять ее содержимое $ inventory = {} scene bg # заполним инвентарь всеми доступными пузырьками в 1 экземпляре $ i = 1 while i <= 12: # вторым параметром можно указать стартовое количество хреновин # третьим - подсказку, появляющуюся при наведении курсора # а можно ничего не указывать, только имя картинки - 1й параметр $ iplus('pot' + str(i), 1, "Хреновина №" + str(i)) $ i += 1 # покажем экран инвентаря show screen scr_inventory "Можно кликнуть по хреновинам в инвентаре." # пример изменения инвентаря из скрипта # iplus(спрайт, [количество, подсказка, описание]) $ iplus('pot9', 2) "{image=pot9} Добавлено еще 2 вот таких хреновины." return
Руслан, добрый день! Подскажите, пжл, как можно определить название предмета, по которому был выбран клик? Что-то не могу сообразить. Т.е., например, мне нужно, чтобы если было использовано зеленое зелье, убавилось его кол-во + появилась надпись типа "Вы выпили супер-пупер зелье!".
ОтветитьУдалитьможно в функцию «def accept(i)» добавить строку
Удалитьlast_item_name = get_hint(inventory.values()[i])
а там, где нужно сообщить об изменениях, проверять содержимое этой переменной. к примеру:
if last_item_name:
__"Потрачено [last_item_name]"
__$ last_item_name = ""
Почему-то last_item_name не присваивается значение get_hint(inventory.values()[i])
Удалитьзабыл сказать, что в функциях нужно указать на то, что переменная глобальная с помощью команды global:
Удалитьglobal last_item_name
last_item_name = ***
Спасибо, Руслан. Я в Ren'Py ещё новичок. А Google не понимал, что я от него хочу. Поэтому Ваш ответ был последней надеждой :D
УдалитьА можно, как то сделать независимые друг от друга предметы со своим описанием, именем и переменной?
ОтветитьУдалитьНапример, что бы в инвентаре например были деньги или некий предмет и при выборе из инвентаря изымались деньги и добавлялся предмет.
Удалитьможно, я разрешаю))
Удалитьэто уже магазин, а не инвентарь.
но кто мешает в функции-обработчике клика сделать проверку на тип предмета, его добавление и уменьшение денег? добавление описано в конце скрипта, деньги любой сам может убавить. дерзайте.
Я просто хочу сделать так, что когда ты нажимаешь на предмет, то, скажем, у тебя,у некого персонажа, повышалась привязанность.
Удалитьда я не против, делайте.
Удалитьнужный код требуется вписать в def accept(i)
либо в def iclick(i), если не нужно подтверждение действия. читайте комментарии к коду и дополняйте его своим.
Не понял, что означает DictEquality в классе. Не подскажете?
ОтветитьУдалитьGracias por tus aportes, son muy buenos, me gustaria saber si este script se puede usar en la ultima versión de RenPy.
ОтветитьУдалить