Текущее время: 09 сен 2010, 03:01

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
 Заголовок сообщения: Сборник решений для RenPy
СообщениеДобавлено: 18 сен 2009, 16:24 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 10 янв 2009, 09:50
Сообщения: 808
Откуда: Nsk
Сейчас мне приходится много работать с бесплатным кросcплатформенным движком RenPy, так что думаю будет полезно поделиться своими наблюдениями и находками.

Итак, первый блок полезного кода:

1. Отключение / включение меню, которое вызывается правой кнопкой мыши:
Отключение:
Код:
$ _game_menu_screen = None

Включение:
Код:
$ _game_menu_screen = save_screen


2. Установка окна игры по центру:
Код:
import os
os.environ['SDL_VIDEO_CENTERED'] = '1'


3. Выключение возможности отката игры назад:
Код:
config.hard_rollback_limit = 0


4. Показ текста в центре экрана:
Код:
centered "text"


5. Поддержка многоязычности:
http://www.renpy.org/wiki/renpy/doc/cookbook/Multiple_Language_Support


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 21 сен 2009, 15:30 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Очень полезные команды. Я, например, давно пытался узнать как отменить rollback, а то в бою (тактическая битва на гексагональной сетке) задетый скролл чинил неприятности.

Вот из моей библиотеки.
1. Перезапуск(не перезагрузка) и мгновенный выход(минуя "yes_no_promt").
Достали меня эти "Вы точно хотите выйти?", вот и сообразил нечто вот такое:

Это в секцию init:
Код:
    def system_buttons():
        if enable_overlays is True:
            ui.vbox()
            ui.textbutton(u"{font=System.ttf}{size=10}Перезапустить",clicked=ui.returns('start'),xmaximum=150,xfill=True,ymaximum=20,yfill=True)
            ui.textbutton(u"{font=System.ttf}{size=10}Выйти",clicked=ui.returns('e_x_i_t'),xmaximum=150,xfill=True,ymaximum=20,yfill=True)
            ui.close()

config.overlay_functions.append(system_buttons)



А это - после:
Код:
label e_x_i_t:
    $ renpy.quit()
    return


2. Среднее арифметическое
Код:
    def avg(list):
        tmp = 0.0
        for i in range(len(list)):
            tmp+=list[i]
        return (tmp/len(list))


3. Сказать что-то в обычном режиме не выходя из питон-блока
Код:
    def say(str):
        ui.window(xalign=1.0,yalign=1.0)
        ui.at(Position(xalign=0.05,yalign=0.1))
        ui.text('%s' % str)


4. Короткий вызов ui.move
Код:
    def uimove (src,dst,time):
        sxp,syp = src
        dxp,dyp = dst
        ui.at(Move ((sxp,syp,0.5,0.5),(dxp,dyp,0.5,0.5),time,subpixel=True) )


5. Фунции для трансформа. Что делают - понятно из названия.
Код:
    def trans_fadein(t, st, at):
        t.zoom = min(1.0, 0.01 + st / 1.0)
        t.alpha = min(1.0, 0.01 + st / 1.0)
        return 0
       
    def trans_alphain(t, st, at):
        t.alpha = min(1.0, 0.01 + st / 1.0)
        return 0
       
    def trans_fadeout(d, st, at):
         d.alpha = max(0.0, 1.0 - st / 2.0)
         return 0


6. Взрыв частиц
Обязательные аргументы
img - файловый обьект или непосредственно имя png-картинки.
xs,ys - стартовая позиция.
xrad,yrad - горизонтальная/вертикальная границы разлёта
Необязательные аргументы
wave - количество волн
cnt - количество частиц в волне
Внимание
Так как содержит renpy.pause прерывает взаимодействие(на экране останутся только оверлеи).
Для плавного исчезновения частиц использует трансформ из предыдущего пункта.
Код:
    def particle_burst(img, xs,ys, xrad,yrad, wave=10,cnt=100):
        for ii in range (wave):
            renpy.pause(0.1)
            for i in range(cnt):
                xd = renpy.random.random()
                if xd > xs + xrad:
                    xd = xs + xrad
                if xd < xs - xrad:
                    xd = xs - xrad
                   
                yd = renpy.random.random()
                if yd > ys + yrad:
                    yd = ys + yrad
                if yd < ys - yrad:
                    yd = ys - yrad
                speed = renpy.random.random()
                renpy.show(img,at_list=[Transform(function=trans_fadeout),Move((xs,ys,0.5,0.5),(xd,yd,0.5,0.5),speed)],tag='%d%d'%(i,ii))
        for ii in range (wave):
            for i in range(cnt):
                renpy.transition(slow_dissolve)
                renpy.hide('%d%d'%(i,ii))


7. Лёгкое расположение текста:
string - форматированная строка к выводу
x,y - позиция
anchor - якорь. Не дробь, а две буквы
Первая буква l - слева m - центр r - справа
Вторая буква u - сверху m - центр d - снизу
lu - слева-сверху, (0,0)
mm - в центре (0.5,0.5)
rm - справа по центру (1.0,0.5)
width = максимальная ширина
text2 не ограничивает ширину

Код:
    def text(string,x,y,anchor,width=80):
        point = anchor[:1]
        if point == 'l':
            xa = 0
        elif point == 'm':
            xa = 0.5
        elif point == 'r':
            xa = 1.0
        else:
            xa = 0.5
           
        point = anchor[1:]
        if point == 'u':
            ya = 0
        elif point == 'm':
            ya = 0.5
        elif point == 'd':
            ya = 1.0
        else:
            ya = 0.5
       
        del point
        ui.at(Position(xpos=x,ypos=y,xanchor=xa,yanchor=ya))
        ui.frame(background = Solid((253, 253, 253, 255)),xmaximum = width)
        ui.text(string,style='txt')
   
    def text2(string,x,y,anchor):
        point = anchor[:1]
        if point == 'l':
            xa = 0
        elif point == 'm':
            xa = 0.5
        elif point == 'r':
            xa = 1.0
        else:
            xa = 0.5
           
        point = anchor[1:]
        if point == 'u':
            ya = 0
        elif point == 'm':
            ya = 0.5
        elif point == 'd':
            ya = 1.0
        else:
            ya = 0.5
       
        del point
        ui.at(Position(xpos=x,ypos=y,xanchor=xa,yanchor=ya))
        ui.text(string)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 15 окт 2009, 19:35 
Не в сети
Новичок

Зарегистрирован: 15 окт 2009, 19:13
Сообщения: 2
Надеюсь никто не против, если я задам здесь вопрос, заключается он в следующем:
есть код для сохранения
Код:
    if result == "slot0":
        $ renpy.save("slot_0", "Slot Save 0")

и есть код для загрузки
Код:
    if result == "slot0":
        $ renpy.load("slot_0")

но вся проблема в том, если загружать из слота в который прежде не была сохранена игра, то происходит ошибка
Код:
I'm sorry, but an exception occured while executing your Ren'Py
script.

IOError:

While running game code:
- script at line 23 of D:\Ren'Py 6.9.3\Heart Flower/game/script.rpy
- python at line 184 of renpy-6.9.3/common/00library.rpy.
- script at line 164 of D:\Ren'Py 6.9.3\Heart Flower/game/mainmenu.rpy
- python at line 167 of D:\Ren'Py 6.9.3\Heart Flower/game/mainmenu.rpy.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 16 окт 2009, 14:51 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 10 янв 2009, 09:50
Сообщения: 808
Откуда: Nsk
Думаю вам стоит воспользоваться функцией renpy.loadable или renpy.can_load

Если интересуют кастомные меню загрузки/сохранения, советую ознакомиться с игрой The Fucking Question, там вообще сделано немало интересных решений.

Вот её код меню загрузки/сохранения:

 Спойлер
Код:
    # This block is responsible for the Load/Save screen
    # AAAAAGHHHHHHHHHHHH!!!! This one is a pain in the ass!...
   
init -2 python:
    layout.imagemap_load_save(
        "gui_loadsave_ground.png",
        "gui_loadsave_idle.png",
        "gui_loadsave_hover.png",
        "gui_loadsave_selected_idle.png",
        "gui_loadsave_selected_hover.png",
        [
            (240, 115, 303, 177, "previous"),
            (309, 115, 372, 177, "page_auto"),
            (378, 115, 441, 177, "page_1"),
            (447, 115, 510, 177, "page_2"),
            (516, 115, 579, 177, "page_3"),
            (585, 115, 648, 177, "page_4"),
            (654, 115, 717, 177, "page_5"),
            (723, 115, 786, 177, "next"),

            (286, 197, 518, 260, "slot_0"),
            (286, 273, 518, 333, "slot_1"),
            (286, 347, 518, 410, "slot_2"),
            (286, 423, 518, 485, "slot_3"),
            (548, 197, 779, 260, "slot_4"),
            (548, 273, 779, 333, "slot_5"),
            (548, 347, 779, 410, "slot_6"),
            (548, 423, 779, 485, "slot_7"),
            ])
   
    style.file_picker_ss_window.xalign = 0.95
    style.file_picker_ss_window.yalign = 0.5
    style.file_picker_text_window.xalign = 0.05
    style.file_picker_text_window.yalign = 0.05
    config.thumbnail_width = 68
    config.thumbnail_height = 52
    config.file_entry_format = "%(time)s\n%(save_name)s"
   
    #config.file_entry_format = "%(time)s"
    #config.file_entry_format = "%(save_name)s"
    #config.disable_thumbnails = True
    #config.load_save_empty_thumbnail = None
    #config.time_format = "%b %d, %H:%M"


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 16 окт 2009, 18:44 
Не в сети
Новичок

Зарегистрирован: 15 окт 2009, 19:13
Сообщения: 2
Спасибо за помощь, все это хорошенько еще раз изучу, но хотелось бы как раз сделать все полностью с нуля, без применения layout.imagemap_load_save и подобного. Все остальное (меню, опции, галерея) готово, но вся загвоздка именно в ошибке с лоад\сейв. Проще сказать, хотелось бы сделать кастомный лоад\сейв как в Katawa Shoujo Act 1.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 26 фев 2010, 18:38 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Взято и переведено из книги рецептов.
Немного модифицировано мной.

А) Движок для автозагрузки всех изображений из папки
Код:
   
python:
        import os
        for fname in os.listdir(config.gamedir + '/char'):
            try:
                if fname.endswith(('.jpg')):
                    tag = fname[:-4]
                    image =  'char/' + fname
                    mask  = 'char/' + fname[:-4] + ' mask.jpg'
                    renpy.image(tag, im.FactorScale(im.AlphaMask(image,mask),0.83))
            except IOError:
                continue

char - папка в которой лежат картинки
if fname.endswith(('.jpg')): - если расширение файла .jpg. Это может быть кортеж из нескольких расширений.
tag - имя уже загруженного в память изображения. В данном случае - имя файла без расширения.
В данном случае предполагается что в папке лежат пары картинок - изображение героя и альфа-маска. Тry-except нужен чтобы не вылетала когда не найдёт маску для маски.

Б) Распаковать rpa архив игры

1) Переместить куда-нибудь файлы script.rpy и script.rpyc
2) Взять из шаблона RenPy файл script.rpy и заменить в нём код на приведённый ниже
Код:
init python:
    image_files = [
    fn
    for dir, fn in renpy.loader.listdirfiles()
    if not fn.lower().endswith(".rpy") and not fn.lower().endswith(".rpyc") and not fn.lower().endswith(".rpa") and not fn.lower().endswith(".rpyb")
    if not fn[0] == "_"
    ]

    def unarchive(original_filename, new_filename):
        import os
        import os.path

        new_filename = config.basedir + "/" + new_filename
        dirname = os.path.dirname(new_filename)

        if not os.path.exists(dirname):
            os.makedirs(dirname)

        orig = renpy.file(original_filename)
        new = file(new_filename, "wb")
        new.write(orig.read())
        new.close()
        orig.close()


label start:
    python:
        for img in image_files:
            unarchive(img, "extracted/"+img)
    return


3) Запустить игру
Если не запустится, значит метка start находится не в script. В traceback.txt будет написано в каком. Переместить и его.
4) Нажать кнопку начала новой игры.
5) Подождать пока она погаснет и выйти.

Появится папка extracted, содержащая в себе все ресурсы.
Не только картинки, но и музыку, звуки, шрифты и так далее.

6) Вернуть перемещённые файлы на место.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 26 фев 2010, 18:46 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 10 янв 2009, 09:50
Сообщения: 808
Откуда: Nsk
С распаковкой хитрый трюк.
Я делал подобное, но не знал как создать список файлов в архиве, и потому генерировал его отдельной тулзой.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 06 мар 2010, 19:54 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Мне тут понадобилось чтобы герои активно и нормально говорили не выходя из питон-блока, но уже имеющиеся функции не устроили, да и не предназначены они для вызова пользователем а не другим скриптом. Поэтому я написал свою, почти не уступающуюю по функционалу и куда удобнее для юзера.

1) Принимаемые параметры
--- Строка с именем героя или обьект-персонаж (Character / DynamicCharacter), функция сама определит тип аргумента и поведёт себя соответсвующим образом.
Если передан обьект, то функция построит текстовое окно для этого героя, взяв необходимые параметры из его экземпляра класса. Иначе (если строка) будет обычное поле и имя, указанное первым параметром.
--- Собственно, что говорится.
--- mod позволяет изменить лицо и имя героя. Позволяет избавиться от необходимости плодить лишних Character'ов если эта мордочка или весь герой возникает всего несколько раз. Так же позволяет использовать класс героя как набор стилей, но картинка и имя будет другое. Можно изменить только картинку или только имя или и то и другое.

2) Внешние элементы
--- show_who_window - логическая. Показывать или нет окошко с именем героя. Используется только если как первый параметр передана строка.
--- blank - строковая. Содержить путь к пустому и полностью прозрачному png. Можно и не полностью, один или оба (imagebutton), например чтобы ctc сделать.

3) Использование.
Функция постоена только с испоьзованием класса ui и предустановленных стилей.
Возвращает результат срабатывания ui.interact
Код:
interaction_result = say("Главный Герой","В путь!")

либо
Код:
boss = Character("ГлавГад",show_side_image="boss.png")
say(boss,"Тебе меня не взять!")

