Главная » Правописание слов » Как написать движок для игры на java

Слово Как написать движок для игры на java - однокоренные слова и морфемный разбор слова (приставка, корень, суффикс, окончание):


Морфемный разбор слова:

Однокоренные слова к слову:

Java: собираем игровой движок

Всё, свершилось. Созрел для Явы. Чтобы процесс обучения шёл интереснее, буду писать игру. К большому для себя интересу обнаружил, что без определённого скилла шаманства всё получается не так как надо. Посему решил для начала набросать игровой движок, определить его возможности и уже на него «вешать» игру.

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

Компиляция и запуск кода.
1. Устанавливаем JDK, отыскиваем в нём папку BIN. У меня это C:\Program Files\Java\jdk1.7.0_72\bin.
2.Там создаём файл Game.java, копируем код.
3.Далее две команды:
javac Game.java
java Game

Команды проще вводить, используя файловые менеджеры вроде Far Manager или Total Commander. Первая компилирует код, вторая запускает.

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

Что делает этот код?
Он строит окно.
Это минимальный код для средств Swing. Давайте посмотрим, что он делает.

2. public class Game < >
Язык Java весь заморочен на классах и объектах. В языках Бейсик, Паскаль, Си классов нет, и маленькие программы в них пишутся достаточно быстро. Даже в Delphi новички часто не задумываются о классах и объектах. Кидают на форму кнопку, потом обрабатывают клик по ней, получая нужный результат. Просто и удобно. А попробуйте написать большую игру? С разрастанием кода программирование превращается в блуждание по тёмному лесу. Начинают появляться ошибки, которые очень трудно отловить, или задачи, которые не удаётся решить.

Метод main, принимающий параметры String[] args всегда должен присутствовать в программе, с него начинается выполнение. Он пишется только так, поэтому надо просто запомнить. В его блоке поместим исполняемый код:

4. JFrame game = new JFrame(«Game»);
Создаём объект с именем «game». Объект game является экземпляром класса JFrame. Что это значит? Чтобы упростить жизнь программиста в Java описано множество разнообразных классов. Класс это своего рода образец, трафарет, форма, на основе которой создаётся объект. Объект получает от класса все свойства, методы и другие характеристики, то есть, имея в качестве образца класс, можно наплодить на его основе сколько угодно объектов, не описывая каждый из них в отдельности. Удобно, а?

В нашем случае на базе класса JFrame создаётся объект, который представляет собой «физическую» реализацию класса JFrame. А это окно с рамкой и строкой заголовка, то есть, то, что нам было нужно. В строке заголовка, кстати, будет написано слово «Game».

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

5. game.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Наше окно ещё надо настроить. Придать ему индивидуальность. Например, окну можно поменять имя. Но в этом пока нет надобности, нам бы просто запустить его.
Приведённый выше код модифицирует объект game следующим образом: при закрытии окна выполнение программы прекращается. Эта строка необходима. Идём далее.

7. game.setVisible(true);
После настройки окна его нужно отобразить, верно?

Часть вторая. Рисование.

public class Game extends JFrame <
public void paint(Graphics g) <
g.fillRoundRect(320, 240, 10, 10, 5, 5);
>

Но этого недостаточно.

Источник

Создание игры на Java без сторонних библиотек, часть первая

Введение и подготовка

Привет хаброжители. Данный пост является «рерайтом» моего поста для песочницы. На этот раз я постараюсь охватить больше тем, чем тогда.

Почему Java?

Ничего объективного я тут не скажу, а скажу лишь то, что я люблю этот язык, и мне нравиться писать на нем. Да, на Java нет игр AAA-класса, но Java предоставляет огромные возможности, больше кол-во встроенных средств и быстроту написания кода.

Начнем с выбора IDE. Я являюсь фанатом Eclipse и посоветую вам его.
Если же почему-то вам он не понравился, вы можете использовать NetBeans, Intellij IDEA или командную строку и ваш любимый редактор.

