• Страница 1 из 1
  • 1
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Как сделать плавное появление текста? (Подробности в теме.)
Как сделать плавное появление текста?

progxaker
Дата: Понедельник, 02.11.2020, 15:38 | Сообщение # 1
Проверенный
Сообщений: 41
Награды: 2
Может кто, поможет. Хотелось бы сделать плавное появление текста(а не то что обычно в Ren'Py - печатная машинка). Как пример, смог найти это видео.



К сожалению, участники обсуждающие тот же вопрос в посту на LemmaSoft, где и было это видео, не смогли найти решение. Но то было лет 10 назад.


"Ничто не может оставаться таким же вечно. И вещи, приносящие радость и счастье, тоже. Ничто не остается неизменным." - Фурукава Нагиса, CLANNAD


СОНЦЕ
Дата: Вторник, 03.11.2020, 16:59 | Сообщение # 2
Разработчик
Сообщений: 230
Награды: 32
Вообще то вот этот пост в указаной теме красноречиво намекает на решение. Просто без реализации. Вот реализация, если угодно. Невероятно тупая и на практике неприменима, но доказывает концепт и задает вектор для ориентира nbaka


Код


transform appear(paus):
    paus*.02
    alpha 0.0
    linear 1.0 alpha 1.0

init python:
    for c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ':
        for i in range(80):
            nameat = c+str(i)+'_at'
            renpy.image('%s'%nameat,At(Text('%s'%c),appear(i)))
    
    def appear_text(what):
        result = ''
        tag = False
        for i,c in enumerate(what):
            if tag or c == ' ':
                result+=c
            elif c == '}':
                result+=c
                tag = False
            elif c == '{':
                result+=c
                tag = True
            else:
                result += '{image='+c+str(i)+'_at}'
        return result
        

screen say(who, what):
    style_prefix "say"

    window:
        id "window"
       

        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what" xpos 5000   
        text appear_text(what) slow True

label main_menu:
    return

label start:
    'Кажется мне удалось это сэмулировать невероятно тупым костылём'
    'Если реально будете применять сделайте поизящнее пожалуйста'
    return

BattlePeasant
Дата: Вторник, 03.11.2020, 18:02 | Сообщение # 3
Проверенный
Сообщений: 31
Награды: 0
Я не хакер, поэтому не понимаю, а почему нельзя переписать функцию, выводящую текст на экран? На C можно же написать свою printf(), чтобы выводить тусклые буквы по таймеру, а затем перекрашивать. Неужели на питоне невозможно вклиниться? Вообще говоря, это ужас, то что выше предлагается.

RobotZero
Дата: Вторник, 03.11.2020, 18:12 | Сообщение # 4
Друг сайта
Сообщений: 135
Награды: 7
BattlePeasant, ты предлагаешь копаться в самой либе RenPy?

Не прошел все новеллы с Anivisual Jam #1.
Будет отписывать комментарии к оставшимся.

СОНЦЕ
Дата: Вторник, 03.11.2020, 19:39 | Сообщение # 5
Разработчик
Сообщений: 230
Награды: 32
Цитата BattlePeasant ()
Вообще говоря, это ужас, то что выше предлагается.

Я абсолютно согласен). Просто паталогическая страсть к ужасному коду. nwow2

Цитата BattlePeasant ()
почему нельзя переписать функцию, выводящую текст на экран?

Это и будет изящным решением. Но это фигура высшего пилотажа, поскольку требует изучения незадокументированного функционала напрямую через исходники. Будет скучно -- вернусь к этому.

BattlePeasant
Дата: Вторник, 03.11.2020, 19:54 | Сообщение # 6
Проверенный
Сообщений: 31
Награды: 0
Удалено.

Сообщение отредактировал BattlePeasant - Вторник, 03.11.2020, 19:55

progxaker
Дата: Среда, 04.11.2020, 15:29 | Сообщение # 7
Проверенный
Сообщений: 41
Награды: 2
Цитата СОНЦЕ ()
Вообще то вот этот пост

Как и указал в своём сообщении) Я тоже попал на него, но да, практической реализации мне не хватало.

Цитата СОНЦЕ ()
Это и будет изящным решением. Но это фигура высшего пилотажа, поскольку требует изучения незадокументированного функционала напрямую через исходники.
Полностью согласен) Мне такой вариант предлагали и в Discord канале, хех. Но не думаю, что любительская бесплатная новелла стоит таких усилий. Разве что для себя, не торопясь)

Добавлено (04.11.2020, 15:42)
---------------------------------------------

Если честно, Я подумываю над таким решением:

https://pastebin.com/tFwAeZy3 ( на форуме нормально добавить не получилось ).



Намешал C++, PHP и Python, но думаю задумка ясна. Правда, как это реализовать в Ren'Py(вывод текста, назначение alpha на символ) понятия не имею nmda
Прикрепления: 2531278.png(36.6 Kb)


"Ничто не может оставаться таким же вечно. И вещи, приносящие радость и счастье, тоже. Ничто не остается неизменным." - Фурукава Нагиса, CLANNAD

Сообщение отредактировал progxaker - Среда, 04.11.2020, 15:57

GCStudio
Дата: Суббота, 07.11.2020, 21:35 | Сообщение # 8
Друг сайта
Сообщений: 68
Награды: 4
А почему именно на символ? Можно же сделать из текста картинку, и выводить его как картинку.

progxaker
Дата: Суббота, 07.11.2020, 21:47 | Сообщение # 9
Проверенный
Сообщений: 41
Награды: 2
Цитата GCStudio ()
А почему именно на символ? Можно же сделать из текста картинку, и выводить его как картинку.

Есть практическая реализация? Я представляю этот вариант так: какая-то функция переводит текст в картинку, другая функция как-то встраивает его в textbox(или вообще создаёт новую, что очень не оптимально), а дальше, какой-то функцией по градиенту появляется текст.
Почему по градиенту? Потому что иначе нет смысла всё это воротить, ведь Ren'Py и так выводит, как печатная машинка, а показ букв, как открывание штор... Не мой случай.


"Ничто не может оставаться таким же вечно. И вещи, приносящие радость и счастье, тоже. Ничто не остается неизменным." - Фурукава Нагиса, CLANNAD

СОНЦЕ
Дата: Воскресенье, 08.11.2020, 06:54 | Сообщение # 10
Разработчик
Сообщений: 230
Награды: 32
progxaker,  смотри какая идея nlove правда я гений? правда? правда? nwow2

Код

transform appear(ti):
    alpha .0
    ti*.02
    linear 1.0 alpha 1.0

image red_box=Solid('#f00',xysize=(20,20))

init python:
    list_for_livecomposite = [(1200,130)]
    i=0
    for y in range(5):
        for x in range(60):
            i+=1
            list_for_livecomposite.append((x*20,y*26))
            list_for_livecomposite.append(At('red_box',appear(i)))
image big_box = LiveComposite(*list_for_livecomposite)

screen say(who, what):
    style_prefix "say"

    window:
        id "window"

        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what" xpos 5000
        fixed xmaximum 1200:
            add AlphaMask(Text(what),'big_box')

label main_menu:
    return
    
label start:
    'Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random Random text lol very random teeeext lol lol random random '
    return

progxaker
Дата: Воскресенье, 08.11.2020, 10:40 | Сообщение # 11
Проверенный
Сообщений: 41
Награды: 2
Цитата СОНЦЕ ()
правда я гений? правда? правда?
Не гений, но и правда, реализация классная)
Можешь добавить комментарии в код?
Допустим, почему range(5) и range(60), почему x*20 и x*26, про верхнюю(appear) функцию и другие.
Также Я бы поправил цикл. Цикл в цикле не самая лучшая затея, поэтому использовал бы while.

Пока игрался, нашёл проблемку. Если нужно пропустить "бегущий" эффект нажатием ЛКМ, то, вместо появления целой фразы, переключается на новую. И сегодня займусь заменой функции cps на предложенную тобой функции.


"Ничто не может оставаться таким же вечно. И вещи, приносящие радость и счастье, тоже. Ничто не остается неизменным." - Фурукава Нагиса, CLANNAD

Сообщение отредактировал progxaker - Воскресенье, 08.11.2020, 11:02

СОНЦЕ
Дата: Понедельник, 09.11.2020, 14:42 | Сообщение # 12
Разработчик
Сообщений: 230
Награды: 32
progxaker, хихи прям на полном серьезе похвалил меня в краску вгоняешь nlove
вот с комментами и менее гоповским кодом
на счет вложенных циклов, я скромно настаиваю что в данном случае это хорошая практика
также внедрена попытка устранить проблему с пропуском бегущего эффекта путем дублирования
но обнаружена другая проблема - теперь применение изменения скорости появления текста требует перезагрузки т_т


Код

#######################################################################
#          Эффект плавного появления текста
#
# Реализован методом внедрения текста в АльфаМаску
# собранную из поочередно появляющихся прямоугольников
# для имитации нужного эффекта

# SMALL_XY - размеры маленького прямоугольника
#            подогнанны под размер символа
# BIG_XY - размер всей маски подогнан под выделенное для текста окошка

# SPEED - скорость появления текста. Хотелось подогнать под CPS
#         но там всё не так просто =_=...

transform offset_appear(delay_offset,speed,GRADIENT = 10):
    #GRADIENT - примерная длина шлейфа градиента в символах
    alpha .0
    delay_offset*speed
    linear speed*GRADIENT alpha 1.0

init python:
    LINE_SPACING = 4
    #LINE_SPACING - это должна быть стандартная переменная отступа
    # между строчками в диалоговом окне но я её не нашел T_т
    
    SMALL_X = gui.text_size
    SMALL_Y = gui.text_size+LINE_SPACING
    BIG_X = (gui.dialogue_width/SMALL_X+1)*SMALL_X
    BIG_Y = (gui.textbox_height/SMALL_Y+1)*SMALL_Y    
    SPEED = 1.0/preferences.text_cps
    
    
    
    list_for_dialogue_mask = [(BIG_X,BIG_Y)]
    delay_offset=0
    for y in range(0,BIG_Y,SMALL_Y):
        for x in range(0,BIG_X,SMALL_X):
            delay_offset+=1
            list_for_dialogue_mask.append((x,y))
            list_for_dialogue_mask.append(At('symbol_box',offset_appear(delay_offset,SPEED)))

image symbol_box=Solid('#fff',xysize=(SMALL_X,SMALL_Y))
image dialogue_mask = LiveComposite(*list_for_dialogue_mask)

screen say(who, what):
    style_prefix "say"

    window:
        id "window"

        if who is not None:

            window:
                id "namebox"
                style "namebox"
                text who id "who"

        text what id "what"
        fixed style 'say_dialogue':
            add AlphaMask(Text(what),'dialogue_mask')

label main_menu:
    return
    
label start:
    'Смеркалось, жаркий день бледнел неуловимо, Над озером туман тянулся полосой, И кроткий образ твой, знакомый и любимый, В вечерний тихий час носился предо мной.'
    'Улыбка та ж была, которую люблю я, И мягкая коса, как прежде, расплелась, И очи грустные, по-прежнему тоскуя, Глядели на меня в вечерний тихий час.'
    return

progxaker
Дата: Понедельник, 09.11.2020, 17:36 | Сообщение # 13
Проверенный
Сообщений: 41
Награды: 2
СОНЦЕ, осталось добавить проверку на то, включён ли cps вообще и делить на скорость появление, а не на "выключатель":

Код
if preferences.text_cps: SPEED = 1.0/preferences.afm_time
Но есть проблема, включён или выключен cps, идёт наложение текста.


А так, большое спасибо nwow2 nlove
Прикрепления: 8226438.png(14.2 Kb)


"Ничто не может оставаться таким же вечно. И вещи, приносящие радость и счастье, тоже. Ничто не остается неизменным." - Фурукава Нагиса, CLANNAD

Сообщение отредактировал progxaker - Понедельник, 09.11.2020, 17:38
Форум о визуальных новеллах » Для разработчиков » Ren'Py » Как сделать плавное появление текста? (Подробности в теме.)
  • Страница 1 из 1
  • 1
Поиск: