Перейти к содержанию
АнимеФорум

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

  • Ответов 1 тыс
  • Создана
  • Последний ответ

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

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

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

Опубликовано (изменено)

http://lemmasoft.ren...3&hilit=textbox

http://lemmasoft.ren...t=9812&p=127872

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

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

Хочу сделать так, чтобы время на ввод кода ограничивалось.

 

init:

   python:

       
       def countdown(st, at, length=0.0):

           remaining = length - st

           if remaining > 5.0:
               return Text("%.1f" % remaining, color="#fff", size=72), .1
           elif remaining > 0.0:
               return Text("%.1f" % remaining, color="#f00", size=72), .1
           else:
               return anim.Blink(Text("0.0", color="#f00", size=72)), None
       image countdown = DynamicDisplayable(countdown, length=20.0)
label start:
   show countdown at Position(xalign=.1, yalign=.1)

 

Меняю так:

if remaining > 5.0:
               return Text("%.1f" % remaining, color="#fff", size=72), .1
           elif remaining > 0.0:
               return Text("%.1f" % remaining, color="#f00", size=72), .1
           else:
               jump end

Ошибка в синтаксисе. Может неправильно использовать команду джамп?

Опубликовано (изменено)
Ошибка в синтаксисе. Может неправильно использовать команду джамп?

Угу, вся функция "countdown" написана в блоке <python>, т.е. все команды должны быть на питоне. Эквивалентом команды <jump> будет <renpy.jump ("end")>

Ах, да - самое главное! Не забудьте в самом начале блока "end" скрыть с экрана этот самый "countdown" <hide countdown> - иначе условие о том, что время истекло будет всегда выполнено, и программа "бесконечно" будет совершать переход к блоку "end".

Изменено пользователем Алекс__ (смотреть историю редактирования)
Опубликовано
Что за переменная (как называется, какое значение по умолчанию присвоено)? В тексте ошибки говориться (если я правильно понял), что вы пытаетесь прибавить числовое значение к функции (а не к другому числовому значению).
Опубликовано (изменено)
label start:
   $ say = 0
   menu:
         "Первый пункт":
             $ say += 1
         "Второй пункт":
             pass

jump result2
label result2:
   if say >0:
       jump dal5
   else:    
       "Плохая концовка."     

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

Понятно, <say> - это функция Рен'пи

$ renpy.say ( e, "Hey, it is me talking!")
e "Hey, it is me talking!"

 

Если в качестве имен переменных использовать слова, зарезервированные Рен'пи для своего использования (названия функций и т.п.), то это приведет к ошибкам (не стоит называть переменные "jump", "int", "str", "show" и т.д.) Здесь, как в том анекдоте, лучше всего использовать "длинные_и_понятные_имена_переменных".

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

Вот собственно и код "ошибки" - http://i071.radikal.ru/1108/a0/ed042686f9a8.jpg

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

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

Вот собственно и код "ошибки" - http://i071.radikal....d042686f9a8.jpg

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

Похоже на использование нескольких countdown'ов...

Можно попробовать скрывать их все после того, как осуществляется перекидка... Либо вообще не использовать countdown если нет необходимости отображать таймер, а воспользоваться функцией <timer> (нужна версия 6.12). Вот несколько ссылок - может пригодятся

http://lemmasoft.ren...ug+in+Ren%27Py.

http://lemmasoft.ren...ug+in+Ren%27Py.

 

http://www.renpy.org...ght=timer#timer

Опубликовано
Отображать таймер надо обязательно, что бы игрок видел, сколько у него времени на раздумье (выбор вариантов). Вот про скрывание - что именно имеете в виду? Например какой командой скрывать, обычной countdown=false или что-то ещё?
Опубликовано

Если countdown сделан так:

def countdown(st, at, length=0.0):

           remaining = length - st

           if remaining > 5.0:
               return Text("%.1f" % remaining, color="#fff", size=72), .1
           elif remaining > 0.0:
               return Text("%.1f" % remaining, color="#f00", size=72), .1
           else:
               return anim.Blink(Text("0.0", color="#f00", size=72)), None
       image countdown = DynamicDisplayable(countdown, length=20.0)

то <show countdown> и <hide countdown>.

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

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

Ну сохраняться во время выбора варианта как-то бредово, так что пофиг :)

 

А вот с "hide countdown" проблемы. Подобное скрывание стоит в самом начале кода какого-либо выбора, и так же стоит в самом начале кода куда кидает принудительно.

Если выбирать какой-либо вариант, то всё в порядке. Когда перекидывает принудительно, то в самой игре тоже всё ок, таймер скрывается как и полагается, с "критом" не вышибает. Просто при завершении самой игры (т.е. при обычном выключении) выдаётся сообщение, что была утеряна память (высвечивается только когда были принудительные перекидывания, в остальном без сообщения)

Опубликовано
Забавно получается - скачал 6.12.2 версию, запустил через неё - сообщение перестало вылезать... но теперь после первого принудительного перекидывания начинает постоянно кидать сразу же без выбора вариантов в следующих действиях. Пойду рыться и смотреть, как можно это дело пофиксить.
  • 1 месяц спустя...
Опубликовано

Приветствую.

Алекс, таймер можно сделать на потоках, например так.

 

А вообще на этом шикарнейшем фреймворке можно писать далеко не только игры и как пример - "Программа-таггер для раздела "Арт" сайта 4otaku.ru.

 

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

(практически чистый питон):

 

# Здесь основные предустановки и функции безотносительные к игре.
# Он у меня кочует из проекта в проект и может быть свободно распространён.
init python: 

##################### Системные установки #####################

   import os,pygame,math,sys,random
   import xml.etree.ElementTree as xmldb
   
   # установка окна игры по центру
   # полезно если запускается не в полный экран
   os.environ['SDL_VIDEO_CENTERESD'] = '1'
   
   sys.setdefaultencoding('utf-8')
   
   # лень писать заглавные
   true = True
   false = False
   none = None
   
   result = True

   # иногда может глючить при сохранении, тогда убрать коммент
   # config.use_cpickle = False

######################## Расположения ########################

   top = Position(xalign = 0.5,yalign=0)
   bottom = Position(xalign = 0.5,yalign=1.0)
   left = Position(xalign = 0.0,yalign=0.5)
   right = Position(xalign = 1.0,yalign=0.5)
   center = Position(xalign = 0.5,yalign=0.5)
   
   almost_top = Position(xalign = 0.5,yalign=0.1)
   almost_bottom = Position(xalign = 0.5,yalign=0.9)
   almost_left = Position(xalign = 0.1,yalign=0.5)
   almost_right = Position(xalign = 0.9,yalign=0.5)
   
   upright = Position(xalign = 1.0,yalign=0.0)
   upleft = Position(xalign = 0.0,yalign=0.0)
   downright = Position(xalign = 1.0,yalign=1.0)
   downleft = Position(xalign = 0.0,yalign=1.0)
   
   up_quarter_left = Position(xalign = 0.25,yalign=0.0)
   up_quarter_right = Position(xalign = 0.75,yalign=0.0)    
   down_quarter_left = Position(xalign = 0.25,yalign=1.0)
   down_quarter_right = Position(xalign = 0.75,yalign=1.0)
   
   center_up = Position(xalign = 0.5,yalign = 0.25)
   
########################## Изображения ##########################
   renpy.image('bg black',Solid((0,0,0,255)))
   renpy.image('bg blood',Solid((150,6,7,255)))
   # цвета определены в colors.rpy

##################### Автоассоциирование #####################
   
   # фоны с автоподгонкой размера изображения под размеры экрана
   # вызов производится "show bg <filename>" 
   # имя файла без расширения
   for fname in os.listdir(config.gamedir + '/gfx/bg'):
       if fname.endswith(('.jpg')):
           tag = 'bg ' + fname[:-4]
           image =  'gfx/bg/' + fname
           renpy.image(tag,im.Scale(image,config.screen_width,config.screen_height))