И скачаем JDK последней версии: JDK 7u4

Скорее всего проблем с установкой IDE у вас не возникнет, а если у вас 64-битная система, все же посоветую устанавливать 32-битный Eclipse, так как иногда бывают ошибки и Eclipse у вас просто не запустится.

Под катом мы приступим к созданию игры.

Класс Game

Итак, создаем проект, в нем класс Game(попутно создав в нем точку входа). Данный класс должен наследовать класс Canvas и реализовать интерфейс Runnable:

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

Создадим функцию start() и в ней мы будем создавать новый поток и переводить running в true:

Создадим три функции — update(long delta), render() и init(). Я надеюсь что их значение вам понятно. В функции run() создадим главный игровой цикл, перед ним будем вызывать init(), а в нем самом render() и update(). Так же мы будем вычислять разницу между кадрами(delta time).

Пока поработаем над функцией render().

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

Примерно вот так выглядит наш класс Game сейчас.

Класс Sprite

Создадим новый класс Sprite. Поскольку этот класс небольшой, я сразу приведу весь его код с комментариями:

Сразу же проверим работоспособность. Возьмем эту картинку и скопируем ее в папку с нашим классом Sprite. Добавим функцию getSprite() в класс Game(временно).

Добавим нашу картинку в папку assets(папку создать в корне проекта), саму папку надо добавить в build path.

Далее создаем переменную hero типа Sprite. В функции init() инициализируем ее. В Функции render() рисуем:

Input

Для обработки инпута мы создадим класс, наследующий KeyAdapter:

Тут же и объявим две переменных в шапке класса Game:

Внутри класса KeyInputHandler создадим две функции:

Теперь в функции init() добавим следующее:

Создадим переменные x и y для героя(так как пока что мы еще не написали класс Entity). Сделаем чтобы герой всегда рисовался на этих координатах.

А теперь в функции update() будем проверять нажаты ли клавиши и изменять x-координату.

Источник

Начинаем работу с jPCT — бесплатным 3d движком для Java

Давайте попробуем сделать небольшую игру про мышку бегающую по лабиринту в поисках сыра. Как наверное и любой 3d движок jPCT предоставляет классы Object3D, Сamera, World. jPCT поддерживает несколько форматов 3d моделей, не буду их все здесь перечислять, если Вам интересно то обратитесь к документации. 3ds модели загружаются с помощью статического метода класса Loader load3DS который вернет Вам массив объектов 3ds сцены. Перед загрузкой 3d объектов желательно загрузить текстуры, тогда текстурирвание призойдет автоматически при условии что имена текстур соответствуют информации полученной из 3ds файла. Текстуры загружаются следующим образом:

final TextureManager texMan = TextureManager.getInstance();
texMan.addTexture( «TextureName.png», new Texture ( «TextureFileName.png» ) );

После создания объектов их нужно добавить в мир с помощью метода addObject класса World. В программе может быть несколько объектов World, но при этом каждый объект может принадлежать только одному из них. Перед тем как отображать объекты их нужно «построить», при этом вычисляются нормали, ограничивающий прямоугольник и др. Это можно сделать вызовом метода buildAllObjects() класса World. Создали мир, теперь как говорится да будет свет! Свет добавляем как Вы уже наверное догадались методом addLight при этом указав его координаты и интенсивность красного зеленого и голубого цвета. Все координаты в jPCT задаются в основном в виде SimpleVector(класс jPCT), хотя сохранилась и «старая» форма с тремя координатами float.
То, как мы все это увидим определяет камера. Камеру можно двигать, поворачивать, направлять на объект и направлять параллельно оси z объекта(align). Кстати в jPCT ось x направлена вправо, ось z — от наблюдателя, а ось y — вниз(под ноги).

Как я уже сказал jPCT поддерживает software рендер и OpenGL. Вот так создается фреймбуффер:

final FrameBuffer buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

Потом когда он нам станет не нужен вернем его в прежнее состояние:

buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();

Нарисовать мир в буфер очень просто:

buffer.clear(java.awt.Color.BLUE);
theWorld.renderScene(buffer);
theWorld.draw(buffer);
buffer.update();
buffer.displayGLOnly();

Как Вы уже наверное догадались все вокруг будет голубое.

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

Также есть детектор столкновений. В нашей игре мышь будет стукаться об стенки а в конце столкновение мыши и сыра вызовет конец игры. Поэтому для объекта мыши вызовем метод setCollisionMode( Object3D.COLLISION_CHECK_SELF ). а для сыра и стенок setCollisionMode( Object3D.COLLISION_CHECK_OTHERS ). Сыр еще будет нас оповещать о столкновении чтобы мы знали что игра закончилась ( addCollisionListener(this) ). Теперь каждый раз когда мышь двигается нужно вызывать метод класса Object3D checkForCollisionEllipsoid( SimpleVector — перемещение, SimpleVector — эллипсоид приблизительно описывающий мышь, 8 — глубина рекурсии). Помимо еллипсоида можно использовать сферу и куб — соответственно методы checkForCollisionSpherical(. ), checkForCollision(. ). Это все что есть в jPCT из физики, если нужно что большее то можно присмотреться например к jBullet.

Ну и напоследок весь код:

В дальнейшем планирую рассказать о переносе игры в интернет (java апплет) и на Android с минимальными изменениями кода.

Источник

Java и создание игр: о движках от А до Я

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

Во время создания игр можно использовать разнообразные языки программирования. Некоторые разработчики предпочитают Си-семейство. Оно универсально, но новичкам «с нуля» приступить к коддингу будет трудно. Поэтому тем, кто только начинает изучать процесс разработки игр и программирования, стоит обратить внимание на Java. Это – весьма простой язык, посредством которого можно создавать уникальные перспективные проекты с минимальными трудностями. Основной принцип Джавы – меньше писать, больше делать.

Движок – это…

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

Игровой движок – совокупность неких модулей программного типа, которые включают в себя различные элементы, задействованных при создании игр и развлекательных приложений. Готовый «сборник» утилит. Выступает в качестве базового программного обеспечения при разработке игрового софта.

При помощи движка можно обеспечить:

Грамотно подобранный движок дает разработчику больше возможностей при коддинге. С ним создавать игры для Андроид, Windows/Mac и iOS просто и интересно. Навыки программирования могут быть минимальными.

Движки для программистов и библиотеки на Джаве

Ява – язык программирования, который пользуется у программистов очень большим спросом. Освоить его способен даже новичок без существенных затруднений. Большинство современных платформ для создания игр поддерживают Java-семейство. Это позволяет программерам и разрабам выбрать оптимальный для себя «пакет» готовых утилит при создания развлекательного контента. Далее будут перечислены лучшие движки JavaScript и библиотеки.

GDevelop

Универсальная утилита – подходит и новичкам, и продвинутым программистам. С ее помощью можно сделать:

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

GDevelop предлагает экспорт на различные платформы: Android, iOS, FaceBook (ныне Meta) Instant Games и не только. Подойдет тем, кто заинтересован в экспортировании игр, но не хочет углубляться в непосредственную разработку софта и долго изучать низкоуровневую архитектуру игровых движков.

MelonJS

Еще один вариант, если хотите научиться делать собственные 2D-игры. Подключив соответствующую библиотеку к коду, можно получить доступ к качественной поддержке:

В успешных проектах все это играет огромную роль. Из минусов – не самая лучшая документация. Зато пользовательского контента у MelonJS полно. А еще имеется отличное комьюнити.

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

ImpactJS

Имеет ориентацию преимущественно на двухмерную графику. В отличие от предыдущих вариантов обладает плагинами, которые при добавлении в Impact позволяют имитировать 3D-среду.

Дополнительно к Impact «идут» следующие инструменты:

Через Impact удается без проблем размещать утилиты в AppStore.

Babylon

Мощный инструмент, предусматривающий веб-рендеринг. Игровым движком его назвать нельзя, но на основе BabylonJS удастся создать game. Движок рендеринга предусматривает доступ к низкоуровневому функционалу.

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

PhaserJS

Среди популярных вариантов, поддерживающих Java, выделяют PhaserJS. Он позволяет программировать не только для компьютеров, но и для мобильных устройств. Обладает поддержкой WebGL. Годится для написания 2D-софта.

Это – бесплатный движок. За дополнительную плату можно подключить особые плагины, значительно увеличивающие мощь «пакета».

Библиотека, задействованная при программировании в двухмерном пространстве. Работает с WebGL, задействуется для воплощения потрясающих интерфейсов. И не обязательно они будут размещаться в играх.

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

PlayCanvas

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

PlayCanvas – условно-бесплатный «набор программиста». Годится для небольших публичных проектов. За «тайные» коммерческие идеи предстоит платить ежемесячно.

A-Frame

Инновационное решение в программировании. A-Frame может предоставить пользователям больше возможностей, нежели предыдущие библиотеки. И все это за счет того, что ориентирован движок на VR и AR.

Синтаксис напоминает HTML-верстку. Подойдет для 3d-программирования с «полным погружением». В основном утилитой пользуются опытные программеры.

PhysicsJS

Основан на физическом взаимодействии имеющихся объектов. Используется при разработке всех видов игрушек. Для Андроид в том числе.

Отличное решение для тех, кому важна сложная физика в реализуемом софте. То же самое касается применения при создании собственных движков на основе уже имеющихся библиотек.

Универсальные решения для программистов

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

Unreal Engine 4

Настоящая легенда в сфере gaming programming. Разрабатывался «пакет» с 1998 года. С тех пор все время совершенствуется и дорабатывается. Современная версия UE 4 является универсальной. При помощи нее создаются развлекательные приложения для:

Является частично бесплатным. Платить за использование оного не нужно, если прибыль с созданного приложения в месяц не переваливает за 3 000 долларов США. В противном случае предстоит переводить создателям движка проценты с получаемых доходов.

Unity

Юнити – популярный вариант среди разработчиков. Обошел иные платформы для создания игр, благодаря простоте осваивания. Развивается с 2005 года.

Подойдет для 3D-игрушек. Как и предыдущий вариант, является кроссплатформенным. На Юнити пишут не только простые игры (головоломки, аркады), но и шутеры от первого лица с тщательно проработанным игровым миром.

Недостаток один – графика в созданных утилитах далека от 100% реалистичности. Если разработчику важна графическая составляющая, лучше пользоваться UE 4. Несмотря на это, более половины утилит для Android написаны именно на Unity. Подходит как новичкам, так и продвинутым программистам.

Corona

Программы для создания игрушек можно перечислять бесконечно долго. И выбрать что-то одно бывает непросто. Добавить к списку наиболее успешных и популярных «пакетов» можно утилиту под названием Corona SDK.

Он выступает в качестве платформы для двухмерных игр. Предусматривает:

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

Обладает разнообразными полезными фитчами:

Через Corona’s Physycs Engine можно отслеживать взаимодействие игровых объектов между собой. Этот прием позволяет довести физику в развлекательном софте до идеального состояния с минимальными временными потерями.

Как создать собственную игру – советы

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

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

Преимуществом такого подхода является то, что человек может выбрать узкую направленность. Пример – изучение только процесса создания игр на Android или iOS. В конце обучения (длится до года) выдается сертификат установленного образца. При желании можно изучать движки для игр iOS, Windows, Android более подробно. Для самых популярных «утилит» существуют отдельные курсы. Делятся они по уровню навыков. Подходящие уроки подберет себе и новичок, и продвинутый программер.

Источник

Движок, скриптовый язык и визуальная новелла — за 45 часов

Приветствую. Так получилось, что уже три года подряд в качестве подарка на Новый год определенным людям я делаю игру. В 2018-ом году это был платформер с элементами головоломки, о котором я писал на хабре. В 2019-ом — сетевая RTS для двух игроков, о которой я ничего не писал. И наконец, в 2020-ом — визуальная новелла, о которой далее и пойдет речь, созданная в условиях сильно ограниченного времени.

Интересно? Тогда добро пожаловать под кат.

Осторожно: тут много текста и

0. Обоснование разработки движка.

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

0. Обоснование разработки движка

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

1. Выбор платформы

Выбор, собственно, был невелик: либо Java, либо C++. Недолго думая, я решил реализовывать задуманное на Java, т.к. для быстрой разработки она даёт все возможности (а именно: автоматическое управление памятью и большую, по сравнению с C++, простоту, которая скрывает много низкоуровневых деталей и, как следствие, позволяет меньше акцентировать внимание на самом языке и думать только о бизнес-логике), а также обеспечивает поддержку окон, графики и аудио из коробки.

Для реализации графического интерфейса был выбран Swing, так как я использовал Java 13, где JavaFX уже не входит в библиотеку, а добавлять в зависимости десятки мегабайт OpenJFX было лень. Возможно, это было не лучшим решением, но тем не менее.

Вероятно, возникает вопрос: что это за игровой движок, да без аппаратного ускорения? Ответ заключается в отсутствии времени для борьбы с OpenGL, а также абсолютной её бессмысленности: для визуальной новеллы неважен FPS (во всяком случае, с таким количеством анимации и графики, как в данном кейсе).

2. Архитектура движка и его реализация

2.1 Постановка задачи

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

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

По задумке, игра должна была состоять из следующих частей:

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

Примечание: Под сценой я понимаю логически выделенную часть игры. Критерием сцены может служить одинаковый фон на протяжении этой самой части.

Также среди требований к движку была возможность воспроизведения аудио и показа сообщений (с опциональной функцией пользовательского ввода).

Пожалуй, самым важным желанием было желание писать логику игры не на Java, а на каком-нибудь простом декларативном ЯП.

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

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

2.2. Архитектура и реализация

Учитывая всё вышесказанное, можно поделить движок на три относительно большие части, которые соответствуют одноимённым java-пакетам:

В данном пункте я рассмотрю первые две части. Начну со второй.

Файловая структура квеста следующая:

Имеется отдельная папка для квеста, в корне которой лежит манифест, а также три дополнительные папки: audio — для звукового сопровождения, graphics — для визуальной части и scenes — для скрипто, описывающих сцены.

Хотелось бы в двух словах описать манифест. Он содержит следующие поля:

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

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

В двух словах о консоли разработчика. Она была разработана по следующим причинам:

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

Его финальная структура имеет следующий вид:

Из постановки задачи можно сделать вывод, что всё, что придется делать, — это рисовать изображения, рисовать текст, воспроизводить аудио.

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

Объект (с точки зрения ООП), который описывает текст/изображение, назовём дескриптором. То есть для пользователя API движка существуют лишь дескрипторы, которые можно добавить в состояние дисплея и удалить из него. Таким образом, в финальном варианте дисплея имеются следующие дескрипторы (они соответствуют одноименным классам):

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

Игровой цикл выглядит примерно так:

Примечание: Возможно, возникает вопрос «Зачем рендерить поля для ввода, если для них созданы соответствующие текстовые дескрипторы, которые рендерятся на шаг раньше?» На самом деле рендеринга в пункте 7 не происходит — происходит лишь синхронизация параметров InputDescriptor ‘а с параметрами TextDescriptor ‘а — такие как видимость на экране, позиция, размер и другие. Это было сделано, как указывалось выше, по той причине, что пользователь не управляет напрямую соответствующим дескриптору ввода дескриптором текста и вообще о нём ничего не знает.

Стоит отметить, что задание размеров и позиций элементов на экране происходит не в пикселях, а в относительных размерах — числах от 0 до 1 (схема ниже). То есть вся ширина для рендеринга — это 1, и вся высота — это 1 (причем они не равны, о чем я несколько раз забыл и позже пожалел). Также стоило бы сделать, чтобы (0,0) был центром, и ширина/высота были равны двум, но я почему-то про это забыл/не подумал. Однако даже вариант с шириной/высотой равной 1 упрощал жизнь разработчику квестов.

Пару слов о системе освобождения памяти.

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

Тут всплыл небольшой баг, полное исправление которого потребовало бы переделывания половины системы рендеринга: если посмотреть на порядок отрисовки в игровом цикле, видно, что сначала рисуются изображения и только потом текст. В то же время, когда тулкит показывает изображение, он располагает его посередине экрана по ширине и по высоте. И если текста в сообщении достаточно много, то он должен частично перекрывать основной текст сцены. Однако так как фон сообщения — это изображение (полностью черное, но тем не менее), а изображения отрисовываются до текста — то один текст накладывается на другой (скриншот ниже). Проблема была частично решена вертикальным центрированием не по экрану, а по области над основным текстом. Полное решение включало бы в себя введение параметра глубины и переделывание рендереров от слова «совсем».

3. Скриптовый язык

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

3.1. Язык

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

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

Итак, код хранится в текстовых файлах с расширением SSF; каждый файл содержит описание одной либо больше сцен; каждая сцена содержит ноль или больше действий (action); каждое действие содержит ноль или больше операторов.

Возможно, вы жаждете увидеть наконец исходный код на SL, вот он:

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

Ради упрощения такое понятие, как «переменная», в язык не вводилось; как следствие, все значения, используемые в коде, — литералы. В зависимости от типа выделяются следующие литералы:

Название литерала: Примечание:
Строковый литерал Возможность экранирования кавычек и слешей (\\) прилагается, также есть возможность вставить в текст перенос
Целочисленный литерал Поддерживает отрицательные числа
Литерал с плавающей точкой Поддерживает отрицательные числа
None-литерал В коде представлен как none
Булев литерал В коде — on / off для истины/лжи соответственно
Общий литерал Если литерал не подпадает ни под один из вышеперечисленных типов и состоит из букв английского алфавита, цифр и знака нижнего подчеркивания, он общий литерал.

Пару слов про парсинг языка. Имеется несколько уровней «загрузки» кода (схема ниже):

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

Операторы для работы со счётчиками — специфичными для сцены целочисленными переменными.

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

В загрузчик скриптов встроено не так много проверок на правильность SL-программы, как хотелось бы. Например, всё, что может выброситься на этапе загрузки скрипта, — это исключение о непредвиденном либо неизвестном токене. Во времени исполнения ситуация лучше: есть проверки на типы аргументов операторов (да-да, операндов), на их количество, на наличие запрашиваемой сущности во время lookup ‘а, возможно, и другие, не помню. Однако нет таких проверок времени загрузки, как вызов только существующих действий или использование только существующих сцен в goto и lookup ‘ах, а также проверки типов аргументов и многих других.

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

Кратко о диалогах. Приведу синтаксис оператора добавления диалога:

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

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

Возможно, стоило сделать ещё удаление знаков препинания (знаков вопроса, в частности)

Пример регулярного выражения для диалога, обозначающее «осмотреться»:

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

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

3.2. Интерпретатор

Рассказывать про сам интерпретатор особо нечего: он тоже модульный, модули — это «исполнители» операторов (по одному для каждого). Больший смысл имеет рассказать про специальные действия и смену состояний дисплея.

Для самого SL специальных действий не существует, но для интерпретатора они все-таки есть. Вот они:

Примечание: init и first_come — вместе составляют некое подобие конструктора, что ещё раз намекает на легкий объектно ориентированный оттенок языка.

