87

Godot Engine - отличный способ реализовать сбор ресурсов в игре

Доброго времени! Пока весь мир занят паникой, я всё ещё пытаюсь привлечь внимание людей к интересному, лёгкому в освоении и весьма функциональному игровому движку Godot Engine!

В данном материале разбираю механику, позволяющую организовать сбор ресурсов в игре.


Визуально это выглядит так:

Godot Engine - отличный способ реализовать сбор ресурсов в игре Godot Engine, Gamedev, Программирование, 3D, Гифка, Видео

Ну и, тем, кто заинтересовался, полноценный урок:

Если в процессе возникнут какие-либо вопросы, буду рад на них ответить!


PS: Пост опубликован специально для сообщества "Лига Разработчиков Видеоигр"

Дубликаты не найдены

+2

Ооочень скептически отношусь к идее реализации своего движка в 2020 году.

Для UnrealEngine4 есть в маркете не очень дорогой плагин, дающий примерно то же самое. Плюс вся мощь UE4, а не вот эта костыльная штука.

раскрыть ветку 31
+5
Насколько я понял, что юнити, что унрил крайне крутые движки, но для 99% инди игр они слишком глобальны. Я сейчас учу юнити, там движок только весит около 10 гиг. При том что игра, которую я хочу делать это сраненький 2д платформер с простой музыкой и минимумом механик. В итоге это все выглядит как попытка забить гвоздь микроскопом.
раскрыть ветку 30
0

Попробуйте тот же Monogame - только фреймворк и утилитка загрузки ресурсов, или любой другой "молоточек вместо микроскопа".  После этого дружелюбная Юнити покажется раем. Если не хотелось найти конструктор, конечно.

раскрыть ветку 1
0

А как размер движка  коррелируется с размером проекта?

Хочешь просто - делай просто. Никто не запрещает.

раскрыть ветку 22
-2
При том что игра, которую я хочу делать это сраненький 2д платформер с простой музыкой и минимумом механик.
В темплейтах анрила уже есть сайд скроллеры. И 2д, и 3д. С выставленной камерой и управлением персонажем.
раскрыть ветку 4
+1

Сто лет уже собираюсь начать что-то пилить на годоте, но как всегда "руки не доходят" (угу, а до очередного сериальчика зато доходят).

+1
Ух ты почти как в зельде )))
0
О, сканер, привет зай)
раскрыть ветку 1
0

-__-      кто ты?

0
Лучше учите Юнити. Может позже найдёте работу
раскрыть ветку 1
0

увы но ты прав

0

Погуглил Ютуб. Чота все игры на этом двигле ужасны. Он вообще поддерживает например terrain? А травку? Хардваре инстансинг там есть, чтоб лесные массивы рисовать? А водичку как? Ну хотябы на уровне FarCry 1 или  HL2.  Хотелось бы запилить простенькую игруху типа леталки на вертолетике от 1-3 литса.

раскрыть ветку 1
+1

Главное чтобы на корованы набигать можно было)

0

Рубить? Мне кажется это всё же пилить надо назвать, а вот эти пеньки потом можно рубить.

раскрыть ветку 2
+1

Дерево можно и спилить, и срубить, так же как и бревно - его можно и распилить на чурки, и разрубить на них же.

раскрыть ветку 1
0

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

-3
Создание чего-то на GoDot на данный момент тупо не имеет смысла. Есть более продвинутые и удобные движки с поддержкой самых современных технологий. Я говорю про Unity, UE4 и на крайняк CryEngine.
Так же я могу сказать что испытываю отвращение к GDScript.
раскрыть ветку 4
+2

Все проекты, созданные на Годо, можно бесплатно реализовать, ни копейки/цента не отчисляя разработчикам движка или компании-владельцу. В этом, я считаю, большой плюс Годо. Да и монополия - это плохо)

раскрыть ветку 3
0
Все проекты, созданные на Годо, можно бесплатно реализовать, ни копейки/цента не отчисляя разработчикам движка или компании-владельцу. В этом, я считаю, большой плюс Годо.

Моё любимое) Повторюсь в очередной раз, но многие люди, будут только рады достичь того момента (той прибыли), чтобы их попросили что-то приплатить за пользование движком.

раскрыть ветку 1
-1
Плюс сомнительный. Юнити не очень дорог и инди студия из пары человек может обойтись и standalone версией. Ну а если у тебя команда то важна скорость и качество, а не денежная подоплёка.
-3

кому нужен годот, если есть анрил и юнити?

-6

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

раскрыть ветку 13
+1

Объектный подход имеет, конечно, много серьезных недостатков. Но на вашем понимании архитектурных шаблонов я бы советовал не выебываться и писать по методичке. Ну или почитайте про Ecs, там, конечно, еще более пиздецовая раздробленность всего и вся, но есть предпосылки на популяризацию подхода)

0
все было внутри одного скрипта.

И это самый хреновый подход к разработке...

раскрыть ветку 11
-2

нет, можно написать скрипт на 300 строк и все будет работать а можно сделать штук пять объектов в каждом сделать свой скрипт, один перетащить туда другой соединить с третьим и еще с пятым и десятым и получится запутанное говно, вот это плохой подход точно

раскрыть ветку 10
-6
А что за игрушка на гифке? Уж больно красиво реализовано
Нифига не грузит сейчас, не могу ни погуглить ничего, ни видео посмотреть, подскажите пожалуйста, под какие платформы подходит?
ещё комментарии
Похожие посты
70

Делюсь архитектурным шаблоном (StarterKit) для Unity проектов

Всем привет!


Периодически я пилю тут посты, которые с переменным успехом то набирают плюсы, то набирают минусы)))


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


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

В репозитории (ссылку приведу в конце) используется как собственный код, так и сторонний (NonDrawingGraphic, UIParticleSystem).


Сейчас это шаблон с примером реализации Главного Меню (назову это "Экраном") и появляющегося окна (назову это "Диалогом").

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


Логика следующая - существует главная сцена с контроллерами/менеджерами. "Главный Игровой Контроллер" при загрузке игры (появлении этой сцены при запуске) отображает загрузочный экран (назову это "Прелоадером").

Затем (не реализовано, т.к. это индивидуально для каждого проекта) предполагается чтение/загрузка настроек, конфигураций, файлов-сохранений и пр.

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


Буду очень рад вопросам, критике и советам по улучшению.
Ссылка на репозиторий: https://github.com/DL-SKY/PrototypeForIndicator

Надеюсь, кому-нибудь пригодится.

Удачи и успеха всем в геймдеве!

224

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy

Little Game Engine (LGE) – это виртуальная игровая консоль выдуманной конфигурации, с выдуманным процессором и онлайн web-SDK, состоящий из компилятора С-подобного кода в ассемблер и дальнейшей перекомпиляцией его в машинный код с возможностью исполнения этого кода там же, в онлайн в эмуляторе.

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Как видно из названия, заточен весь комплект на быстрое создания 2d ретро игр. Более 20 игр уже готовы, несколько в разработке.

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Чтобы поиграть онлайн, перейдите по ссылке игры ниже, выберете «compile» и затем «run».


TankCity, 1916, FourINaRow, BlackJack, ZombieDefence, MicroRace, DwarfClicker, Galaxies, Memories, NinjaEscape, Mines, Breakout, TowerDefence, FlappyBird, WormBlast, ESProgue, Snake, FishLife, Columns, MarsAttack, CityRunner, Asteroids, Bashe

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Отдельный плюс в том, что эмулятор LGE virtual machine помимо онлайн версии написан и для ESPboy гаджета, который имеет сходную с LGE VM переферию воплощенную в железе и про который я уже писал.


* цветной экран разрешением 128х128,

* 8 кнопок,

* однобитный звук

* RGB светодиод

* подходящий по скорости эмуляции микроконтроллер ESP8266

* встроенную флеш память с файловой системой SPIFFS

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Таким образом можно загружать откомпилированные в онлайн LGE SDK игры в портативный ESPboy, брать его с собой и с интересом коротать свободные минуты.

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Загружать игры можно, как по проводу (см. заргрузка файлов на spiffs), так и через WiFi. Удерживая при запуске ESPboy кнопку «B», мы превращаем гаджет в точку доступа, и подключившись к ее WiFi сети с именем «ESPboy» через браузер, попадаем в веб интерфейс файловой системы, где можно, как удалять файлы, так и загружать новые.

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Остается только собрать гаджет, на что есть схемы, инструкции и kit набор для сборки, который вскоре будет доступен на tindie.com.

Наигравшись в существующие игры – можно довольно быстро начать писать свои.

Игровая консоль и игры к ней своими руками. Little Game Engine + ESPboy Esp8266, Arduino, Gamedev, Программирование, Микроконтроллеры, Длиннопост

Краткая спецификация LGE виртуальной машины:


- Набор из 108 инструкций навеян CHIP8/SCHIP и микропроцессором MOS6502.

- 16 регистров по 16 бит, нулевой регистр является указателем стека.

- Каждая инструкция двухбайтовая, некоторые инструкции содержат после себя два байта данных

- Адресуемая память 20Kб.

- Кроме обычных арифметических инструкций и инструкций перемещения данных, есть отдельные инструкции для работы со спрайтами, экраном и звуком.

- Размер экрана 128х128 пикселей, 16 цветов на точку, что занимает 8Kб памяти, еще столько же занимает буфер для рисования спрайтов и частиц.

- Обновление экрана около 20 кадров в секунду.

- Можно рисовать тайлы и 32 спрайта размером до 128х128 пикселей с возможностью вращения и зеркалирования.

- Поддерживается работа с частицами.

- Для экономии памяти можно использовать однобитные изображения или RLE сжатие.

- Присутствует упрощенная физика: обнаружение столкновений спрайтов со спрайтами и тайлами, разрешение столкновений, гравитация.

- Экран обновляется построчно, только если в строке произошло изменение пикселей.

- Скорость VM в зависимости от того, сколько строк отрисовывается в кадре, варьируется от 100 тысяч до 900 тысяч операций в секунду.

- Можно использовать разные цветные экраны, есть программное растягивание изображения.


Чтобы не писать напрямую в опкодах, в SDK входит самописный компилятор «LGE С», представляющий из себя «C» образный язык высокого уровня. На данный момент этому компилятору далеко до полной поддержки стандартов языка C и при компиляции можно легко столкнуться с непонятной ошибкой в непонятном месте. Зато он быстр, ведь он занимает меньше 2000 строк исходного кода, а также постоянно развивается.


LGE онлайн среда разработки с компилятором и эмулятором

Описание виртуальной машины LGE

Руководство по LGE компилятору «C» образного языка

Исходный код игр LGE на LGE C


На LGE SDK уже сделано не мало игр и можно продолжать создавать новые прямо сейчас, однако до совершенства далеко. Если кто-то желает принять участие в создании новых игрушек на LGE или улучшении самого LGE SDK, а так же если кто-то заинтересовался сборкой ESPboy, добро пожаловать на форум www.espboy.com.

Там постараемся ответить на все вопросы и помочь в реализации идей.


Всем добра и успехов в творчестве.


С уваженеием,

Роман

Показать полностью 5
49

Клон контры на Unity - часть 8

И вот, спустя ГОД я наконец-то добрался до продолжения!
Все основные механики геймплея доделаны, при желании в это даже можно играть!

Будет ещё один, заключительный пост с последним наборов визуально-менюшно-звуковых роликов, и можно считать серию завершённой!

Клон контры на Unity - часть 8 Программирование, Игры, Gamedev, Unity, Contra, Гифка, Видео, Длиннопост
Показать полностью 2
36

Зелья маны

Всем хорошего вечера!
Сделал зелье маны, не одно, а целых 3.
Не исключаю что в самой игре размножу эти 3 на еще несколько + перекрашу цвета.

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

Зелья маны RPG, 3D, Видео, Gamedev, Игры, Компьютерные игры, Steam, Геймеры, Фэнтези, Длиннопост
Зелья маны RPG, 3D, Видео, Gamedev, Игры, Компьютерные игры, Steam, Геймеры, Фэнтези, Длиннопост
Зелья маны RPG, 3D, Видео, Gamedev, Игры, Компьютерные игры, Steam, Геймеры, Фэнтези, Длиннопост
Показать полностью 2
41

Видео создания малого зелья жизни для рпг.

Всем хорошего дня! Не давно моделировал малое зелье жизни для своей изометрической рпг, собс-но делюсь видео на котором процесс создания такой колбы, если вдруг кому-то это интересно. =)
Еще планирую создать около 5 разных зелий, но это не точно. Точно будет еще малое зелье маны.

Покрутить на скетчфабе: https://skfb.ly/6M8t7

Видео создания малого зелья жизни для рпг. Gamedev, Игры, Компьютерные игры, Steam, Геймеры, RPG, 3D, Фэнтези, Видео
169

Создание 3D персонажа "от" и "до".

Привет, друзья!

Меня зовут Антон, я CG художник.


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

Я надеюсь, что кому-нибудь мой труд будет полезен или интересен :) have fun!


Сразу хочу показать то, над чем мы сейчас будем "трудиться", чтобы вы понимали мой уровень.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

Это "гейм-реди" лоу-поли персонаж разбойницы-нежити. Дальше я расскажу подробнее.


1. Поиск концепта.

Началось всё с того, что я хотел сделать себе для портфолио какую-нибудь небольшую работу по созданию персонажа. Изначально план был сделать скульпт девушки-мага, что-то среднее между Катарой и Джайной. В дальнейшем планы поменялись, но Pinterest выдал мне очень классный концепт лучницы (без лука, ага), нарисованный художницей Sennoma (Sennoma, привет!).


Концепт был такой.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

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


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

Оказалось, что автором является (или сейчас правильно говорить авторкой?) замечательная талантливая девушка по имени Ангелина (я так и не понял можно ли здесь указывать ссылки хотябы на её artstation или паблик ВК, но ник прекрасно гуглится), и она была совсем не против использования её работы как концепта для моей 3дшки. Плюс она очень помогла разобраться как устроен костюм в районе ног, за что отдельное спасибо)

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

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

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

А так мне буквально спустя пару минут ответили по ногам. <3 концептер мечты просто.


2. Блокинг (создание основных форм).


Делал я эту работу довольно долго, в основном из-за того, что свободное время либо куда-то исчезало, либо упорно тратилось на другие вещи. Плюс, с самого начала я бросился с места в карьер и совершил большую на тот момент для себя ошибку - я начал блокинг в ZBrush и Marvelous, в чём, спустя какое-то время, сильно закопался, начав прорабатывать мелкие детали, не закончив базовые формы. Да и прямо скажем - мои навыки скульпта пока довольно низкие, не хватает практики, хоть и с возможностями программы я знаком неплохо.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

Примерно такого результата я добился в Zbrush (да, она без век, но это временно)


Спустя какое-то время мне на глаза попалось видео от 3Dex (очень крутой художник) по созданию лоу-поли персонажа-приста, и я решил перенять его пайп-лайн и начать, грубо говоря, заново.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

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

Единственное - я использовал голову и волосы из наработок в ZBrush, сделав ретопологию стандартными инструментами Maya.


3. UV-развёртка.

Когда я понял, что новых геометрических объектов я создавать не буду, а весь остальной "рельеф" я проработаю через текстуры, то решил перейти к развёртке.

Мне было удобнее назначить швы в Maya, а оптимизировать полученные шеллы и собрать их в кучу помог UV-Layout. Всё произошло довольно быстро, поэтому даже и показать особо нечего.

Вот такой салат вышел.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

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


4. Создание хай-поли модели.


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


Сглаженная форма -

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

5. Следующим этапом было запечение текстур.


Я использовал Marmoset, ибо он большой умница. Может запекать текстуры быстро, красиво, в белом пальто, и сразу много пересекающихся мешей.

Я волновался, что всю модель под 50 миллионов поликов он за один раз не съест, но ничего, вытянул и не пожаловался :)

Важным моментом для себя я выделил использование ID карты. Достаточно уделить лишние 5 минут на выделение цветным материалом нужных участков хай-поли модели, которые запекутся в текстуру, и на этапе текстурирования будет гораздо проще назначить этому участку текстуры свой материал, не нужно будет сидеть и обрисовывать маску кисточкой. В моём случае я так выделил металлические накладки на бёдрах, нитки на швах, металлические ободки на кожаных доспехах.


6. Текстурирование.


Один из моих любимых этапов.


Я использовал Substance Painter, он тоже большой умница. Можно довольно быстро добиться неплохих результатов, даже если вы впервые его откроете. Конечно, чтобы быть совсем гуру, хорошо бы открыть ещё и Substance Designer, но пока что у меня до него не дошли руки, а прямой необходимости ещё не появлялось.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

Скриншот из пэинтера. Такой результат меня, в итоге, устроил. Зелёное "слизеринское" свечение я поставил специально, мне показалось, что оно задаёт атмосферу нежити. В этом отлично помог фильтр "Запеченный свет".

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

Добавил ещё немножечко деталек на наплечниках, ладонях и кожанке, т.к. мне показалось, что эти места вызывающе неприлично пустые. Боже храни того, кто вообще придумал альфы <3.


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


7. Риггинг. (Создание "скелета" персонажа, дабы потом его анимировать)


Было бы правильнее озаглавить этот пункт "Гугл и Ютьюб".

Спустя пару лекций по риггингу, я случайно наткнулся на отличный плагин для Maya, облегчающий риггинг и скиннинг. Называется - advanced skeleton. Он очень облегчает задачу, и, если вам вдруг необходимо сделать анимацию персонажа - смело юзайте. Конечно, идеального результата добиться не получится (или это мои кривые руки виноваты), но в любом случае выйдет очень достойно. Дальше потребуется только доработать скиннинг кисточкой в Maya, распределив какая косточка как влияет на какой участок тела, но это не особо сложная задача.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

За пару часов я получил такой результат, что меня, человека, всегда мечтавшего заниматься анимацией, очень порадовало.

За все эти кружочки можно подвигать, и оно шевелится! (оно живое!)


Этим скрином я перешёл уже к следующему, практически заключительному этапу - к выставлению позы и анимации.


8. Анимация.


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

В общем это было довольно увлекательное занятие, я получил удовольствие от процесса.. Ты шевелишь, например, кисть руки и фиксируешь то, в какой момент времени и как она должна поменять своё положение. И так, грубо говоря, с каждой созданной косточкой.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

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


Осталось последнее - закинуть всё полученное в Marmoset, выставить свет и поработать фотографом.

Такие снимки у меня получились.

Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка
Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка
Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка
Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка
Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка
Создание 3D персонажа "от" и "до". 3D, Компьютерная графика, Gamedev, Gamedev-Tutorial, Создание персонажа, Длиннопост, Гифка

Надеюсь, что тот, кто прочёл этот пост до конца - провёл своё время со мной не зря :)

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

Показать полностью 17
71

Распознавание нарисованных фигур

В 2016 Google опубликовал игру-дудл Magic Cat Academy. Она напомнила мне  игру Гарри Поттер и Философский камень, где для изучения заклинания его нужно было максимально точно нарисовать. Вдохновившись этим геймплеем, я решил разработать собственный распознаватель жестов.


Среди общедоступных вариантов есть весьма неплохая библиотека $1, но она иногда слишком параноидальна и видит правильный жест там, где его нет.


Изначально я сделал распознавание фигуры через приведение ее к прямым и диагональным линиям. Этот способ хорошо работает с фигурами типа V, ^, Z, W, но для распознавания округлых фигур необходимо поддерживать вариативность правил распознавания. На рисунке ниже изображены правила для распознавания фигуры pigtail (хвост свиньи). Секции с вопросительным знаком могут присутствовать или отсутствовать, в остальных блоках должна присутствовать хотя бы одна из указанных секций.

Распознавание нарисованных фигур Программирование, Javascript, Gamedev, Разработка игр, Длиннопост

Для того, чтобы упростить работу с округлыми фигурами, я заменил ламанные линии на кривые Безье.  Это немного снизило скорость распознавания, но позволило распознавать более сложные фигуры.

Распознавание нарисованных фигур Программирование, Javascript, Gamedev, Разработка игр, Длиннопост

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


Вот как теперь выглядят правила для распознавания pigtail:

Распознавание нарисованных фигур Программирование, Javascript, Gamedev, Разработка игр, Длиннопост

Код библиотеки я выложил на github, надеюсь кому-то он пригодится :)

Показать полностью 2
307

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов

Ранее мы публиковали пост про то, как у нас получилось воссоздать подмосковный город Серпухов в компьютерной игре. Мы пообещали, что большинство обновлений нашей игры, автобусного симулятора Bus Driver Simulator, будет бесплатными. Сегодня мы выпустили очередное глобальное обновление, которое добавило новый город - Кёльн.

Почему именно этот немецкий город?

Дело в том ,что большая часть нашей аудитории не из России. И одна из самых многочисленных стран среди игроков - Германия (все же мы помним, как немцы любят симуляторы?). Конечно, достаточно много и британцев, и поляков, и других европейских народов.

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

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

Кроме этого, Кёльн ни разу не моделировали для компьютерных игр.

А ещё, в Кёльне проходит крупнейшая европейская игровая выставка GamesCom.


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

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

Да, по улицам Кёльна у нас ездят и российские автомобили - трафик пока что един.

Вообще, моделирование города - очень сложная задача, особенно для такой маленькой команды, как мы (буквально несколько человек). А на моделирование одного здания уходит минимум 2 полных рабочих дня. Отсюда и некоторая экономия - если здания похожи, то используем уже имеющуюся модель. С Серпуховым мы поступали также, хотя уникальных зданий там больше (впрочем, как и размер карты). Отличие также заключается в том, что там мы использовали фототекстуры. Да, ходили по городу и фотографировали здания со всех сторон, чтобы поместить в игру. С Кёльном это было бы очень затратно, поэтому мы ориентировались на карты гугл, панорамы и 3D вид.

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

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