##################### Остальное #####################
   
   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_fadeout(d, st, at):
        d.alpha = max(0.0, 1.0 - st / 2.0)
        return 0

   def particle_burst(img, xs, ys, xrad=0.05, yrad=0.05, wave=13, cnt=10):
       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))
   
   # возвращает последовательнось например 1-2-3-2-1
   def arcrange(start,end,step=1):
       list = []
       
       for i in range(start,end+1):
           list.append(i)
       
       pos = len(list)
       
       for i in range(start,end):
           list.insert(pos,i)
       
       return list
    
   # округление
   def math_round(number):
       integer,fraction = math.modf(number)
       if fraction >= 0.5:
           integer = math.ceil(number)
       else:
           integer = math.floor(number)
       return int(integer)

   # получить знак числа
   def sign(number):
       if number > 0:
           return 1
       elif number < 0:
           return -1
       else:
           return 0
   
   # эта функция не делает ничего, совсем ничего...
   def do_nothing():
       pass
   
   # боремся с целочисленным по умолчанию делением
   def divide(n1,n2):
       return float(n1)/float(n2)
   
   # бросок стогранной кости. value - шанс, max - грани
   # например if dice(60): означает вероятнось в 60% 
   def dice(value,max=100):
       number = random.randrange(0,max+1)
       if number <= value:
           result = True
       else:
           result = False
       if config.developer:
           notify(u"Выпало %d из %d, предел - %d, итог - %s."%(number,max,value,str(result)))
       return result
    
   # выбрать случайный вариант из предложенных
   def select(variants):
       result = random.choice(variants)
       if config.developer:
           notify(u"Выбрано '%s'."%str(result))
       return result
   
   # выяснить что за нафиг путём записи нужных сообщений в файл
   # хотя вообще-то wtf = Write To File, но пользоватьей приходится
   # когда думаешь WTF?! в другой расшифровке...
   def wtf(message,logfile="bughunt.txt"):
       file = open(renpy.loader.transfn(file),"a")
       file.write(str(message)+"\n")                
       file.close()
       
   # обёртка над оповещалкой
   def notify(message,style=False):
       if config.developer:
           if style: 
               msg = "{=%s}%s"%(style,str(message))
               renpy.notify(u"%s"%msg) 
           else:
               renpy.notify(u"{size=+10}%s"%str(message))          
   
   # безопасный джамп
   # если метки нет, игра не вылетит а просто сообщит об этом
   def jump(labelname):
       if renpy.has_label(labelname):
           notify("jump %s"%labelname)
           renpy.jump(labelname)
       else:
           notify(u"Метки '%s' не существует."%labelname)  
    
   # анализ строк и превращение их целые, дробные, и логические значения
   def parse(string):
       try:
           value = int(string)
       except TypeError:
           value = string
       except AttributeError:
           value = string
       except ValueError:
           try:
               value = float(string)
           except ValueError:
               if string.lower() in ['true','yes','on']:
                   value = True
               if string.lower() in ['false','no','off','none']:
                   value = False
               else:
                   value = string
       return value
   
   # Первая часть работы с базами данных - автокласс
   # Универсальная структура данных
   class Structure(object):
       def __init__(self,namespace=None): 
           self.flags = []
           if namespace:
               for key in namespace:
                   self.set(key,namespace[key])
       def get(self,par): return self.__dict__[par]
       def namespace(self): return self.__dict__
       def has(self,par): return self.__dict__.has_key(par)
       def set(self,par,value): self.__dict__[par] = value
       def mod(self,par,value): self.__dict__[par] += value
       def flag(self,flag): return flag in self.flags
       def setflag(self,flag): 
           if flag not in self.flags:
               self.flags.append(flag)
       def delflag(self,flag): 
           if flag in self.flags:
               self.flags.remove(flag)
   
   # вторая часть движка для работы с базами
   # разбор файла и загрузка его в словарь
   # выловленный в инете скрипт разбора ини доработан
   # для работы ещё и с хмл 
   def dict_from_config_file(file, raw=false, vars=None): 
       result = dict()

       if file[-3:] == 'ini':
           """Convert an INI file to a dictionary""" #from cherrypy 
           inifile = ConfigParser() 
           inifile.read(renpy.loader.transfn(file))     # Parse config file 
        
           # Load INI file into a dict 
           for section in inifile.sections(): 
               result[section] = dict() 
               for option in inifile.options(section): 
                   v = inifile.get(section, option, raw, vars) 
                   result[section][option] = v
                   
       elif file[-3:] == 'xml':
           tree = xmldb.parse(renpy.loader.transfn(file)).getroot()
           for node in tree:
               if not node.attrib.has_key('id'): node.attrib['id'] = node.tag 
               result[node.attrib['id']] = node.attrib
               result[node.attrib['id']]['xml'] = node
       return result    
    
   # Третья часть движка для работы с базами
   # превращаем словари в объекты и обрабатываем значения
   # 'true','yes','on','false','no','off' - станут логическими
   # числа без точки - станут целыми
   # числа с точкой - станут дробными
   # строки - строками и останутся ))
   # за это отвечает функция parse() определённая ранее
   # Параметры:
   # dic - можно вставить в существующий словарь, или использовать новый
   # entity - класс который создавать, имненно ссылка на тип существующего класса
   # perform_init - выполнить метод "init" ( не __init__ ) после загрузки 
   def load_database(file,dic = None,entity = Structure,perform_init = False):
       db = dict_from_config_file(file)
       if not dic:
           dictionary = dict()
       else:
           dictionary = dic
       for entry in db:
           dictionary[entry] = entity()
           for key in db[entry]:
               dictionary[entry].__dict__[key] = parse(db[entry][key])
               dictionary[entry].id = entry 
       
       if perform_init: 
           for entry in dictionary:        
               dictionary[entry].init()

       return dictionary

   # покажет позицию курсора если вывести рисунок cursorPosition
   # show cursorPosition on bottom
   def cursorPositionFunction(st, at):
       x,y = pygame.mouse.get_pos()
       return Text("{size=+10}%d - %d"%(x,y)), .1   

       