Это состояние состоит из состояния дисплея и состояния тулкита (обертки, которая добавляет понятие «фон», «основной текст», «поле для ввода» и т. д.). Стало понятно, что нельзя просто выбрасывать эти состояния, а их где-то надо хранить и как-то заменять. Проблема была в том, что все дескрипторы дисплея и тулкита хранились прямо в классах их представляющих (в полях), а сохранять вручную с десяток объектов никоим образом не хотелось.

На помощь пришла композиция и выделение состояния дисплея и тулкита в отдельный класс (что, вероятно, нужно было сделать сразу). Оставалась одна проблема: каким образом заменять состояния с текущего на старое? Ведь нельзя же во время игрового цикла, а именно во время итерации по спискам дескрипторов, просто взять и заменить эти списки. Поэтому тут пришлось добавить метод provideState в дисплей, в который передавался колбэк и состояние для загрузки; а после завершения очередной итерации игрового цикла это состояние заменялось и вызывался колбэк, в котором происходила замена состояния тулкита.

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

4. Разработка игры

Тут я кратко опишу саму игру и процесс её разработки. Как в 2019-м и 2018-м, я решил начать с чего угодно, кроме графики, и начал с истории.

4.1. История и разработка логики игры

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

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

Как оказалось, для разработки задуманной игры мне не понадобилось 25% (5) существующих операторов, а именно: все операторы, связанные со счётчиками; оператор анимирования ( animate ), а также оператор внешнего вызова ( call_extern ).

Помимо основной игры, для ознакомления игроков с кор-механиками игры был разработан демоуровень (скриншот ниже), который состоял из одной сцены (двух, если быть точным, но вторая — просто заглушка, типа «You won»).

4.2. Графика

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

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

5. Статистика и итоги

На разработку первой версии движка и языка (с 11 операторами) у меня ушло 30 часов 40 минут. На реализацию дополнительных 9 операторов ушло ещё 4 часа 55 минут. Разработка логики непосредственно игры (вместе с демо) потребовала 7 часов 41 минуты. Рисование графики —

4-6 часов (графика не учтена в 45 часах из заголовка).

Примечание: Время кодинга мерялось через расширение «Darkyen’s Time Tracker» для продуктов JetBrains (абсолютно не реклама).
Примечание: Я начал писать это все за 2 дня до Нового года, но не успел — релиз пришлось перенести на Рождество. Так что 45 часов из заголовка были распределены примерно на 8 дней.

Количество чистых строк кода для движка: 4777, для игры (без демо) — 637.

Целью было создать 30 минут игрового времени. В итоге прохождение (с моими подсказками) заняло: демо —

8 минут, основная игра на первую концовку —

24 минуты, на вторую (с быстрым прохождением до момента разветвления) —

8 минут. То есть план был выполнен.

Размер квеста — 232 мегабайта (так много из-за музыки, записанной в WAV).

Было нарисовано 28 изображений (и ещё 3 для демо). Это была моя первая игра с адекватным аудио сопровождением — всего с просторов интернета было скачано и запихнуто в игру 17 единиц звуков/музыки.

Все жалобы на игру заключались в абсолютно не юзер-френдли интерфейсе ввода: очень часто регулярные выражения не покрывали вводимых фраз, хотя смысл этих фраз был более чем верный. То есть, например, игрок вводил «вставить ключ в дверь», а предусмотрено было лишь «вставить ключ». Однако были и моменты (один, насколько я помню), когда пользовательский ввод с первого раза совпадал с задуманным (и это было даже не «да»/»нет» или что-то очевидное).

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

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

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

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

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

Исходный код движка может быть найден по данной ссылке на GitHub.

Демо и основная игра находится в файлах (assets) в разделе «Releases» для версии «v1.0» там же.

Источник

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

Какие вы еще знаете однокоренные слова к слову Как написать движок для игры на java:



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

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