Форум Anivisual закрыт. Вы не можете создавать новые темы или писать ответы. Форум будет работать в режиме архива.
Пользователи · Поиск по форуму · · · Регистрация

Помощь по Ren'Py (Вопрос\Ответ)

Admin

#1
Сюда пользователи сайта могут писать вопросы о тех или иных функциях движка Ren'Py, а мы попытаемся на них ответить:)

KripWorland

#661
Цитата BenjaminFR ()
Как в ren'py использовать язык как переменную? Т.е., нужно, чтобы при определенном языке вызывалась определенная картинка. Занимаюсь переводом готовой новеллы через renpy translate, был язык по умолчанию - английский, и русский, соответственно. Подскажите, пожалуйста, как это сделать.
Если перевод делался через tl, то нужно в папку второго языка положить картинку с тем же путем, который был для основного языка.
Например, в игре есть картинка "game\images\img1.png" содержащая английский текст. Для того, чтобы при игре на русском выводилась соответствующая картинка с русским текстом, она должна иметь путь "game\tl\russian\image\img1.png"

Если же нужно именно в скрипте узнать, какой язык установлен, можно использовать переменную _preferences.language
Код
if _preferences.language is None:
    # здесь язык оригинала, т.е. английский
elif _preferences.language == 'russian':
    # здесь русский язык
else:
    # здесь какой-то еще язык
Сообщение отредактировал KripWorland - Воскресенье, 02/Фев/2020, 14:21

BenjaminFR

#662
Цитата KripWorland ()
Если перевод делался через tl, то нужно в папку второго языка положить картинку с тем же путем, который был для основного языка.Например, в игре есть картинка "game\images\img1.png" содержащая английский текст. Для того, чтобы при игре на русском выводилась соответствующая картинка с русским текстом, она должна иметь путь "game\tl\russian\image\img1.png"

Если же нужно именно в скрипте узнать, какой язык установлен, можно использовать переменную _preferences.language
Благодарю, все вышло. Довольно глупо было не догадаться до этого самостаятельно

СОНЦЕ

#663
Цитата KripWorland ()
Всем доброго времени суток. Помогите пожалуйста решить такую задачку:в ренпи есть весьма удобная штука - экран уведомлений, вызываемый функцией renpy.notify()
проблема в том, что при повторном вызове функции предыдущее уведомление скрывается.

Вот и хотелось бы сделать функцию, которая бы помещала уведомления в некую очередь и показывала их последовательно.
Т.е. если в данный момент нет экрана notify, то сразу выводим его, если же такой экран есть, ставим уведомление в очередь и показываем только тогда, когда предыдущее уведомление будет скрыто.


Код

init python:
    _notify_list = []
    
    def notify_queue():
        global _notify_list
        if all((not renpy.get_screen('notify'), _notify_list)):
            renpy.notify(_notify_list.pop(0));

screen notify_check():
    timer .5 repeat True action Function(notify_queue)

label main_menu:
    return
    
label start:
    show screen notify_check
    'foo'
    python:
        for i in range(50):
            _notify_list.append(str(i))
            
    'bar'
    return


мой вариант; косее некуда, но, думаю, можно вычленить функцианал и сделать по-нормальному

Цитата AxelK ()
как взять пиксели с самой картинки? Что-то не то я делаю, по всей видимости.

а можно рабочий пример без троеточий? тогда возможно быстрее разберусь

AxelK

#664
Цитата СОНЦЕ ()
а можно рабочий пример без троеточий? тогда возможно быстрее разберусь

Можно, конечно. Вырезал всякие лишние переменные, размеры, списки цветов.


Код
init python:
    import pygame_sdl2 as pygame
    import threading
    blit_lock = threading.Condition()
    
    class MyBlit(renpy.Displayable):

        def __init__(self, child, **kwargs):
            super(MyBlit, self).__init__(**kwargs)
            self.child = child
        
        def render(self, width, height, st, at):
            # это всё стандартная часть
            displayable_child = renpy.displayable(self.child)
            child_render = renpy.render(displayable_child, width, height, st, at)
            self.width, self.height = child_render.get_size()
            render = renpy.Render(self.width, self.height)
            render.blit(child_render, (0, 0))
            
            c = child_render.canvas().get_surface()
            try:
                blit_lock.acquire()

                # теста ради рисую прямоугольную рамку. такой цвет есть и на картинке
                pygame.draw.rect(c,
                             renpy.easy.color((191, 143, 127, 255)),
                             (1, 2, 100, 200),
                             2)

                rx, ry = 200, 200
                c.lock()
                for i in range(rx):
                    for j in range(ry):
                        pix = c.get_at((i, j))
                        if pix == (191, 143, 127, 255):   # перекрашивает только нарисованную рамку
                            c.set_at((i, j), (255,255,255,255))
                c.unlock()
                
            finally:
                blit_lock.release()
                 
            return render

label test_blit:
    python:
        renpy.scene()
        test_image = MyBlit('test.png')
        renpy.show('_', at_list=[], layer='master', what=test_image, zorder=1, tag='bg', behind=[])

    ' blah blah '
    return

СОНЦЕ

#666
AxelK,

Код
init python:
    import pygame_sdl2 as pygame
    import threading

    
    class MyBlit(renpy.Displayable):

        def __init__(self, child,cf,ct, **kwargs):
            super(MyBlit, self).__init__(**kwargs)
            self.child = child
            self.child_surf = renpy.load_surface(child)
            self.cf = cf
            self.ct = ct
        
        def render(self, width, height, st, at):
            displayable_child = renpy.displayable(self.child)
            child_render = renpy.render(displayable_child, width, height, st, at)
            self.width, self.height = child_render.get_size()
            c = self.child_surf

            rx, ry = self.width, self.height
            c.lock()
            for i in range(int(rx)):
                for j in range(int(ry)):
                    pix = self.child_surf.get_at((i, j))
                    if pix == self.cf: 
                        self.child_surf.set_at((i, j), self.ct)
            c.unlock()
            
            render = renpy.Render(self.width, self.height)
            render.blit(c, (0, 0))
                 
            return render
label main_menu:
    return
label start:
label test_blit:
    python:
        renpy.scene()
        test_image = MyBlit('test.png',(0,0,255,255),(255,0,0,255))
        renpy.show('_', at_list=[truecenter], layer='master', what=test_image, zorder=1, tag='bg', behind=[])

    ' blah blah'
    return


вот в таком виде пиксели перекрашиваются непосредственно на картинке.
если дорисованный квадратик тоже надо перекрасить: это очевидно можно сделать отдельно.

Код

  c = child_render.canvas().get_surface()

похоже эта строчка не подтягивает пиксели из скормленной рендеру картинки, а лишь дает пространство для квадратика. Почему? пока не знаю smile_82
Сообщение отредактировал СОНЦЕ - Среда, 05/Фев/2020, 23:45

AxelK

#667
Цитата СОНЦЕ ()
.load_surface

Так вот куда надо было это пихать... Интересно, ушёл думать.
Спасибо.

Чуть подправил, в том числе для нескольких цветов по списку.
Делает то что нужно, вопрос только не слишком ли это медленно :-)

Код
init python:
    import pygame_sdl2 as pygame
    import threading

    class MyBlit(renpy.Displayable):

        def __init__(self, child, colors, **kwargs):
            super(MyBlit, self).__init__(**kwargs)
            self.child = child
            self.child_surf = renpy.load_surface(child)
            self.colors = colors
        
        def render(self, width, height, st, at):
            displayable_child = renpy.displayable(self.child)
            child_render = renpy.render(displayable_child, width, height, st, at)
            self.width, self.height = child_render.get_size()
            surf = self.child_surf

            rx, ry = self.width, self.height
            surf.lock()
            for i in range(int(rx)):
                for j in range(int(ry)):
                    pix = surf.get_at((i, j))
                    for cf, ct in self.colors:
                        if pix == cf:
                            surf.set_at((i, j), ct)
            surf.unlock()
            
            render = renpy.Render(self.width, self.height)
            render.blit(surf, (0, 0))
                 
            return render

label start:
    python:
        renpy.scene()
        file_name = 'images/__test.png'
        test_image = Image(file_name)
        renpy.show('_', at_list=[truecenter], layer='master', what=test_image, zorder=1, tag='bg', behind=[])
        renpy.with_statement(None)
    ' day '

    python:
        colors = (
            ((137,103,69,255), (2,2,69,255)),
            ((186,152,103,255), (3,3,103,255)),
            ((239,220,152,255), (4,4,152,255))
        )
        test_image = MyBlit(file_name, colors)
        renpy.show('_', at_list=[truecenter], layer='master', what=test_image, zorder=1, tag='bg', behind=[])
        renpy.with_statement(Dissolve(0.7))
        renpy.pause(0.7, hard=True)
    ' night '

    return


Цитата СОНЦЕ ()
лишь дает пространство для квадратика

Дык да, по всей видимости, это новая канва.
Цитата СОНЦЕ ()
если дорисованный квадратик тоже надо перекрасить

не надо :-) это было просто чтоб убедиться в подгрузке модуля

AxelK

#668
Новый день, новые проблемы.
Решил сделать экран со статами с помощью layeredimage
предположим, деньги отображаются картинками и нужно для каждого разряда отобразить свою цифру-картинку
digits.png = все цифры в ряд через 16 пикселей

