Как создать игровой движок
Перейти к содержимому

Как создать игровой движок

  • автор:

Как написать игровой движок?

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

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

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

Под планированием понимается:

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

2. Требования. Это может быть простота. Не пытайтесь сделать игру с абсолютной свободой действий и абсолютно реалистичной графикой. Или, например, требования к производительности, количеству персонажей, особенностям сюжета. Полезно, чтобы требования вам выставили другие. Таким образом вы будете делать игру для других, что увеличит вашу мотивацию. Их требования могут быть лучше чем ваши, что обеспечит лучшую игру. Отсеивайте невыполнимые требования.

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

4. Проектирование. Более высшие функции состоят из вызовов более нижних, то есть они почти реализованы на этапе создания архитектуры. Спроектируйте реализацию самых нижних функций на псевдокоде. Псевдокод не должен быть кодом на С только на русском языке. Он должен быть короче минимум в 2 раза и описательно реализовывать алгоритм, отвечать не на вопрос как, а что, должен позволить сосредоточиться на самых сложных вещах. Из хорошего псевдокода получаются хорошие комментарии, не дублирующие код, а поясняющие его. Создайте тесты для нижних функций. Попытайтесь доказать правильность программы.

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

На тестировании и отладке останавливаться не будем.

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

2. Немного трёхмерной математики в случае использования трёхмерной грфики. Досконально вам знать её не надо благодаря инкапсуляции. Она описана во многих книгах и справках о DirectX, OpenGL или программном рендеринге.

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

4. API (интерфейс программирования) для вывода графики, обработки ввода и другого.

5. Базовые навыки работы в редакторе для создания графики.

20 октября 2005 (Обновление: 15 апр 2010)

Игровой Движок — Написать Самому или Взять Готовый?

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

Почему не стоит писать свой игровой движок

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

Сизифов труд иногда доводит до такого

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

Помимо бесплатных систем разработки игр, многие коммерческие игровые движки, полностью готовые к немедленному началу использования в игровых проектах, предлагают сразу несколько очень привлекательных схем лицензирования: полностью бесплатную ( Unity 3D в бывшей Indie-редакции ), смешанную схему с выплатой Royalties ( Unreal Development Kit ) — 99 $ взнос за лицензию и выплаты 25 % прибыли после первых заработанных 5000 $, либо же доступную стоимость полновесной коммерческой лицензии ( Unity Pro за 1500 $ ).

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

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

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

Подводим итог: написанием собственного игрового движка могут заниматься те, кто чётко представляет, что именно и зачем ему это нужно, видит адекватные преимущества такого подхода и способен за вменяемые сроки претворить свой план в жизнь. Всем остальным следует поискать готовое решение, благо оных в последнее время появилось достаточно — взять хотя бы те же Unity 3D и UDK.

(Решено) Как создать свой игровой движок с мягкой физикой …

Внимание! Ответы искусственного интеллекта могут быть неточными. Не полагайтесь на них в медицине, юриспруденции, финансах и вопросах безопасности. При принятии важных решений всегда консультируйтесь с профильными специалистами.
Администрация сайта не несет ответственности за любой автоматически созданный контент. Если вы обнаружили ошибки, пожалуйста, сообщите об этом через кнопку «репорт» внизу ответа и мы примем соответствующие меры. Спасибо за вашу помощь в улучшении качества нашего сервиса.

Ответ нейросети:

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

Что такое мягкая физика? Это моделирование твердых тел, сгибаемых и деформируемых объектов, систем воды и воздуха, а также любых других объектов, которые могут изменить свою форму под воздействием внешних сил. При создании игрового движка с мягкой физикой требуется ряд существенных шагов.

Шаг 1: выберите язык программирования

Первым шагом является выбор языка программирования. В зависимости от того, какую операционную систему используется, могут быть использованы различные языки программирования, такие как C++, Java, C#, Python, Lua и другие. Для создания игры с мягкой физикой наиболее подходящим языком будет C++.

Шаг 2: обзор физических движков

