Перейти к содержанию
Обновление форума
Опубликовано
comment_1946405

Являясь не только анимешником, но и геймером, я большой любитель визуальных новелл. Видя их достаточно простое в большинстве случаев исполнение, я давно задумывался о возможности создания новелл своими руками. И вот недавно, бродя по просторам Сети, я наткнулся на движок визаульных новелл (), берущий большую часть технических трудностей этого процесса на себя, и к тому же очень простой в обращении. И теперь я хочу поделиться своим открытием со всеми.

Я взял на себя смелость и создал локализацию игрового интерфейса движка (файл template\localize.rpy) а также перевёл на русский демонстрацию. Всё это согласованно с создателем движка и включено в распространяемый архив, доступный с [url="http://www.renpy.org/wiki/renpy/rus" target="_blank" rel="nofollow">Русской Странички движка Ren'Py

Также я написал небольшое руководство по быстрому старту и маленькую игру-пример с некоторой информацией по визуальным новеллам по этому руководству, доступные там же

Спойлер
(не ждите ничего сверхъестественного. Сделана на скорую руку, только как пример. Приведённая в игре информация может быть предметом дискуссии. Если считаете, что она неточна -- милости прошу.)

 

От всей души надеюсь, что вас это заинтересует.

И помните, теперь судьба визуальных новелл на русском и в ваших руках!

 

ЗЫ. ОГРОМНАЯ просьба: протестируйте демо и файл локализации на предмет очепяток и отпишитесь сюда. Пожалуйста!

Изменено пользователем Гость (смотреть историю редактирования)

Цензуре - твёрдое и решительное "НЕТ"!!!

YesToFreedom.org

  • Ответов 1 тыс
  • Просмотры 379,6 тыс
  • Создана
  • Последний ответ

Топ авторов темы

Популярные посты

  • Рен'пи ожидал конец строки, а обнаружил двоеточие... (должно быть просто <jump dush>) Двоеточие ставится в конце первой строки блока - оно показывает, что последующие строки этого блока должны и

  • Что ж, не думаю что это хорошо браться с середины, но надо же хоть как то начинать)) К концку недели ждите первый перевод... наверно по порядку, так что - ATL. Может кому пример подам ^_^   Кому инте

  • Вот файл немного доделанного (не полностью) перевода для новой версии Ren'Py 6.14.1 (Откуда взял первоначальный файл не помню. Может и с этого форума ) Скачать   Положить в <Ren'Py 6.14.1/launcher/

Изображения в теме

Рекомендуемые сообщения

Опубликовано
comment_2813502

Я наверное уже всех достал но никак не могу понять в чём тут проблема

http://slav-online.at.ua/other/aaa1.png

код вроде правильный а персонажи не хотят занимать нужные позиции на экране выходит такая фигня

http://slav-online.at.ua/other/aaa2.png

да и спасибо за splashscreen_effect

 

http://slav-online.at.ua/_tbkp/33.gifААА персонаж за спиной не в форму одета а я обрезал края где она в форме

http://slav-online.at.ua/_tbkp/18.gifя нашёл причину сильно большие отступы прозрачного фона на изображении персонажа. Всем спасибо

Изменено пользователем tynmax111 (смотреть историю редактирования)

Опубликовано
comment_2814397

Мне интересно, меню загрузки/сохранения можно сделать с помощью двух фонов, как главное меню?)

Ну или трёх, с дополнительным фоном, который показывает неактивные кнопки.

В этой теме http://lemmasoft.renai.us/forums/viewtopic.php?f=51&t=14237 показано создание меню, но там куча картинок, ничерта не понятно хД

Пробовала сделать с целым фоном, всё съезжает. Подозреваю, что где-то создана сетка или дополнительные области. Просветите, нэ)

Опубликовано
comment_2814435

Хм, в этой теме как раз и показано меню сохранения/загрузки из трех картинок...

Если при использовании imagemap'ов картинки начинают "глючить", то поможет удаление постоянных данных ("Delete persistent").

