Инвентарь со счетчиком
Перейти к навигации
Перейти к поиску
В 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()
# скролл вверх
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:
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
- Ссылка на архив с проектом: test-inventory.zip
- Источник: Renpy для чайников: Инвентарь со счетчиком
На главную страницу | Книга рецептов Энциклопедии Ren'Py | Renpy для чайников | Вернуться к началу статьи |