Наиболее распространенные физические движки — это Box2D, Bullet, ODE, Havok, PhysX. В каждом из них есть свои плюсы и минусы. Box2D — это простой физический движок, который позволяет создавать простые игры, такие как арканоид или платформер. Bullet — более сложный и детальный движок, основанный на коробке Rigid Body Dynamics. ODE (Open Dynamics Engine) более продвинутый, чем Box2D. Havok – это один из самых популярных физических движков, который используется в таких играх, как Skyrim и Assassin’s Creed. PhysX – это физический движок от компании NVIDIA, который используется в таких играх, как Borderlands 2 и Batman: Arkham Asylum.

Шаг 3: работа с физическим движком

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

Шаг 4: создание сетки объектов и движение объектов

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

Шаг 5: добавление коллизий

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

Шаг 6: настройка свойств мягкой физики

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

Шаг 7: интеграция мягкой физики с другими частями игры

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

Шаг 8: отладка и тестирование

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

Шаг 9: оптимизация и дополнительные улучшения

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

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

Чтобы оставить комментарий, необходимо авторизоваться.

Задай любой вопрос нейросети!

она справится с любой поставленной задачей быстрее чем поиск в Яндекс.

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

Последние вопросы

Последние вопросы:

(c) ChatGPT по русски 2023. Все права защищены. При обнаружении неправомерного контента пишите на [email protected]

Хотите задать любой вопрос нейросети?

Нажимая «Регистрация» или «Войти через Google», вы соглашаетесь с Публичной офертой, даете Согласие на обработку персональных данных, а также подтверждаете что вам есть 18 лет»

Форма репорта неправомерного контента.
Обратная связь с администрацией проекта

Уведомление об использовании cookie файлов

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

При использовании данного сайта, вы подтверждаете свое согласие на использование файлов cookie и других похожих технологий в соответствии с настоящим Уведомлением.

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

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

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

Что такое файл cookie и другие похожие технологии

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

Некоторые посещаемые Вами страницы могут также собирать информацию, используя пиксельные тэги и веб-маяки, представляющие собой электронные изображения, называемые одно-пиксельными (1×1) или пустыми GIF-изображениями.

Файлы cookie могут размещаться на вашем устройстве нами («собственные» файлы cookie) или другими операторами (файлы cookie «третьих лиц»).

Мы используем два вида файлов cookie на сайте: «cookie сессии» и «постоянные cookie». Cookie сессии — это временные файлы, которые остаются на устройстве пока вы не покинете сайт. Постоянные cookie остаются на устройстве в течение длительного времени или пока вы вручную не удалите их (как долго cookie останется на вашем устройстве будет зависеть от продолжительности или «времени жизни» конкретного файла и настройки вашего браузера).

Cookie файлы бывают различных типов:

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

Файлы cookie, относящиеся к производительности, эффективности и аналитике. Данные файлы позволяют анализировать взаимодействие посетителей с сайтом, оптимизировать содержание сайта, измерять эффективность рекламных кампаний, предоставляя информацию о количестве посетителей сайта, времени его использования, возникающих ошибках.

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

Рекламные файлы cookie определяют, какие сайты Вы посещали и как часто, какие ссылки Вы выбирали, что позволяет показывать Вам рекламные объявления, которые заинтересуют именно Вас.

Электронная почта. Мы также можем использовать технологии, позволяющие отслеживать, открывали ли вы, прочитали или переадресовывали определенные сообщения, отправленные нами на вашу электронную почту. Это необходимо, чтобы сделать наши средства коммуникации более полезными для пользователя. Если вы не желаете, чтобы мы получали сведения об этом, вам нужно аннулировать подписку посредством ссылки «Отписаться» («Unsubscribe»), находящейся внизу соответствующей электронной рассылки.

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

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

Как управлять файлами cookie?

Большинство интернет-браузеров изначально настроены на автоматический прием файлов cookie.

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

Если вы используете несколько устройств и (или) браузеров для доступа в интернет, соответствующие настройки должны быть изменены в каждом из них.

