RU

Новый метод программирования

HIman #6 07.09.2011 07:04 18 comments 18049 views

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

Какие могут быть варианты решения?

Вариант 1. В редакторе QSP нет ограничений по числу локаций, поэтому можно создать несколько вариантов одной и той же локаций на каждый новый случай. Получится список «комната1», «комната2», «комната3» и т.д. В каждой локации можно добавить уникальное действие, нового персонажа или определенные условие при посещении.

Вариант 2. В одно локации «комната» в условии при посещении писать программный код учитывающий все возможные варианты которые могут происходить в локации. За частую, появляется много условий, и логическая составляющая кода усложняется на столько, что найти ошибку становиться очень проблематично.

У вас есть свое решение? Обязательно поделитесь ?

Рассмотрим плюсы и минусы этих вариантов.

Вариант1.
+ Каждая локации подчиняется изначальной структуре заложенной в QSP. Описание локации в своем окне, действия в своем и код при посещении на месте.
+ Простота кода при посещении, только тот код который в данный момент нужен на локации, нет нагромождения условий.

- Увеличение числа локаций в дереве игры затрудняет ориентирование в редакторе.
- В каждой локации присутствуют однотипный (общий) код при посещении, действия на локации, что увеличивает размер игры. А также потребность исправления во всех локация однотипных участков, если вдруг потребуется их изменить или что-то добавить.
- В каждой локации будут уникальные переходы в действиях на смежные локации, которые также имеют свои «версии локации», что затрудняет навигацию по переходам между локациями. Т.е. в локации «комната1» будет действие «Выйти из комнаты»: goto «коридор1» в локации «комната2» будет действие «Выйти из комнаты»: goto «коридор2» или может быть другой вариант и т.д. Таким образом, появляются ошибки: переходы могут либо совпасть, либо действие перехода никуда не ведет, либо отсутствует необходимое действие перехода совсем.

Резюме по варианту1.
Неплохой подход при написании игры, но требует предварительной работы по разбивки всего сюжета на локации и в свою очередь действий внутри локации на серию локаций. А также необходимость в четком дереве (графе) переходов между локациями. Не наглядное представление, куда можно перейти из локации.

Вариант2.
+ Число локаций соответствует задумке автора, и если комната одна в доме, то и локация «комната» одна.
+ Весь код на локации со всеми действиями, условиями и персонажами в одном месте.
+Возможность «программировать на лету». Т.е. по мере появления потребности в переменных, условиях, персонажах и т.п. вставляется новый код или модифицируется код написанный.
+ Вытекает из предыдущего плюса - широкое поле творчества, так как буквально все находиться в окне выполнение при посещении и тут полет фантазии ограничен только самой фантазией.

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

Резюме по варианту2.
Такой подход к написанию игр выбирается в большинстве случаев из-за «программирования на лету», годиться лишь для написания небольших игр и за один подход, иначе игра просто остается недописанной.

Что же делать?

На просторах интернета я нашел интересный метод программирования, который как нельзя лучше подходит под наши нужды, красивого писания игр на QSP. Этот метод объединяет лучшие качества рассмотренных выше двух вариантов. Заключается он в дополнительной структуре программного кода, в результате чего программа выглядит сложенной из кирпичиков, однотипных блоков кода.

На рисунке изображено схематически что из чего следует.

Проведем аналогии с QSP терминологией:
Табл Автоматы – Перечень наших локаций то что мы видим в левой части QSP редактора.
Табл. Описание автомата – Описание на локации обратите внимание, описание зависит от состояния,т.е. у одной локации может быть несколько описаний локации.
Табл. Описание состояния – Состояния локации, где могу быть свой код при посещении см Процедура, Обратите внимание, переходы (переходы между состояниями или локациями или ещё точнее между стояниями локаций) в каждом состоянии индивидуальны.
Табл Описаний переходов – Наши действия с переходом goto «новая локация». Здесь могут быть условия перехода на картинке изображено блоком Булева функция, а так же номер нового состояние локации куда мы перейдем по выбора этого действия.

Пока выглядит немного запутано, но рассмотрим программный код, написанный по этому методу на примере игры «Дом пустоты».

В левой части мы видим перечень локаций. Каждая локация это наш автомат, который может иметь несколько состояний.
В окне выполнить при посещении мы видим некие блоки которые начинаются комментарием, затем идет IF, далее тело блока, и заканчивается END.
Так как локация спальня у нас одна, по сюжету ГГ может посещать её несколько раз, то в окне «Выполнить при посещении» пишем шаблон:.
1. Комментарий описывающий состояние автомата – для себя чтобы быстро найти нужное состояние локации.
2. Условие входа в локацию, здесь переменная sp будет отражать состояния локации спальня. Значение sp = 0 первое появление ГГ в спальне, значение =1 – ГГ вышел из спальни и сразу же вернулся, обратите внимание описание с первым посещением спальни поменялось.
3. Описание локации в нужном состоянии локации
4. Действия на входе в состояние локации, это может быть переопределение переменных, или другие функции которые должны выполниться при посещении, я для удобства разделили переопределение переменных и вынес их в верх тела шаблона над описанием локаций, а все функции идут ниже описания, но это не принципиально.
5. Переходы из локации. Здесь можно писать уникальные переходы или переходы появляющиеся по условию, а также если в локации есть стандартный набор действий то его можно вынести в соответствующее место и этот набор действий будет общим для всех состояний локации.

Для удобства и наглядности может потребоваться ( и я настоятельно рекомендую применять) графическое представление.
На листке бумаги нужно нарисовать граф нашей игры. Где узлы обозначим их точками или кружочками будут означать состояния локации, а линии со стрелками между узлами будут означать переходы между состояниями локаций. В интернете полно программ позволяющих упростить рисование таких графов, одна из подобных программ которой пользуюсь я Explain. Программка очень маленькая 1Мб, с минимальным, но вполне достаточным набором инструментов для наших целей.

Вот такой получился у меня граф для игры «Дом пустоты», (это только часть)

Хочу дать несколько советов.
1. Посмотрите на мой пример, все состояния одной локации идут в столбик. Для локация «спальня» sp0, sp1,sp2 …, для локации «коридор» kor0, kor1, kor2 и.т.д. При таком расположении узлов можно сразу найти нужную локацию и все её состояния. Здесь sp0, sp1 это наше состояние в коде можно увидеть if sp=0… if sp=1.
2. У переходов есть направление, обозначается стрелочкой, если переход возможен обратно в исходное состояние, то нужно соединить 2 узла 2 раза сначала в одну сторону, а потом в другую.
Переходы лучше писать в теле шаблона сразу после условия входа в состояние:
IF sp=0: - текущее состояние локации спальня
kor=0 - переменная отвечающая за состояние локации коридор
*p ‘ ………

Exit
end
А ниже в списке действий на локации всегда есть возможность выйти в коридор безусловным переходом gt «коридор».
В локации коридор мы попадает сразу в блок-состояния коридора со значением 0
IF kor=0: - текущее состояние локации коридор
sp=1 - переменная отвечающая за состояние локации спальня
zal=0 - состояние локации зал
*p ‘ ………

Exit
end

3. Если в локации ГГ находит предмет или при переходе предмет теряется то удобно обозначать в тексте узла или перехода «+ Имя предмета» предмет добавлен в инвентарь или «– Имя предмета» предмет удален из инвентаря. А также при использовании предмета «исп. Имя предмета»

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

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

Прикрепить файл не могу, посему даю сылку на программу Explain http://www.bestfree.ru/soft/graph/mindmap.php

Edited at 07.09.2011 07:14 (14 years ago)

Есть ли какой мануал или док по этим автоматам?
Можно ли либо сделать более крупные картинки, либо прикладывать файлы? А то на таких маленьких картинках трудно что-то разобрать.
А мысль в целом интересная…

Неплохая методика для локаций с изменяющимися состояниями. Оформишь в статью? Добавим в раздел “Разработчикам”.

