РенПай поддерживает покупки товаров в игре. Сегодня разберёмся, как настроить покупки в Google Play, добавить их в свою новеллу и заставить влиять на игровой процесс.
Покупки можно использовать для разблокирования полной версии игры или отдельных глав, для открытия секретных выборов и диалогов, а также для реализации дополнительных возможностей.
# После того, как вы добавите товары в консоли Google Play заполняем ключ и соль в файле options.rpy
# Скопируйте свой ключ из Google Play
define build.google_play_key = "MIIBIjANBgkqhkiG9w0BAQEFA…HGTQIDAQAB"
# 20 чисел от -128 до 127 через запятую
define build.google_play_salt = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
# Регистрируем наши товары в РенПай в блоке init
init:
$ iap.register("some_tovar", identifier="some_tovar")
# Получаем цену товара из Google Play и записываем её в переменную
$ tovar_price = iap.get_price("some_tovar")
# На нужный экран добавляем кнопку для покупки товара. В кнопке используем переменную с ценой
textbutton "Купить [tovar_price]" action iap.Purchase("some_tovar", success=None)
# Добавляем кнопку для восстановления покупок
textbutton "Восстановить покупки" action iap.Restore()
# Если вы хотите сделать покупку не с помощью кнопки на экране, а в самом коде новеллы (например, в обычном меню с вариантами действий), пользуйтесь этой командой
$ iap.purchase("some_tovar")
# Восстановить покупки командой
$ iap.restore()
# В самой игре можно проверять купил ли игрок товар и в зависимости от этого производить действия
if iap.has_purchased("some_tovar"):
# Какой-то код. Например:
jump secret_label # Переход на секретную метку
# Секретный вариант ответа
"Ответ игрока" if iap.has_purchased("some_tovar"):
Разбираемся, как перевести новеллу на английский (или другой) язык. Смотрим на нюансы переводи и производим различные действия в зависимости от выбранного языка.
Если в вашей игре есть выбор с вариантами ответов "Да" и "Нет", то РенПай не сформирует отдельные строки с переводами для кнопок Да/Нет при выходе из игры. Достаточно перевести варианты ответов Да/Нет, и тогда этот же перевод подтянется и для кнопок подтверждения выхода.
Если переводите команду ввода (input), то имя по умолчанию нужно заключить в скобки и поставить перед ним не один, а ДВА знака подчеркивания.
Делаем кнопки из любых изображений с помощью imagebutton.
По пути учимся привязывать к кнопке сразу несколько действий.
# Создаём новый экран с названием blue_butt
screen blue_butt:
# Добавляем на экран кнопку-изображение
imagebutton:
# Задаём расположение кнопки с помощью xalign и yalign
xalign 0.05
yalign 0.05
# Картинка с кнопкой в обычном состоянии
idle "gui/blue_idle.png"
# Картинка с кнопкой, когда на неё наведён курсор
hover "gui/blue_hover.png"
# Действие, которое выполняется при наведении мышью на кнопку
# Play - проигрывает звук
hovered Play("sound", "sounds/hover.ogg")
# Действие, которое выполняется при нажатии на кнопку
# Чтоб указать сразу несколько действий, указываем их через запятую в квадратных скобках
action [Play("sound", "sounds/click.ogg"), Show("info_panel")]
# Не забываем, что экран нужно показать игроку во время игры
show screen blue_butt
Изменяем внешний вид визуальной новеллы с помощью настроек и изменения картинок элементов.
Заменяем стандартный курсор мыши.
Учимся изменять курсор мыши по ходу игры и при наведении на объекты.
Добавляем анимированный курсор.
# Изменяем стандартный курсор. Используется png картинка 32х32 пиксела.
define config.mouse ={}
define config.mouse["default"] = [ ("gui/cursors/pointer001.png", 0,0) ]
# Добавляем дополнительные курсоры. Числа 0,0 и 16,16 - это координаты на которые должен реагировать курсор. 0,0 - левый верхний угол курсора. 16,16 - центр курсора.
define config.mouse["cross"] = [ ("gui/cursors/pointer006.png", 0, 0) ]
define config.mouse["quest"] = [ ("gui/cursors/question002.png", 16,16) ]
# Добавляем анимированный курсор. Перечисляем кадры через запятую.
define config.mouse["spin"] = [
("gui/cursors/pointer006.png", 16,16),
("gui/cursors/pointer007.png", 16,16),
("gui/cursors/pointer008.png", 16,16),
("gui/cursors/pointer009.png", 16,16),
("gui/cursors/pointer008.png", 16,16),
("gui/cursors/pointer007.png", 16,16),
]
# Меняем курсор во время игры.
$ default_mouse = "cross"
# Меняем курсор при наведении на imagebutton. В параметрах кнопки добавляем нужный курсор.
mouse "spin"
Разбираем, что такое звуковые каналы и зачем они нужны.
Добавляем свои звуковые каналы в РенПай и их настройки в меню.
# Добавляем каналы в блок init python
init python:
# Звуковой канал "ambient", который будет проигрываться по кругу
renpy.music.register_channel("ambient", loop=True, mixer="ambient")
# Звуковой канал "sound2", который не будет проигрываться по кругу, громкость привязана к громкости остальных звуков
renpy.music.register_channel("sound2", loop=False, mixer="sfx")
# В экран preferences добавляем полоску громкости канала "ambient"
bar value Preference("mixer ambient volume")
# Запускаем звук на каналах так же, как и обычные звуки и музыку
play ambient "audio/birds.ogg"
stop ambient
play sound2 "audio/cry.ogg"
Создаём словарь, который постепенно открывается по ходу игры.
Так как в словаре может быть много строк и он может не вместиться в окно игры, мы добавим к словарю полосу прокрутки.
# Подготовка словаря состоит из нескольких этапов.
# 1. Нужно создать экран, который будет содержать словарь (код ниже).
# 2. Добавить кнопку открытия словаря в экран navigation:
textbutton _("Словарь") action ShowMenu("dictionary")
# 3. В двух стилях с названием style vscrollbar нужно добавить следующую строку, чтоб полоса прокрутки скрывалась, когда она не нужна:
unscrollable "hide"
# 4. В игре открывать слова в словаре, изменяя persistent переменные.
$ persistent.dict1 = True
screen dictionary():
# Заменяет другие экраны меню
tag menu
# Добавляем фоно
add "gui/dictbg.jpg"
# Контейнер, который содержит вьюпорт и полосу прокрутки
hbox:
xsize 1900
ysize 900
xpos 60
ypos 60
# Контейнер с прокруткой
viewport id "vp":
draggable True
mousewheel True
xsize 1800
# Контейнер, который располагает элементы словаря сверху вниз
vbox:
xalign 0.05
yalign 0.05
spacing 30
# Элмент, который отображается, если persistent.dict1 равна True
if persistent.dict1:
hbox:
add 'images/dict/bee.png'
null width 40
text 'Текст 1.'
if persistent.dict2:
hbox:
add 'images/dict/lips.png'
null width 40
text "Текст 2"
if persistent.dict3:
hbox:
add 'images/dict/santa.png'
null width 40
text "Текст 3"
# Полоса прокрутки
vbar value YScrollValue("vp")
# Кнопка возврата
textbutton _("Назад") xalign 0.05 yalign 0.95 action Return()
Разбираемся с функцией LayeredImage. С помощью неё мы можем объединять несколько отдельных спрайтов в одну картинку, и менять элементы на ходу.
Кроме того можно легко делать картинки, которые автоматически изменяются в зависимости от указанных условий.
# Создаём картинку со слоями с названием felicia
layeredimage felicia:
# always - указывает спрайт, который всегда выводится
always:
"felicia_base"
# Используем обычное условие if и указываем, какой спрайт выводить в зависимости от условия
if angry:
"felicia_eyes_angry"
else:
"felicia_eyes_normal"
# Аттрибут может отображаться, если мы его укажем
# Раз наша картинка называется felicia, то РенПай будет искать файл "felicia_gloves"
attribute gloves
# Создаём группу для обуви. Из группы может присутствовать только один спрайт.
# Раз наша картинка называется felicia, то РенПай будет искать файлы, которые начинаются с "felicia_shoes_"
group shoes auto:
# Обувь, которая отображается по умолчанию, если мы не указываем другую.
attribute brown default # Это файл "felicia_shoes_brown"
# Аналогично группа costume отвечает за костюм персонажа.
group costume auto:
attribute jeans default # По умолчанию отображается одежда "felicia_costume_jeans"
# Используем картинку в игре
show felicia # Отображается стандартный спрайт - база + обувь и костюм с параметром default
show felicia white # Отображается спрайт с белой обувью. У нас должна присутствовать картинка "felicia_shoes_white"
show felicia gloves # Отображается спрайт с перчатками.
show felicia -gloves # Знак минус означает, что нужно убрать перчатки.
show felicia gloves white bluedress # Можно комбинировать любые аттрибуты.
$ angry = True
# Меняем переменную, от которой зависят глаза спрайта. Теперь будут отображаться глаза из картинки "felicia_eyes_angry"
Создаём экран с полосой, которая отображает значение переменной. Это можно использоваться для счётчика отношений, полосы здоровья или маны и для многого другого.
# Добавляем переменную с максимальным уровнем отношений.
default maxlove = 100
# Переменная отношений с Джеки.
default love_jacky = 50
# Экран с полоской отношений Джеки
screen lovemeter:
# Добавляем в экран единственный элемент - вертикальную полоску
vbar:
# Прописываем параметры полоски - ширину, высоту и расположение в экране
xsize 120
ysize 600
xalign 0.95
yalign 0.3
# Привязываем значение полоски к переменной love_jacky, а максимальное значение - к maxlove. При изменении переменной полоска будет плавно изменяться за 1 секунду (delay).
value AnimatedValue(value=love_jacky, range=maxlove, delay=1.0)
# Указываем картинки для полной и пустой полоски
bottom_bar Frame("gui/bar/bottom.png",10,10)
top_bar Frame("gui/bar/top.png",10,10)
# В игре нам остаётся только показать наш экран.
show screen lovemeter
# В любой момент мы можем изменить отношения с Джеки, и это отобразится на полоске.
$ love_jacky += 10
# Для горизонтальной полоски нужно заменить vbar на bar, и вместо bottom_bar и top_bar укажем параметры left_bar и right_bar.