Заключительные положения

По собственному усмотрению мы можем периодически изменять настоящее Уведомление.

По возникающим вопросам с нами можно связаться, используя контакты, размещенные на нашем сайте.

Написать игровой движок на первом курсе: легко! (ну почти)

Привет! Меня зовут Глеб Марьин, я учусь на первом курсе бакалавриата «Прикладная математика и информатика» в Питерской Вышке. Во втором семестре все первокурсники нашей программы делают командные проекты по С++. Мы с моими партнерами по команде решили написать игровой движок.

О том, что у нас получается, читайте под катом.

Всего нас в команде трое: я, Алексей Лучинин и Илья Онофрийчук. Никто из нас не является экспертом в разработке игр, а тем более в создании игровых движков. Для нас это первый большой проект: до него мы выполняли только домашние задания и лабораторные работы, так что едва ли профессионалы в области компьютерной графики найдут здесь новую для себя информацию. Мы будем рады, если наши идеи помогут тем, кто тоже хочет создать свой движок. Но тема эта сложна и многогранна, и статья ни в коем случае не претендует на полноту специализированной литературы.

Всем остальным, кому интересно узнать о нашей реализации, — приятного чтения!

Графика

Первое окно, мышь и клавиатура

Для создания окон, обработки ввода с мыши и клавиатуры мы выбрали библиотеку SDL2. Это был случайный выбор, но мы о нем пока что не пожалели.

Важно было на самом первом этапе написать удобную обертку над библиотекой, чтобы можно было парой строчек создавать окно, проделывать с ним манипуляции вроде перемещения курсора и входа в полноэкранный режим и обрабатывать события: нажатия клавиш, перемещения курсора. Задача оказалось несложной: мы быстро сделали программу, которая умеет закрывать и открывать окно, а при нажатии на ПКМ выводить «Hello, World!».

Тут появился главный игровой цикл:

Event ev; bool running = true; while (running): ev = pullEvent(); for handler in handlers[ev.type]: handler.handleEvent(ev);

К каждому событию привязаны обработчики — handlers , например, handlers[QUIT] = . Их задача — обрабатывать соответствующее событие. QuitHandler в примере будет выставлять running = false , тем самым останавливая игру.

Hello World

Для рисования в движке мы используем OpenGL . Первым Hello World у нас, как, думаю, и во многих проектах, был белый квадрат на черном фоне:

glBegin(GL_QUADS); glVertex2f(-1.0f, 1.0f); glVertex2f(1.0f, 1.0f); glVertex2f(1.0f, -1.0f); glVertex2f(-1.0f, -1.0f); glEnd();

Затем мы научились рисовать двумерный многоугольник и вынесли фигуры в отдельный класс GraphicalObject2d , который умеет поворачиваться с помощью glRotate , перемещаться с glTranslate и растягиваться с glScale . Цвет мы задаем по четырем каналам, используя glColor4f(r, g, b, a) .

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

Камера

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

Мы хотим нарисовать в координатах экрана вершину, зная ее координаты относительно центра объекта, которому она принадлежит.

  1. Сначала нам понадобится найти ее координаты относительно центра мира, в котором находится объект.
  2. Затем, зная координаты и расположение камеры, найти положение вершины в базисе камеры.
  3. После чего спроецировать вершину на плоскость экрана.

Начнем с получения координат объекта в базисе мира. С объектом можно делать три преобразования: масштабировать, поворачивать и перемещать. Все эти операции задаются домножением исходного вектора (координат в базисе объекта) на соответствующие матрицы. Тогда матрица Model будет выглядеть так:

Model = Translate * Scale * Rotate. 

Дальше, зная положение камеры, мы хотим определить координаты в ее базисе: домножить полученные ранее координаты на матрицу View . В C++ это удобно вычислить с помощью функции:

 glm::mat4 View = glm::lookAt(cameraPosition, objectPosition, up);

Дословно: посмотри на objectPosition с позиции cameraPosition , причем направление вверх — это «up». Зачем нужно это направление? Представьте, что вы фотографируете чайник. Вы направляете на него камеру и располагаете чайник в кадре. В этот момент вы можете точно сказать, где у кадра верх (скорее всего там, где у чайника крышка). Программа не может за нас додумать, как расположить кадр, и именно поэтому нужно указывать вектор «up».

Мы получили координаты в базисе камеры, осталось спроецировать полученные координаты на плоскость камеры. Этим занимается матрица Projection , которая создает эффект уменьшения объекта при его отдалении от нас.

Чтобы получить координаты вершины на экране, нужно перемножить вектор на матрицу по крайней мере пять раз. Все матрицы имеют размер 4 на 4, так что придется проделать довольно много операций умножения. Мы не хотим нагружать ядра процессора большим количеством простых задач. Для этого лучше подойдет видеокарта, у которой есть необходимые ресурсы. Значит, нужно написать шейдер: небольшую инструкцию для видеокарты. В OpenGL есть специальный шейдерный язык GLSL, похожий на C, который поможет нам это сделать. Не будем вдаваться в подробности написания шейдера, лучше наконец-то посмотрим на то, что вышло:

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

Физика

Какая же игра без физики? Для обработки физического взаимодействия мы решили использовать библиотеку Box2d и создали класс WorldObject2d , который наследовался от GraphicalObject2d . К сожалению, не получилось использовать Box2d «из коробки», поэтому отважный Илья написал обертку к b2Body и всем физическим соединениям, которые есть в этой библиотеке.

До этого момента мы думали сделать графику в движке абсолютно двумерной, а для освещения, если решим его добавлять, использовать технику raycasting. Но у нас под рукой была замечательная камера, которая умеет отображать объекты во всех трех измерениях. Поэтому мы добавили всем двумерным объектам толщину — почему бы и нет? К тому же в перспективе это позволит делать довольно красивое освещение, которое будет оставлять тени от толстых объектов.

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

Текстуры

Для загрузки изображений мы использовали библиотеку DevIL. Каждому GraphicalObject2d стал соответствовать один экземпляр класса GraphicalPolygon — лицевая часть объекта — и GraphicalEdge — боковая часть. На каждую можно натянуть свою текстуру. Первый результат:

Все основное, что требуется от графики, уже готово: отрисовка, один источник освещения и текстуры. Графика — на данном этапе все.

Машина состояний, задание поведений объектов

Каждый объект, каким бы он ни был, — состоянием в машине состояний, графическим или же физическим — должен «тикать», то есть обновляться каждую итерацию игрового цикла.

Объекты, которые умеют обновляться, наследуются от созданного нами класса Behavior. У него есть функции onStart, onActive, onStop , которые позволяют переопределить поведение наследника при запуске, при жизни и при завершении его активности. Теперь нужно создать верховный объект Activity , который бы вызывал эти функции от всех объектов. Функция loop, которая это делает, выглядит следующим образом:

void loop(): onAwake(); awake = true; while (awake): onStart(); running = true while (running): onActive(); onStop(); onDestroy();

Пока running == true , кто-нибудь может вызвать функцию pause() , которая сделает running = false . Если же кто-то вызовет kill() , то awake и running обратятся в false , и активность остановится полностью.

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

Решение: у каждого Behavior пусть будет массив subBehaviors , которые он будет обновлять, то есть:

void onStart(): onStart() // не забыть стартовать себя самого for sb in subBehaviors: sb.onStart() // а только после этого все дочерние Behavior void onActive(): onActive() for sb in subBehaviors: sb.onActive()

И так далее, для каждой функции.

Но не любое поведение можно задать таким образом. Например, если по платформе гуляет враг — enemy, то у него, скорее всего, есть разные состояния: он стоит — idle_stay , он гуляет по платформе, не замечая нас — idle_walk , и в любой момент может заметить нас и перейти в состояние атаки — attack . Еще хочется удобным образом задавать условия перехода между состояниями, например:

bool isTransitionActivated(): // для idle_walk->attack return canSee(enemy);

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