То Воден
Картинки кликабельны и на них вполне можно рассмотреть что написано.
документации увы нет, но за-то есть пример готовой игра “Дом пустоты” написанный именно по этой методике,
и именно для этой статьи, сценарий игры, и полный граф сюжета которой можно посмотреть через программу Explain.
у меня не размещаются файлы посему могу только высылать почтой :) (вечерком так как файлы не с собой)

To Nex
Тот же текст с картинками есть в формате word, размещу доп.материалы на своей страничке, добавлю сылки и могу выслать на почту.

так я про картинки и говорю - не про превьюшки в тексте :) на картинках виден лишь общий контур, буквы видны не везде. Напряжно очень :)
И есть ли ссылка на “просторы интернета”, где был найден “интересный метод программирования, который как нельзя лучше подходит под наши нужды”? или хотя бы его официальное название?

Сылка http://is.ifmo.ru/ находится первой (после ВИКИ :)) в яндексе по запросу “автоматное программирование”.
Там очень много чего есть, и на картинку схему я вышел случайно изучая размещенную на этом ресурсе презентацию,
все остальное я додумал и применил к QSP и вроде получилось не плохо.

HIman,
лучше будет если ты сам опубликуешь. Я занес тебя в группу авторов, см. в “Меню пользователя” кнопку “Опубликовать статью”. За консультациями по интерфейсу редактирования статей можешь всегда обратиться ко мне на канале #aqsp.

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

Живой, небольшой рабочий пример стал бы отличным дополнением к статье.

Есть случаи, когда со временем в локации меняется часть описания, или часть действий, причём, от каких-то нюансов, например, от “посещённости” места, зависит одно, а от других - другое. В результате, даже создавая такие блоки, в конце мы всё равно получим переизбыток дублируемых кусков кода\описания. При этом, я всегда все действия и описания пишу в “выполнить при посещении” поскольку так проще добавлять динамические условия. И никогда ещё не путался. Возможно, стоит просто комментировать код, в тех случаях когда есть риск в нём запутаться?

To WladySpb
Это будет не переизбыток, просто большой набор состояний локации, и если подойти системно к этому вопросу, то можно упростить код, а следовательно и понимание его, как в момент написание так и через пол года :)

Почему я пришел к этому виду программирования? Написав кучку игр, заметил за собой что у меня совсем нет какого либо стиля написания, т.е. код в играх совершенно разный хотя действия выполняет одни и те же, даже на разных локациях один и тот же код мог выглядеть по разному. Возможно это был мой неосознанный поиск оптимального кодирования. Таким вот образом я и пришел к этой теме попробовал на примере игры “Дом пустоты” и оказалось очень неплохо.

Я тоже обращал внимание на разность написания, со временем просто начал стараться не изобретать велосипед, а повторять старые отработанные методы(если нашёл их удобными). Не всегда получается, но многие вещи уже не повторяю)

Aleks Versus Moderator 08.09.2011 07:24 (14 years ago)

Очень интересно. Хотелось воскликнуть: где ты был пару лет назад? :=D Мне бы это очень помогло.
И тем не менее все хорошо в меру. Не для всех игр подойдёт такой код.

HIman:

просто большой набор состояний локации

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

У меня обычно локация состоит из “стабильного” куска текста, который всегда одинаков, а дальше “возможный” текст, зависящий от переменных, например:
‘В комнате стоит стол.’
if int=1:’На столе стоит лампа.’
if int=2:’На столе пусто.’
Причём, при желании, таким образом может генерироваться достаточно динамичный текст, который будет меняться в зависимости от многих факторов.
Код же вообще может находиться на рабочих локациях, для облегчения восприятия.

Aleks Versus:

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

Да будет 25 однотипных блоков в одной локации, завязанных на одну переменную состояния, но даже в этом случае описание локации, если он не меняется к примеру 20 раз из 5, удобно вынести все тексты в отдельную локацию. А в самих блоках писать код *p sp[sp]
Где sp - переменная от 1 до 25 состояние локации “спальня”,
sp[] - массив текстов для локации “спальня”.

Таким образом можно локализовывать игры. Перед стартом выбирается язык и в зависимости от выбора активируется массивы текстов либо на русском, локация “RUS”, либо на английском локация “ENG”и .т.п.
Содержание же локаций для локализации будет простой набор массивов, в каждой локации под свой язык.
Для примера:
! тексты локации спальня
sp[1]=‘описание спальни1’
sp[2]=‘описание спальни2’
sp[3]=‘описание спальни3’

sp[25]=‘описание спальни25’
! тесты локации коридор
kor[1]=‘описание коридора1’
kor[2]=‘описание коридора2’

kor[30]=‘описание коридора30’

Обратите внимание, цифра отражает состояние локации посему код описания в блоке упрощается до *pl sp[sp] или *pl kor[kor]

WladySpb:

У меня обычно локация состоит из “стабильного” куска текста, который всегда одинаков, а дальше “возможный” текст, зависящий от переменных, например:
‘В комнате стоит стол.’
if int=1:’На столе стоит лампа.’
if int=2:’На столе пусто.’
Причём, при желании, таким образом может генерироваться достаточно динамичный текст, который будет меняться в зависимости от многих факторов.

Вот у меня подобным образом написана игра “Великая пустота-9” в коде при посещении локации и динамические тексты, и проверки на предметы, и проверки на условия, и диалоги, и чего там только нет, сотня переменных которые пора выписывать столбиком и писать к каждой описание, и вообще страшно туда заглядывать, так как дернешь в одном месте отвалится в другом. Именно от такого программирования я и пытался уйти, а подвернувшийся метод очень хорошо справляется со своими задачами.

Aleks Versus Moderator 09.09.2011 07:17 (14 years ago)

HIman:

Да будет 25 однотипных блоков в одной локации, завязанных на одну переменную состояния, но даже в этом случае описание локации, если он не меняется к примеру 20 раз из 5, удобно вынести все тексты в отдельную локацию.

А. Так вот в чём соль. Весьма-весьма удобно.

почитал тему решил попробовать ,конечно в прямом виде слишком сложно особенно когда в локации происходит взаимодействие нескольких персонажей в разное время,если брать тупо и срисовать как здесь то порой можно достичь десятки описания локаций и того что в них происходит нереально абсолютно,но с explain очень понравилось,беру чистую полосу в центре, пишу с одной стороны время, с другой локации, с третьей персонажи, с четвертой условия ,и т.д.и пытаюсь провести героя через игру ,это в центре создавая точки-узлы и соединяя их со следующим узлом создавая идеальный проход героя если такой проход есть, и соединяя в них локацию,персов, время ,рюкзак и т.д. подписываю кратко чтоб не забивало поле,а основные описания в комментах к узлу что внутри него,если идут разные варианты раздваиваю узел создавая полоску узлов сколько надо раз и в каждой коммент или условия или что необходимо и оставляю на узле. в результате получается абракадабра из синих и красных линий с подписанными узлами ,но видно траекторию движения героев от начала к концу игры и что творится в каждой точке движения ,если надо подробнее просто тяну узел в сторону от траектории игры и разбираю узел и все что с ним связано линиями, исправляю текст и прочее и загоняю обратно на траекторию,конечно знание QSP мне это не заменяет но становится наглядно видно все связи всех персонажей если локация усложняется сзади создаю точки её описаний и все обязательно соединяю линиями связи. Для меня такой вариант оказался понятным и наглядным так как опыта у меня никакого ,кстати мне кажется очень удобно задавать таким макаром массивы описаний и уже затем вводить их в редактор ,похоже я просто переталдычиваю автора темы но повторение мать учения и расшифровка чайника возможно будет понятнее другому чайнику)
Если кто то тоже этим пользуется хотел узнать,у меня иногда комменты к узлу не полностью сохраняются так как пишу и затем дописываю кусками ,причина какая то простая но пока не пойму почему один раз сохраняет а в другой может добавленный кусок не сохранить,наверно подозреваю то ли от курсора мышки то ли от чего то подобного, может кто сталкивался подскажите.
и по поводу сохранения,если надо несколько параллельных проектов,то тупо перетаскиваешь лист на чистое место и все?или есть возможность классического сохранения,кто как решает эту проблему если это проблема?

Log in or Register to post comments.