либо
Код:
say(boss,"Мимикрия-десу",("Главный Герой","hero.png"))


Сама функция, вернее их две.
Код:
    def say(who='???',what='...',mod=('','')):
        #Проверка типа переменной who - для адекватной реакции
        whois = str(type(who))
        ThisIsHero = False
        if 'Character' in whois:
            ThisIsHero = True
            #если он DynamicCharacter
            if who.name is 'name':
                whois = name
            else:
                whois = who.name
       
        #Строка то есть
        elif 'unicode' in whois:
            whois = who
       
        #Отладки ради
        else:
            whois = '%s'%type(who)
       
        # если имя заменено
        if mod[0] is not '':
            whois = mod[0]
       
        ui.at(Position(xalign=0.0,yalign=1.0))
        ui.vbox()
        #Если who является Character'ом
        if ThisIsHero:
            if who.show_args.has_key("two_window"):
                if who.show_args["two_window"]:
                    #Кто сказал 'мяу'?
                    ui.at(Position(xalign=0.01,yalign=0.0))
                    ui.frame(style='say_who_window')
                    ui.text("{=say_label}%s"%whois)
                    #Само текстовое окно
                    build_text_window(who,what,mod[1])
                else:
                    build_text_window(who,whois+':\n'+what,mod[1])               
            else:
                build_text_window(who,whois+':\n'+what,mod[1])
           
        #Строка
        else:
            if show_who_window:
                ui.at(Position(xalign=0.01,yalign=0.0))
                ui.frame(style='say_who_window')
                ui.text("{=say_label}%s"%whois)               
                ui.frame(style='say_window')
                ui.at(Position(xalign=0.01,yalign=0.1))
                ui.text('%s' %what)   
            else:
                ui.frame(style='say_window')
                ui.at(Position(xalign=0.01,yalign=0.1))
                ui.text('%s:\n%s' %(whois,what)) 
        ui.close()   
        #Прозрачная кнопка во всё текстовое поле
        ui.at(Position(xalign=0.0,yalign=1.0))
        ui.imagebutton(im.Scale(blank,1024,style.say_window.yminimum),im.Scale(blank,1024,style.say_window.yminimum),clicked=ui.returns(0))
        return ui.interact()
     
    #Функция строит текстовое окно
    def build_text_window(who,what,img):
        ui.null(height=5)
        ui.frame(style='say_window')
        ui.at(Position(xalign=0.01,yalign=0.1))
        ui.hbox()
        # если изображение не будет заменено
        if img is '':
            if who.show_args.has_key("side_image"):
                ui.at(Position(xalign=0.01,yalign=0.5))
                ui.image(who.show_args["side_image"])
                ui.null(width=5)
        # показать переданное изображение
        else:
            ui.at(Position(xalign=0.01,yalign=0.5))
            ui.image(img)
            ui.null(width=5)
        ui.text('%s' %what)
        ui.close()   


Если чего не хватает (мне достаточно. пока...) напиши(те).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 23 мар 2010, 14:35 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Сетевая игра в Renpy.
Для винды, в линуксе немного по другому будет.
Правда, это не готовое решение, скорее наоборот...

Эхо-сервер:
Имеет два открытых соединения с неблокирующими сокетами которые по очереди опрашивает. Обнаружив данные - обрабатывает их функцией и отправляет назад.
Пример взят из учебника по линуксу и переработан под винду->неблокирующие сокеты->2 канала->RenPy

 ЭхоСервер Script.rpy
Код:
init python:
    import socket, string, time
   
    config.log = "server.log"
   
    def do_something(x):
      lst = map(None, x);
      #lst.reverse();
      return string.join(lst, "")
     
label start:
    " "
    python:
        HOST = ""               

        conn1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        conn2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        conn1.setblocking(0)
        conn2.setblocking(0)

        conn1.bind((HOST, 12345))
        conn2.bind((HOST, 54321))
       
        renpy.log('Listening...')
        list = [conn1,conn2]   
        while True:
           
            for link in list:
                try:
                    #list.remove(link)
                    link.listen(1)
                    sock, addr = link.accept()
                    #list.append(link)
                    connect = True
                except:
                    connect = False
                    continue
               
                break
           
            if connect:
                renpy.log("---------------Connection----------------")
                try:
                    pal = sock.recv(1024)
                except:
                     renpy.log('Receiving error.')
                if not pal:
                    break
                renpy.log("Recieved %s:%s:"% (addr, pal))
                lap = do_something(pal)
                renpy.log("Send %s:%s:" % (addr, lap))
                sock.send(lap)
                sock.close()
                connect = False
                renpy.log("---------------Disconnect----------------")
    return


Клиент:
Случайно выбирает один из двух портов и ломится по нему.
Не вылетает если сервер не работает.
Кстати, сервер корректно работает если клиентов два, но каждый по конкретному порту идёт.

 Клиент Script.rpy