image cursorPosition = DynamicDisplayable(cursorPositionFunction)
           
label _instant_exit: 
   $renpy.quit()
   
label _full_restart: 
   $renpy.full_restart()

# добавляет в нижний левый угол несколько полезных на стадии разаработки примочек
screen debugTools:
   hbox:        
       xalign 0
       yalign 1.0
       button:
           text "X"
           action ui.callsinnewcontext("_instant_exit")
       button:
           text "R"
           action ui.callsinnewcontext("_save_reload_game")
           
       add(DynamicDisplayable(cursorPositionFunction)) yalign 0.5

 

Полная версия прикреплена к сообщению.

 

До недавнего времени ковырял свой проект, начатый в августе 2009, после завершения работы над модом "Конец одиночества" к игре "Проект воспитания Аянами Рей" но недавно присоединился к разработке Alkion (солянка из WhoreMaster, OtherWorld, RoyalHunt) и сейчас работаю с ними, перетащив туда большую часть кода (так как игры схожие по плану с технической стороны) с планами доработать его во время разработки Алькиона и перетащить назад усовершенствованные.

Скриншоты текущей версии можно посмотреть здесь.

 

Если кому интересно - контакты в профиле.

library.zip

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

Посидел вечерок и организовал таймер на версии Ренпи 6-12-2.Под спойлером полный код.

Создай новый проект и замени содержимое script.rpy содержимым спойлера.

 


define e = Character('Eileen', color="#c8ffc8")

init python:
   import thread,time
   
   # функция, которая будет запущена в другом потоке
   def timer():
       renpy.notify(u"Таймер запущен.")
       while True: # бесконечный цикл
           time.sleep(1) # ждём секунду
           persistent.timer_counter -= 1 # уменьшаем счётчик
           renpy.notify(u"%d"%persistent.timer_counter) # оповещаем пользователя
               
           if persistent.timer_counter == 0: # время почти вышло
               time.sleep(1) # последняя секунда
               persistent.timer_result = False # результат - не успели
               return
    
   # запуск таймера
   def start_timer(time):
       persistent.timer_counter = time # время в секундах 
       persistent.timer_result = True # результат Истина пока время не истечёт
       thread.start_new_thread(timer,()) # запускаем поток.
    
   # переход по результатам таймера
   def timed_jump(success,failure):
       # если успели
       if persistent.timer_result:
           persistent.timer_counter = 1 # фактически, это отключает таймер
           renpy.jump(success) 
       # если не успели
       else:
           renpy.jump(failure)
    
   # отключение таймера и переход, вне зависимости от результатов
   def no_timed_jump(destination):
       persistent.timer_counter = 1
       renpy.jump(destination)
        
# Поехали!         
label start:
   e "На следующий выбор вам будет дано ограниченное время."
   $start_timer(10) # запускаем таймер на 10 секунд
   menu timed_menu:
       "Выбирай мудро (и быстро)!"
       "Сесть на автобус":
           $timed_jump("MadeInTime","TooSlow")
       "Подождать другого":
           $no_timed_jump("WaitingAnotherBus")
           
   return

label MadeInTime:
   e "Вы успели."
   return

label TooSlow:
   e "Автобус ушёл."
   jump WaitingAnotherBus
   return    
   
label WaitingAnotherBus:
   e "Подожду другого, может хоть там свободные места будут."
   return    

 

Если что - обращайся.

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

Здравствуйте. Пытаюсь в Ren'Py реализовать такую идею: подводим курсор к определенному месту экрана, картинка начинает двигаться, убираем курсор, движение прекращается.

Вопрос Элионту. Как переделать твою функцию:

 

def cursorPositionFunction(st, at):
   	x,y = pygame.mouse.get_pos()
   	return Text("{size=+10}%d - %d"%(x,y)), .1  

 

чтобы она возвращала x,y мыши в реальном времени? И как ее правильно вызывать в Ren'Py?

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

Здравствуйте. Пытаюсь в Ren'Py реализовать такую идею: подводим курсор к определенному месту экрана, картинка начинает двигаться, убираем курсор, движение прекращается.

 

Если используете версию Рен'пи 6.13.х то вам поможет <mousearea>. Здесь пример кода, который показывает экран с кнопками когда подводишь мышь к верхнему краю экрана и убирает его, когда мышь отводят вниз http://www.renpy.org/doc/html/screens.html#sl-mousearea (transition=dissolve - эффект с которым показывается/скрывается окно).

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

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

Вопрос Элионту.

Определяем скрин.

# добавляет в нижний левый угол несколько полезных на стадии разаработки примочек
# X - мгновенный выход, в обход диалога подтверждения
# R - перекомпиляция игры
# также отображает текущие координаты курсора
screen debugTools:
   hbox:        
       xalign 0
       yalign 1.0
       button:
           text "X"
           action ui.callsinnewcontext("_instant_exit")
       button:
           text "R"
           action ui.callsinnewcontext("_save_reload_game")
           
       add(DynamicDisplayable(cursorPositionFunction)) yalign 0.5

Показываем его при запуске игры.

Будет в реальном времени.

# The game starts here.
label start:
   show screen debugTools

Common.rpy.new_version.zip

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

Вот код:

init:
python:
   	def cursorPositionFunction(st, at):
       	x,y = pygame.mouse.get_pos()
       	return x

label start:
python:
       	x = cursorPositionFunction
       	if x > 600:
           	ui.image ("photo2.jpg")
centered ""
return

Координата х определяется, но только один раз, при вызове функции.

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

(как при DynamicDisplayable)

С <mousearea> пока не получается. Хотелось бы решить эту задачу на одном screen.

Опубликовано (изменено)

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

 

Используй скрин а не функцию. С функцией в версии старше 6.12 работать не будет.

 

А пример работы (и код) mousearea можно посмотреть в этой новелле-рецепте (подведя мышку к верхнему краю экрана) которую я делал для знакомого с 4otaku.

 

Является переделанной версией "Набора для создания визуальной новеллы Хроники Валькирии".

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

Элионт и Алекс__ еще раз спасибо за помощь. Все получилось. Кстати очень понравилась новелла-рецепт.

Выкладываю пример: "Прокрутка панорамы". Может кому пригодится :rolleyes:

ps. (Как реализовать бесшовную прокрутку пока не придумал)

panorama.zip

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

(Как реализовать бесшовную прокрутку пока не придумал)

 

 

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

хм, сам не понял, что написал...(

Вобщем, начало картинки и конец картинки должны быть одинаковыми (панорама будет не 360 градусов а больше).

 

 

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

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

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

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

Загрузка...
×
×
  • Создать...

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