Код

  layeredimage Stats:
        always:
            "frame.png"

        if money >= 100:
            pos (0, 0)
            crop (0, 0, 16, 16)   # 0 в первую позицию
            "digits.png"

        if money >= 10:
            pos (16 , 0)
            crop (0, 0, 16, 16)   # 0 во вторую позицию
            "digits.png"

        if money >= 0:
            pos (32 , 0)
            crop (0, 0, 16, 16)   # и 0 в третью позицию
            "digits.png"


Это всё работает и копирует нули как надо.
А можно как-то использовать Money внутри pos или crop ?

dmit

#669
а стоит ли использовать в экране layeredimage? не проще показать файлы цифр по числу? типа:
Код
screen nomer(nn=""):
    frame:
        align (0.5, 0.1)
        has hbox
        for cfr in nn:
            add cfr
СОНЦЕ подвиг на создание примера и с SFont шрифтом - пример
Сообщение отредактировал dmit - Четверг, 13/Фев/2020, 08:21
планета FOREVER!!!      Unkenbro team

СОНЦЕ

#670
Двачую пост dmit-а. можно вот таким кодом объявить циферки, после чего использовать в скрине напрямую

Код

    for i in range(10):
        renpy.image(str(i),Crop((i*16, 0, 16, 16), "digits.png"))


А если удастся запустить это через layeredimage, кинешь в меня исходником плз. Потому что судя по всему на переменные многократно оно реагирует только в команде if. в остальных местах берет значение один раз и навсегда.

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

Код

init python:
    renpy.register_sfont(u'my_num_font',22,filename='digits.png',charset='0123456789')
    money = 1234567890

label main_menu:
    return

label start:
    scene expression '#aaa'
    show expression Text(str(money),font='my_num_font',size=22,color='#fff') at truecenter
    pause

    return



а файл sfont шрифта - это буквально символы в ряд. только еще для парсинга ему нужна магентовая точка в левом верхнем углу над каждым символом. вот для примера



Вот тут подробнее про то как самому рисовать и регистрировать для ренпи шрыфты
https://www.renpy.org/doc....d-fonts
Прикрепления: 2458931.png (6.6 Kb)

Floyd

#671
Может, и мне кто-нибудь поможет... В общем, хочу сделать выравнивание текста по ширине, ну, как в ворде или в книге. Искал на англоязычных форумах возможные решения, но так и не нашел. Может быть, кто-нибудь знает, как такое реализовать и возможно ли это вообще?

СОНЦЕ

#672
Floyd
Код

init python:
    style.default.justify=True

это по дефолту для всех

Код

define e = Character("Eileen",what_justify=True)

это конкретному персонажу или для конкретного случая

крч justify

Floyd

#673
СОНЦЕ, большое спасибо. Потратил, наверное, больше часа на поиски, а Вы тут почти сразу ответили.

AxelK

#674
dmit , СОНЦЕ : спасибо за подсказки
.

Свой шрифт в данном месте, пожалуй, ни к чему.
Хочу отобразить автоматом весь экран вообще (по идее)
Кроме денег надо несколько других параметров "градусниками" и числами, время суток, день недели и т.д.

Через Layeredimage не выходит.
Попробовал сделать экран. Не знаю, можно проще или нет

Код
## Generic frames.
define gui.frame_borders = Borders(0, 0, 0, 0)
~~~

python:

    # создание картинок
    for i in range(10):
        renpy.image('money_%d' % i, Crop((i*16, 0, 8, 16), "util.png"))
    renpy.image('money_a', Crop((160, 0, 8, 16), "util.png")) # это графическое изображение точки

    # вспомогательная функция
    # добавляю точку для тысяч
    def format_money (a):
        if a < 1000:
            return str(a)
        return '%da%d' % (int(a/1000), int(a%1000))

    screen money (nn=""):
        frame style "money_frame":
            has hbox
            for cfr in nn:
                add 'money_%s'%cfr

    screen Stats:
        modal False
        zorder 0
        style_prefix "stats"
        window:
            add "frame.png"
            use money (format_money (money))

    style money_frame:
        xpos 600
        ypos 20
        xanchor 1.0 # чтоб прижималось к правому краю

    style stats_window is empty
    style stats_window:
        xpos 0
        ypos 0
        xsize 640
        ysize 400


    $ money = 0
    show screen Stats

    pause
    $ money = 10
    pause
    $ money = 200
    pause
    $ money = 304050
    pause

AxelK

#675
Упс. Переменная money  у меня - значение из массива. Конечно, не пересекается с  названием экрана money
Поиск: