Как я писал кросплатформенный 3d игровой движок
Что меня побудило писать движок
Началась история довольно давно и с того, что мне захотелось поиграть в замечательную логическую головоломку «Pusher» на Vista 64. Однако оригинальная игра была 16 битной и напрочь отказывалась запускаться. Ничего лучше, чем написать на Си её клон, я не придумал (иногда не лучшее изначально решение приводит к более полезным результатам). Спустя небольшое время я реализовал игру на платформе SDL v1.2 + OpenGL.
Для удобства переноса карт добавил редактор уровней и вручную клонировал все 64 карты. Через какое-то время интерес к «Pusher» ослаб, и мне уже захотелось погонять в Tomb raider 1 с 3dfx графикой. И как многие уже догадались, существующие решения это сделать меня не особо порадовали (скорее даже субъективно) и я занялся поиском портов. Кроме известного проекта Open raider я ничего не нашел. До сих пор помню как мучился с его сборкой под windows с помощью компилятора mingw (среду разработки не помню, либо code::blocks, либо netbeans). Результат сборки меня совсем не порадовал: загрузка уровня около минуты и черный экран в итоге. Умения ковырять чужой код, понимать его структуру и смысл функций у меня не было. Попытки собрать «лучше» прекратились. Однако я загорелся идеей собрать хоть один из открытых движков вручную, не автоконфигом Die GNU Autotools, а с самостоятельно собранного проектника в среде разработки.
Таким образом, после кучи времени за монитором, определенного количества мата и т.д., я собрал Quake Tenebrae без звука. Зато он работал! Это была маленькая победа, которая принесла плоды: я стал лучше разбираться в чужом коде и наконец-то стал хоть что-то понимать в организации работы компилятора – без чего вообще никак нельзя. После было сделано несколько мелких доработок, устранены некоторые баги и запущен звук, но проект так и не был залит в интернет (даже тогда он был морально устаревшим, особенно с учетом наличия Dark places engine). Однако из кода движка Quake Tenebrae я узнал как организована работа игры в целом, отдельных её компонентов и менеджера памяти (я добавил в него функцию realloc, пусть довольно простую, но все работало без вылетов).
Пишем движок
Когда я немного освоился, то решил начать писать свой движок с нуля. Просто ради интереса и саморазвития. Базой для создания движка служило следующее: компилятор GCC-TDM v4.Х.Х + msys и среда разработки Netbeans; библиотеки: SDL v1.2 + OpenGL. Первая реализованная функция была созданием скриншота и его сохранением в файл *.bmp с применением самописной библитечки для работы с этим форматом. Какой движок может обойтись без консоли для ввода читов команд и вывода текста – наверное никакой, поэтому следующим делом я изучил вопрос о том, как выводить текст в окно OpenGL и выбрал связку freetype 1 + gltt. Первой распознаваемой командой была команда exit и уже после – команды для игры с размерами шрифтов, строк и т.д…. Для справки: мне понравился код, используемый в Quake I для парсинга строк и последовательного его разбития на токены, который до сих пор присутствует в движке:
Забегая вперед: когда потребовалась поддержка скриптов я решил использовать подход к разработке движка как в «ID software» на примере «DOOM 3 engine», который был очень хорошо описан здесь, на Хабре =) (хочется еще раз сказать огромное спасибо авторам за статью, перевод и написавшим интересные комментарии к ней людям). Под впечатлением статьи я решил внедрить в свой движок LUA не только для внутриигровых скриптовых нужд, но еще для парсинга конфигурационных файлов и консольных команд (т.е. везде используется единообразная система). Подход оправдал себя абсолютно.
Перейдем к 3d
Мне повезло, что в институте мне нравились линейная алгебра, матричные преобразования, вектора и численные методы. Без этих основ к программированию движка с нуля приступать очень опрометчиво (разве для того, чтобы изучить эти разделы на примерах, однако без определенной теоретической базы знаний это будет мало реально). В освоении графики мне сильно помогла книга А. Борескова «Графика трехмерной компьютерной игры на основе OPENGL». Перечитал ее не один раз (для ознакомления с математическим аппаратом, типами рендереров и структурой движков). Без понятия о принципе построения сцены и предназначения видовой матрицы и матрицы проекции продвинуться никуда не удастся. После изучения некоторого материала в интернете и просто литературы, я решил делать портальный рендерер. Первое что было реализовано в движке – это свободно летающая камера и несколько порталов, которые можно было увидеть только друг через друга.
После хардкодом была добавлена wireframe сцена из 3-х комнат (две побольше и коридор). Но разве интересно летать в таком примитивном мире… И тут я решил воспользоваться загрузчиком ресурсов из Open raider и порендерить уровни. Результат меня порадовал и тут уже окончательно было решено реализовывать замысел по созданию порта для игры в Tomb raider, хотя бы в первую её часть. Для позиционирования объектов в пространстве я использовал матрицу в формате OpenGL так как это позволяет обращаться к базовым векторам локальной системы координат объекта, задавать положение объекта одной командой glMultMatrixf(transform) и задавать ориентацию объекта в физическом движке bullet одной командой setFromOpenGLMatrix(transform), о чем чуть позже. Ниже приведено изображение со структурой матрицы OpenGL с выше приведенной ссылки:
Для ведения истории изменений в движке и возможности бэкапа и просто для саморазвития было решено использовать систему контроля версий mercurial. Её применение позволило не только прослеживать прогресс в написании кода, но и дало возможность загрузить результаты на sourceforge.com. Следует отметить, что когда в движок начала загружаться информация о порталах с реальных карт, сразу всплыло огромное количество недоработок моей реализации портальной системы. На борьбу с пропадающими объектами и вылетами ушло немало времени, и даже сейчас я считаю, что портальный модуль нуждается в серьезной доработке. Сейчас рендерер движка в зависимости от положения камеры и ее ориентации начинает прохождение по порталам комнат и добавляет в список только видимые комнаты. Потом рендерер рисует комнаты и их содержимое из списка. Понятно, что для больших открытых пространств такой подход не самый удачный, однако для целей проекта его вполне достаточно. Вот пример рекурсивной функции обхода по комнатам:
Скелетные анимированные модели
И вот началась одна из самых кропотливых работ в проекте. Рендерить статичные комнаты со статичными объектами оказалось сравнительно несложно, но вот когда дело дошло до анимированных скелетных моделей… Первое что я понял: загрузчик ресурсов Open raider не грузит всю необходимую информацию о скелетной модели. Количество фреймов в анимации определяется некорректно, из-за чего одна анимация содержит в себе фреймы сразу от нескольких.
В ходе попыток решения этих проблем я нашел различные документации по формату уровней Tomb raider и заодно проект vt, в котором был свой загрузчик ресурсов. Пусть в этом проекте не было загрузки кадров анимации моделей, зато в нем был более структурированный код, удобный для чтения и доведения до ума. Так я заменил загрузчик в проекте на vt. Для примера: в Open raider все 5 частей Tomb raider грузятся одной длинной функцией с кучей if и switch по номеру версии игры, что заметно усложняло чтение кода и поиск ошибок. В vt было 5 модулей, каждый из которых отвечал за свою версию уровня, благодаря чему код читался достаточно легко, и внесение изменений не представляло трудностей.
Главной проблемой с анимациями оказалось извлечение углов поворотов костей в скелетной модели. Дело в том, что для экономии места углы хранились в байткоде с шагом в 2-4 байта. В первые 2 байта входит флаг о том один ли здесь поворот и вокруг какой оси, или сразу три и сами углы. В случае 3-х поворотов флаги и углы хранятся в 4-х байтах, в случае одного используются только 2 байта. При этом углы для всех моделей, анимаций и кадров хранятся в одном массиве и смещения надо вычислять. К тому же в этом байткоде еще хранятся заголовки отдельных фреймов модели и путаница со смещениями критична, а теперь прибавим то, что количество фреймов грузится некорректно (в последствии оказалось, что количество фреймов дано для «интерполированных» анимаций с частотой 30 fps, а реально, кадры могут хранятся в «ужатом» виде с fps со множителями 1, 1/2, 1/3 и 1/4). После допиливания загрузчика фреймов анимаций, скелетные модельки перестали выворачиваются наизнанку и превращаться в кашу из искаженных полигонов! Теперь надо «оживить» Лару. Ниже приведен код функции, генерирующей скелетную модель, сохранена орфография и закомментированые участки кода для отладки:
Выход в свет
Когда скелетные модели заработали, уже можно было переходить к их расстановке по уровню и «оживлять» Лару, что требовало наличия физики. Для начала было решено писать свой физический движок, чтобы лучше ознакомиться с темой и потом уже более основательно подойти к выбору уже готовых продуктов. Первое что требуется для создания контроллера персонажа – это определение высот. Изначально была написана (на основе барицентрического алгоритма) функция определения пересечения треугольника и луча. После были добавлены такие базовые методы, как определение пересечения движущихся отрезков, треугольника и сферы, треугольника и треугольника. Следует отметить, что такой подход исключает возможность появления так называемого «туннельного эффекта» (когда из-за большой скорости объекты с большими скоростями могут пролететь друг сквозь друга без столкновения), присущего impulse based физическим движкам.
И вот Лара бегает по уровням, пусть и минуя все ступени любых размеров, зато не вываливается за пределы карты! Когда проект был в таком состоянии мне написал Анатолий Lwmte о том, что круто, что хоть кому-то интересны первые части Tomb raider. Так началась переписка, благодаря которой к проекту начал заново появляться интерес. После я зарегистрировался на tombraiderforums.com (Анатолий был там уже достаточно долго, со своим проектом по улучшению движка четвертой части Tomb raider). Благодаря нему на этом форуме появилась тема с моим движком и много доработок в коде: менеджер звука, переделка системы контроля состояний (до этого у меня был switch по номерам анимаций, теперь он по номерам состояний) и т.д. Наличие заинтересованных в проекте людей хорошо мотивирует развивать проект.
Физика + оптимизация рендерера
Поскольку я использовал свою физику, да еще и с плохой оптимизацией, в некоторых местах стало проседать fps. Путем долгих ковыряний различных физических движков с открытым исходным кодом был выбран bullet. Первой делом я добавил фильтр на столкновения в случае пересекающихся комнат. Дело в том, что дизайн оригинальных уровней допускает пересечение 2-х и более совершенно различных комнат в одном месте, при этом объекты одной комнаты ни как не должны влиять на объекты другой; аналогично и с отрисовкой. В настоящее время я стараюсь довести до ума контроллер персонажа: устранить возможность прохода сквозь стены (происходит в ряде анимаций в упор к стене) и доделать реакцию и поведение персонажа в случае климбинга по стенам и потолку.
Вернемся к OpenGL. Изначально в движке отрисовка полигонов велась с помощью glVertex3fv(. ) и т.д.; Про производительность такого подхода и скорость работы движка можно сказать одно: их нет. Поэтому после изучения части, касающейся VBO (Vertex Buffer Object), я сделал оптимизацию и стал по возможности хранить данные вершин полигонов в видео памяти и отрисовывать меш одним заходом. Скорость заметно возросла. Однако из-за того, что для одного меша текстуры могли лежать в разных массивах пикселей, переключение OpenGL текстур было чаще чем надо, а то, что текстуры многих различных объектов могут храниться в одном массиве пикселей, создавало «артефакты» при включенном сглаживании. Cochrane с tombraiderforums.com взялся за оптимизацию рендерера и написал текстурный атлас с границами между текстурами. Благодаря этому нововведению все текстуры уровня хранятся в 1 – 2 OpenGL текстурах и сглаживание не приводит к появлению «артефактов». К тому же он сделал порт проекта на MacOS.
Когда совсем не было идей за что и как браться в движке, я просто искал ошибки в коде, подправлял его структуру или менял подключаемые библиотеки. Таким образом было проведено «переселение» с SDL1 на SDL2, с freetype1 + gltt к freetype2 + ftgl. Аналогичным образом мне пришла идея добавить сглаживание анимациям с помощью сферической интерполяции slerp. Здесь я хочу добавить: будьте внимательны к математическим алгоритмам, особенно когда дело касается «арок» (asin, acos, atan…) – потеря знака чревата убойными кадрами с перекошенным и перекрученным скелетом. Советую посмотреть реализацию slerp в исходном коде bullet. После добавления сглаживания, я уже не мог смотреть на несглаженные анимации. Далее возникла необходимость грузить и проигрывать звук, а то бегать по уровням в гробовой тишине не очень-то, хоть и Tomb raider.
Добавляем звук
Для использования звука применение SDLAudio + SDLMixer совершенно недостаточно, а лезть в алгоритмы преобразования звукового потока и делать велосипеды для создания эффектов – совсем плохая идея. Посоветовавшись с Анатолием было решено использовать OpenAL. Поскольку я руководствовался тем, чтобы как можно больше платформо-зависимого кода переложить на SDL, то ничего лучше написания SDL_backend для OpenAL я не придумал. Однако оно сработало, я добавил инструмент в движок, а Анатолий заставил все играть когда надо, где надо и еще с нужными эффектами.
И вот подошла пора оживлять всевозможные рычаги, ловушки и прочие триггеры игрового мира. Фактически здесь разработка шла по логике: мне нужно что-то реализовать, какие для этого нужны инструменты, как их реализовать. Основная функция, применяемая для работы скриптов – это получение указателя на объект по числовому id, дальше любая LUA функция сможет обрабатывать все необходимые объекты. Для динамического добавления и удаления объектов и возможности быстрого доступа к ним по id я применил красно-черные деревья. По идее можно было применить хэш таблицы, но тут скорее уже сработали личные предпочтения.
В итоге уже сейчас скриптовая система позволяет проводить практические любые манипуляции с объектами и анимациями, создавать задачи (и на их основе таймеры), подбирать предметы, нажимать рычании и кнопки, открывая и закрывая тем самым двери и не только. Благодаря стараниям людей из сообщества tombraiderforums.com был добавлен gameflow_manager, отвечающий за переход с одного уровня на другой, загрузку нужных скриптов и экранных заставок, загрузка информации об источниках света и реализация простейшего lightmap на основе корректировки цветов вершин и cmake скрипт для сборки под OS Lunux.
Послесловие
В конце хочется обратить внимание на то, что когда используешь сторонние ресурсы, то проще с тестами и не надо нагружаться созданием контента, однако это накладывает ограничения на архитектуру движка или приводит к необходимости конвертирования форматов при загрузке для того, чтобы не городить ужасных костылей уже внутри игрового движка. А костылей в оригинальных Tomb raider очень много.
Дальнейшие планы в проекте просты:
1) исправить существующие баги, в особенности с физикой, и расширить возможности контроллера персонажей;
2) «оживить» врагов на картах, добавить ИИ и оружие;
3) расширить систему управления анимациями скелетных моделей для переключения мешей;
4) расширить возможности скриптовой системы и написать ключевые уровневые скрипты, чтобы можно было пройти по нормальному игру;
5) улучшить графику в игре, добавить эффекты, однако здесь я рассчитываю на помощь более квалифицированных программистов OpenGL;
Напоследок несколько видео с примером работы движка:
Разработка игрового движка
Игровой движок довольно сложная часть в разработке игры. Выбор в сторону готового движка сокращает время разработки в разы и позволяет сразу приступить к игре. Популярные движки имеют комьюнити, поддержку и много разработчиков, которые уже попробовали его в деле и выпустили свои разработки. Поэтому поиск проблем и их решение обычно занимает не так много времени, есть кто-то кто уже решал проблему до Вас.
Выбор движка по бэкграунду знаний:
Для реализации простых 2D игрушек решил присмотреться к движкам и определиться с подходящим. Среди всего многообразия вариантов присматривался в первую очередь на Unity. Но обдумав все за и против, решил писать свой.
Причины написать сейчас свой движок:
Посколько я начал работать с С++ с 2005 года выбор языка отпал сам собой. За основу был взят стандарт C++11.
В следующих статьях я опишу структуру движка, его основные компоненты и написание игры.
Спасибо за внимание.
Мои любимые статьи про то как начну что-то делать 😉 можно открывать тотализатор, на сколько статей без воды хватит автора 😉
Обычно, не более 3-х.
Ставка принята, я пожалуй поставлю на то, что эта статья будет последняя 😀
Разработка игрового движка
Не нужна.
Не опен сорс? А нафига тогда ты о нём пишешь? Кому он нужен такой?
Описать детали разработки, выслушать мнение других. Дальше опишу о разных аспектах разработки. Будет взаимовыгодная польза для тех кто также работает над своим движком.
Почему бы не перекопать исходники условного Godot или UE, или чего попроще типа Love, если чуть пониже уровнем то условный SDL, при этом реализуя какие-то фишечки рендеринга/оптимизации/работы с медиа/физики/контроллеров/чегоугодно в качестве отдельных либ/кусков кода/примеров, чтобы не терять время? Человек сверху хорошо написал про пруф оф концепты.
Ну т.е. не похоже что у тебя есть хоть какой-то план. Какая-то минимальная спека хотя бы в голове, видение MVP движка, кроме как хочу на C++ 11, чтобы было кроссплатформенно, а еще потом будут тесты, а вообще, чтобы сделать игру где можно грабить корованы.
Пишем собственный игровой движок с помощью C++
С нуля создадим собственный игровой движок с помощью библиотеки SFML и C++, чтобы разобраться, как происходит создание ядра.
В этом проекте мы создадим собственный игровой движок на C++. Движок будет очень простым, но готовым к расширению возможностей. Конечная игра с использованием этого кода тоже крайне проста: наш персонаж сможет перемещаться влево и право, а из графики – только бэкграунд и фигурка персонажа.
Подготовка Visual Studio
Создадим новый проект в Visual Studio. Обратите внимание, что проект требует библиотеку SFML, поэтому если вы не настраивали окружение для нее, прочтите сначала небольшое руководство по настройке.
Теперь можно приступить к коду. Исходный код и дополнительные ресурсы будут доступны на этой странице.
Проектируем собственный игровой движок
Самое важное – запуск движка, который будет происходить в файле Main.cpp, но им мы займемся немного позже.
Класс персонажа
Bob – простой класс для представления фигурки персонажа, управляемой игроком. Код класса будет легко расширяться, а что самое главное – его несложно переписать под любой другой игровой объект, который вы захотите добавить. Для этого потребуется заменить текстуру и описать поведение нового объекта в методе update().
Займемся заголовками класса. Выберите правой кнопкой Header Files в Solution Explorer и нажмите Add | New Item. В окне Add New Item выберите Header File (.h), затем в поле Name введите Bob. Нажмите Add и добавьте код заголовка класса:
Здесь мы объявили объекты типа Texture и Sprite. Дальше мы свяжем эти объекты и любое действие на экране с объектом Sprite будет сопровождаться изображением Боба:
Кликните правой кнопкой, чтобы сохранить
Bob.cpp
Теперь приступим к описанию методов.
Выберите правой кнопкой мыши Source Files в Solution Explorer и откройте Add | New Item. В окне Add New Item кликните по C++ File (.cpp), а в поле Name укажите Bob.cpp. Теперь добавьте в файл код:
В конструкторе мы установили значение переменной m_Speed на 400. Это значит, что Боб пересечет экран шириной в 1920 пикселей за 5 секунд. Также мы загрузили файл Bob.png в Texture и связали его с объектом Sprite. В переменных m_Position.x и m_Position.y установлено начальное положение Боба.
Функция update обрабатывает два If. Первое If проверяет, нажата ли правая кнопка (m_RightPressed), а второе следит за левой (m_LeftPressed). В каждом If скорость (m_Speed) умножается на elapsedTime. Переменная elapsedTime рассчитывается в функции Start движка (класс Engine). Им мы и займемся далее.
Пишем класс Engine
Класс Engine будет контролировать все остальное.
Engine.h
Добавим заголовок. Откройте окно Add New Item (так же, как для класса Bob), выберите Header File (.h) и в поле Name введите Engine.h. Добавьте в файл следующий код:
Класс библиотеки SFML, RenderWIndow, используется для рендера всего, что есть на экране. Переменные Sprite и Texture нужны для создания фона. Также в заголовке мы создали экземпляр класса Bob.
Engine.cpp
В Engine.cpp мы опишем конструктор и функцию start. Создайте файл класса так же, как для Bob.cpp, и добавьте в него код:
Функция конструктора получает разрешение экрана и разворачивает игру на весь экран с помощью m_Window.create. В конструкторе же загружается Texture и связывается с объектом Sprite.
Пример фонового изображения
Скачайте пример изображения или используйте любое другое на свое усмотрение. Переименуйте файл в background.jpg и поместите в каталог Simple Game Engine/Simple Game Engine.
Игровой цикл
Следующие три функции будут описаны каждая в своем файле, но при этом они должны быть частью Engine.h. Поэтому в начале каждого файла укажем директиву #include «Engine.h», так что Visual Studio будет знать, что мы делаем.
Обрабатываем пользовательский ввод
Создайте файл Input.cpp и добавьте в него код:
Функция input обрабатывает нажатия клавиш через константу Keyboard::isKeyPressed, предоставляемую SFML. При нажатии Escape m_Window будет закрыто. Для клавиш A и D вызывается соответствующая функция движения.
Обновляем игровые объекты
Теперь опишем простую функцию update. Каждый игровой объект будет иметь собственную функцию update.
Создайте файл Update.cpp и добавьте в него код:
Поскольку у нас пока только один объект «Боб», мы вызываем только функцию m_Bob.update.
Отрисовка сцены
Это последняя функция класса Engine. Создайте файл Draw.cpp и добавьте в него код:
Экран очищается методом clear, затем отрисовывается фон. Первым делом должен быть отрисован фон, чтобы потом поверх него можно было отрисовать Боба.
Запускаем движок в main()
Теперь вернемся к нашему Main.cpp. Время добавить в него немного кода:
Несколько слов в конце
Наш собственный игровой движок получился очень простым: он умеет только двигать главный объект и закрывать программу. Он не умеет обрабатывать столкновения, работать с интерфейсом и еще много чего. Однако он отлично описывает то, как строится ядро игрового проекта с нуля. К тому же, как мы уже выяснили, класс Bob расширяется и адаптируется под другие объекты, так что дайте волю фантазии и попробуйте поэкспериментировать с окружением.
Как программировать игры: языки, движки и все, что нужно знать начинающему разработчику
Сперва это кажется дико сложным, но чем глубже погружаешься, тем лучше получается. Рассказываем, как начать делать игры,
Главное — в самом начале узнать, что нас ждёт, чтобы потом не свернуть на полпути, пройти все этапы и выпустить релиз. Подробно всем тонкостям, навыкам и хитростям мы обучаем на курсе «Профессия разработчик игр на Unity». Здесь же рассмотрим первые шаги, которые ждут разработчика.
С чего начать разработку игры
Рассчитываем, что вы уже придумали, какой будет игра, разработали концепт и уже ищете способы разработки. Настало время реализовать свои задумки. Есть несколько вариантов, как это сделать.
Все три способа подразумевают какое-никакое программирование, так что знать хотя бы основы вам точно придётся.
Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Языки программирования
Подойдут любые, от Python и C до Pascal и Java. От выбора зависит то, сколько времени уйдёт на игру и для какой платформы будет релиз. Также язык влияет на производительность.
На C++, например, пишут для любой платформы, а вот PHP или JavaScript лучше подходят для браузерных игр. Если же вы используете один из движков, то лучше вдобавок изучать C# — на нём прописывают скрипты. Главное — не недооценивать языки. Движок Unity дружит и с JavaScript, а MineCraft был написан на Java.
Движки для создания игр
Среди современных выделим:
Crysis, Far Cry, Sniper II: Ghost Warrior.
Gears of War 4, Dead Pool, Mortal Kombat X, Tekken 7
Outlast, Assassin’s Creed: Identity, Temple Run, Deus Ex: The Fall.
Большой популярностью пользуется Unity, он рассчитан как на 2D-, так и на 3D-игры. Он подходит под разные платформы и языки. На нём создается большинство мобильных и инди-игр. Он бесплатный, но если вы зарабатываете на своих играх больше 100 тысяч долларов в год, то придётся делиться ими с разработчиками Unity.
Как строится игровой код
Допустим, вы выбрали язык и движок, составили план. Что дальше? Продумайте всё от и до. В зависимости от выбранного вами пути (чистый язык или использование движка) будет отличаться и то, что вас ждёт на разных этапах разработки.
Если делаете всё своими силами, то на ваши плечи ляжет работа над физикой, механикой, графикой, искусственным интеллектом и балансом. Если выбрали движок — можно вздохнуть спокойно.
Физика
Физика — это то, как мир игры реагирует на действия игрока или объектов внутри мира. Вот какие могут быть физические действия:
Если пишете сами, то для обычного прыжка придется:
Не говоря уже о том, что нужно работать над анимацией всего этого.
В движках уже прописана физика, и нужно лишь подогнать её под свои нужды. Для примера:
И для этого не придётся писать код вообще — всё уже предусмотрено.
Механика
Игровая механика — это то, какими способами игрок взаимодействует с миром. Совокупность игровых механик составляет игровой процесс. Например, вы уже реализовали возможность ходьбы и прыжков. Эта игра, скорее, платформер.
А если добавите механику получения опыта, повышения уровней, прокачки навыков, — игра станет походить на RPG. Механика — такая же важная составляющая игры, как и сюжет или графика.
Ещё один пример: вы написали сценарий к игре, в которой нужно сбежать из тюрьмы. Даже если игра будет самой линейной в мире, игровая механика может всё изменить:
Будучи программистом, придётся уделять много времени механике.
Графика
Раньше графика создавалась с помощью программного кода, потом придумали текстуры и спрайты, а для 3D-игр используются модели. Подготовив все текстуры и модели, нужно добавить их в игру.
В движке достаточно просто загрузить нужные файлы и прикрепить их к нужным моделям. Иначе — прописывать всё вручную, в том числе и анимацию.
Для анимации 2D-объектов создаётся текстура по типу той, что на изображении выше. Она разбивается на равные части, которые сменяют друг друга. То есть игрок сначала видит первый кадр, который потом сменяется на второй, а затем на третий — это создает иллюзию движения.
Если брать 3D-модель, то используется скелетная анимация — модель как бы нанизывается на специальный каркас (скелет) с подвижными частями. Движение этих частей прописывается в коде.
На скриншоте видно, как персонаж сгибает руку в местах с точками (вершинами). Таких точек может быть очень много, если требуется сложная анимация — жесты, мимика и так далее.
Создаётся анимация так: прописываются точки координат или захватываются движения реального актера.
Первый способ сложный, но дешёвый, потому что от программиста требуется только прописать движения — сдвинуть точку A1 на координаты (50,240).
Второй проще, потому что достаточно одеть актеров в специальные костюмы с маячками, отснять это и перенести в игру. Но тут, конечно, придётся оплатить костюмы, павильон, работу операторов, постановщиков и актёров.
Баланс
Чтобы играть было интересно, нужен баланс. Это значит, что у каждого противника должны быть сильные и слабые стороны. Так геймплей не превратится в убийство одуванчиков или десятичасовые перестрелки с боссом.
Искусственный интеллект
Если геймплей предусматривает взаимодействие с NPC, то им нужно прописать модели поведения: реакцию на действия игрока, агрессивность, возможность вести диалоги или торговать.
Работа с ИИ — одна из самых сложных, потому что стоит учитывать множество ситуаций, для которых задумана реакция. Например, когда вы пытаетесь пройти в дверь, ваш компаньон обязательно должен преградить вам путь, чтобы жизнь малиной не казалась.
На какие платформы ориентироваться
Разобравшись с тем, как всё будет устроено в игре, можно приступать к разработке. Но чтобы проект был коммерчески успешен, выбирайте популярные платформы. Всего можно выделить четыре:
У каждой из этих платформ своя аудитория с вполне конкретными предпочтениями. На мобильных устройствах предпочитают головоломки (2048, 94%, Cut the Rope), аркады (Subway Surf, Temple Run, Angry Birds) и казуалы (Talking Cat Tom, Kitty Kate Baby Care, Hair Stylist Fashion Salon).
На компьютерах играют в MMORPG (Lineage II, World of Warcraft, Skyrim) или шутеры (Battlefield, Call of Duty, Counter-Strike).
Приставки подходят для гонок (Need for Speed, Blur, Burnout Paradise), приключенческих игр (Assassin’s Creed, Portal, The Walking Dead) и так далее.
В браузерах собирают пазлы и строят фермы.
Конечно, можно сделать и головоломку для PS4, и гонку для браузера — никто никого не ограничивает.
Заключение
Будьте готовы к тому, что ваша первая игра не станет шедевром. Но не расстраивайтесь, потому что такие проекты отлично подходят для обучения.
Подтяните свои навыки в программировании, чтобы научиться создавать игры, изучите современный язык, который часто используется разработчиками, и выпустите свой первый проект. А наш курс поможет вам в этом.