У состояния есть три стадии: оно началось, оно тикает, оно остановлено. К каждой из стадий можно добавлять какие-то действия, например, прикрепить к объекту текстуру, применить к нему импульс, установить скорость и так далее.

Сохранения

Создавая уровень в редакторе, хочется иметь возможность сохранить его, а сама игра должна уметь загружать уровень из сохраненных данных. Поэтому все объекты, которые нужно сохранять, наследуются от класса NamedStoredObject . Он хранит строку с именем, названием класса и обладает функцией dump() , которая сбрасывает данные об объекте в строку.

Чтобы сделать сохранение, остается просто переопределить dump() для каждого объекта. Загрузка — это конструктор от строки, содержащей всю информацию об объекте. Загрузка завершена, когда такой конструктор сделан для каждого объекта.

На самом деле, игра и редактор — это почти один и тот же класс, только в игре уровень загружается в режиме чтения, а в редакторе — в режиме записи. Для записи и чтения объектов из json-а движок использует библиотеку rapidjson.

Графический интерфейс

В какой-то момент перед нами встал вопрос: пусть уже написана графика, машина состояний и все прочее. Как пользователь сможет написать игру, используя это?

В первоначальном варианте ему пришлось бы отнаследоваться от Game2d и переопределить onActive , а в полях класса создавать объекты. Но во время создания он не может видеть того, что создает, и нужно было бы еще и скомпилировать его программу и прилинковать к нашей библиотеке. Ужас! Были бы и плюсы — можно было бы задавать столь сложные поведения, на какие только хватило бы фантазии: например, передвинуть блок земли на столько, сколько жизней у игрока, и делать это при условии, что Уран в созвездии Тельца, а курс евро не превышает 40 рублей. Однако мы все-таки решили сделать графический интерфейс.

В графическом интерфейсе количество действий, которые можно произвести с объектом, будет ограничено: перелистнуть слайд анимации, применить силу, установить определенную скорость и так далее. Та же ситуация с переходами в машине состояний. В больших движках проблему ограниченного количества действий решают связыванием текущей программы с другой — например, в Unity и Godot используется связывание с C#. Уже из этого скрипта можно будет сделать что угодно: и посмотреть, в каком созвездии Уран, и какой сейчас курс евро. У нас такой функциональности на данный момент нет, но в наши планы входит связать движок с Python 3.

Для реализации графического интерфейса мы решили использовать Dear ImGui, потому что она очень маленькая (по сравнению с широко известным Qt) и писать на ней очень просто. ImGui — парадигма создания графического интерфейса. В ней каждую итерацию главного цикла все виджеты и окна отрисовываются заново только если это нужно. С одной стороны, это уменьшает объем потребляемой памяти, но с другой, скорее всего, занимает больше времени, чем одно выполнение сложной функции создания и сохранение нужной информации для последующего рисования. Тут уже осталось только реализовать интерфейсы для создания и редактирования.

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

Редактор уровня

Редактор машины состояний

Заключение

Мы создали только основу, на которую можно вешать что-то более интересное. Иными словами, есть куда расти: можно реализовать отрисовку теней, возможность создания более чем одного источника освещения, можно связать движок с интерпретатором Python 3, чтобы писать скрипты для игры. Хотелось бы доработать интерфейс: сделать его красивее, добавить больше различных объектов, поддержку горячих клавиш…

Работы еще предстоит много, но мы довольны тем, что имеем на данный момент.

За время создания проекта мы получили много разнообразного опыта: работы с графикой, создания графических интерфейсов, работы с json файлами, обертки многочисленных C библиотек. А еще опыт написания первого большого проекта в команде. Надеемся, что нам удалось рассказать о нем так же интересно, как было интересно им заниматься 🙂

  • вшэ
  • hse
  • питерская вышка
  • обучение программированию
  • прикладная математика и информатика
  • бакалавриат
  • c++
  • проект
  • игровой движок
  • Блог компании Питерская Вышка
  • Программирование
  • C++
  • Учебный процесс в IT
  • Дизайн игр

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *