Войти на сайт

Авторизация, ждите ...
×
  • Страница:
  • 1
  • 2

ТЕМА: ООП на ГеймМейкере

ООП на ГеймМейкере 7 года 10 мес. назад #91555

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Я очень люблю традиционную парадигму объектно-ориентированного программирования (ООП): полиморфизм, инкапсуляция, наследование. Умея ей пользоваться и зная некоторые полезные приёмы (например, композиция), можно делать игру гибкой и легко вносить изменения, которые изначально не предвидел. Статичные классы, как в php, динамические и изменяемые на лету, как в Руби, или даже прототипное наследование, как в JS - всё замечательно подходит для игр и ускорения их разработки.

К сожалению, ГеймМейкер поддерживает ООП только частично. Если считать его понятие "Объекта" классом, а понятие "Инстанса" - экземпляром или объектом (чтобы терминология данной статьи совпадала с принятой в ООП), то у объектов в ГеймМейкере могут быть параметры, но туго - с методами. Методами, в принципе, можно считать реакции на события, поскольку там доступен вызов "родительская реакция", то есть то же, что в ООП часто делается при переопределении метода. Но все реакции относятся к тем или иным событиям, таким как отрисовка сцены или столкновение с другим объектом - кроме шестнадцати (!) пользовательских реакций, которые вызываются только специально из кода. Мало того, что их количество ограничено - они ещё и не имеют названия, только номер. Даже QBasic не вызывает функции по номерам!

Можно, конечно, забить кучу констант: ПУЛЯ_ИНИЦИАЛИЗАЦИЯ=1, ПУЛЯ_ПОСЧИТАТЬ_УРОН=2, ПУЛЯ_ПРОИЗВЕСТИ_ВЗРЫВ=3... Но ограничение на 16 методов никуда не денется (значит, невозможно будет писать "Чистый код", одним из принципов которого является разбиение на минимальные по смыслу фрагменты), и к тому же я предчувствую, что такой код чреват ошибками, если вызвать у объекта метод не той константой: ты будешь думать, что это пуля производит взрыв (ведь это и написано в коде!), а это самолёт катапультирует экипаж.

Мне кажется, я нашла способ лучше.

ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DeadElf79, DK, Демий, yuryol, Doctor_Bug, Xitilon

ООП на ГеймМейкере 7 года 10 мес. назад #91615

  • DeadElf79
  • DeadElf79 аватар
  • Вне сайта
  • Звездный Страж
  • Сообщений: 3147
  • Спасибо получено: 2650
  • УчительВетеран3 местоОрганизатор конкурсовПроект месяца 2 местоПисатель 3 местоПрограммист Ruby1 место в ГотвПроект месяца 1 место
Немного оффтопика: прочитав про вызов методов при помощи констант, долго смеялся. Вспомнил дарк-бейсик, в котором отсутствовали переменные и обращение к любому объекту происходило по индексу. Конечно, он был, насколько я помню, ни разу не ООП, но отказ от именования переменных в пользу цифр до сих пор остается для меня загадкой.

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

ООП на ГеймМейкере 7 года 9 мес. назад #92562

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Вроде бы они сейчас делают новый ГеймМейкер, который наконец оставит всё это в прошлом. Есть и негатив: поддержка текущей студии будет прекращена, а она стоит куда побольше, чем РПГ Мейкер, например. Лицензию на новый придётся покупать заново, разве что с какой-то скидкой.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93802

  • Xitilon
  • Xitilon аватар
  • Вне сайта
  • Познающий
  • Сообщений: 22
  • Спасибо получено: 32
Был очень удивлён увидеть в принципе такой раздел на форуме по РПГ Мейкеру, да ещё и такого грамотного автора. Это событие.
EvilCat пишет:
Вроде бы они сейчас делают новый ГеймМейкер, который наконец оставит всё это в прошлом. Есть и негатив: поддержка текущей студии будет прекращена, а она стоит куда побольше, чем РПГ Мейкер, например. Лицензию на новый придётся покупать заново, разве что с какой-то скидкой.
А откуда, коль не секрет, такая информация? Где-то в 2015 промелькнула какая-то хилая новость о том, что у YoYo Games сменился владелец, и они пообещали выпуск в 2016, но тут же сказали что поторопятся, и это будет прямо ещё в 2015. А в итоге вот, последний квартал 2016 наступает, тогда как 31 марта 2016 выпустили новый экспортер - зачем бы, если скоро GM:S должен был прийти конец?

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

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

До-студийный Game Maker был лучше - в нём была кое-какая рефлексия, можно было добавлять объектам события на лету, и даже интерпретировать код, собранный на лету из любых строк.

В GM8.1 я мог сделать вспомогательный инструмент вон какой. А в GM:S - только этот огрызок. Впрочем, это уже совсем оффтоп.
Последнее редактирование: 7 года 6 мес. назад от Xitilon.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: EvilCat

ООП на ГеймМейкере 7 года 6 мес. назад #93808

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Спасибо за комментарии %)

Я, к сожалению, уже не помню, где читала о грядущей новой версии, но тревога и досада, что распродажа ГМ устроена из-за того, что вот-вот выпустят новую версию и сделают свежекупленное устаревшим, тогда витала много где.

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

ООП на ГеймМейкере 7 года 6 мес. назад #93809

  • Xitilon
  • Xitilon аватар
  • Вне сайта
  • Познающий
  • Сообщений: 22
  • Спасибо получено: 32
Когда эта новость была на горизонте, я отнёсся к ней скептически - и оказался прав. ЙоЙо вообще очень инертная фирма, они что-то меняют редко. Но работают над продуктом стабильно, что плюс.

Я сам постоянно использую полиморфизм на практике, в нашей игре, которую я тут показал в этом же разделе, его порядочно много. Всё это достигается, увы, только через скрипты. Но Гамак того правда стоит, уж поверьте. Скоро вот в Стим выходим, а сколько мы бы торчали на ЯП общего назначения, даже не знаю.

В общем, пробуйте, люди, Гамак. Он с точки зрения типичного программирования странный, но для своих целей вполне функциональный.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: strelokhalfer

ООП на ГеймМейкере 7 года 6 мес. назад #93814

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Сказать по правде, я в последнее время даже для 2Д-проектов использую Юнити, но! я достаточно подготовлена к тому, чтобы использовать C#, который необходим, если магазина ассетов недостаточно. Правда, единственной подлинной трудностью мне кажется строгое типизирование, которого нет ни в Руби, ни в Яваскрипте, ни в GML, насколько я помню.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93818

  • Xitilon
  • Xitilon аватар
  • Вне сайта
  • Познающий
  • Сообщений: 22
  • Спасибо получено: 32
В GML точно нет, в JS не припомню, но гарантировать не стану, в Руби не знаю. А чем же оно так подлинно трудно? Я раньше думал, что только так игры и надо писать, с жёсткими типами, и всё.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93820

  • strelokhalfer
  • strelokhalfer аватар
  • Вне сайта
  • Архитектор Миров
  • Знатный грамотей
  • Сообщений: 1640
  • Спасибо получено: 1078
  • Даритель Стимкея2 место Сбитая кодировка2 место Организатор конкурсовПереводчикПрограммист Ruby
СОгласен, нестрогая типизация проще, но порождает другие проблемы, вроде лишних проверок.
P.S. В руби нестрогая)
"Стрелок, что-то ты неочень похож на свой аватар..."(с)
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93821

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Строгая типизация имеет много недостатков для игроделов-любителей.

Для начала, это не просто "в ту переменную можно записать только числа, а в другую - только строки". Числа отличаются по наличию знака, минимальному и максимальному значению, точности после запятой. Причём некоторые типы - это или очень большое число, или очень много знаков после запятой. Если думал, что HP влезет в 32 000, а потом оказалось, что нужно поднять до 50 000 - придётся ползать по всей программе, менять какой-нибудь int на longint во всех полях и аргументах, которые оперируют хитами. В противном случае - либо останов программы, либо, что хуже, молчаливая ошибка. С точки зрения естественного рассуждения этот нонсенс, потому что ты хотел просто работать с _целым числом_, не думая о том, два байта оно занимает в памяти или три.

В строго типизированных языках есть такие сюрпризы как "деление целого на целое всегда даёт целое". Поделили 5 на 2, получили 2, а не 2.5, даже если записали в дробную переменную. Надо было делить 5.0 на 2.0 или (float)a/(float)b. А если потом понял, что возможностей float не хватает, придётся и тут менять на double какой-нибудь!

Объекты - отдельная песня. Объявил список животных: List<Animal>. Положил туда один объект - класса Dog. Достал объект, удостоверился, что он класса Dog, и попросил его залаять: if (animals[0] is Dog) animals[0].Bark(). Ошибка! Программа считает, что обращается к нему как к Animal, а не Dog, а родительский класс Animal ещё не умеет лаять. Но Animal умеет издавать звуки. Вызываем animals[0].Cry() - но даже если у Dog есть метод Cry, где сказано "гав!", вместо этого вызовется родительский метод класса Animal, скажем, "пика-пика!" - если программист забыл написать в заголовке родительского метода, что метод виртуальный, то есть зависит от объекта, а не класса обращения. А в первом случае нужно было делать (animals[0] as Dog).Bark().

Строгая типизация хороша при отлове некоторых ошибок, для оптимизации работы с памятью и для того, чтобы удобнее писать методы, рассчитанные на разные входные данные (сигнатуры). А если цель - просто писать игру, это лишний груз (я считаю).
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: DK, strelokhalfer, Lipton

ООП на ГеймМейкере 7 года 6 мес. назад #93829

  • Lekste
  • Lekste аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 911
  • Спасибо получено: 565
  • ВетеранОраторДаритель СтимкеяПрограммист RubyПрограммист JavaScript
Ну, если цель писать игру, а потом неделями искать случайную опечатку... :)
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93830

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
В этом плане лучше всего языки с опциональной типизацией: например, в php типизация не строгая, но (с последних версий) можно указать типы аргументов и возвращаемого значения функции.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: strelokhalfer

ООП на ГеймМейке 7 года 6 мес. назад #93831

  • Lekste
  • Lekste аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 911
  • Спасибо получено: 565
  • ВетеранОраторДаритель СтимкеяПрограммист RubyПрограммист JavaScript
Но все все-равно делают на нем какую-то херню, где не поймёшь, что лежит в переменной, откуда оно взялось и когда оно внезапно превратится в другой тип и устроит внезапный сюрприз. Скорей всего даже не в месте реальной ошибки.

+ ненужное усложнение сборки

От них может быть польза только в скриптах.
Последнее редактирование: 7 года 6 мес. назад от Lekste.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: strelokhalfer

ООП на ГеймМейкере 7 года 6 мес. назад #93834

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Знаешь, в большинстве случаев переменные в нестрого типизированных языках имеют строгий тип на уровне компилятора, потому что очень редко когда нужно в одной и той же переменной последовательно хранить значения разных типов. Компиляторы, соответственно, оптимизируют это за кадром.

Большая часть случаев, когда переменная должна принимать значения разных типов - это переменные вида "true, false или null" (троичная логика), ленивые значения (null - если ещё не вычислено), всеядные аргументы функций и пользовательский ввод (считали "1", привели к 1 в ту же переменную). Очень редко когда шёл-шёл и внезапно присвоил числовой переменной строку! Нестрогая типизированность заключается в том, что язык или компилятор заботится о том, сколькими байтами описывать число.

Так или иначе, факт остаётся фактом. Если начнёшь объяснять вчерашнему пользователю ивентов на командах, что нельзя поделить 5 на 2 и получить 2.5, он просто не будет пользоваться этим минным полем. И правильно сделает. Хотя, возможно, в твоём понимании уровень использования языка, не отягощающий себя думами о байтах, и есть скрипты.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93838

  • Amphilohiy
  • Amphilohiy аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 547
  • Спасибо получено: 666
  • Победитель Сбитой кодировкиПрограммист RubyОраторУчитель2 место Готв
Тред медленно скатывался к холивару, причем даже не про гамак.

И я выскажу свое мнение, Амфи я или кто? В целом - это побоку вообще. Динамическая (нестрогая, я так буду изъясняться, ибо) типизация позволяет не запарываясь реализовывать всякие полиморфизмы, ибо суть объекта можно представить словарем с методами и свойствами, индексируемых по имени. И при этом не надо париться по поводу наследований или интерфейсов.
Статическая, конечно же, помогает в отладке, ибо ты получишь жирное сообщение об ошибке при первых проявлениях симптомов. Приятно, да. Ну и плюшек производительности как правило больше.

Но блин, так и в обоих случаях минусы же тоже! Для динамической вряд ли будет полный отчет по переменной в вашей любимой ide, гадание что лежит в самой переменной (в мукере меня особенно радует гадание - ид ли героя тут, или сам герой?) и в целом неуверенность что метод\свойство у объекта попросту существует.
В статических не всегда есть встроенная рефлексия (впрочем уже редко), требуется везде озабачиваться интерфейсами, и строить лапшу для примера с псом, описанным ранее (если пес, то явное приведение + гавкнуть, если утка и т.п.). Далее курить паттерны, радоваться тому, что объясняешь программе как ей быть с памятью, хотя в другом ЯПе не заморачиваясь расписывал бы сами алгоритмы.

Но Амфи, скажете вы, что насчет игорь?
И тут самое главное. Играм побоку на чем они работают.
Но Амфи, вы снова перебьете меня, что насчет программистов?
Захотят приспособятся к ЯПу. Не захотят - не приспособятся.

Да, методы разные, да, каждый имеет свои плюсы/минусы, нет, играм глубоко наплевать, а прогеры пусть сами разберутся. Не нравится ЯП в конструкторе - не используй или меняй конструктор. Заставляют - учи или уходи с команды. Эта хрень не стоит холивара.

Ну и p.s. с гамаком не знаком, топик не читал, так что ничего по теме не скажу. И мне даже не стыдно.
Я верю, что иногда компьютер сбоит, и он выдает неожиданные результаты, но остальные 100% случаев это чья-то криворукость.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: Xitilon

ООП на ГеймМейкере 7 года 6 мес. назад #93842

  • Lekste
  • Lekste аватар
  • Вне сайта
  • Светлый дракон
  • Сообщений: 911
  • Спасибо получено: 565
  • ВетеранОраторДаритель СтимкеяПрограммист RubyПрограммист JavaScript
Долбаная Светлая опять не отправила мое сообщение.

Вобщем краткий пересказ:
1. Про излишнее усложнение сборки и было сказано к ненужной нагрузке на компилятор, что приведет к увеличению времени сборки, шансу появления ошибок и псевдоошибок из-за недопонимания.
2. Вчерашний ивентист с той же легкостью передаст в функцию вместо строки число и будет долго не понимать, что-за нафиг.
3. Гораздо проще объяснить разницу между 2 и 2.0, чем между строкой и числом
4. Скрипты в моем понимании - относительно небольшие фрагменты кода, описывающие логику на верхних уровнях абстракции, найти несоответствие типов в которых гораздо проще и из-за малого размера, не сильно влияющие на проект в целом.


Амфи, приводить вобще не обязательно - есть виртуальные методы.
Описывать то, как программе быть с памятью тоже не обязательно, если есть сборшик мусора.

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

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

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

+ Если залезешь в уже готовый код, всегда сможешь понять где и что (как ты уже сказал) и не гадать, что ж там лежит и откуда оно там взялось
++ Какой-нибудь странный напарник не испортит тебе все, переписав в своей части переменную с объектом Player на его ID.
Последнее редактирование: 7 года 6 мес. назад от Демий. Причина: Убрал даблпост
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93843

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Зря вы перескакиваете на большое программирование большими программистами. Какая игра будет компилироваться 10 минут? RPG Maker, GameMaker, Unity3D, php для браузерок, JavaScript в браузере - ничто из этого не компилирует 10 минут. И играм на этих движках (во всяком случае любительским) вполне себе наплевать на производительность, они просто не делают ничего такого тяжёлого. По меркам игр десятилетней давности всё то, что делает Юнити с её модными компонентами или RPG Maker с его каждофреймовыми апдейтами всего и вся - страшная неоптимальность. Когда-то даже экран не перерисовывали раз во фрейм, а только правили кусочки файла с картинкой экрана. Но современные компы нам позволяют - позволяют пользоваться удобными архитектурами без оглядки на микрооптимизацию. Вы как будто уже говорите о серьёзных проектах, которые пишутся с нуля на каком-нибудь C++ и, да, компилируются от 10 минут и выше.

И тут порог вхождения в язык программирования отнюдь не последнее дело, стоит только сравнить трудности объяснения классов в Яваскрипте с его "Game_Object.prototype.someFunc = function(...)" и в Руби, где просто def someFunc. По моей оценке, всего человека три на форуме разобрались/знакомы с этим, а скрипты на Руби продолжают выкладываться. И если честно, я не понимаю, как это - проще объяснить разницу между 2 и 2.0, чем между строкой и числом.

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

P.S. В php, если передаёшь строку туда, где ожидается число, ничего плохого не происходит, "2"+"2" всё равно будет 4. Чтобы сделать "22", нужно использовать строковое сложение - точку. В Яваскрипте по-другому, но это не из-за типизации, а из-за принятых особенностей языка.
Последнее редактирование: 7 года 6 мес. назад от EvilCat.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93847

  • Xitilon
  • Xitilon аватар
  • Вне сайта
  • Познающий
  • Сообщений: 22
  • Спасибо получено: 32
EvilCat пишет:
Если думал, что HP влезет в 32 000, а потом оказалось, что нужно поднять до 50 000
То это значит, что плохо думал. Вариант 1 - выбирать тип данных с запасом. Вариант 2, "не думая о том, два байта оно занимает в памяти или три" - везде писать double (или Decimal). А вот если будет тормозить - тогда и оптимизировать. К слову, int в C# 32-битный, а не 16-битный, а количество хитпоинтов более миллиона - как-то редкость.

В Game Maker'е вообще все числа это real, то есть вещественные, целочисленного типа данных в принципе нет, а true и false определены как константы 1 и 0. И прекрасно работает. Конечно, на нём не сделаешь каких-то крутых вычислений, но для этого есть 1) встроенная система шейдеров, если для графики 2) подключаемые DLL и врапперы.
EvilCat пишет:
придётся ползать по всей программе, менять какой-нибудь int на longint
Хотел было возразить про автоматический рефакторинг, но вспомнил, что это было переименование переменных, а не смена их типа. И всё же, неправильный выбор типа - это ошибка на уровне проектирования. Чтобы не мучаться с типами переменных для вычислений, не обязательно переходить на другой язык - опыт с GM'ом показывает что в наш век N-ядерных N-гигагерцовых процессоров можно почти всё закатать в плавающие точки, а критичные к скорости вычисления (которых обычно нет) вынести за пределы среды, заточенной под разработку именно игры. А тут как раз были подняты вопросы написания движка, а не игры. В GM'е писать движок не нужно, нужно только наполнить его игровой логикой. Ну и поставить пару костылей там и вот там... Но где ж без этого, скажите мне?

Сюрприз "деление целого на целое всегда даёт целое" таким образом тоже мгновенно пропадает, так как везде будут изначально вещественные числа.
EvilCat пишет:
Объекты - отдельная песня. Объявил список животных: List<Animal>. Положил туда один объект - класса Dog. Достал объект, удостоверился, что он класса Dog, и попросил его залаять: if (animals[0] is Dog) animals[0].Bark(). Ошибка! Программа считает, что обращается к нему как к Animal, а не Dog, а родительский класс Animal ещё не умеет лаять. Но Animal умеет издавать звуки. Вызываем animals[0].Cry() - но даже если у Dog есть метод Cry, где сказано "гав!", вместо этого вызовется родительский метод класса Animal, скажем, "пика-пика!" - если программист забыл написать в заголовке родительского метода, что метод виртуальный, то есть зависит от объекта, а не класса обращения. А в первом случае нужно было делать (animals[0] as Dog).Bark().
Вот на это возразить нечего - да, там нужно делать так. И это плавно подводит к мысли "так почему всё-таки не Game Maker?".
EvilCat пишет:
Строгая типизация имеет много недостатков для игроделов-любителей.
Из перечисленных, половина недостатков решается подходом к вопросу с другой стороны. Но вот с классами - нет. На этот счёт был какой-то шаблон (паттерн) проектирования, собирающий разные виды (фрагменты) поведения в один класс, чтобы не создавать разные классы, и вести себя различным образом в зависимости от внутреннего состояния (как бы флагов принадлежности тех или иных поведений к текущему экземпляру), и вообще не использовать ни is, ни as, но я забыл, как он называется. (ну естественно, так как игры на C# я и не делаю, хотя когда-то пытался начинать)
Amphilohiy пишет:
Но Амфи, скажете вы, что насчет игорь?
И тут самое главное. Играм побоку на чем они работают.
Но Амфи, вы снова перебьете меня, что насчет программистов?
Захотят приспособятся к ЯПу. Не захотят - не приспособятся.
Ну и да, вот это - золотые слова.
Последнее редактирование: 7 года 6 мес. назад от Xitilon.
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93848

  • EvilCat
  • EvilCat аватар
  • Вне сайта
  • Просветлённый
  • Сообщений: 469
  • Спасибо получено: 850
  • 3 место Готв2 место Учитель
Это, конечно, хорошо - говорить, что неправильный выбор типа - ошибка на уровне проектирования. Но почти никогда не бывает так, что ставишь точку в проектировании, а затем начинаешь разрабатывать собственно игру. Сейчас почти никто так не рекомендует делать, а в чести - итеративная разработка: запроектировал - сделал - посмотрел - исправил предпосылки - сделал - посмотрел - исправил... Именно в такой разработке я как-то раз вляпалась со строго типизированным языком в такую ситуацию. Язык, кстати, был VBA - Visual Basic, встроенный в Эксель, Ворд и другие продукты Microsoft Office, а "игрой" был собственно один из инструментов (симуляторов) для большого проекта. Да, VBA строго типизированный, даже в плане классов...

Я согласна с Кси, лучше в такие ситуации не попадать потому, что среда просто оперирует "числами" или хотя бы "целыми"/"дробными". Современные компы могут себе это позволить, не тормозя. Если не ошибаюсь, не только GML, но и Руби с Яваскриптом думают так же.
На этот счёт был какой-то шаблон (паттерн) проектирования, собирающий разные виды (фрагменты) поведения в один класс, чтобы не создавать разные классы, и вести себя различным образом в зависимости от внутреннего состояния (как бы флагов принадлежности тех или иных поведений к текущему экземпляру),

Этот паттерн называется "God Object", то есть объект, который знает слишком многое, и это антипаттерн. Фактически это выбрасывание всего ООП в окно. Подобные вещи начинают требоваться, когда в одном месте нужен стреляющий летающий враг, в другом - хилящий летающий, а втретьем - хилящий стреляющий неподвижный. Ты как бы начинаешь думать, что враг должен уметь и стрелять, и хилить, и летать, просто некоторые враги решают этого не делать. Но решать это обычно следует композицией объектов, как, например, и делает Юнити, и даже в GM это можно сделать (собственно, в таком проекте мне и захотелось полифорфизма в GM).
Администратор запретил публиковать записи гостям.

ООП на ГеймМейкере 7 года 6 мес. назад #93849

  • strelokhalfer
  • strelokhalfer аватар
  • Вне сайта
  • Архитектор Миров
  • Знатный грамотей
  • Сообщений: 1640
  • Спасибо получено: 1078
  • Даритель Стимкея2 место Сбитая кодировка2 место Организатор конкурсовПереводчикПрограммист Ruby
Вообще, все проблемы с определением типа данных на препроцессорном уровне можно решить через #define
#define _NUM_HP int
Тогда все переменные здоровья указывать по _NUM_HP и в функциях работать с ними же.
И в случае чего достаточно изменить дефайн. Но я соглашусь, если работать с серьезным ЯП и\или движком, то об этом надо думать заранее.
Ещё, если с++ и дргие умеющие языки, то можно делать перегрузку метода, с параметром нужного типа.
Или как в руби, получать аргументы в хеш\массив. Но оба эти решения откровенно плохие.
Забавный факт [ Нажмите, чтобы развернуть ]
"Стрелок, что-то ты неочень похож на свой аватар..."(с)
Последнее редактирование: 7 года 6 мес. назад от strelokhalfer.
Администратор запретил публиковать записи гостям.
За этот пост поблагодарили: EvilCat
  • Страница:
  • 1
  • 2
Время создания страницы: 0.363 секунд