Создаем текстовый файл с любым названием и расширением rpy
Сразу же оговорюсь, никаких модов в общий доступ я не выкладывал пока , по причине того что сценарист из меня так себе (ИМХО). Я лишь делал небольшие мини моды, которые выкидывались в корзину спустя 1-2 дня после их завершения. В моем руководстве будет лишь теория для Steam версии (совместимость с другими версиями возможна но не гарантированна)
Начинаем творить
Для создания мода нам понадобится:
- Сама игра, в нашем случае Everlasting Summer
- Текстовый редактор, я советую использовать Notepad++
В принципе для небольших и простеньких модов этого должно хватать, но если вы захотите использовать собственные bg, cg и спрайты, то необходим либо графический редактор, либо собственный художник.
Создаем текстовый файл, с любым названиме и расширением .rpy (Надеюсь вы знаете, как создавать файлы с другими расширениями)
А теперь открываем его нашим текстовым редактором (У меня это Notepad++) и продолжаем вникать в это руководство
Время усложнять мод!
Все что мы узнали раньше позволяет нам писать лишь статичные моды, в которых от игрока ничего не зависит. Теперь же нам пора добавить игроку возможность выбора
Если вы хотите, чтобы игра запоминала каждый выбор игрока, то без переменных нам не обойтись.
Объявление переменных происходит в специальном блоке init. Имена и значения у переменных могут быть любые, но рекомендуется использовать короткие английские слова или цифры (цифры только в значении)
Изменение значения переменных будет выглядеть так:
После выполнения данных команд переменная “choice” будет иметь значение “True”, а переменная “Count” увеличит свое значение на единицу.
Если вы хотите дать игроку выбор, то вам необходимо использовать специальный блок menu:
mt “Возьми-ка этот мешок с сахаром” menu: “И куда мне его девать?”: $ good += 1 jump good_label “Да идите вы со своим сахаром на …”: jump bad_label
В приведенном примере Ольга Дмитриевна попросит нас взять мешок с сахаром, мы же можем как подчиниться и увеличить переменную “good” на 1, так и отказаться, причем в зависимости от нашего выбора события в игре могут измениться
Будьте осторожны: Варианты ответа тоже открывают блок, и если мы не поставим после каждого двоеточие, мод может не запуститься
Что нам делать если мы хотим чтобы какие то из возможностей были у игрока в зависимости от его выборов? Для этого то мы и использовали переменные! Сейчас же мы воспользуемся специальной конструкцией
Поясню данный отрезок. Если значение переменной “good” больше нуля, то игра продолжится на метке “good”, если же нет, то мы переходим на метку “bad”
… mt “Семен, сегодня после обеда ты будешь убираться в столовой” menu: “Почему именно я?”: jump why_me? “Я же уже помог вам сегодня” if good > 0: jump help “Не намерен я вам тут прислуживать!” if good == 0: jump angry
Заселяем лагерь
Вполне возможно, что вашем моде вам понадобится персонаж, которого по какой-то причины разработчики не стали заселять в лагерь, что же делать в этом случае? Правильно создать его!
Любой персонаж игры – простая переменная, с которой мы вольны делать что захотим (*зловещий смех*)
Переменные создаются двумя способами, методом движка – с помощью команды define и методом “Питона” – с помощью символа – $.
Далее мы присваиваем переменной свойство Character().
Для примера создадим Вашего покорного слугу:
define vladya = Character(u”Владя”)
(прим.: Символ u используется, для отображения русского текста у людей, у которых он не установлен в системе.)
Теперь мы можем использовать переменную vladya в своём моде. Давайте, я поздороваюсь с Вами:
vladya “Привет”
И давайте я вновь поздороваюсь с Вами:
vladya “Привет”
Намного лучше, не правда ли?
Окей, окей. Без проблем.
Что мне делать.
I'm sorry, but an uncaught exception occurred.
Full traceback:
File "renpy/common/00start.rpy", line 181, in script call
call expression "splashscreen" from _call_splashscreen_1
File "game/script.rpy", line 529, in script
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\ast.py", line 1266, in execute
renpy.exports.with_statement(trans, paired)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\exports.py", line 1358, in with_statement
return renpy.game.interface.do_with(trans, paired, clear=clear)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\core.py", line 1987, in do_with
clear=clear)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\core.py", line 2425, in interact
repeat, rv = self.interact_core(preloads=preloads, **kwargs)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\core.py", line 2779, in interact_core
self.draw_screen(root_widget, fullscreen_video, (not fullscreen_video) or video_frame_drawn)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\core.py", line 1848, in draw_screen
renpy.config.screen_height,
File "renpy/display/render.pyx", line 416, in renpy.display.render.render_screen (gen\renpy.display.render.c:6685)
rv = render(root, width, height, 0, 0)
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\layout.py", line 649, in render
surf = render(child, width, height, cst, cat)
File "renpy/display/render.pyx", line 103, in renpy.display.render.render (gen\renpy.display.render.c:3319)
cpdef render(d, object widtho, object heighto, double st, double at):
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\transition.py", line 363, in render
top = render(self.new_widget, width, height, st, at)
File "renpy/display/render.pyx", line 103, in renpy.display.render.render (gen\renpy.display.render.c:3319)
cpdef render(d, object widtho, object heighto, double st, double at):
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\layout.py", line 649, in render
surf = render(child, width, height, cst, cat)
File "renpy/display/render.pyx", line 103, in renpy.display.render.render (gen\renpy.display.render.c:3319)
cpdef render(d, object widtho, object heighto, double st, double at):
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\layout.py", line 649, in render
surf = render(child, width, height, cst, cat)
File "renpy/display/render.pyx", line 103, in renpy.display.render.render (gen\renpy.display.render.c:3319)
cpdef render(d, object widtho, object heighto, double st, double at):
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "renpy/display/accelerator.pyx", line 104, in renpy.display.accelerator.transform_render (gen\renpy.display.accelerator.c:1965)
cr = render(child, widtho, heighto, st - self.child_st_base, at)
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\image.py", line 261, in render
return wrap_render(self.target, width, height, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\image.py", line 124, in wrap_render
rend = render(child, w, h, st, at)
File "renpy/display/render.pyx", line 103, in renpy.display.render.render (gen\renpy.display.render.c:3319)
cpdef render(d, object widtho, object heighto, double st, double at):
File "renpy/display/render.pyx", line 185, in renpy.display.render.render (gen\renpy.display.render.c:2857)
rv = d.render(widtho, heighto, st, at)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\im.py", line 478, in render
im = cache.get(self)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\im.py", line 200, in get
surf = image.load()
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\im.py", line 950, in load
self.rmap, self.gmap, self.bmap, self.amap)
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\module.py", line 147, in map
*endian_order(dst, rmap, gmap, bmap, amap))
File "C:\Program Files (x86)\Steam\steamapps\common\Everlasting Summer\renpy\display\module.py", line 46, in convert_and_call
function(src, dst, *args)
File "_renpy.pyx", line 159, in _renpy.map (gen\_renpy.c:2065)
TypeError: expected string or Unicode object, int found
Windows-7-6.1.7601-SP1
Ren'Py 6.99.10.1227
Everlasting Summer 1.2
Бог Мальцев запись закреплена
Максим Куракин
Бог, посмотри видео сразу
Скорее всего у тебя были ошибки в коде
Скинь трейс если можешь
Я лично создаю так:
- создаю новый текстовый файл
- меняю название и расширение на .rpy
(к примеру, mod_d4.rpy)
- готово.
Витя, ну не знаю. Я так делаю уже давно, и все в порядке. Редактирую в Notepad++, если кодировка не та - прямо в нем и меняю.
просто .rpy из любого мода скопируй, и удали из него всё кроме строчек init:
$ mods[""]=u"" в "" пиши как называется твой мод
Никита Ведерников ответил Вите
Веня Володарский
запись закреплена
Есть ли какой-то скрипт для перевода текстового файла в код для Ренпая?
А то я сценарий писал в Нотпаде, и определенным образом.
По такому типу.
Или все придется вручную копировать и вставлять в код? Это же задолбаешься.
Николай Зазвонов
Ярик Ланг
Эмм, если ты в notepad ++ работал, то нажимаешь "Сохранить как", а там уже переименовываешь при сохранении фалы в rpy.
Если так делать лень, то берешь, создаешь текстовый файл в папке игры, переименовываешь его в rpy. После заходишь в свои txt файлы, нажимаешь "Ctrl + a", "Ctrl + c", Ctrl + v". Не так уж и сложно.
(Я хз зачем это пишу)) Делать, видимо, нечего) )
Сергей Романов
Ты как перевод создаегь то? Ориг текст меняешь или создаешь поддержку 2 языков?
В любом случае тебе проще будет текстовый редактор разделить на пополам и вставлять
Веня Володарский
Наверное, вы не поняли, что я имею в виду. Адаптировать строчки и имена под Ренпай без ручного копирования. Это возможно?
Веня, если я правильно понял, то ты хочешь переоформить свой произвольно написанный сценарий в код ренпая.
Это возможно и даже не сильно сложно.
Тебе просто нужно написать простенький скрипт (например, на том же питоне), который будет построчно читать твой сценарий и переоформлять прочитанное по правилам ренпая.
Роман Панов
Руслан, 17)как сделать кнопку с рабочей ссылкой:textbutton _("Посетить сайт") action OpenURL("http://vk.com/renpy")
А как сделать что бы она отображалась в игре,вернее в конце игры после титров.
66(6) Выпуск игры или Ответ на вопросы типа:
«как собрать новеллу?»; «как создать .exe файл?»; «как сохранить новеллу, чтобы она открывалась не через Ren'Py?»; «я закончил с новеллой. Куда нажать, чтобы выложить игру?» и т.п.
Так вот, нажать нужно на кнопку "Построить дистрибутивы" (Build Distributions).
Находится она в главном меню launcher'a Ren'Py справа под кнопкой "Навигация по сценарию".
Нажать и следовать инструкциям. Всё.
67) Заставка при запуске игры.
а)Вам нужно зайти в файл script.rpy (в старых версиях) находите строку label start: (с которой вы начинаете печатать текст общения персонажей в игре). Опускаете строку label start: и на его месте печатаете следующее(на черном экране)
label splashscreen:
scene black with dissolve
pause 1
show text "Ваш текст" with dissolve
pause 2
show text "Ваш текст"
pause 2
scene black with dissolve
pause 1
return
Далее прописываем в файле screen
screen main_menu():
python:
if stopm == 1:
renpy.music.queue("music/mainmenu.mp3",channel = "music", fadein = 1)
Далее заходим в script.rpy и пишем после laber start: в начале stop music
если этого не сделать после завершения музыки или игры у вас выйдет ошибка
68) Добавление видео в стартовое меню
Заходим в файл script.rpy и вставляем туда такой текст перед label start:
init python:
style.mm_root.background = None
69) Сжатие ресурсов (для версии 6.99.12 (в противном случае не поддерживает webp) и новее.)
А пока маленькая инструкция по ffmpeg:
Ffmpeg прописывает свой путь в папку bin, именно там находится главный исполняемый файл ffmpeg.exe и именно туда нужно скидывать всё, что нам надо сконвертировать.
-i файл — входящий файл. Его имя и расширение. Я задаю стандартное имя и расширение, так что вы можете переименовать всё сами или использовать решение с батниками.
"1.webp" — выходящий файл.
"newfiles/" — выходящая, УЖЕ СУЩЕСТВУЮЩАЯ, папка. Новую папку не создаёт и ругается, если её нет.
На самом деле ffmpeg очень функциональная программа, но пока она нужна нам только как конвертер.
Картинки
===============
Webp. Не рекомендуется переводить форматы с потерями *.jpg и подобные в webp без потерь. В большинстве случаев это только увеличивает размер картинки.
Без потерь: ffmpeg -i 1.jpg -lossless 1 -compression_level 6 newfiles/1.webp
С потерями: Убирайте "-lossless 1" из кода выше и дописывайте вместо него "-qscale float", где вместо float пишите любое число от 0 до 100 в зависимости от нужного вам качества. 0 — низшее (хотя по сравнению с 0 jpg неплохо и меньше.)
Аудио
===============
С потерями (Opus): ffmpeg -i 1.mp3 -acodec libopus -vn newfiles/1.ogg
или (Vorbis): убирайте из кода выше "-acodec libopus", по умолчанию ogg ассоциируется с vorbis
(-vn удаляет видеоканал, если он имеется, что позволяет ещё сильнее уменьшить вес.)
Видео
===============
Канал видео — vp8, vp9
Канал аудио — opus, vorbis
Контейнер — webm
Наибольшие потери: ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -acodec libopus 1.webm
Настраиваемые потери: ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -crf 0 -b:v 0 -acodec libopus 1.webm
Где:
"-crf 0" значение может быть от 0 до 63, где 0 — лучшее качество. Можно использовать этот параметр если вы ориентируетесь на определённое качество
"-b:v 0" значение означает среднюю скорость потока. Написав "1000K" у вас будет скорость 1000 кбит в секунду, написав "1M" у вас будет скорость 1 мегабит в секунду. Рекомендуется, если вы ориентируетесь на определённый размер видео.
Любой из параметров выше можно использовать как отдельно, так и вместе.
Минимальные потери (не рекомендуется из-за размеров): ffmpeg -i 1.mp4 -vcodec libvpx-vp9 -lossless 1 -acodec libvorbis -q 10 1.webm
Как вариант работы со старыми видео (mpg) можно поступать так:
ffmpeg -i 1.mpg 1.mp4 (видео автоматически обрабатывается кодеком h264, но mp4 не очень хорошо для renpy)
и затем ещё раз, но в свойствах получившегося файла смотрим на среднюю скорость, например получилось 10 мбит/c, значит мы ориентируемся на эту скорость.
ffmpeg -i 1.mpg -vcodec libvpx-vp9 -b:v 10M -acodec libopus 1.webm
Пора бы уже и поговорить
Как мы все знаем “Бесконечное Лето” – это визуальная новелла и весь сюжет в ней разворачивается посредством диалогов персонажей и выборами Главного Героя,
Благодаря движку игры, это было реализовано донельзя просто.
Просто в виде команды пишем следующий текст
Все просто, этот ID говорит нам о том, с кем же сейчас ГГ разговаривает
Для текста от автора ID не нужен
Остальных говорящих вы можете увидеть на прикрепленной картинке да, картинка копипаст
Для примера мы попросим поздороваться каждого из основных говорящих
ID персонажей без определенного имени (Для использования пока имена персонажей не известны):
Больше о изображениях и их появлениях.
Вполне может быть, что по сюжету Вашего мода, может не хватить имеющихся БГ, ЦГ и спрайтов. В таком случае, мы добавим свои. Где искать картинки, спрайты и т.д. – разбирайтесь сами, но вот что с ними делать дальше…
Для начала нам надо объявить изображение в блоке init. Делается это, с помощью объявления переменной image. Покажем на примере. Допустим, мы нашли изображение с видом города и называется оно у нас gorod.jpg Для его объявления, пропишем такую команду:
image gorod = “gorod.jpg”
(Прим.: При условии, что изображение лежит в папке game. Если оно лежит в другом месте, например в папке вашего мода, который в свою очередь находится в папке mods, объявление изображения будет выглядеть так:
image gorod = “mods/nazvanie_moda/gorod.jpg” )
Теперь мы можем использовать имеющееся изображение так-же, как и остальные:
scene gorod with dissolve
или
show gorod with dissolve
Если Вам не хватает стандартных вышеперечисленных команд (cleft, center, fright и т.д.) на положение изображения на экране – не беда. Здесь поможет встроенный в РенПи язык – ATL. Для его использования надо сделать следующее:
Вместо команды at, мы пишем после изображения двоеточие и параметризируем его по следующим командам:
anchor(a, b) – якорь, от которого будут отсчитываться прочие коодинаты. Задаётся десятичными долями.
pos(a, b) – Положение на экране, относительно якоря. Задаётся, как десятичными долями, так и координатами в пикселях.
xpos a – координата горизонтальной оси, так-же задаётся, как десятичными долями, так и координатами в пикселях. Не используется вместе с pos.
ypos a – координата вертикальной оси. Свойства, как и у xpos.
align(a, b) – Положение на экане, относительно якоря и собственного размера изображения.
xalign и yalign – аналогично предыдущему примеру.
Для начала этих трёх команд нам хватит, с их помощью мы сможем разместить изображение в любом месте экрана.
Покажем на примере.
Разместим изображение нашего города ровно по центру экрана. Для этого мы поставим якорь на середине экрана, и укажем позицию.
Что за странные циферки? Ничего не понятно!
Сейчас объясним.
Возьмём наши координаты pos(0.5, 0.5), где первая цифра – xpos (положение по горизонтали), а вторая ypos (положение по вертикали).
Весь экран условно делится на части, где 0.0 – крайняя левая часть, а 1.0 – крайняя правая (по аналогии верхняя и нижняя). Соответственно, наше 0.5 – это середина. Назревает вопрос. Можно ли использовать отрицательные числа, и числа больше одного? Да. Но в этом случае изображение будет вылезать за пределы экрана.
У align назначение похожее, но немного отличается. Этот элемент, помимо указанных координат, использует собственный размер изображения. Для примера:
Если при якоре (0.5, 0.5) мы зададим позицию pos(1.0, 0.5) – у нас пропадёт половина изображения, ибо точкой его появления будет указан край экрана. С align ситуация обстоит иначе. При использовании align(1.0, 0.5) изображение прижмётся к краю экрана, но не исчезнет.
При назначении позиции координаты pos и align можно комбинировать.
Давайте, для примера выведем спрайт улыбающейся Мику слева экрана.
Так-же мы можем заранее назначать позиции. Давайте повторим предыдущий пример, но назначим всё заранее. Для этого реализуем переменную transform в блоке init:
После этого мы можем использовать её, так-же, как и остальные.
Очень и очень многое. Допустим, анимации.
Вот стоит у нас слева на экране Мику, объявленная в прошлом блоке, но вдруг появилась Ульяна, и Мику из вежливости решила подвинуться чуть правее. Как мы это сделаем? Можно просто задать координаты положения, и Мику “телепортируется” туда, но разве это красиво? Не. У нас другие методы.
Смена положения.
Для смены положния существует 4 метода: linear, ease, easein, easeout. Для начала нам понадобится только linear. Как он работает? Очень просто. После linear мы пишем время в секундах, а после новые координаты в системе ATL.
Пример. Созданим перемещение к правому краю экрана:
Теперь добавим это в наш код.
show mi smile pioneer far at sleva_na_ekrane with dissolve mi “Привет, как дела?” show mi smile pioneer far at peremeshenie mi “Ой, Ульяна, я тебя не заметила. Давай я подвинусь.”
В одной трансформации можно создавать несколько анимаций, а так-же зацикливать их. Для зацикливания используется команда repeat и после неё пишется количество повторов. Если число не указано, повторы будут бесконечно.
Например. Добавим такую трансформацию:
И импортируем её в код:
show mi smile pioneer far at sleva_na_ekrane with dissolve mi “Привет, как дела?” show mi smile pioneer far at peremeshenie mi “Ой, Ульяна, я тебя не заметила. Давай я подвинусь.” show mi smile pioneer far at tuda_syda mi “А теперь мне что-то побегать захотелось.”
Как можно украсить спрайты, bg и cg
Мы можем показать спрайты, bg и cg с некоторым замедлением, плавно
Так же есть еще несколько эффектов, о которых речь пойдет далее, некоторые из эффектов можно применить не только к изображениям, но и даже друг к другу!
Чтобы показать наши картиночки более красиво для человеческого глаза, мы можем использовать специальный атрибут. Это будет выглядеть примерно так:
Атрибутов для плавности 6, они отличаются лишь своей скоростью.
dspr – 0,2 сек – Самый быстрый, на практике не особо заметен
dissolve – 1 сек – Средняя скорость, считаю оптимальной для смены cg на bg и наоборот и для эмоций спрайтов
dissolve2 – 2 сек – Самая плавная картинка, считаю хорошим вариантом для переходов между локациями лагеря
dissolve_fast – 0.5 сек.
hell_dissolve – 50 секунд – на практике не особо применим, но вдруг пригодится.
dissolve_long – 100 секунд.
Так же можно группировать несколько обьектов для одновременного начала эффекта
В приведенном примере мы попадем в ночной автобус и перед нами предстанет улыбающаяся Славя, и все это с задержкой в 2 секунды.
Так же атрибут плавности может применяться к другим эффектам.
Если все вышеприведённые примеры Вас не устраивают, можно добавить свой атрибут плавности. Для этого, пропишите его в блоке init.
После этого мы можем использовать наш переход, так-же, как и все остальные.
Я более чем уверен, что вы видели эффект того, как иногда ГГ моргает или вовсе закрывает глаза. Мы можем реализовать подобную возможность!
show blink – Закрыть глаза
show unblink – Открыть глаза
show blinking – Моргание
Будьте осторожны: blink и unblink это разные эффекты, они не могут отменить друг друга
Как открыть глаза:
Так же к эффектам моргания можно применить атрибут плавности.
Как украсить речь персонажей?
В игре вы встречались с тем, что некоторые слова во фразах персонажей были как-то выделены или вовсе были в ковычках. Для этого используются специальные теги.
Как мы уже знаем, ковычки ограничивают реплики персонажей, так как же нам использовать их внутри этих реплик?
Чтобы ковычки не учитывались игрой, перед ними нужно поставить
Как мне показать где происходят действия героев?
В самой игре при смене местоположения нашего ГГ меняется и картинка на фоне (bg)
Так как же нам показать где сейчас наш герой?
А делается это при помощи команды scene bg
Так же в архиве приложен текстовый файл из которого сразу можно скопировать нужную строку
Персонажи в игре – не что иное, как тоже картинки, только именуются они спрайты.
Перечислять их все на буду, но скажу, что их более 350
Вызываются все спрайты командой show
Имя спрайта обычно состоит из нескольких слов, разделенных пробелами
В оригинальной игре имя персонажа совпадает с ID говорящего из предыдущего раздела этого руководства
Если персонаж уже на экране, то повторное использование show будет менять эмоцию и/или одежду
Всего в игре 7 позиций где может находиться спрайт:
fleft, left, cleft, center, cright, right, fright
На приведенном скриншоте были использованы команды:
scene bg ext_bus_night show dv angry pioneer2 at left show un smile pioneer at right show mi cry_smile pioneer at cleft show sl serious pioneer at cright show mt rage panama pioneer at center
Так же можно показать персонажа ближедальше. Для этого можно воспользоваться атрибутом close/far
На втором скриншоте как раз были использованны эти атрибуты. Команды:
scene bg ext_bus_night show dv angry pioneer2 far at left show un smile pioneer far at right show mi cry_smile pioneer at cleft show sl serious pioneer at cright show mt rage panama pioneer close at center
Для того, чтобы убрать персонажа воспользуйтесь
Если вы хотите вслед за этим сменить декорации, то прописывать hide для каждого персонажа не обязательно, команда scene сама их уберет
Тут принцип как и с bg, только надо использовать scene cg
Примеры думаю не нужны.
Как добавить звук?
Наверное вы и сами слышали, что в “Совенке” никогда не бывает тихо, где-то играет приятная музыка, иногда мы слышим стуки в двери, три раза в день, звук горна собирает всех обитателей у столовой.
Для того чтобы проигрывания музыки используется всего две команды
play music music_list[“”] – Начинает проигрывать указанную музыку
и
stop music – Завершает проигрывание музыки
Послушать эту музыку можно прямо в игре, зайдя в раздел Галерея
Для проигрывания прочих звуков нам понадобится все та же команда play, только немного в другом виде
play ambience ambience_ – Игра включает нам выбранный звук
и
stop ambience – Выключает его
Увы, подобрать нужный звук вам поможет лишь базовое знание Английского языка и “метод научного тыка”
Использование карты
Иногда по нуждам сюжета необходимо дать игроку выбор куда ему пойти, использование для этого обычного меню выбора выглядит несколько не эстетично, так давайте же научимся ориентироваться в “Совенке” при помощи карты!
Чтобы дать игре понять. когда развернуть перед игроком карту необходимо всего несколько простых команд.
Далее заполняем конструкцию set_zone()
Где первым значением будет выделенная на карте зона, а вторым – лейбл, куда прыгать, при клике на неё.
Вот список всех зон и как они обозначены в игре:
“me_mt_house” – “Мой домик”
“estrade” – “Эстрада”
“music_club” – “Музклуб”
“square” – “Площадь”
“dining_hall” – “Столовая”
“sport_area” – “Спорткомплекс”
“beach” – “Пляж”
“boat_station” – “Лодочный причал”
“clubs” – “Клубы”
“library” – “Библиотека”
“medic_house” – “Медпункт”
“camp_entrance” – “Ворота в лагерь”
“forest” – “о. Лес”
т.е. чтобы при нажатии на клубы мы прыгали на лейбл mymodlabel2 (название, примера ради) нужно реализовать такую конструкцию:
И в конце, выводим саму карту командой:
Показываю пример полностью. Допустим нам нужны три зоны. Сцена, Муз. клуб и Пляж, и каждая ведёт к совим лейблам label1, label2 и label3, для этого мы делаем всё то, что я уже описал выше:
$ disable_all_zones() $ set_zone(“estrade”, “label1”) $ set_zone(“music_club”, “label2”) $ set_zone(“beach”, “label3”) $ show_map()
Где мой мод? Почему передо мной пустой файл?
Весь моддинг “Бесконечного Лета” заключается в писании магических фраз в файлах .rpy, которые игра будет читать и делать то что мы захотим (но конечно же есть ограничения)
Подожди, писать заклинания еще рано, сначала нужно понять, как правильно расставлять слова для эффекта
Структура файла выглядит примерно так:
Команды в блоке ВСЕГДА имеют отступ в 4 пробела относительно команды говорящей нам о начале блока.
Есть несколько команд начинающих блок, пока стоит лишь запомнить то, что после команды, начинающей блок всегда ставится двоеточие (:)
На данном этапе создания мода нам понадобится лишь одна блоковая команда
label : – Обычно используется для разделения мода на части, для удобной навигации между ними
Существует 2 варианта перейти от одного блока к другому
Вариант 1 – “Прыжок”
В этом варианте сначала выполняется первый блок, а затем второй. При этом используется команда
Вот уже знакомый нам пример:
В этом случае если написать в блоке vasya_mod_d1 что либо после jump’a, то игра просто пропустит это
Вариант 2 – “Вызов”
В отличии от прыжка, при использовании этого варианта после полного выполнения блока на который переходит игра, она вернется в первоначальный и продолжит его выполнение после команды. Команда для этого:
Ну и как же без примера:
Окончание блоков, переход к которым осуществляется именно этим методом имеет некоторые особенности, о которых можно узнать дальше
Если к этому блоку ведут jump’ы, то конец блока можно ничем не выделять, если только это не последний блок в вашем моде (Последний блок 1/x концовки). В ином же случае последней командой блока должна быть команда return. Зачем? В случае если это последний блок, чтобы игра могла закончить обработку мода и вернуться в главное меню. Если же на блок привела команда call, то игре просто необходимо знать, когда вернуться в предыдущий блок.
Получается что наш пример call не будет работать и нам придется привести его к такому виду:
Из всего этого можно понять то, что ваш мод запускается именно методом вызова, где блок из которого вызывают – главное меню игры.
Читайте также: