Форум » » Всякие полезные механики » Ответить

Всякие полезные механики

Ajenta: Пришло мне тут в голову, что у нас давно никто не делился опытом грабленаступания. Поэтому создаю тему, где все могут рассказать какими извратами и хитростями пользуются при написании игр. Начну вот с чего: Конечно, всегда хочется, чтобы игра была сложной, интересной и отвечала на все твои реакции. А для этого у одной и то й же локации должно быть много описаний. Сейчас как раз делаю игру, где у меня минимум пять описаний одного и того же места. Дабы не плодить сущности, можно делать так - :озеро if были_озеро = 1 then goto озеро_грязное if были_озеро = 2 then goto озеро_замёрзло if были_озеро = 3 then goto озеро_высохло if были_озеро = 4 then goto озеро_больше_не_озеро pln Описание end Удобно то, что всё это одна и та же локация, и курлок будет всегда одинаковым. Так же я не плодю безмерно условия в самой локации, а делю её, это очень помогает, потому что ифы это слабая сторона урки.

Ответов - 39, стр: 1 2 All

Ajenta: Продолжу. Когда пишешь код условий, он превращается порой в нечитабельное страшное нечто, в котором сложно что-то быстро поправить и сложно не наделать ошибок при этой самой правке. Приведу пример кода из своей последней игры. Как бы это выглядело, если бы было написано обычным способом if ледяной_показался = 0 then ледяной_показался = 1 & pln Войдя в пещеру, я тут же наткнулся на ледяного элементаля. Конечно же он попытался меня убить. Погонявшись за мной кругами по пещере и так и не догнав, он издал душераздирающий вопль и во все стороны полетели острые ледяные шипы. Но всё же, я успел выбраться из пещеры. Фуух. Это было опасно. & pln & pln & pln [[~ Отойти от пещеры.|ледник]] & proc ударить_молотом_ледника else pln С холодеющим сердцем, я зашёл в пещеру. Ледяной элементаль издал вопль радости и набросился на меня. Что ж, кажется, это была плохая идея. & if молот_взят = 1 then pln & pln & pln [[~ Ударить элементаля молотом.|элементаль_молот]] else anykey & goto провал Вроде бы и нормально, но мне не нравится. А теперь как это написано у меня в игре. if ледяной_показался = 0 then _ ледяной_показался = 1 & _ pln Войдя в пещеру, я тут же наткнулся на ледяного элементаля. Конечно же он попытался меня убить. Погонявшись за мной кругами по пещере и так и не догнав, он издал душераздирающий вопль и во все стороны полетели острые ледяные шипы. Но всё же, я успел выбраться из пещеры. Фуух. Это было опасно. & _ pln & pln & _ pln [[~ Отойти от пещеры.|ледник]] & _ proc ударить_молотом_ледника _ else _ pln С холодеющим сердцем, я зашёл в пещеру. Ледяной элементаль издал вопль радости и набросился на меня. Что ж, кажется, это была плохая идея. & _ if молот_взят = 1 then _ pln & pln & _ pln [[~ Ударить элементаля молотом.|элементаль_молот]] _ else _ anykey & goto провал Длиннее, но зато всё понятно - что в каком блоке и что вообще происходит.

Ajenta: Решение для пола в игре или "иду на Вы". Захотелось мне однажды сделать в игре выбор пола для главного персонажа. Но тут возникли трудности, ведь нужно не только учесть разное отношение неписей к гг, но и все эти описания поступков и действий написать от правильного лица. Мне сильно помогло то, что во всех историях с возможностью выбора пола, я употребляю форму обращения к игроку на вы. Потому что если написать предложение "Вы пошли налево и встретили своего давнего знакомого." - это одинаково подойдёт для любого пола героя. :) Возможно, это очевидно, но вдруг кто-то будет мучиться такой же проблемой.

Saint: О Великая и Ужасная гуру кода урки снизошла до нас с небес своей блистательной славы! (знаки препинания сами расставляйте) Я прям для себя нашел весчи интересные! Ну оно и понятно - опыта у Адженты ого-го!!! Продолжай!!!


Cheshire: Ajenta пишет: Длиннее, но зато всё понятно - что в каком блоке и что вообще происходит. Могу ещё посоветовать использовать табуляцию: [pre2]if ледяной_показался = 0 then _ ледяной_показался = 1 & _ pln Войдя в пещеру, я тут же наткнулся на ледяного элементаля... & _ pln & pln & _ pln [[~ Отойти от пещеры.|ледник]] & _ proc ударить_молотом_ледника _ else _ pln С холодеющим сердцем, я зашёл в пещеру. Ледяной элементаль издал вопль радости и набросился на меня. Что ж, кажется, это была плохая идея. & _ if молот_взят = 1 then _ pln & pln & _ pln [[~ Ударить элементаля молотом.|элементаль_молот]] _ else _ anykey & goto провал[/pre2]

Saint: Не всегда примеры в документации понятны, поэтому когда-то попросил Серого Волка мне помочь, и вот что он мне написал: zagadka=1 ; не отгадана, принимает значение 2 после отгадки :vopros1 pln Отгадай загадку! pln "Два кольца, два конца, посредине - гвоздик" btn vopros2, Ответить end :vopros2 instr otvet= input otvet pln - #%otvet$! - говоришь ты. if otvet="ножницы" or otvet="Ножницы" then zagadka=2 & pln Да, ты прав. Уж если ты прав, то ты прав! else pln А вот и нет! if zagadka=2 then btn konec, Ура! if zagadka=1 then btn vopros1, Пробуй ещё end :konec pln Ты с треском победил! end Отличный пример использования оператора input

Cheshire: На просторах интернета можно найти множество свободных шрифтов, в том числе символьных. (Например, такой — Sosa). Если в текстовом декораторе в ссылках использовать такой шрифт, то можно получить основанный на иконках интерфейс. [pre2]:0 decoradd one (350,250,0) text "[[c|%1]]", 0xFFFFFFFF, "sosa.ttf[25,1,0.3,0xFF000000]" decoradd two (450,250,0) text "[[e|%1]]", 0xFFFFFFFF, "sosa.ttf[25,1,0.3,0xFF000000]" decoradd three (350,350,0) text "[[9|%1]]", 0xFFFFFFFF, "sosa.ttf[25,1,0.3,0xFF000000]" decoradd four (450,350,0) text "[[j|%1]]", 0xFFFFFFFF, "sosa.ttf[25,1,0.3,0xFF000000]" decorcol one 0xFFFFFFFF,0xff999999,0xFFffffff decorcol two 0xFFFFFFFF,0xff990000,0xFFff0000 decorcol three 0xFFFFFFFF,0xff009900,0xFF00ff00 end :1 btn z, Раз btn z, Два btn z, Три end [/pre2] Результат.

Ajenta: Не знала что так можно O__o instr otvet= Это оно пустую строку присвоит что ли?

Ajenta: Вдруг кому-то понадобится. Вычисление приблизительного квадратного корня. Делала пример для Эдди, ему нужно было хитро как-то декораторы вращать, но мало ли ещё кому пригодится. :1 a = 500 ;ставь любое число, из которого хочешь извлечь корень pln число равно = #a$ i = 1 :metka if i < #a$/2 then pln мы тут & _ x1 = i+1 & pln x1 = #x1$ & ;вычисляем первое число по формуле Xn+1 = (A/Xn + Xn)*1/2 _ x2 = (a/i + i)*1/2 & pln x2 = #x2$ & ;вычисляем второе число по формуле Xn+1 = (A/Xn + Xn)*1/2 _ fp_prec=0 & ;эта фигню нужна, чтобы отбросить цифры после запятой _ int_x2=#x2$ & pln int_x2 = #int_x2$ & ;приводим второе число к целому значению _ if x1 = int_x2 then pln корень равен - #x1$ else i = i + 1 & goto metka end

vito: Ajenta пишет: Не знала что так можно O__o instr otvet= Это оно пустую строку присвоит что ли? Ага. Это равноценно otvet="" А я думала, только настоящие мачо не читают документацию :)

frodo: Дополню совет Адженты насчет пола персонажа. Иногда можно перефразировать предложение. Например: Ты встретил(а) друга. -> Тебе встретился друг.Ты захотел(а) уйти. -> Тебе захотелось уйти. Настоящее время вместо прошедшего (что естественно для ИЛ) решает почти все проблемы: Ты решил(а) остаться -> Ты решаешь остаться.Ты устал(а) -> Ты чувствуешь усталость. А если сменять точку зрения, предложение получится не только универсальным, но и более емким: Ты пошёл(ла) налево и встретил(а) своего давнего знакомого. -> Тропинка увела тебя налево, взгляд уловил вдали знакомый силуэт.

frodo: Если игрок нажимает на кнопку, которая оставляет его на прежней локации, текст должен хоть как-то меняться. Самый "ленивый" вариант - если в начале локации или в Common есть cls, дописывать к тексту пробел: [pre2] :нажать cls пробел = not пробел if пробел then p ; Обратите внимание, 2 пробела после p pln Ничего не произошло. btn нажать, Нажать на кнопку. end [/pre2] Конечно, пробел можно заменить любой фразой, а также использовать if/else. Вариант чуть получше - внедрять в текст различные варианты фраз: [pre2]:нажать cls retry0="" retry1=" снова" retry2=" еще раз" retry3=" снова" retry4=" опять" retry5=" вновь" summary0="Кажется," summary1="По-прежнему" summary2="Все-таки" summary3="Можно больше не пытаться -" summary4="Бесполезно -" summary5="Как и первый раз," if count_нажать then _ x=rnd5 & y=rnd5 _ else _ x=0 & y=0 pln Ты нажимаешь на кнопку#%retry#x$$. #%summary#y$$ ничего не происходит. btn нажать, Нажать на кнопку#%retry#rnd5$$. end[/pre2] Недостаток такого подхода: если у вас всего лишь 1 набор фраз, а не 3, как в примере, они могут повторяться дважды подряд. Тогда лучше использовать ротацию вместо rnd: [pre2]if x >= 5 then x = 1 else x = x + 1[/pre2] Вот мой шаблон для ротации двух несвязанных реплик: [pre2] ;первая реплика temp10="" temp20="" temp30="" temp40="" temp50="" ;вторая реплика temp11="" temp21="" temp31="" temp41="" temp51="" temp61="" реплика1=реплика1+1 реплика2=реплика2+1 if реплика1>5 then реплика1=1 if реплика2>6 then реплика2=1 pln #%temp#реплика1$0$ pln #%temp#реплика2$1$ [/pre2] Первая фраза дает нам 5 вариантов, вторая 6. Если моя память не изменяет мне со знаниями математики , такой шаблон будет генерировать уникальные комбинации реплик, которые начнут повторяться лишь после 5 * 6 = 30 (тридцати) вызовов. Замечу, что для того, чтобы шаблон работал, разность между количеством реплик должна быть простым числом (в нашем случае 5-6=1). Простые числа: 1, 2, 3, 5, 7, 11, 13, 17 ...

frodo: Пример цензуры, как в Памяти Вселенной. В настройках устанавливаем флаг "censured". В локациях пишем: [pre2] temp0 = "Вся правда, как есть!" temp1 = "Зайчики, цветочки" pln #%temp#censured$$ [/pre2] Горшочек, не вари! :)

Prime: Frodo, есть ещё один способ осуществить смену пола без подбора синонимичных универсальных предложений: :start Pln Ваш пол: xbtn 1,{okonchanie1=""&okonchanie2="ёл"}, Мужской. xbtn 1,{okonchanie1="а"&okonchanie2="ла"}, Женский. end :1 Pln Ты решил#%okonchanie1$ выйти из комнаты, и подош#%okonchanie2$ к двери. end

Saint: Пример использования оператора common. Пример был написан для игры "Бабочки, мосты, хоббиты" и был использован в игровом лабиринте. Пример не мой, но очень понятный и доступный к пониманию. Заводим локацию common_1 при входе в лабиринт включаем переменную common=1 при выходе снова common=0 :common_1 безумие = безумие+1 if безумие = 5 then pln Мимо нас пробежала сосед Фрого, за которым гналась его жена Мила, с деревянной скалкой в руках. Странно, они всегда были дружной семьей... if безумие = 7 then pln Из подворотни выскочил старый пес и молча попытался вцепиться Корвусу в ногу. Корвус стукнул его обухом по голове и пес успокоился, виновато завилял хвостом и ушел обратно в подворотню.#/$ - Не нравится мне это - сказал Кровн. if безумие = 9 then pln Из-за забора доносились крики, шум и детский плач.#/$ - Маркус колотит детей, а Роза бегает за ним с метлой - сообщил Корвус заглянув в окно. Мы должны торопиться! end Как-то так.

Ajenta: Prime пишет: Frodo, есть ещё один способ осуществить смену пола без подбора синонимичных универсальных предложений: :start Pln Ваш пол: xbtn 1,{okonchanie1=""&okonchanie2="ёл"}, Мужской. xbtn 1,{okonchanie1="а"&okonchanie2="ла"}, Женский. end :1 Pln Ты решил#%okonchanie1$ выйти из комнаты, и подош#%okonchanie2$ к двери. end Это лучше использовать в диалогах, когда нпц обращается к персу или говорит о нём. Там действительно от окончаний пола не отделаешься.

frodo: Еще нашел в своей копилке полезностей. Процедура, которая позволяет автоматически генерировать сообщения о том, что инвентарь пытаются использовать неправильно. Полезна еще как примар трех идей: аргументы по умолчанию, описание использования в комментариях, "говорящие" названия переменных (по умолчанию это="это", этим="этим"). А еще к тексту дописываются пробелы (см. мой предыдущий пост) [pre2]:set_noinv ; set_noinv("это", "этим", "Комментарий") ; Неправильное использование инвентаря ; if set_noinv_1 then это = set_noinv_1 else это = "это" if set_noinv_2 then этим = set_noinv_2 else этим = "этим" if set_noinv_3 then noinv = set_noinv_3 else noinv = "Ничего не произошло." if tab=" " then tab = "" else tab = " " noinv1=" #%noinv$" noinv2=" Здесь #%это$ нельзя применить." noinv3=" Тут с #%этим$ нечего делать." noinv4=" Наверное, #%это$ следует применить в другом месте." noinv5=" Может, применить #%это$ в другом месте?" noinv6=" #%noinv$" noinv7=" И что с #%этим$ делать?" noinv8=" Что-то сделать с #%этим$? Слабо представляется..." noinv9=" #%noinv$" noinv10=" Наверное, с #%этим$ не сюда." noinv11=" Скорее всего, #%это$ стоит отнести куда-нибудь еще." noinv12=" Здесь #%это$ нельзя пристроить." noinv13=" #%noinv$" noinv14=" Очевидно, #%это$ нужно применить не здесь." noinv15=" Наверное, есть другой вариант использовать #%это$." noinv = "#%tab$#%noinv#rnd15$$" end[/pre2] Процедура устанавливает значение переменной noinv. Обратите внимание - комментарий (строки вида 'noinv1=" #%noinv$"') повторяется несколько раз, так что будет появляться чаще других сообщений. Пример использования: [pre2]:Use_Поднос_Применить clst proc set_noinv("поднос", "подносом", "Нет, поднос тут определенно не нужен.") if <условие> then pln Кэл отмывает поднос от грязи. if <другое условие> then proc Поднос_Применить if not <условие> and not <другое условие> then pln #%noinv$ End[/pre2] P.s. Может быть, следует как-то каталогизировать советы? Напримпр, хранить в шапке перечень со ссылками.

frodo: Иногда приходится выдавать пользователю большое количество текста. Обычно я стараюсь выводить текст так, чтоб он занимал не более чем 2/3 экрана - тогда он легче читается и не так вызывает скуку. Обычно это выглядит как часть текста, которая обрывается на интересном месте - плюс единственная кнопка "Дальше". В "Памяти Вселенной" я попробовал еще один подход - тест выводится побуквенно, словно его кто-то печатает. Таким образом, читатель следит взглядом за словами, что появляются на экране в умеренном темпе. Если нажать любую клавишу, печать ускоряется, но лишь до определенной точки. Конечно, такой подход требует тонкой настройки - с какой скоростью выводить слова, какой кусок выводить, если была нажата кнопка и проч. Программно это выглядит так: [pre2] temp=50 ; Стандартная пауза между символами temp1=2000 ; Пауза в конце абзаца temp2=500 ; Пауза в конце строки proc не_ускорить ; Just in case ; Начинаем неспеша proc type_string(" Бедный, бедный Калашников... ", 150, 1) proc type_string(" Вот, пришел и мой черед тебя навестить. Это я, Марина.", 150, 1) proc не_ускорить ; Если пользователь нажал на любую кнопку, до этого места текст выскакивает быстро proc type_string(" Пару месяцев назад Мангуст рассказывал о Неизбежности. ", temp, temp2, 1) proc type_string("Знаешь смысл", temp, temp) ; Тонкая настройка, как было сказано proc type_string("этого слова?", temp, temp1) ; Чтобы текст шел плавно, перевод строки вставляем вручную proc type_string(" Представь, что на шкафу стоит ваза. Однажды тебе покажется, что она #/$ _разобьется. Ты лезешь на шкаф, чтобы спасти вещицу, и случайно роняешь. ", temp, temp1) [/pre2] А вот код этих двух процедур: [pre2] :type_string ;type_string_1 - строка ;type_string_2 - пауза между символами ;type_string_3 - пауза в конце ;type_string_4 - не делать перевод строки ;ускорить - глобальная, если не равна 0, символы выводятся без задержки. instr tokens_delim=char tokens type_string_1 i=1 :type_string_cycle p #%token#i$$ if ускорить = 0 then anykey ускорить, #type_string_2$ i=i+1 if i<=tokens_num then goto type_string_cycle if type_string_4=0 then pln if ускорить = 0 then anykey ускорить, #type_string_3$ end :не_ускорить ; Используется вместе с type_string. Сбрасывает глобальную переменную "ускорить". ; Если была возведена, пауза (2 сек. по умолчанию) if not ускорить then end if not не_ускорить_1 then не_ускорить_1 = 2000 ускорить = 0 anykey ускорить, #не_ускорить_1$ end [/pre2]

Ajenta: Круто, но слишком сложно для меня :) Я с токенами до сих пор не лажу.

frodo: Ajenta, ничего сложного. Как говорил Вицин в "Операции "Ы"", всё уже украдено до нас. Если лень разбираться, достаточно запомнить что этот код: [pre2]proc type_string("Печатаю текст", 50, 200)[/pre2] выведет "Печатаю тест" с паузами в 50мс между буквами и 200мс в конце вывода. Разберем по командам: [pre2] instr tokens_delim=char ; указываем оператору "tokens" разбивать строки на отдельные символы (иначе будет разбивать на слова - см. документацию); tokens type_string_1 ; Тут понятно - первый аргумент (строка "Печатаю текст") передается оператору tokens ; Оператор tokens заполняет переменные: token1="П", token2="е", token3="ч", ... , а также tokens_num=13 (количество токенов, в нашем случае равно длине строки "Печатаю текст") p #%token#i$$ ; Выводим буквы по одной if i<=tokens_num then goto ... [/pre2] Отдельно хочу указать на эту конструкцию: [pre2]if ускорить = 0 then anykey ускорить, #type_string_2$[/pre2] Это довольно полезная штука. Ее суть: "Делать паузы, пока пользователь не нажмет на кнопку. Если нажал, больше пауз не делать." Чтобы паузы опять выполнялись, нужно переменную "ускорить" установить в 0. Если у вас в квесте пользователю приходится ждать больше 3 секунд, возьмите на вооружение, т.к. тех, кто будет проходить квест второй раз, ожидание будет раздражать.

Ajenta: Спасибо за пояснения. :)

Saint: frodo пишет: пользователю приходится ждать больше 3 секунд, возьмите на вооружение, т.к. тех, кто будет проходить квест второй раз, ожидание будет раздражать. а можно использовать оператор anykey z, - с тем же эффектом

frodo: Разница - в деталях. В этом случае пользователю нужно трижды нажать на кнопку, чтобы не ждать, пока напечатается "1 2 3 4": [pre2] p 1 anykey z, 1000 p 2 anykey z, 1000 p 3 anykey z, 1000 p 4[/pre2] В этом случае пользователю достаточно нажать на кнопку один раз: [pre2] z = 0 p 1 if not z then anykey z, 1000 p 2 if not z then anykey z, 1000 p 3 if not z then anykey z, 1000 p 4[/pre2]

vito: Как известно, в Фурке можно выводить ссылки, но нет возможности отключить их вывод. В следующем примере удаление ссылок из исходной строки реализовано в процедуре str_delink. Исходной строке соответствует переменная p_1, "обезссыленной" - dest_str. Процедура p_smb осуществляет посимвольный вывод строки dest_str; такой режим вывода позволяет "обмануть" фурочную систему форматирования ссылок. Тестовый пример выводит после цифры 1 - исходную строку, после 2 - строку, из которой удалены ссылки, после 3 - ее же, но посимвольно. [pre2] instr p_1=У [[Юрасоффа-Павловски]] [[]] [[|]] [[ ]] рябило в глазах от [[квадратных скобок||скобок]], [[в том числе[[ вложенных]].]] pln 1: #%p_1$ pln proc str_delink pln 2: #%dest_str$ p #/$ 3: proc p_smb end :str_delink ; Процедура удаления ссылок из строки mark_link_start=0 ; Флаг начала ссылки mark_long_opening=0 ; Флаг длинной (больше 2-х) последовательности открывающих скобок mark_link_end=0; Флаг конца ссылки dest_str="" ; Результирующая строка link_start_pos=0 ; Начальная позиция ссылки skip_start_pos=0 ; Начальная позиция неотображаемой части ссылки string_flushed=0 ; Флаг того, что строка уже выгружена i_str=1 ; Счетчик символов в строке ; Разбивка исходной строки на символы, перебор tokens_delim="char" tokens p_1 nr_tok0=tokens_num :str_cyc ; Начало цикла instr cur_symb=#%token#i_str$$ if cur_symb=="[" then proc parse_start_link & goto str_cyc_end ; Начало ссылки? if cur_symb=="|" then proc parse_skip_link & goto str_cyc_end ; Неотображаемая часть ссылки? if cur_symb=="]" then proc parse_end_link & goto str_cyc_end ; Конец ссылки? ; Все прочие символы if mark_link_start=1 or mark_link_end=1 then proc flush_string & goto str_cyc_end ; До этого была одиночная правая или левая квадратная скобка - в любом случае она "терминирует" ссылку (особенность Фурки) :str_cyc_smb ; Обработчик текущего символа в зависимости от установленных флагов начала и конца ссылки if mark_link_start=0 then dest_str=dest_str+token#i_str$ ; Ссылки нет - просто копируем очередной символ в результиирующую строку if mark_link_end=2 then proc flush_string & goto str_cyc_end; Ссылка окончилась - копирование "буфера" в результирующую строку с учетом неотображаемых символов ; Все остальные варианты означают, что идет обработка ссылки, и пока неизвестно, что именно будем копировать :str_cyc_end ; Замыкаем цикл i_str=i_str+1 if i_str<=nr_tok0 then goto str_cyc i_str=nr_tok0 if mark_link_start<>0 and string_flushed=0 then proc flush_string; Если мы здесь, это означает, что строка кончилась внутри предполагаемой ссылки - просто копируем "буфер" токенов в результирующую строку end :parse_start_link ; Отработка символа начала ссылки (левой квадратной скобки): устанавливаем необходимые флаги if mark_link_start=0 then mark_link_start=1 & link_start_pos=i_str & end ; Потенциальное начало ссылки if mark_link_start=1 then mark_link_start=2 & end; Двойная квадратная скобка - начало ссылки ; Все остальные случаи - мы внутри ссылки; "терминируем" ее и копируем пропущенные символы (до собственно скобки) в результирующую строку if i_str-link_start_pos<=2 then i_str=i_str-2 & mark_long_opening=1 else i_str=i_str-1 proc flush_string ; Возвращаемся на текущий символ i_str=i_str+1 if mark_long_opening=1 then i_str=i_str+1 ; Если была длинная последовательность, то мы сдвигались на два символа - вводим поправку if mark_long_opening=1 then mark_link_start=2 else mark_link_start=1 ; Устанавливаем значение флага начала ссылки - вдруг она сейчас и последует (с учетом наличия нескольких открывающих скобок подряд) if mark_long_opening=1 then link_start_pos=i_str-1 & mark_long_opening=0 else link_start_pos=i_str end :parse_skip_link ; Отработка символа, начинающего неотображаемую часть ссылки if mark_link_start=0 then dest_str=dest_str+token#i_str$ & end ; Мы вне ссылки - копируем очередной символ в результирующую строку if mark_link_start=1 or mark_link_end=1 then proc flush_string & end; До этого была одиночная правая или левая квадратная скобка - "терминируем" ссылку ; Если мы здесь, значит, мы внутри ссылки if skip_start_pos=0 then skip_start_pos=i_str ; С этого момента начинается неотображаемая часть ссылки ; Если уже началась неотображаемая часть ссылки, просто игнорируем данный символ end :parse_end_link ; Отработка символа окончания ссылки (правой квадратной скобки): устанавливаем необходимые флаги if mark_link_start=1 then proc flush_string & end ; До этого была одинарная левая квадратная скобка if mark_link_start=0 then dest_str=dest_str+token#i_str$ & end ; Мы не внутри ссылки - просто копируем очередной символ if mark_link_start=2 and (i_str-link_start_pos)<=2 then proc flush_string & end ; Сразу за двойной левой скобкой - правая, это не воспринимается как ссылка if mark_link_end=1 then mark_link_end=2 & proc flush_string & end ; Корректно завершенная ссылка if mark_link_end=0 then mark_link_end=1 ; Первая правая скобка, встретившаяся при обработке ссылки end :flush_string ; Процедура копирования "задним числом" ссылки в результирующую строку с последующим сбросом всех соответствующих флагов и переменных ; Имеется три режима копирования: (1) без учета ссылочного форматирования (когда предполагаемая ссылка не оказалась таковой); (2) копирование простой ссылки (сводится к пропуску обрамляющих ссылку двойных квадратных скобок); (3) копирование ссылки с невидимой частью if mark_link_end=2 then i_copy=link_start_pos+2 else i_copy=link_start_pos & skip_start_pos=0 & link_start_pos=0 ; Если нормальное завершение ссылки, устанавливаем позицию начала копирования строки с учетом пропуска двух открывающих скобок, в противном случае - без учета скобок и еще сбрасываем переменные, соответствующие позициям начала и окончания копирования if skip_start_pos=0 and link_start_pos=0 then i_copy_end=i_str ; Режим 1: ссылки нет - копируем до текущей позиции исходной строки включительно if skip_start_pos=0 and link_start_pos<>0 then i_copy_end=i_str-2; Режим 2: ссылка без невидимой части - копируем с учетом пропуска завершающих скобок if skip_start_pos<>0 then i_copy_end=skip_start_pos-1 ; Режим 3: ссылка с невидимой частью if i_copy>i_copy_end then goto fsl_fin ; Сразу после открывающих скобок начинается неотображаемая часть ссылки - просто пропускаем ее ; Собственно копирование :fsl_copy dest_str=dest_str+token#i_copy$ ; Перенос очередного символа в конечную строку i_copy=i_copy+1 if i_copy<=i_copy_end then goto fsl_copy ; Финальная часть: сброс всех флагов и переменных :fsl_fin mark_link_start=0 mark_link_end=0 link_start_pos=i_copy_end skip_start_pos=0 end :p_smb ; Процедура посимвольного вывода целевой строки - позволяет избежать преобразования в ссылки возможных оставшихся "вложенных" квадратных скобок tokens_delim="char" tokens dest_str nr_tok0=tokens_num i_str=1 :p_smb_cyc p #%token#i_str$$ i_str=i_str+1 if i_str<=nr_tok0 then goto p_smb_cyc pln end[/pre2]

Ajenta: Вот такой драгндроп возможен в урке :nachalo x = 100 y = 100 ;decoradd text (160,160) TEXT "zzz" ;decor_rec_XX = 50 ;decor_rec_YY = 20 decoradd rec (x, y, -1) RECT 50, 20, 0xffffffff decoradd rec_clic (x, y, -2) CLICKAREA 50, 20, "!dragndrop" decoradd rec1 (600, 500, -1) RECT 50, 20, 0xff777777 end :dragndrop anykey z, 1 mouse_xx=mouse_x mouse_yy=mouse_y xx=decor_rec_x-mouse_xx yy=decor_rec_y-mouse_yy :drag anykey z, 25 ;decor_text_text ="z=#z$ is_syskey = #is_syskey$ x= #mouse_x$ X=#decor_rec_x$ xx=#xx$ y=#mouse_y$ Y=#decor_rec_y$ yy=#yy$" if mouse_xx<>mouse_x or mouse_yy<>mouse_y then decormov rec mouse_x+xx, mouse_y+yy, 10 & mouse_xx=mouse_x & mouse_yy=mouse_y if z<>256 then goto drag :drop decormov rec_clic mouse_x+xx, mouse_y+yy end Если кликнуть на белый квадратик, то он потащится за мышкой, ещё раз кликнуть - отпустится.

Ajenta: Как известно, в урке нет абсолютного перехода. То есть и при goto и при proc каррент лок не поменяется и коммон не выполнится. Что же делать, если нам всё же нужен абсолютный назначаемый переход. Решение такое. ;создаём свою локацию перехода :mygoto ;вызываем коммон proc common ;присваиваем свой карент лок current_loc = mygoto_1 ; делаем переход goto #%mygoto_1$ end В игре же пишем ;где используем :локация ; вместо простого гоуту вызываем наш гоуту с названием локации на которую нужно перейти, ; то есть заменяем действие (goto название_локации) на то, которое написано ниже goto mygoto("название_локации") end

Ajenta: Ещё одна интересная фишка, которая будет полезна новичкам и тем, кто делает масштабные рпг игры. Дело в том, что фурка, при загрузке сохранения в игре, выполняет локацию, на которой вы сохранились. Соответственно, если вы брали там какой-то предмет или у вас динамический текст, то всё это поедет: предметов может оказаться больше одного, а текст может вывестись совсем не тот, который вы ожидали. Как с этим бороться: Не давать сохраняться в любом месте игры. Выделить под сохранения специальные локации, при загрузке на которых вы точно знаете, что ничего не поломается. Простая локация с описанием и парой кнопок вполне подойдёт. А уж как сюжетно обыграть такое "местечковое" сохранение - придумаете.

Ajenta: Отредактировала стандартный скин для разрешений 1024х768 и 1024х600 Вдруг кому-то пригодится. Просто положите файлы из соответствующих архивов рядом с игрой и наслаждайтесь. https://yadi.sk/d/SktTS4SadxqbL

qwerty: *PRIVAT*

qwerty: какой такой приват? я писал следующее: --- qwerty (в соседней теме) пишет: Я порылся в документации и не понял- как на фурке организовать целочисленное деление? Допустим, имеется x монет, которые по команде "накупить барахла", тратятся по 5 монет на 1шт барахла. На самом деле ситуация чуть сложнее, НО в данный момент интересует как можно проще получить целочисленное деление, которое будет очень востребовано в моей игре. то моё сообщение попало в закрытую тему, сюдасюда. там я писать ничего не могу, поэтому пишу здесь, в этой замечательной теме, созданной, как будто, специально для того, чтобы отпугивать новичков, демонстрируя недостаки urql . ну и правильно- остаться с нами должны самые смелые и несгибаемые ))) по этому моему вопросу нашёл(меня любезно ткнула носом Ajenta в) описалово Корвина, в котором, оказывается, всё было расписано уже почти 10 лет назад. да, на urql есть таки и целочисленное деление и даже можно задавать точность- например, деление с одним знаком после запятой. или с двумя. или тыпы. пока не знаю, как это можно применить, но возможность потенциально интересная. НО, как это в urql часто бывает, эта возможность реализована не через то место. так, при целочисленном делении результат округляется не вниз, а вверх! то есть, чтобы получить именно целую часть, нужно проводить доп проверки и вычисления. так сказать, "лёгким движением руки брюки превращаются... брюки превращаются..."... а теперь, очередная полезная механика, которая бы непонадобилось, если бы urql был продуман чуть лучше: как я сделал целочисленное деление: :div if divx >= divy then divx = divx-divy & divz = divz+1 else end goto div end как вы можете видеть, это процедура, использующая следующие переменные: divx - делимое. после вычислений в divx остаётся остаток от деления divy - делитель. в ходе вычислений не изменяется. divz - после вычислений к divz прибавляется целая часть результата деления. то есть, если divz изначально выставим в 0, то в итоге получим в нём результат целочисленного деления divx/divy

Iunel: Скажите, кто нибудь разобрался с переменной TIME? А именно, когда она обнуляется? По теории она хранит время после полуночи, то есть сразу после 00:00 переменная хранит ровно 00,000,000. Таким образом максимальное число в TIME - 86,400,000, т.к. в сутках 86400 секунд. А может быть она обнуляется после 99,999,999? Тогда обновление происходит каждые 27 часов, 42 минуты. Я решил сделать игру, которая будет якобы работать, даже когда программа выключена (и даже когда выключен компьютер) на основе переменной TIME. Все просто, когда ты в первый раз начинаешь игру, компьютер сохраняет значение TIME на тот момент. В следующий раз при запуске игры, снова создается значение уже на тот момент времени. Ну и вычитая одно из другого мы получаем время между этими двумя запусками. К сожалению, это будет работать только в пределах одного дня, но все равно можно придумать много интересных вещей, основываясь на этом. Осталось только узнать время обновления.

vito: Решила опубликовать давние наработки - так называемые уроки FireURQ, посвященные новым функциям-возможностям Фурки, которых не было в "классическом" URQ. Надеюсь, ссылка скоро будет доступна: http://urq.plut.info/node/1209 Если интересно - пишите, принимаются заявки на темы для продолжения (только, пожалуйста, декораторы и скины не предлагать).

Серый Волк: Ссылка доступна, vito, огромное спасибо за труды!

Ajenta: Запостила шрифты для фурки. Можно полистать, посмотреть, выбрать подходящий. http://urq.plut.info/node/1519

Серый Волк: Ajenta, спасибо, здорово. Теперь ждём пак скинов :)

Ajenta: Серый Волк, скины, это всё-таки слишком индивидуально. Сложно придумать какие-то общие.

qwerty: На текущий момент FireURQ поддерживает потрясающие возможности оформления: Может быть, ст0ит открыть обучающую тему по созданию интерфейсов и всяческому оформлению квестов?

Korwin: qwerty - поддерживаю!!!

Ajenta: Сделала библиотечку функций для работы с одномерными массивами. Надеюсь, это упростит авторам жизнь. Мне так точно. http://urq.plut.info/node/2281

Ajenta: Добавила удаление элемента массива по номеру и интерактивный пример использования функций. Можно перекачать. http://urq.plut.info/node/2281



полная версия страницы