Во-первых, как уже было сказано, можно представить, сколько времени нужно на создание карты, если только одно здание требует как минимум двух рабочих дней. А сама дорога? А мелкие объекты? Ещё больше. Моделирование Серпухова началось в конце 2016 года и было закончено в августе 2018, продолжаясь почти беспрерывно.

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

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

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

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

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

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

Коммьюнити у симуляторов достаточно активное в плане создания модификаций и мы даже предложили такой вариант - вы можете создавать свой город с использованием инструментария движка Unity (мы даже обещали работу на денежной основе, если будут показаны хорошие результаты). Но, конечно, это гораздо, гораздо сложнее, чем создание карты в редакторе карт для, например, Euro Truck Simulator. Были люди, которые начинали что-то делать, даже показывали скриншоты. Но, в итоге, запал быстро сходил на нет.

А, кроме этого, многие мододелы не особо заботятся, например, о создании правильной развертки. В итоге получается по 30 текстур и материалов на одну маленькую модель. Или по 30 тысяч полигонов на домик. И без ЛОДов. 

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост
Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

Есть ещё одна достаточно серьезная проблема. Это касается не только карт, но и игры в целом. Чем больше - тем сложнее. Сложность возрастает в разы с увеличением размеров. Одна из проблем Unity и почти всех игровых движков в том, что на некотором расстоянии (обычно свыше 5км) от начала координат начинаются проблемы с точностью вычислений позиционирования объектов. Для игрока это выглядит, как-будто объект трясётся, или один проходит через текстуру другого. Проблема решается периодическим сдвигом карты к началу координат.

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

Город Кёльн для автобусного симулятора. Сравнение с реальностью и немного о сложностях моделирования городов Кельн, Симулятор, Автобус, Водитель, Моделизм, 3D, Gamedev, Длиннопост

В общем, сложностей хватает. Постоянно в выборе - куда потратить драгоценное время. Может, на детализацию имеющегося? Или добавить ещё один квартал? А ведь кто-нибудь обязательно будет недоволен - "а я там был и там вот разметка не соответствует действительности".


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

Спасибо за внимание!

Показать полностью 14
467

Способы применения и искажения меткости в играх. Наглядные графики для сравнения

Вычислять факт попадания в играх на основе полученной меткости можно по разному:

— сравнивая с одним псевдослучайным числом (которое тоже можно получать по разному [1]);

— сравнивая с наибольшим или наименьшим из двух псевдослучайных чисел;

— сравнивая среднее из двух и более случайных чисел (среднее тоже можно считать по разному).

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

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

Точно также по разному можно рассчитывать наносимый урон, особенно на основе дайсов (кубиков).

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

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

=== Манипуляции с меткостью ===

Обычно, когда игроку сообщается, что меткость у персонажа равна 60%, то он воспринимает эту информацию как: «из 10 выстрелов я могу рассчитывать на 6 попаданий». И если из 10 попаданий он будет наблюдать 1 попадание вместо 6, то он почти наверняка посчитает, что случайность в игре поломана. Особенно сильно он в этом уверится, если такое случится на отрезке из 100 выстрелов. Чтобы избежать таких неприятностей, разработчики часто скрытно манипулируют с реальной вероятностью попадания (либо вообще отказываются от элемента случайности).

Например, в игре Fire Emblem: The Binding Blade для определения попадания с меткостью сравнивалось не одно случайное число, а среднее из двух случайных чисел [2].

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Результат этой манипуляции таков, что меткие атаки (>50%) попадают значительно чаще, чем им полагается при нормальном распределении, а неметкие (<50%) попадают значительно реже. Вот как меняется это распределение вероятностей:

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Для примера, при 10% показываемой меткости фактическая при этом является 1.9%. А при 75% фактическая будет 87.24%.


Но, если уж на то пошло, то менять меткость можно и многими другими способами.

Например, можно взять среднее из 3 случайных чисел:

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Искажение в результате этого становится еще более разительным: меткость 10% становится 0.41%; меткость 75% становится 92.69%.


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

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Тут 10% превращаются в 4.83%, а 75% в 88.18%. Но, что самое интересное, переход происходит при 30%, а не при 50%, как в среднем арифметическом. Поэтому если Вам хочется уж точно быть уверенными, что у игрока всегда будет преимущество, то достаточно удостовериться, что его минимальная меткость никогда не будет ниже 30%, а у врагов она будет настолько низкой довольно часто (для врагов можно использовать и среднее арифметическое, или что-то еще более искаженное).


Среднее геометрическое из 3 чисел приводит примерно к тем же результатам, но только с большим разбросом:

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Тут 10% превращаются в 1.95%, а 75% в 93.98%.


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

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

В результате этого вероятность попадания меняется очень сильно. Например, при выбирании наименьшего числа меткость в 10% преобразуется в 19.02%, а меткость в 75% — в 93.75%.

Такой способ, например, используется в игре Neverwinter Nights в навыке «Скользкий разум», при котором в случае провала проверки на спасение производится повторная проверка на силу воли [3].

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Neverwinter Nights 2 — Pixie Warrior [4]


Ниже приводится таблица искажения меткости при разных способах вычислений.

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

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

Разработчик Carsten Germer использует функцию контролируемой случайности для редких и не только событий [5]. Например, чтобы гарантировать периодическое выпадение особо редкого бонуса с шансом 1 к 10000, он после каждого «промаха» увеличивает шансы по порядку: 1 к 9900; 1 к 9800; 1 к 9700… и так до фиксации события. А чтобы гарантировать отсутствие частых редкостей, он ввел дополнительную переменную, блокирующую срабатывание на 100% в течение 10 следующих проверок после прошлого срабатывания.

Заблуждения игроков при оценке рисков [1]


Вот как изменяется вероятность этого редкого события при использовании этого способа:

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

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


Ниже я привожу также изменение 1% события, что оно произойдёт хотя бы раз по мере роста числа попыток. Алгоритм искажения: первые 10 попыток — гарантированный промах. Затем с каждым промахом вероятность повышается на 1% (0,1% и 0,01%) до попадания. Потом всё с начала.

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Впрочем, если ваша основная цель, как разработчика, гарантировать то, что пользователь в 1% событии не попадёт на серию из 1000 промахов подряд, то легче и прозрачнее будет после 200 промахов подряд выставлять 100% попадание. Это избавит вас от редких недоумений игроков и позволит оставить программный код лаконичнее и дружелюбнее для будущих доработок.



=== Разные способы начисления бонусов к меткости ===


Если бонусов к меткости в игре немного и они легко контролируются разработчиком, то проще всего использовать самый простой подход с линейным увеличением меткости простым сложением с базовой величиной. Этот способ легче всего внедрить в игру и всегда понятен игрокам. При таком подходе возможно достижение 100% меткости, что не всегда соответствует планам разработчика.

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Если в игре планируется множество значительных бонусов к меткости, то, чтобы не переваливать за гарантированные 100% меткости, можно вычислять окончательную меткость как серию дополнительных бросков (чаще всего маловероятных по отдельности). Например, при меткости 70% и бонусе 50% окончательная вероятность попадания будет равна 85%, как проверка двух последовательных бросков, когда достаточно хотя бы одного попадания.

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

Немного экзотическим является подход по изменению сути бонуса к меткости на бонус уменьшения вероятности промаха.

// newAccuracy - новая меткость в %
// baseAccuracy - изначальная меткость в %
// bonusAccuracy - бонус к меткости в %
let newAccuracy = 100 - ( (1 - baseAccuracy * 0.01) / (1 + bonusAccuracy * 0.01) ) * 100;

Гарантирует, что всегда будет вероятность промаха при любом бонусе. Благодаря этому игра может давать бонусы к «меткости» больше 100%, хоть 1000%. И всё равно будет оставаться вероятность промаха. Но игрока это скорее может запутать, а, значит, и разочаровать.

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост
Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

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



=== Распределение урона на основе дайсов ===


Данный пункт целиком основан на наглядных данных публикации «Probability and Games: Damage Rolls from Red Blob Games [6]». Здесь я кратко представляю некоторые примеры и выводы этой публикации. В оригинальной статье Вы получите более детальные выводы и интерактивные графики распределений, а также интерактивно настраиваемые функции для подбора разных уникальных комбинаций.


Самый наглядный (но не единственный) пример различного подсчета урона дайсами представлен на основе вычисления урон при максимальном значении, равном 12. Результат может быть получен с помощью разных кубиков (например, если вы играете в настольную игру и каких-то специальных кубиков у вас нет):

1d12 — одним кубиком с 12 гранями

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

2d6 — двумя кубиками с 6 разными гранями

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

3d4 — тремя кубиками с 4 разными гранями

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

4d3 — четырьмя кубиками с 3 разными гранями

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

6d2 — шестью кубиками с 2 разными гранями

Способы применения и искажения меткости в играх. Наглядные графики для сравнения Игровая механика, Разработка игр, Меткость, Случайность, Gamedev, Манипуляция, Программирование, Компьютерные игры, Длиннопост

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

Заключение


Таким образом, были рассмотрены следующие темы:

— манипуляции с меткостью с помощью разных способов её проверки;

— разные способы начисления бонусов к меткости;

— различное распределение урона на основе дайсов.

Каждый из способов может быть полезен разработчику. Для игр с более казуальной аудиторией чаще выбирают щадящие алгоритмы, в которых вероятность успеха игрока завышается, а чтобы поднять азарт создаётся иллюзия маловероятной победы (подробнее в одной из прошлых статей: [7]).

Список литературы


1. Заблуждения игроков при оценке рисков. Контроль генератора случайных чисел в разработке.

2. Fire Emblem Wiki — Random Number Generator.

3. Neverwinter Nights 2 — Class Abilities — Slippery Mind.

4. Neverwinter Nights 2 — Pixie Warrior.

5. «Not So Random Randomness» in Game Design and Programming.

6. Probability and Games: Damage Rolls from Red Blob Games.

7. Генерация Close call в играх: «На волосок от поражения» или «Чуть-чуть не победил».

Показать полностью 23
58

Клон контры на Unity - часть 7

Здравствуйте! Для тех, кому всё ещё это интересно, выкладываю очередную порцию видеороликов о том, как я делаю клон игры Contra на движке Unity.

Сразу отвечу на один из самых частых вопросов, задаваемых в комментариях:


"Зачем это вообще нужно, когда есть оригинальная контра на эмуляторе?"


Ответ простой:
Смысл ни разу ни в том, чтобы сделать замену оригинальной контре. Смысл в практике программирования - задать себе задачку и успешно её выполнить.

В сегодняшней порции роликов реализованы три вида врагов - настенные крутящиеся пушки, подземные бункеры и стрелки-снайперы.

Клон контры на Unity - часть 7 Программирование, Игры, Разработка игр, Gamedev, Unity, Гифка, Видео, Длиннопост
Показать полностью 3
150

Мой шеф на досуге написал игру 

Называется Snek Fite. Она любопытная — хотя бы потому, что там надо заниматься сценарным программированием. А еще она про змей. Расскажу немного и добавлю своих корявых рисунков. Сразу предупреждаю, что игра далеко не казуальная. Даже хардкорная, хотя это слово уже и потеряло смысл от многократного повторения. В общем, хэв фан :)

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Графика


Самый короткий пункт, потому что ее нет. Ну, то есть, есть, конечно. Но исключительно затем, чтобы вы могли отличить змею от стены. Ниже будет геймплейное видео, и вы сможете увидеть все своими глазами. А начнем мы с истории.


Ведь мы любим хардкорные игры не за графон, верно?
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Откуда хвост растет


Кто жил в девяностые, играл в «змейку». Она еще была на Brick Game — это тот самый черный кирпич, где еще был тетрис, гоночки и вот эта игра, где нужно было из пушки стрелять по сосулям.


«Змейка» у многих была любимой.


А те, у кого в то время уже был ПК, помнят еще одну «змейку» — ее издала российская компания Gamos в 1992 году. Те самые ребята, которые потом подарят миру «Братьев Пилотов» и непроходимый квест с холодильником.


Место, где осталось 20 часов детства
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Так вот, эта «змейка» выглядела вот так и называлась Snake Battle (или «Змеиные бои»):

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


Так выглядел экран настройки змеиной логики. Змею надо было программировать, никаких тебе WASD.
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Чтобы побеждать, тебе нужна была не реакция, а логика. Ну или как минимум папа-программист.


Разница между обычной «змейкой» и этой — как между трехмерным и четырехмерным миром
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

В общем, для большинства знакомство с игрой было таким:


— Так, что это у нас здесь? О, новая игра, класс!

5 минут спустя…


— Нафиг это, пойду лучше в Doom поиграю. Или Duke Nukem. Да хоть в шахматы.
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

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


Как вы поняли, Snek Fite — это такой духовный наследник Snake Battle. Только в ней есть то, чего не было у оригинала (а так хотелось) — возможности поиграть с друзьями и выяснить, у кого змея длиннее.


— Эй, Ёрмунганд, как насчет партии на троих?
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Правила. Я предупреждал


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

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Каждое поле — это «дальность обзора» змеи (в центре ее голова). Ты размещаешь доступные объекты в клетках, поведение змеи меняется.


Красный цвет обозначает твою змею, белый — любую вражескую. Есть три объекта для частей тела (голова, хвост, тело) и два нейтральных объекта (пустая клетка, стена). На каждый объект можно повесить один из логических операторов: must, must not или optional.


Если на этом месте вы широко зеваете, то, скорее всего, игра вам будет не по зубам. Хотя попробовать могут даже решительные гуманитарии (как я, например. Мой Uroboros занимает почетное тридцатое место в таблице лидеров — ему просто везет).


Грамотно настроенная змея ведет себя осторожно
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

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

Пример 1. Снек движется в случайном направлении, так как перед ним нет двух вражеских хвостов.
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост
Пример 2. Снек движется в направлении вражеского хвоста, так как в правилах есть условие optional — то есть сценарий запускается, если соблюдается хотя бы одно условие
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост
Пример 3. Снек «сохраняет форму», то есть на картинке он будет двигаться вниз.
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Если вы провели настройки не методом Священного Рандома, то ваш снек станет машиной по превращению противников в кучку золы.


Ну на крайний случай они просто останутся без хвоста
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Можно, кстати, придерживаться неагрессивной тактики — а вместо этого вовремя подставлять «блоки» и уходить от погони. Пример такого защитного поведения прислал один из игроков, настройка выглядит вот так:

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

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