(или дело опять в использовании прозрачных картинок для imagemap'ов)

Опубликовано
comment_2814512

Хм, в этой теме как раз и показано меню сохранения/загрузки из трех картинок...

Если при использовании imagemap'ов картинки начинают "глючить", то поможет удаление постоянных данных ("Delete persistent").

(или дело опять в использовании прозрачных картинок для imagemap'ов)

 

Нет, там есть какие-то дополнительные мелкие картинки, например для переключателя страниц, а я не хочу это) И плюс нестандартные возможности, назначены кнопки клаиватуры для всех действий и всё такое.

Опубликовано
comment_2814578

Нет, там есть какие-то дополнительные мелкие картинки, например для переключателя страниц, а я не хочу это) И плюс нестандартные возможности, назначены кнопки клаиватуры для всех действий и всё такое.

 

Ну, начинается - хочу/нехочу... (шутка)

По поводу кнопок клавиатуры - если вам не нужны такие возможности, то просто удалите все строки

key ...

У вас все слоты сохранения будут на одной странице? Если да, то переключение между страницами в file_picker'е вам не понадобится - удалите эту часть кода

           hotspot (528, 39, 14, 23) clicked FilePage(1)
           hotspot (566, 40, 22, 23) clicked FilePage(2)
           hotspot (611, 39, 18, 23) clicked FilePage(3)
           hotspot (653, 40, 18, 21) clicked FilePage(4)
           hotspot (694, 40, 17, 22) clicked FilePage(5)
           hotspot (735, 41, 21, 20) clicked FilePage(6)
           hotspot (776, 39, 22, 23) clicked FilePage(7)
           hotspot (819, 39, 20, 23) clicked FilePage(8)
           hotspot (860, 39, 23, 24) clicked FilePage(9)
           hotspot (900, 39, 27, 23) clicked FilePage(10)

(никаких дополнительных картинок для них нет - это мелкие белые циферки на темном фоне, которые просто нарисованы на картинках, используемых imagemap'ом)

 

А кнопки возврата в главное меню и вызов настроек - они у вас сделаны в отдельном окне (как в варианте по умолчанию screen navigation)? Если да, то можете удалить и эту часть кода

           hotspot (523, 68, 62, 31) action ShowMenu("load")
           hotspot (589, 70, 59, 29) action ShowMenu("save")
           hotspot (653, 70, 60, 31) action Help()
           hotspot (787, 72, 62, 27) action Quit()
           hotspot (718, 71, 65, 27) action MainMenu()
           hotspot (877, 69, 62, 29) action Return()

 

 

Останется что-то похожее на

##############################################################################
# Save, Load
#
# Screens that allow the user to save and load the game.
# http://www.renpy.org/doc/html/screen_special.html#save
# http://www.renpy.org/doc/html/screen_special.html#load

# Since saving and loading are so similar, we combine them into
# a single screen, file_picker. We then use the file_picker screen
# from simple load and save screens.
   
screen load_save_slot:
   $ file_text = "%2s. %s\n  %s" % (
                       FileSlotName(number, 4),
                       FileTime(number, empty=_("Empty Slot.")),
                       FileSaveName(number))

   add FileScreenshot(number) xpos 61 ypos 69 
   text file_text xpos 215 ypos 92 size 18 color "#261d0c"
   
screen file_picker:

   imagemap:
           ground "ui/sl_ground.png"
           idle "ui/sl_idle.png"
           hover "ui/sl_hover.png"
           selected_idle "ui/sl_idle.png"

           hotspot (22, 121, 444, 235) clicked FileAction(1):
               use load_save_slot(number=1)
           hotspot (483, 121, 444, 235) clicked FileAction(2):
               use load_save_slot(number=2)
           hotspot (22, 356, 444, 235) clicked FileAction(3):
               use load_save_slot(number=3)
           hotspot (483, 356, 444, 235) clicked FileAction(4):
               use load_save_slot(number=4)
               
   
screen save:
   # This ensures that any other menu screen is replaced.
   tag menu

   use file_picker
   add "ui/sl_save.png"
   use navigation

screen load:
   # This ensures that any other menu screen is replaced.
   tag menu

   use file_picker
   add "ui/sl_load.png"
   use navigation

Изменено пользователем Алекс__ (смотреть историю редактирования)

Опубликовано
comment_2814601
А кнопки возврата в главное меню и вызов настроек - они у вас сделаны в отдельном окне (как в варианте по умолчанию screen navigation)? Если да, то можете удалить и эту часть кода

 

То есть в отдельном?)

 

Вот у меня такое щас:

http://img.by/i/7MUxn.jpg

 

В скрин_навигейшн так:

 

screen navigation:

   # The background of the game menu.
   window:
       style "gm_root"

   # The various buttons.
   imagemap:
       ground "ui/sl_ground.png"
       idle "ui/sl_idle.png"
       hover "ui/sl_hover.png"
       
       hotspot (579, 410, 272, 43) action Return()
       hotspot (602, 315, 142, 47) action ShowMenu("preferences")
       hotspot (603, 366, 137, 38) action ShowMenu("save")
       hotspot (579, 410, 164, 42) action ShowMenu("load")
       hotspot (579, 410, 163, 38) action MainMenu()
       hotspot (614, 500, 125, 36) action Help()
       hotspot (618, 555, 121, 37) action Quit()

 

То есть таки действительно там не одним фоном?) Эти кнопки в каком-то другом фрейме и тд?

Опубликовано
comment_2814630

В примере на ЛеммаСофт все кнопки нарисованы в одном imagemap'е. Если у вас сделан отдельный скрин с кнопками для навигации (т.е. нарисованы только кнопки справа, а слева прозрачный фон), то пример кода из моего поста должен сработать.

Так, как у вас сделаны меню?

Опубликовано
comment_2814649

В примере на ЛеммаСофт все кнопки нарисованы в одном imagemap'е. Если у вас сделан отдельный скрин с кнопками для навигации (т.е. нарисованы только кнопки справа, а слева прозрачный фон), то пример кода из моего поста должен сработать.

Так, как у вас сделаны меню?

 

У меня всё одним фоном, да.

Однако:

add "ui/sl_save.png"
...
add "ui/sl_load.png"

 

Этих картинок у меня нет, что это?)

Опубликовано
comment_2814664
Хороший вопрос... скорее всего это картинки с прозрачным фоном и надписью "save"/"load" соответственно, которые отображаются поверх меню, чтобы было понятно на каком именно экране находится игрок (оба экрана абсолютно одинаковы - оба используют file_picker, и только надпись поможет их различить). Если у вас также все нарисовано на одном imagemap'е, то надо использовать код из примера на ЛеммаСофт, т.е. все активные области (для перехода на страницы и для навигации к другим меню) должны быть указаны. Также у вас есть области для перехода к следующей странице и к предыдущей, для перехода к страницам быстрого и авто сохранения - действия для этих активных областей можно списать из экрана file_picker, который используется по-умолчанию.
Опубликовано
comment_2814722

Если кому-нибудь интересно - посмотрите перевод документации по Музыкальной Комнате на предмет ошибок, неточностей и т.п. (оригинал здесь - http://www.renpy.org...html#music-room)

 

 

Музыкальная Комната (МК)

 

МК – это экран, который позволяет пользователю выбрать и воспроизвести музыкальные треки из игры. Изначально, эти треки могут быть заблокированы, когда игрок впервые начинает прохождение игры, и будут разблокированы по мере того, как пользователь прослушивает музыку в процессе игры.

 

МК управляется экземпляром класса MusicRoom. В игре может быть больше одного экземпляра MusicRoom, что позволяет сделать несколько МК. Создание МК состоит из следующих шагов:

1. Создание экземпляра
MusicRoom
. В конструкторе
MusicRoom
задаются параметры, определяющие канал, в котором будет проигрываться музыка, и длительность усиления / затухания музыки.

2. Добавление музыкальных файлов в этот экземпляр.

3. Создание экрана, который использует этот экземпляр
MusicRoom
для создания действий (
action
) для кнопок (
button
), графических кнопок (
imagebutton
) и активных зон (
hotspot
). Этими действиями могут быть выбор трека, следующий / предыдущий трек, или остановка и воспроизведение музыки.

 

Заметим, что используемые действия являются элементами экземпляра
MusicRoom
, так что если экземпляр MusicRoom был назван mr, то использование действия «воспроизвести» будет выглядеть так –
mr.Play(“track1.ogg”)
.

4. Добавим экран МК в главное или дополнительное меню.

Вот пример первых трех шагов:

init python:

   # Шаг 1. Создаем экземпляр MusicRoom.
   mr = MusicRoom(fadeout=1.0)

   # Шаг 2. Добавляем файлы музыки.
   mr.add("track1.ogg", always_unlocked=True)
   mr.add("track2.ogg")
   mr.add("track3.ogg")


# Шаг 3. Создаем экран музыкальной комнаты.
screen music_room:

   tag menu

   frame:
       has vbox

       # Кнопки для воспроизведения каждого трека.
       textbutton "Track 1" action mr.Play("track1.ogg")
       textbutton "Track 2" action mr.Play("track2.ogg")
       textbutton "Track 3" action mr.Play("track3.ogg")

       null height 20

       # Кнопки, позволяющие переключать треки.
       textbutton "Next" action mr.Next()
       textbutton "Previous" action mr.Previous()

       null height 20

       # Кнопка, позволяющая пользователю покинуть МК.
       textbutton "Main Menu" action ShowMenu("main_menu")

   # Начнем воспроизводить музыку при входе в МК.
   on "replace" action mr.Play()

   # При выходе из МК вернем музыку главного меню.
   on "replaced" action Play("music", "track1.ogg")

Шаг 4 будет варьироваться в зависимости от того как структурирована ваша игра, один из вариантов – это добавление следующей строки кода

textbutton "Music Room" action ShowMenu("music_room")

в экран главного меню.

 

Используя функцию Preferences(), а именно Preferences("music volume"), можно добавить на экран МК ползунок громкости.

 

class MusicRoom(channel='music', fadeout=0.0, fadein=0.0)

Музыкальная комната, содержащая наборы песен, которые могут быть разблокированы пользователем, и действия для их последовательного воспроизведения.

 

channel

Канал, который будет использовать МК.

fadeout

Время (в секундах), в течение которого будет происходить затухание текущей мелодии при смене трека.

fadein

Время (в секундах), в течение которого будет происходить усиление звука новой мелодии при смене трека.

Next(self)

Действие МК, которое приводит к воспроизведению следующего разблокированного трека в списке воспроизведения.

Play(filename=None)

Воспроизведение музыки. Если задано название файла (
filename
), то начинается его воспроизведение. В противном случае, воспроизведение текущего музыкального файла начинается заново (если он разблокирован), или начинается воспроизведение первого файла.

Если задано название файла (
filename
), то кнопки, содержащие данное действие, будут неактивны, если данный файл заблокирован, и будут отображаться как выбранные во время воспроизведения файла.

Previous(self)

Действие, которое воспроизводит предыдущий разблокированный файл в списке воспроизведения.

Stop(self)

Останавливает музыку.

add(filename, always_unlocked=False)

Добавляет названия файлов музыки в МК. Данные файлы будут воспроизводиться в том порядке, в каком они добавлены (при условии, что они разблокированы).

always_unlocked

Если значение Истина (
True
), то файл будет постоянно разблокирован. Это позволяет показать музыкальный файл в МК до того как он был воспроизведен в игре.

is_unlocked(filename)

Возвращает значение Истина (
True
), если файл был разблокирован (или разблокирован всегда) и Ложь (
False
), если файл все еще заблокирован.

 

Upd: Статья добавлена на русскую вики-страничку Ren'Py (http://www.renpy.org/wiki/renpy/rus )

Изменено пользователем Алекс__ (смотреть историю редактирования)

Опубликовано
comment_2815833

У меня снова вопрос... А как в новелле сделать так, чтобы персонажи, когда меняют эмоции, не закрывали друг друга? Если их, например, трое на экране, у одного изменилась эмоция и он начинает закрывать другого. Когда эмоции начинает менять другой, то он начинает закрывать первого.

Как закрепить персонажа, чтобы когда менялось его изображение, он не закрывал другого?

Надеюсь, понятно объяснила. И извиняюсь, если вопрос уже был.

Опубликовано
comment_2816033

Вопрос - как вы сделали объявление ваших картинок?

Если так

image pic_a:
   "eileen_concerned.png"
image pic_b:
   "eileen_vhappy.png"

То это две разных картинки, они могут появляться на экране одновременно и последняя из появившихся картинок будет отображаться поверх остальных.

 

Если же так

image e concerned:
   "eileen_concerned.png"
image e vhappy:
   "eileen_vhappy.png"

То эти картинки будут замещать друг друга на экране, т.к. в их названиях присутствует общий тэг - "e". В этом случае все должно работать так как вам надо.

Опубликовано
comment_2817583

У меня снова вопрос...

Решила, наконец, поставить музыку в новеллу. Получилось. Но когда я выхожу в меню, а потом возвращаюсь, то музыка пропадает. Это ещё происходит и тогда, когда я загружаю игру на том моменте, где должна играть музыка. А вот если попасть на начало, то всё в порядке.

Как это исправить?

Изменено пользователем Tansia (смотреть историю редактирования)

Опубликовано
comment_2817812
Вопрос - как вы начинаете воспроизводить музыку (покажите часть кода - в каком блоке, какой командой, настраивали ли музыку главного и игрового меню)?
Опубликовано
comment_2817822

Пишу в скрипте просто play sound "Shionari II.mp3".

В блоке init не объявляла.

На счёт того, настраивала ли музыку... это не знаю. Видимо нет.

Опубликовано
comment_2817838

Команда sound воспроизводит звуковой файл один раз, для проигрывания музыки используйте команду music

play music "Shionari II.mp3"

Опубликовано
comment_2817949

Спасибо, вроде получилось.

В первый раз использовала эту команду, но почему то не вышло. Наверно просто ошибка где-то была.

  • 3 недели спустя...
Опубликовано
comment_2821946

Решил заглянуть на форум и скинуть ссылку на на наш проект "Легенды Алькиона" - http://eliont-twilight.blogspot.ru/

Ну и пожалуй, далее позаглядываю, по крайней мере в эту тему =)

Не закрывай рта тем кто открывает тебе глаза.

И твердо встав на ноги, не забывай тех, кто поднимал тебя на руках.

  • 3 недели спустя...
Опубликовано
comment_2826129

Всем привет, вот какой у меня вопрос… Отчаялась разобраться сама, может, кто подскажет.

Как сделать на движке эффект парящей в воздухе пыли? Например, как в

, 6:30. Я так понимаю, что через SpriteManager, но вот как заставить частицы двигаться по рандомной траектории?

 

Еще интересно, как в Cinders были сделаны «светлячки» (

, 1:30, те, что движутся кругами, оставляя световой след за собой) и мерцание при появлении текста. Ну да это скорее для общего образования, а вот вопрос с пылью очень животрепещущий. Отозвавшемуся - вагон кексиков за мой счет и вечная благодарность!
Опубликовано
comment_2826137

    class StarField(object):

       def __init__(self):

           self.sm = SpriteManager(update=self.update)

           # A list of (sprite, starting-x, speed).
           self.stars = [ ]

           # Note: We store the displayable in a variable here.
           # That's important - it means that all of the stars at
           # a given speed have the same displayable. We render that
           # displayable once, and cache the result.

           d = Transform("star.png", zoom=.02)
           for i in range(0, 50):
               self.add(d, 20)

#            d = Transform("star.png", zoom=.025)
#            for i in range(0, 25):
#                self.add(d, 80)

#            d = Transform("star.png", zoom=.05)
#            for i in range(0, 25):
#                self.add(d, 160)

#            d = Transform("star.png", zoom=.075)
#            for i in range(0, 25):
#                self.add(d, -320)

#            d = Transform("star.png", zoom=.1)
#            for i in range(0, 25):
#                self.add(d, -640)

#            d = Transform("star.png", zoom=.125)
#            for i in range(0, 25):
#                self.add(d, 1280)
           
       def add(self, d, speed):
           s = self.sm.create(d)

           start = renpy.random.randint(0, 840)
           s.y = renpy.random.randint(0, 600)

           self.stars.append((s, start, speed))
           
       def update(self, st):
           for s, start, speed in self.stars:
               s.x = (start + speed * st) % 840 - 20
               s.y = (s.y+renpy.random.randint(-1,1)) % config.screen_height
           return 0

 

Обрати внимание на строчку s.y = (s.y+renpy.random.randint(-1,1)) % config.screen_height - случайное изменение координаты по вертикали на плюс или минус пиксель.

Этот код из обучалки кстати - renpy-6.14.1-sdk\tutorial\game\tutorial_sprite.rpy.

 

Со вторым случаем - не знаю. Может там тоже спрайты, а может SplineMotion. Насчёт следа нет идей.

Не закрывай рта тем кто открывает тебе глаза.

И твердо встав на ноги, не забывай тех, кто поднимал тебя на руках.

Опубликовано
comment_2826299

Ооо, огромное спасибо! Это действительно похоже на то, что нужно. Только такой момент: частицы движутся очень резко, я так понимаю, потому, что они меняют координату по вертикали постоянно и случайным образом. Нельзя ли их заставить двигаться более плавно? Еще я попробовала тем же способом задать им случайное движение по х, и чтобы при этом они все одновременно медленно смещались вверх:

 

        def update(self, st):
           for s, start, speed in self.stars:
               s.x = (start + speed + renpy.random.randint(-1,1)) % 840 - 20
               s.y = (s.y - 0.2 + renpy.random.randint(-1,1)) % config.screen_height
           return 0

 

Работает, но, опять же, точки припадочно трясутся и двигаться плавно не хотят :) Я нашла здесь такой код для движения по спирали:

 

        def add(self, d, speed):
           s = self.sm.create(d)
           start = renpy.random.randint(0, 840)
           self.stars.append((s, start, speed))
           
       def update(self, st):
           for s, start, speed in self.stars:
               s.x =512+start*math.cos(st)*speed
               s.y =384+start*math.sin(st)*speed
               ##  s.x = (start + speed * st) % 840 - 20
               ##  s.y = (start + speed * st) % 840 - 20
           return 0

 

Через math.cos и math.sin получается задать плавное движение по собственно синусоиде и по кругу, но проблема в том, что движутся все частицы вокруг одного центра, а мне нужно, чтобы они плавали каждая сама по себе.

Извиняюсь, если вопросы глупые, но этот SpriteManager сводит меня с ума х)

Опубликовано
comment_2826306

Не глупые =) СпрайтМенеджер действительно нечто.

 

Кажись получилось.

 

            d = Transform("star.png", zoom=0.1)
           for i in range(0, 10):
               self.add(d, 1)

           d = Transform("star.png", zoom=.2)
           for i in range(0, 10):
               self.add(d, 2)

           d = Transform("star.png", zoom=.3)
           for i in range(0, 10):
               self.add(d, 3)

           d = Transform("star.png", zoom=.4)
           for i in range(0, 10):
               self.add(d, 4)
           
       def add(self, d, speed):
           s = self.sm.create(d)
           # дополнительный модификатор к скорости, я так понял
           start = renpy.random.randint(10, 50)
           # рандомизируем радиусы вращения
           modifier = renpy.random.uniform(-0.9,0.9)
           # разные точки центра окружности
           x = renpy.random.randint(100, 700)
           y = renpy.random.randint(100, 500)
           self.stars.append((s, start, speed, modifier, x, y))
           
       def update(self, st):
           for s, start, speed, modifier, x, y in self.stars:
               s.x = (x + start * math.cos(st*modifier) * speed)
               s.y = (y + start * math.sin(st*modifier) * speed)
           return 0

Не закрывай рта тем кто открывает тебе глаза.

И твердо встав на ноги, не забывай тех, кто поднимал тебя на руках.

Опубликовано
comment_2827106

Ооо, ты просто волшебник! :wub:

Огромное спасибо за помощь, это действительно то, что нужно, я бы сама точно не разобралась.

Опубликовано
comment_2827139
Пожалуйста =) А тебе спасибо за наводку на рецепт с синусами/косинусами.

Не закрывай рта тем кто открывает тебе глаза.

И твердо встав на ноги, не забывай тех, кто поднимал тебя на руках.

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

Последние посетители 0

  • Ни одного зарегистрированного пользователя не просматривает данную страницу

Важная информация

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.