Код:
init python:
    import socket
    import time
    import random
    config.log = "client.log"

# The game starts here.
label start:
    python:
        while True:
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                port = random.choice([12345,54321])
                client.connect(('localhost', port))
            except:
                renpy.log('Server does not respond.')
                client.close()
                time.sleep(1)
                continue

            client.send("Hello from %s-%s"%client.getsockname())
            str1,str2 = client.getsockname()
            renpy.log("Send Hello from %s-%s-%d"%(str1,str2,port))
            try:
                result = client.recv(1024)
            except:
                renpy.log('Receiving error.')
            client.close()
            renpy.log("Receive: %s"%result)
            time.sleep(1)
    return


Результаты работы:
 Server.log
Код:
--- Tue Mar 23 17:15:52 2010



Listening...
--- Tue Mar 23 17:18:12 2010



Listening...
---------------Connection----------------
Recieved ('127.0.0.1', 2219):Hello from 127.0.0.1-2219:
Send ('127.0.0.1', 2219):Hello from 127.0.0.1-2219:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2220):Hello from 127.0.0.1-2220:
Send ('127.0.0.1', 2220):Hello from 127.0.0.1-2220:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2222):Hello from 127.0.0.1-2222:
Send ('127.0.0.1', 2222):Hello from 127.0.0.1-2222:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2223):Hello from 127.0.0.1-2223:
Send ('127.0.0.1', 2223):Hello from 127.0.0.1-2223:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2224):Hello from 127.0.0.1-2224:
Send ('127.0.0.1', 2224):Hello from 127.0.0.1-2224:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2226):Hello from 127.0.0.1-2226:
Send ('127.0.0.1', 2226):Hello from 127.0.0.1-2226:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2227):Hello from 127.0.0.1-2227:
Send ('127.0.0.1', 2227):Hello from 127.0.0.1-2227:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2232):Hello from 127.0.0.1-2232:
Send ('127.0.0.1', 2232):Hello from 127.0.0.1-2232:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2234):Hello from 127.0.0.1-2234:
Send ('127.0.0.1', 2234):Hello from 127.0.0.1-2234:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2235):Hello from 127.0.0.1-2235:
Send ('127.0.0.1', 2235):Hello from 127.0.0.1-2235:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2236):Hello from 127.0.0.1-2236:
Send ('127.0.0.1', 2236):Hello from 127.0.0.1-2236:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2237):Hello from 127.0.0.1-2237:
Send ('127.0.0.1', 2237):Hello from 127.0.0.1-2237:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2238):Hello from 127.0.0.1-2238:
Send ('127.0.0.1', 2238):Hello from 127.0.0.1-2238:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2241):Hello from 127.0.0.1-2241:
Send ('127.0.0.1', 2241):Hello from 127.0.0.1-2241:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2242):Hello from 127.0.0.1-2242:
Send ('127.0.0.1', 2242):Hello from 127.0.0.1-2242:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2243):Hello from 127.0.0.1-2243:
Send ('127.0.0.1', 2243):Hello from 127.0.0.1-2243:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2244):Hello from 127.0.0.1-2244:
Send ('127.0.0.1', 2244):Hello from 127.0.0.1-2244:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2246):Hello from 127.0.0.1-2246:
Send ('127.0.0.1', 2246):Hello from 127.0.0.1-2246:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2247):Hello from 127.0.0.1-2247:
Send ('127.0.0.1', 2247):Hello from 127.0.0.1-2247:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2248):Hello from 127.0.0.1-2248:
Send ('127.0.0.1', 2248):Hello from 127.0.0.1-2248:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2249):Hello from 127.0.0.1-2249:
Send ('127.0.0.1', 2249):Hello from 127.0.0.1-2249:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2250):Hello from 127.0.0.1-2250:
Send ('127.0.0.1', 2250):Hello from 127.0.0.1-2250:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2252):Hello from 127.0.0.1-2252:
Send ('127.0.0.1', 2252):Hello from 127.0.0.1-2252:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2253):Hello from 127.0.0.1-2253:
Send ('127.0.0.1', 2253):Hello from 127.0.0.1-2253:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2254):Hello from 127.0.0.1-2254:
Send ('127.0.0.1', 2254):Hello from 127.0.0.1-2254:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2255):Hello from 127.0.0.1-2255:
Send ('127.0.0.1', 2255):Hello from 127.0.0.1-2255:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2256):Hello from 127.0.0.1-2256:
Send ('127.0.0.1', 2256):Hello from 127.0.0.1-2256:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2257):Hello from 127.0.0.1-2257:
Send ('127.0.0.1', 2257):Hello from 127.0.0.1-2257:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2258):Hello from 127.0.0.1-2258:
Send ('127.0.0.1', 2258):Hello from 127.0.0.1-2258:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2259):Hello from 127.0.0.1-2259:
Send ('127.0.0.1', 2259):Hello from 127.0.0.1-2259:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2260):Hello from 127.0.0.1-2260:
Send ('127.0.0.1', 2260):Hello from 127.0.0.1-2260:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2261):Hello from 127.0.0.1-2261:
Send ('127.0.0.1', 2261):Hello from 127.0.0.1-2261:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2264):Hello from 127.0.0.1-2264:
Send ('127.0.0.1', 2264):Hello from 127.0.0.1-2264:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2266):Hello from 127.0.0.1-2266:
Send ('127.0.0.1', 2266):Hello from 127.0.0.1-2266:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2268):Hello from 127.0.0.1-2268:
Send ('127.0.0.1', 2268):Hello from 127.0.0.1-2268:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2270):Hello from 127.0.0.1-2270:
Send ('127.0.0.1', 2270):Hello from 127.0.0.1-2270:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2271):Hello from 127.0.0.1-2271:
Send ('127.0.0.1', 2271):Hello from 127.0.0.1-2271:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2272):Hello from 127.0.0.1-2272:
Send ('127.0.0.1', 2272):Hello from 127.0.0.1-2272:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2273):Hello from 127.0.0.1-2273:
Send ('127.0.0.1', 2273):Hello from 127.0.0.1-2273:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2274):Hello from 127.0.0.1-2274:
Send ('127.0.0.1', 2274):Hello from 127.0.0.1-2274:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2278):Hello from 127.0.0.1-2278:
Send ('127.0.0.1', 2278):Hello from 127.0.0.1-2278:
---------------Disconnect----------------
---------------Connection----------------
Recieved ('127.0.0.1', 2279):Hello from 127.0.0.1-2279:
Send ('127.0.0.1', 2279):Hello from 127.0.0.1-2279:
---------------Disconnect----------------


 Client.log
Код:
--- Tue Mar 23 17:15:35 2010

Server does not respond.
Server does not respond.
Server does not respond.
Server does not respond.
Send Hello from 127.0.0.1-2165-54321
Receiving error.
--- Tue Mar 23 17:18:24 2010

Server does not respond.
Send Hello from 127.0.0.1-2219-12345
Receive: Hello from 127.0.0.1-2219
Send Hello from 127.0.0.1-2220-54321
Receive: Hello from 127.0.0.1-2220
Send Hello from 127.0.0.1-2222-54321
Receive: Hello from 127.0.0.1-2222
Send Hello from 127.0.0.1-2223-12345
Receive: Hello from 127.0.0.1-2223
Send Hello from 127.0.0.1-2224-12345
Receive: Hello from 127.0.0.1-2224
Send Hello from 127.0.0.1-2226-54321
Receive: Hello from 127.0.0.1-2226
Send Hello from 127.0.0.1-2227-54321
Receive: Hello from 127.0.0.1-2227
Send Hello from 127.0.0.1-2232-12345
Receive: Hello from 127.0.0.1-2232
Send Hello from 127.0.0.1-2234-12345
Receive: Hello from 127.0.0.1-2234
Send Hello from 127.0.0.1-2235-54321
Receive: Hello from 127.0.0.1-2235
Send Hello from 127.0.0.1-2236-54321
Receive: Hello from 127.0.0.1-2236
Send Hello from 127.0.0.1-2237-54321
Receive: Hello from 127.0.0.1-2237
Send Hello from 127.0.0.1-2238-54321
Receive: Hello from 127.0.0.1-2238
Send Hello from 127.0.0.1-2241-54321
Receive: Hello from 127.0.0.1-2241
Send Hello from 127.0.0.1-2242-12345
Receive: Hello from 127.0.0.1-2242
Send Hello from 127.0.0.1-2243-12345
Receive: Hello from 127.0.0.1-2243
Send Hello from 127.0.0.1-2244-54321
Receive: Hello from 127.0.0.1-2244
Send Hello from 127.0.0.1-2246-12345
Receive: Hello from 127.0.0.1-2246
Send Hello from 127.0.0.1-2247-54321
Receive: Hello from 127.0.0.1-2247
Send Hello from 127.0.0.1-2248-54321
Receive: Hello from 127.0.0.1-2248
Send Hello from 127.0.0.1-2249-54321
Receive: Hello from 127.0.0.1-2249
Send Hello from 127.0.0.1-2250-54321
Receive: Hello from 127.0.0.1-2250
Send Hello from 127.0.0.1-2252-12345
Receive: Hello from 127.0.0.1-2252
Send Hello from 127.0.0.1-2253-12345
Receive: Hello from 127.0.0.1-2253
Send Hello from 127.0.0.1-2254-12345
Receive: Hello from 127.0.0.1-2254
Send Hello from 127.0.0.1-2255-12345
Receive: Hello from 127.0.0.1-2255
Send Hello from 127.0.0.1-2256-54321
Receive: Hello from 127.0.0.1-2256
Send Hello from 127.0.0.1-2257-12345
Receive: Hello from 127.0.0.1-2257
Send Hello from 127.0.0.1-2258-12345
Receive: Hello from 127.0.0.1-2258
Send Hello from 127.0.0.1-2259-12345
Receive: Hello from 127.0.0.1-2259
Send Hello from 127.0.0.1-2260-54321
Receive: Hello from 127.0.0.1-2260
Send Hello from 127.0.0.1-2261-12345
Receive: Hello from 127.0.0.1-2261
Send Hello from 127.0.0.1-2264-12345
Receive: Hello from 127.0.0.1-2264
Send Hello from 127.0.0.1-2266-54321
Receive: Hello from 127.0.0.1-2266
Send Hello from 127.0.0.1-2268-54321
Receive: Hello from 127.0.0.1-2268
Send Hello from 127.0.0.1-2270-12345
Receive: Hello from 127.0.0.1-2270
Send Hello from 127.0.0.1-2271-54321
Receive: Hello from 127.0.0.1-2271
Send Hello from 127.0.0.1-2272-54321
Receive: Hello from 127.0.0.1-2272
Send Hello from 127.0.0.1-2273-54321
Receive: Hello from 127.0.0.1-2273
Send Hello from 127.0.0.1-2274-54321
Receive: Hello from 127.0.0.1-2274
Send Hello from 127.0.0.1-2278-54321
Receive: Hello from 127.0.0.1-2278
Send Hello from 127.0.0.1-2279-54321
Receive: Hello from 127.0.0.1-2279
Server does not respond.
Server does not respond.
Server does not respond.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 17 май 2010, 17:48 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Создание анимаций в автоматическом режиме.

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

Первым делом определить класс Animate_From_List, являющийся изменённым классом TransitionAnimation.
Код:
    class Animate_From_List(renpy.display.core.Displayable):
        """
        A displayable that draws an animation with each frame separated
        by a transition.
        """

        def __init__(self, animlist, **properties):
            """
            This takes arguments such that the 1st, 4th, 7th, ...
            arguments are displayables, the 2nd, 5th, 8th, ... on arguments
            are times, and the 3rd, 6th, 9th, ... are transitions.

            This displays the first displayable for the given time, then
            transitions to the second displayable using the given
            transition, and shows it for the given time (the time of the
            transition is taken out of the time the frame is shown), and
            so on.

            The last argument may be a displayable (in which case that
            displayable is used to transition back to the first frame), or
            a displayable (which is shown forever).

            There is one keyword argument, apart from the style properties:
           
            @param anim_timebase: If True, the default, use the animation
            timebase. Otherwise, use the displayable timebase.
            """

            properties.setdefault('style', 'animation')
            self.anim_timebase = properties.pop('anim_timebase', True)

            super(Animate_From_List, self).__init__(**properties)

            images = [ ]
            delays = [ ]
            transitions = [ ]
           
            for i, arg in enumerate(animlist):

                if i % 3 == 0:
                    images.append(renpy.easy.displayable(arg))
                elif i % 3 == 1:
                    delays.append(arg)
                else:
                    transitions.append(arg)

            if len(images) > len(delays):
                delays.append(365.25 * 86400.0) # One year, give or take.
            if len(images) > len(transitions):
                transitions.append(None)

            self.images = images
            self.prev_images = [ images[-1] ] + images[:-1]
            self.delays = delays
            self.transitions = [ transitions[-1] ] + transitions[:-1]
               
               
        def render(self, width, height, st, at):

            if self.anim_timebase:
                orig_t = at
            else:
                orig_t = st

            t = orig_t % sum(self.delays)
               
            for image, prev, delay, trans in zip(self.images, self.prev_images, self.delays, self.transitions):
                if t < delay:
                    if not renpy.game.less_updates:
                        renpy.display.render.redraw(self, delay - t)

                    if trans and orig_t >= self.delays[0]:
                        image = trans(old_widget=prev, new_widget=image)
                   
                    im = renpy.display.render.render(image, width, height, t, at)
                    width, height = im.get_size()
                    rv = renpy.display.render.Render(width, height)
                    rv.blit(im, (0, 0))

                    return rv
               
                else:
                    t = t - delay

        def visit(self):
            return self.images


Затем, собственно функция:
Код:
    def animate(set,delay=0.25,function=None,transition=None):
        list1 = []
        list2 = []
        # if set is path
        if set[0] is '/':

            #build image list
            for fname in os.listdir(config.gamedir + set):
                if fname.endswith(('.png')):
                    list1.append(set[1:]+'/'+fname)
       
        # if set is list
        else:
            list1 = set
       
        #build list with delays and transitions
        for image in list1:
            list2.append(image)
           
            if function:
                list2.append(function(delay))
            else:
                list2.append(delay)
               
            list2.append(transition)
           
        return Animate_From_List(list2)


Входные параметры:
set - путь к папке с файлами (внимание, обязательно должен начинаться на слэш, как абсолютный путь в линуксе) или готовый список файлов.

delay - задержка. По умолчанию четверть секунды.

function - Если None, то задержка линейна. Если это указатель на функцию распределения, то delay рассматривается как её коэффициент.

transition - переход, например Dissolve(0.25)

Возвращаемое значение:
Анимация, которую можно выводить через show (или renpy.show)

Использование:
image anim = animate("/gfx/units/ally/00/idle")
или
image anim = animate(["frame1.png","frame2.png"],delay=0.5,function=exp_distribution,transition=Dissolve(0.5))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 26 май 2010, 18:48 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Автоматическое конвертирование bmp и jpg в png с удалением фона (если фон - один цвет, "цветовой ключ") и обрезкой (с точностью до пикселя).

Это не прямо для RenPy, но несомненно будет полезно обработать этим скриптом изображения перед их использованием. Скрипт заменит весь цветовой ключ прозрачными пикселями путём наложения маски (аналогично im.AlphaMask), а затем обрежет все пустые области.


Вложения:
Комментарий к файлу: Содержание:
1) Исходное изображение
2) Обработанное изображение
3) Сам скрипт

convert_&_crop.zip [17.65 Кб]
Скачиваний: 26
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 11 июн 2010, 07:06 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Отрыл на лемма-софт пару довольно любопытныхх рецептов, которые лично мне оказались очень полезны.

1) Тултипы (всплывающие подсказки)
Код:
init python:
    class Tooltip(object):
        def __init__(self, x, y, message):
            self.x = x
            self.y = y
            self.message = message
           
            self.tip = None

        def show(self):
            self.tip = ui.frame(xpos=self.x, ypos=self.y)
            ui.text(self.message)
            renpy.restart_interaction()
           
        def hide(self):
            if self.tip:
                ui.remove(self.tip)
                renpy.restart_interaction()
                self.tip = None
           
label start:

    python:
        ui.hbox()
        tt = Tooltip(0, 100, "The force is with you!")
        ui.textbutton("Yes", clicked=ui.returns(True), hovered=tt.show, unhovered=tt.hide)
        tt = Tooltip(0, 100, "If you only knew the power of the Dark Side.")
        ui.textbutton("No", clicked=ui.returns(False), hovered=tt.show, unhovered=tt.hide)
        ui.close()

        ui.interact()


2) Функция, определяющая размер изображения
Код:
def getsize(img):
    myDisplayable = im.Image(img)
    myRender = renpy.render(myDisplayable, 800, 600, 0, 0)
    sizes = myRender.get_size()
    x = sizes[0]
    y = sizes[1]
    return x,y


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Сборник решений для RenPy
СообщениеДобавлено: 23 июн 2010, 17:24 
Не в сети
Фанат
Аватара пользователя

Зарегистрирован: 09 июл 2009, 11:16
Сообщения: 51
Контроль позиции курсора.

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

Это - в блок init.
Код:
    def cursor_control_function(st,at):
        return Text(''), 0.01
   
    renpy.image('cursor_control_anchor',DynamicDisplayable(cursor_control_function))
   
    class MouseControl(object):
        def __init__(self, x1, y1, x2, y2, anchor = 'cursor_control_anchor'):
            self.x1 = x1
            self.x2 = x2
            self.y1 = y1
            self.y2 = y2
            self.anchor = anchor
        def control(self,dsp,st,at):
            x,y = pygame.mouse.get_pos()
            if x < self.x1:
                pygame.mouse.set_pos(self.x1,y)
            if x > self.x2:
                pygame.mouse.set_pos(self.x2,y)
            if y < self.y1:
                pygame.mouse.set_pos(x,self.y1)
            if y > self.y2:
                pygame.mouse.set_pos(x,self.y2)
        def grab(self):
            renpy.show('cursor_control_anchor',at_list=[Transform(function=self.control)],tag=self.anchor)
        def release(self):
            renpy.hide(self.anchor)


Инициализация - cursor = MouseControl(0,0,1024,768)
Координаты прямоугольника который не должен покинуть курсор в виде координат верхего левого угла затем нижнего правого.

Захват курсора - cursor.grab()

Отключение режима контроля движения - cursor.release()

Применять её как правило надо сразу после ui.interact.
Можно и несколько зон назначить, но надо для каждой свой якорь. И можно даже их одновременно запустить - всё будет работать. Только если так получится что зоны не пересекаются ни в одном пикселе - будут проблемы.

Нигде не вычитал, писал сам.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
 cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB

Evangelion only Evangelion Not End! Всё Лучшее о Евангелион - Здесь! WinKiller Studio Zidane's Blog VNDb - Visual Novels Database