— Снек, тебя обнаружили!
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Еще вы поначалу будете сталкиваться вот с таким явлением. «Кольцо смерти» или «крысиные бега» — змеи бесконечно гоняются за хвостами друг друга, двигаясь кругами.

Хорошо обученная змея такого не допустит.

Фигура вторая, печальная
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Вот, в общем-то и вся программная логика. Она не такая страшная, как могло показаться, и вместе с тем открывает простор для экспериментов. Опыты над змеями — это вообще главная механика игры. Не бывает «победных» тактик, импровизация — наше всё.


Игровые режимы и другие механики


Их пока что три. В любом режиме схватка продолжается 1000 ходов — то есть пока не закончится время.


Дуэль. Тут все понятно, две змеи бьются один на один. Это как финальная битва Дарта Вейдера с Люком или Гарри Поттера с Волдемортом.


— Прости, Северус, импровизируй.
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Снейкоцид. Четыре змеи, deathmatch (каждый за себя) до победного. Веселее тем, что происходит больше экшна — а лидер может потерять преимущество в самый последний момент.


Гибрид щуки и белой березоньки включил режим снейкоцида
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

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

Змеиная безножка
Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Победитель получает очки и если наберет достаточно — попадает в турнирную таблицу.

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

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

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Ну вот вроде и всё.


На игру у автора ушло примерно 100 часов. Это притом, что она сделана на технологии VUE, с которой тот не был знаком на момент начала работы — приходилось обучаться по ходу дела.

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост

Игра сейчас находится в свободном доступе по адресу snek.app (играть можно в браузере), а код лежит в репозитории на GitHub — так что любой желающий может присоединиться к команде.


Будем рады, если найдем тут неравнодушных к симуляторам программирования. Пополняйте ряды, вместе грызть друг друга веселей. Thanksssss.


Бонус: новая книга для тех, кто хочет достичь нирваны в воспитании змей-чемпионов :)

Мой шеф на досуге написал игру  Игры, Программирование, Инди, Gamedev, Змейка, Иллюстрации, Юмор, Видео, Длиннопост
Показать полностью 22 2
65

Пишем 2D игру на Unity3d | исходники игры на гитхабе!

В этом видео мы продолжим создавать игру на движке Unity. Для более быстрой и эффективной разработки я написал небольшой фреймворк и назвал его Actors. Это компонентно-ориентированный подход для создания игровых сущностей на основе компонентов даты и поведений в Unity. Я использую его на своем основном проекте и в данный момент активно обновляю.

=======================================================

Скачать фреймворк

Скачать исходники игры

Поиграть в игру в браузере
=======================================================

174

Рисуем в 3d на c++ поверхность, заданную формулой

Всем привет, меня зовут TaHk и по ночам я программирую на c++.

Недавно я столкнулся с задачей (не столько про c++, сколько математической), решение которой показалось мне красивым, и я хочу им поделиться.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

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


Итак. Задача -- нарисовать в 3d поверхность, которая задана не набором полигонов, а формулой.

Алгоритм был выбран следующий:

0. Исходные данные.

*Координаты нулевой точки поверхности (точка в глобальной системе координат, являющаяся центром координат для формулы, которой задана поверхность);

*Вектор нормали поверхности в нулевой точке (показывает, как наклонена поверхность относительно глобальных координат);

*Размеры поверхности по x, y и z (чтобы она просчитывалась не по бесконечность во все стороны, а в рамках определенного объема);

*Координаты "глаза";

*Вектор направления взгляда;

*Вектор, показывающий, где у "глаза" верх;

1. Формируем лучи из каждого пикселя экрана и проверяем на пересечение с поверхностью.

2. Если луч не пересекается с поверхностью -- окрашиваем пиксель в черный.

3. Если пересекается -- определяем освещенность точки. Для этого определяем нормаль к поверхности плоскости, и чем меньше угол между нормалью и лучом из камеры -- тем ярче точка.


Давайте разбираться с каждой задачей в отдельности.

1. Лучи из каждого пикселя экрана.

Ну, тут все просто. Чтобы задать луч -- нужна точка и вектор. Точка у нас есть -- это координаты "глаза". И направление взгляда есть. Соответственно, луч для координат [0,0] у нас уже есть. Что же делать с остальными координатами? Ответ на этот вопрос даст (или нет) эта картинка:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Для начала, нам нужны единичные векторы dx и dy, перпендикулярные друг другу и вектору взгляда, чтобы построить на них плоскую систему координат, которая будет для нас экраном. Вектор dy у нас уже есть («Вектор, показывающий, где у "глаза" верх» в исходных данных). Что же на счет dx? А тут приходит на помощь векторная алгебра, из которой мы помним (или нет), что результатом векторного произведения двух векторов является вектор, перпендикулярный векторам-множителям, с нормой равной площади параллелограмма, построенного на этих векторах. Соответственно, если исходные векторы перпендикулярны друг другу и оба с длиной равной единице – длина результата тоже будет равен единице. А это прекрасно, ведь нам нужен именно единичный вектор.

Таким образом,

dX[0] = tv[1]*dY[2] - tv[2]*dY[1];
dX[1] = tv[2]*dY[0] - tv[0]*dY[2];
dX[2] = tv[0]*dY[1] - tv[1]*dY[0];

где tv — вектор направления взгляда, а dY вектор, показывающий где у взгляда верх.

Дальше, было бы неплохо определиться с длиной векторов dx и dy, определив таким образом размер экрана (по сути, это управление углом обзора). Мне оптимальным показался вариант, когда у экрана размер равен единице

dX[0] /= max_x;
dX[1] /= max_x;
dX[2] /= max_x;
dY[0] /= max_x;
dY[1] /= max_x;
dY[2] /= max_x;

Где max_x – разрешение экрана по x. Да, dy тоже делится на max_x, чтобы длина вектора dx была равна вектору dy, так как иначе изображение будет растянуто по одной из осей.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Итак, у нас есть:

dX, dY – векторы, определяющие плоскость экрана.

dZ – вектор направления взгляда.

for (int y = 0; y <= max_y; ++y) {
for (int x = 0; x <= max_x; ++x) {
tv[0] = dZ[0]+x*dX[0]+y*dY[0];
tv[1] = dZ[1]+x*dX[1]+y*dY[1];
tv[2] = dZ[2]+x*dX[2]+y*dY[2];
// tv – вектор, показывающий направление луча из точки [x,y] экрана
// ...
};
};

В рамках этого цикла мы и будем работать дальше.


2. Пересечение луча с поверхностью.

Обычно лучший способ найти в пространстве точку пересечения луча с поверхностью, которая задана формулой – это решить систему уравнений, состоящую из уравнения плоскости и уравнения луча. Но если в уравнение плоскости проникает тригонометрия – решений становится бесконечное множество (буквально бесконечное, вида x = 0 ± 2πn, где n∈R ), и что делать программно с этой бесконечностью – не ясно. Поэтому мы будем искать точку пересечения итеративно:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

1. Определяем параллелепипед, ограничивающий нашу поверхность (мы помним, что по условиям ограничили ее в размерах).

2. Ищем точки пересечения луча и параллелепипеда. Получаем 2 точки – «вход» и «выход» в пределы параллелепипеда.

3. В точке «входа» переводим координаты из глобальной системы координат в локальную для параллелепипеда.

4. В локальных x и у находим по формуле поверхности координату z. Если найденная координата z больше, чем у точки «входа», фиксируем, что мы «под» поверхностью. Иначе – фиксируем, что мы «над» поверхностью.

5. От точки «входа» до «выхода» проверяем аналогичным образом все точки на луче с заданным шагом. Как только на следующем шаге состояние отличается от того, что было на предыдущем – значит, нашли точку пересечения.

6. Если до точки «выхода» состояние не менялось – значит пересечения не было.


Теперь по пунктам.

Существует простой и понятный алгоритм быстрого поиска пересечения прямоугольника с лучом на плоскости. Для его понимания нужно ввести пару терминов:

Точка входа – точка пересечения луча с прямой, в случае если нормаль этой прямой направлена навстречу лучу.

Точка выхода – точка пересечения луча с прямой, в случае если нормаль этой прямой направлена навстречу лучу.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Алгоритм такой:

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

К чему это я? А вот к чему. Этот подход отлично работает и в пространстве, если заменить 4 прямые на 6 плоскостей.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Как мы помним, поверхность задана точкой и нормалью и ограничена в размерах по x, y и z. Причем эти x y и z – в локальных координатах. То есть наш параллелепипед, ограничивающий поверхность, должен уметь вращаться вместе с поверхностью.

Поэтому для начала определим эти плоскости с учетом поворота параллелепипеда с поверхностью. Для этого нам понадобятся 3 вектора:

ddX[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси X нашей поверхности
ddY[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси Y нашей поверхности
ddZ[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси Z нашей поверхности

с ddZ все понятно – это нормаль к поверхности.

С ddX и ddY сложнее. Одной только точкой и нормалью можно задать в пространстве только бесконечную поверхность. А тут нам нужно зафиксировать поворот этой плоскости вокруг оси z. Это можно сделать разными способами – я беру еще одну точку на плоскости и фиксирую ее координаты в глобальной системе координат. Допустим, это точка point2, а нулевая точка поверхности — point. Тогда

ddX[0] = point2[0] - point[0];
ddX[1] = point2[1] - point[1];
ddX[2] = point2[2] - point[2];
len = sqrt(ddX[0]*ddX[0]+ddX[1]*ddX[1]+ddX[2] *ddX[2]) ;
ddX[0]/=len;
ddX[1]/=len;
ddX[2]/=len;

Как мы видим, я не забыл, что нам нужен именно единичный вектор (с длиной равной единице), поэтому я посчитал длину вектора от точки point к точке point2 и разделил каждую координату на длину. Эта процедура называется нормализация вектора – приведение его к единичной длине с сохранением направления.

Ну и ddY по старой схеме (как в пункте 1, где мы экран рисовали) определяем как векторное произведение ddX на ddZ:

ddY[0] = ddX[1]*ddZ[2] - ddX[2]*ddZ[1];
ddY[1] = ddX[2]*ddZ[0] - ddX[0]*ddZ[2];
ddY[2] = ddX[0]*ddZ[1] - ddX[1]*ddZ[0];

Таким образом, мы можем задать все 6 плоскостей. Например, плоскость, ограничивающая параллелепипед «снизу» определяется так:

spoint[0] = point[0] - z * ddZ[0];
spoint[1] = point[1] - z * ddZ[1];
spoint[2] = point[2] - z * ddZ[2];
n[0] = -ddZ[0];
n[1] = -ddZ[1];
n[2] = -ddZ[2];

где point — нулевая точка нашей поверхности, а z - половина высоты параллелепипеда.

Остальные – по аналогии, меняем только - на + и буквы координат.


Дальше нужно в общем виде понимать, как мы будем искать точки пересечения луча и плоскости. Допустим, плоскость задана точкой point[3] и нормалью n[3]. Луч задан точкой tp[3] и вектором tv[3]. Еще одна картинка в стиле «я у мамы paint master»:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Несложно догадаться, что если векторы n и tv имеют единичную длину, то расстояние от точки tp до точки пересечения с плоскостью будет равно -h/p. Шучу, сложно догадаться. Но при желании вы можете это проверить. Даже так – если вы сейчас в школе проходите векторную алгебру – вы должны это проверить и выложить в комментариях доказательство. Иначе вам поставят двойку. Или что там сейчас ставят в школах…

Как же найти эти h и p? Тут на помощь снова приходят определения из векторной алгебры. Скалярное произведение векторов численно равно длине проекции одного из этих векторов на другой. Как определить скалярное произведение? А примерно так:

float MulVecSc(float *Vec1, float *Vec2){
return Vec1[0]*Vec2[0] + Vec1[1]*Vec2[1] + Vec1[2]*Vec2[2];
};

Как мы видим из рисунка, h – это проекция на нормаль вектора от точки tp до точки point, принадлежащей плоскости, а p – это проекция на нормаль вектора tv.

vp[0] = point[0] - tp[0];
vp[1] = point[1] - tp[1];
vp[2] = point[2] - tp[2];
p = MulVecSc(n,tv);
h = MulVecSc(n,vp);
t = - h/p;

Знак p покажет нам, с какой стороны плоскости мы находимся (а значит покажет, нашли мы точку «входа» или «выхода»).


Резюмируем. В пространстве точки пересечения луча с параллелепипедом находятся так:

float ddY[3] = {point2[0],point2[1],point2[2]};
float ddX[3] = {0,0,0};
float ddZ[3] = {n[0],n[1],n[2]};
tmMulVec(n,ddY,ddX);
// 6 плоскостей. Ищем самый поздний "вход" и самый ранний "выход"
// Плоскость 1
spoint[0] = point[0] + x * ddX[0];
spoint[1] = point[1] + x * ddX[1];
spoint[2] = point[2] + x * ddX[2];
vp[0] = tp[0]-spoint[0];
vp[1] = tp[1]-spoint[1];
vp[2] = tp[2]-spoint[2];
n[0] = ddX[0];
n[1] = ddX[1];
n[2] = ddX[2];
p = tmMulVecSc(lv_n,tv);
t = - tmMulVecSc(lv_n,lv_vp)/p;
if(p>0.0f){ // выход
if(t<t_out)
t_out = t;
}else{ // вход
if(t>t_in)
t_in = t;
};
// Плоскость 2
spoint[0] = point[0] - x * ddX[0];
spoint[1] = point[1] - x * ddX[1];
spoint[2] = point[2] - x * ddX[2];
vp[0] = tp[0]-spoint[0];
vp[1] = tp[1]-spoint[1];
vp[2] = tp[2]-spoint[2];
n[0] = -ddX[0];
n[1] = -ddX[1];
n[2] = -ddX[2];
p = tmMulVecSc(lv_n,tv);
t = - tmMulVecSc(lv_n,lv_vp)/p;
if(p>0.0f){ // выход
if(t<t_out)
t_out = t;
}else{ // вход
if(t>t_in)
t_in = t;
};
// Плоскость 3
// ...
// Плоскость 4
// …
// Плоскость 5
// …
// Плоскость 6
// ...
if(t_in<t_out&&t_out>0){
// есть пересечение
};
Так. Теперь мы знаем, что в промежутке от t_in до t_out мы внутри параллелепипеда.
Дальше, как и планировали, будем проверять каждую точку с неким шагом h на то, находится она выше или ниже поверхности в локальных координатах.
Что такое локальные координаты?
Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Это система координат, образованная теми самыми ddX, ddY, ddZ которые мы определили выше. Как очевидно из рисунка (на этот раз действительно очевидно), если у нас есть точка p, то вектор, ведущий от нулевой точки нашей поверхности до точки p будет определяться векторной суммой x*ddX+y*ddY+z*ddZ, где x y и z локальные координаты этой точки. Что ж, в таком случае, зная глобальные координаты точки p мы можем получить локальные таким образом:

vtp[0] = p[0]-point[0];
vtp[1] = p[1]-point[1];
vtp[2] = p[2]-point[2];
x = MulVecSc(ddX,vtp);
y = MulVecSc(ddY,vtp);
z = MulVecSc(ddZ,vtp);

Дальше, проверяем, находимся мы в этой точке под поверхностью или над.

F = F_xy; // тут у нас определение значения функции, описывающей плоскость. Его мы рассмотрим позже, в 3й части.
if(z<F){ // определяем, находимся мы в точке входа «над» или «под» поверхностью
in = true;
}else{
in = false;
};

Дальше – просто делаем это в цикле, перемещая точку p:

for(t = t_in+h;t<=t_out;t+=h){
pt[0] = tp[0] + tv[0]*t;
pt[1] = tp[1] + tv[1]*t;
pt[2] = tp[2] + tv[2]*t;
vtp[0] = point[0]-pt[0];
vtp[1] = point[1]-pt[1];
vtp[2] = point[2]-pt[2];
x = -tmMulVecSc(ddX,vtp);
y = -tmMulVecSc(ddY,vtp);
z = -tmMulVecSc(ddZ,vtp);
F = F_xy;
if(z<F){ // сейчас внутри
if(!in){ // были снаружи
break;
};// были снаружи
}else{ // сейчас снаружи
if(in){ //были внутри
break;
};//были внутри
}; // внутри/снаружи
}; // for t_in ... t_out
if(t>=t_out){
break; // никакого пересечения не было
};
// на данный момент t – это расстояние от точки tp до точки пересечения
// фактически точка на расстоянии t уже после пересечения с плоскостью, поэтому
// в качестве точки пересечения берем t-h
t-=h
collision_pt[0] = tp[0] + tv[0]*t;
collision_pt[1] = tp[1] + tv[1]*t;
collision_pt[2] = tp[2] + tv[2]*t;

Вот мы и нашли, где луч пересек поверхность. Запихнув это решение в цикл, который мы получили в первой части, мы получим картинку, на которой будут видны очертания поверхности. Но на 3d картинку это не будет похоже – чтобы одна точка поверхности отличалась от другой (что создаст объем) нужно определить освещенность.


3. Определение освещенности точки.

В рамках этой задачи мы не будем заморачиваться с источниками света – будем считать, что у нас один источник и он расположен непосредственно за «глазом». В таком случае расчет освещенности сводится к простому определению нормали к поверхности. Чем меньше значение проекции – тем темнее точка, так как свет падает под большим углом. Поскольку векторы у нас единичные, значение проекции будет изменяться в диапазоне [0..1], что позволяет просто домножать значение цвета на проекцию и получать нужную картинку.

Итак, вернемся к «простому определению нормали».

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Пора наконец определиться с тем, какую поверхность мы рисуем. В коде ранее была конструкция F = F_x; Тут F_x это макрос, в который я подставляю формулу, которую хочу рисовать. Разумеется, в последствии в код можно будет подставить любую формулу, но для примера нужно взять что-то конкретное. Я выбрал такое:

#define F_xy cos((x*x+y*y)/20.0)/(1+(x*x+y*y)/100.0)

Чтобы понимать, что мы хотим увидеть в программе, построим этот график в каком-нибудь инструменте, который это уже умеет:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

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

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Для примера возьмем двумерный график:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

(графики касательных смещены для наглядности)

Функция Y=x^2. Её производная Y'=2x. Соответственно, в точке X=0.5 коэффициент угла наклона равен единице, а в точке 2 – четырем. Из графика видно, что коэффициент угла наклона с обратным знаком показывает угол наклона линии, перпендикулярной касательной. Эта же логика работает и для более сложных графиков. Так же она работает и в пространстве.

Поэтому запишем уравнение поверхности в виде cos((x*x+y*y)/20.0)/(1+(x*x+y*y)/100.0) - z = 0 и возьмем производные по трем координатам:

F'x = ((sin((x*x+y*y)/20.0)*x/10.0)*(1+(x*x+y*y)/100.0)-(x/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))

F'y = ((sin((x*x+y*y)/20.0)*y/10.0)*(1+(x*x+y*y)/100.0)-(y/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))

F'z = -1

Вернемся к коду. Теперь зная точку пересечения и ее локальные координаты – мы можем найти нормаль. Она будет определяться как N[3] = {-F'x,-F'y,-F'z}. Но нужно помнить, что это ее значения в локальных координатах. Чтобы перевести в глобальные – нужно каждый компонент умножить на значение вектора той оси, которой он соответствует:

#define F_x ((sin((x*x+y*y)/20.0)*x/10.0)*(1+(x*x+y*y)/100.0)-(x/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))
#define F_y ((sin((x*x+y*y)/20.0)*y/10.0)*(1+(x*x+y*y)/100.0)-(y/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))
#define F_z 1.0
float Fx = F_x;
float Fy = F_y;
float Fz = F_z;
collision_normal[0] = ddX[0]*Fx+ddY[0]*Fy+ddZ[0]*Fz;
collision_normal[1] = ddX[1]*Fx+ddY[1]*Fy+ddZ[1]*Fz;
collision_normal[2] = ddX[2]*Fx+ddY[2]*Fy+ddZ[2]*Fz;

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

Shade = 255.0f * MulVecSc(collision_normal,tv);
if(Shade < 0)
Shade = -Shade;
r = Shade * rgb[0];
g = Shade * rgb[1];
b = Shade * rgb[2];

Оценим результат:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Сменим формулы:

#define F_xy 0.3*(sin(x)*cos(y/2.0)+cos(x/2.5)*sin(y/1.5))
#define F_x -0.3*(cos(x)*cos(y/2.0)-sin(x/2.5)*sin(y/1.5))
#define F_y -0.3*(-sin(x)*sin(y/2.0)+cos(x/2.5)*cos(y/1.5))
Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Ок.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

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

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост
Показать полностью 15
80

Визуальный редактор скриптов в Godot Engine

Руководитель разработки бесплатного движка Godot Engine Хуан Линьетски (Juan Linietsky) поделился в своём твиттере очередными новшествами, которые ждут разработчиков уже совсем скоро. На этот раз в обновлениях появится визуальное редактирование скриптов, похожее на Blueprint из Unreal Engine.

Визуальный редактор скриптов в Godot Engine Godot Engine, Unreal Engine, Gamedev

Похожая логика работы с узлами уже есть в движке Godot, но используется она исключительно в редакторе шейдеров для материалов. Учитывая, что Хуан также пообещал добавить поддержку C# (в дополнение к собственному языку GDScript), ситуация выглядит очень интересной.


Движок доступен на официальном сайте или в Steam, а также в виде исходников на Github. Как и раньше, разработка на нём не требует платной подписки или отчислений от дохода. Живёт команда на пожертвования, а также на призовые от различных конференций разработчиков открытого ПО.

Похожие посты закончились. Возможно, вас заинтересуют другие посты по тегам: