Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.07.2019, 17:18   #11
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию

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

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

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

Код:
manager.addState('first', ['scene1']);
manager.addState('second', ['scene2']);
manager.setState('first');
Ранее все сообщения между элементами интерфейса рассылались от родителя ко вложенным (в прямом порядке), что привело к проблемам с передачей сообщений ввода. Представим, что есть два перекрывающих друг друга элемента - obj1 и obj2. Второй элемент должен выводиться на экран после первого (перекрывать его). Однако, в случае с сообщением mouseDown такая последовательность обработки приведет к тому, что obj1 (который рисуется снизу) перехватит это сообщение, и оно не дойдет до верхнего obj2. Для избежания этой проблемы мы разделили все сообщения по методу рассылки на 'прямые' и 'обратные'. В примере выше, сообщение mouseDown должно обработаться в обратном порядке, а draw - в прямом.

uiManager

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

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

Убраны некоторые неиспользуемые функции.

uiElement

Значительные изменения коснулись модуля uiElement. Доработан механизм обработки элементов под фокусом и наведенных (hovered) элементов. Элемент, помеченный как focused, может быть только один - теперь это же условие относится и к hovered-элементу. При установке этих флагов элемент обращается к самому верхнему родителю с просьбой снять флаг focused/hovered с текущего отмеченного им элемента и затем устанавливает его себе. Если с фокусом такая ситуация видится полностью логичной, то в случае с наведением вносит некоторые ограничения, которые, однако, пока не мешают работе системы.

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

Добавлены свойства offsetWidth и offsetHeight для реализации пиксельного отклонения от ширины и высоты (если эти значения заданы в процентах). Свойство offsetWidth, например, бывает полезно, когда надо растянуть элемент на всю ширину родителя с заданием отступов справа и слева.

Напомню, что ранее был реализован метод animate() для плавного изменения значений свойств типа Integer и Single. Теперь есть возможность анимировать текстовые свойства (если они содержат числовые значения). Это может быть полезно для анимации количества здоровья персонажа при нанесении ему урона. Также, метод animate() теперь принимает callBack-функцию в качестве последнего параметра - эта функция будет вызвана после окончания анимации. Помимо прочего, это можно использовать для реализации нескольких анимаций подряд, воспроизводящихся одна за другой.

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

Код:
nowPanel.animateBack('y', 5, 100,
  procedure(element: TUiVisualElement)
  begin
    element.animateBack('y', -5, 100);
  end
);
Также, добавлен метод animateStop(), останавливающий все воспроизводящиеся в данный момент анимации.

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

В класс TUiTextElement добавлена возможность указать цвета текста для определенных состояний элемента: normal, hovered, pressed, focused, disabled - все эти цвета можно задать в файле стилей при помощи специальных свойств. Также, в этот класс добавлено свойство autoWidth, которое позволяет автоматически определять его ширину при задании однострочного текста.

В класс TUiEdit добавлено свойство markerColor, определяющее цвет маркера.

Для вывода графических элементов, основанных на спрайтах, добавлен класс TUiBorderedElement, который задает и обрабатывает набор спрайтов для каждого состояния элемента, причем, механизм состояний реализован с учетом расширяемости - новые состояния и спрайты для них можно добавлять в унаследованных классах. Сам TUiBorderedElement заполняет область элемента, составляя его общее изображение из нескольких частей. Доступны следующие варианты построения элемента:
  • 9 частей - по краям область элемента заполняется рамкой, а внутри - центральным изображением
  • 3 части - левая, средняя и правая картинки при горизонтальном расположении; также, доступно вертикальное расположение
  • 1 часть - элемент полностью заполняется одним изображением

Для реализации автоматического заполнения области текстурой (с повторениями), в движок Perfect Engine добавлен специальный параметр, задающийся при загрузке текстуры. Таким образом, для вывода рамки в TUiBorderedElement, рисуется только один прямоугольник, заполненный повторяющейся (или растягивающейся) текстурой. Будет текстура повторяться или растягиваться - полностью зависит от параметра, переданного в движок при ее загрузке.

Изображение, выводимое в TUiBorderedElement, может быть тонировано при помощи параметра tone - технически, для этого используется специальный шейдерный фильтр движка:

Код:
if (FTone.a <> 0) then
  pe.addFilter('tone', FTone.r, FTone.g, FTone.b, FTone.a);
Добавлен модуль uiComposite для описания стандартных составных элементов. В данный момент этот модуль содержит класс TUiCheckBox, состоящий из кнопки и текста, при нажатии на который, также, переключается состояние компонента.

Последний раз редактировалось SaiLight; 14.07.2019 в 17:29.
SaiLight вне форума Ответить с цитированием
Старый 14.07.2019, 17:19   #12
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию

Структура файлов

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

В дополнение к функции rgba() в стили добавлена новая функция hex(), которая переводит цвет из 16-ричного формата (используемого в Photoshop) в TRGBA.

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


Последний раз редактировалось SaiLight; 14.07.2019 в 17:30.
SaiLight вне форума Ответить с цитированием
Старый 28.08.2019, 21:14   #13
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию


Приветствую тебя, мой безмолвный читатель. Рад сообщить, что процесс разработки игры доведен до первой обозначенной нами контрольной точки. Прошло каких-то несколько месяцев, и вот уже мы имеем возможность двигать по экрану первый квадратик. Это, несомненно, успех. Такого результата можно было бы достичь намного раньше, если бы перед нами не встала необходимость разработки крупных модулей UI, ECS и Perfect Engine, работу над которыми мы планировали проводить значительно позднее. Однако, их наличие необходимо для реализации заготовки крупного проекта, чем на данный момент и является наша тестовая программа.

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

Состав игры

Графический движок Perfect Engine

Основные моменты, касающиеся новой версии графического движка Perfect Engine, уже были описаны в одном из сообщений выше. Конечно, за это время в нем произошло много структурных изменений (например, было введено понятие "Слой"), но здесь я коснусь этого вопроса поверхностно, надеясь в будущем посвятить описанию движка отдельное сообщение.

1. Благодаря возможностям Perfect Engine, все изображения графического интерфейса хранятся в одной текстуре - это достигается за счет алгоритма построения разметки (разбиения на кадры) изображения, загружаемого в память. Причем, разметка может как строиться автоматически (если все кадры одного размера), так, в более сложных случаях, и загружаться из файла. Для изображения, скажем, "image.png", достаточно положить в ту же папку файл "image.mrk", содержащий его разметку - и движок автоматически использует его при загрузке изображения. В дополнение к этому, Perfect Engine поддерживает разные способы вывода текстур - с заполнением или растягивающиеся на всю область выводимого объекта. Способ вывода, как и некоторые другие полезные параметры, можно задать при загрузке текстуры.

2. Метод работы с мипмапами не позволил нам добиться желаемого качества при использовании шрифтов разных размеров. В своей программе мы предпочли загружать один и тот же шрифт разного размера как несколько разных шрифтов - для этого в функцию загрузки шрифта в движке было внесено понятие "alias" - имя, по которому можно получить загруженный шрифт. Например, "Calibri_18" или "Calibri_30" для 18px и 30px, соответственно. Но затем мы пошли еще дальше: дали возможность отключать сглаживание шрифта - как дополнительный параметр в функции загрузки - это дает возможность выводить шрифт маленького размера без искажений.

Код:
pe.loadFont('/fonts/taurus.ttf', 18, 'taurus_18', 0, false);
pe.loadFont('/fonts/taurus.ttf', 30, 'taurus_30', 0, true);
В примере выше параметры в функцию loadFont() передаются в следующем порядке:
  • name - путь к файлу шрифта (либо, название системного шрифта)
  • size - размер символов в генерируемом спрайте
  • alias - имя, по которому будет доступен шрифт в дальнейшем
  • interval - межсимвольный интервал
  • smoothing - флаг, отвечающий за сглаживание

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

Библиотека UI

Финальная на данный момент версия библиотеки содержит следующие модули:
  • uiElement (стандартный) - набор простых классов, на основе которых создаются элементы управления. В составе модуля, помимо прочих, можно найти 4 основных класса:
    • TUiInputElement - реализует интерфейс обмена сообщениями ввода (клавиатура и мышь)
    • TUiVisualElement - является предком всех визуальных элементов
    • TUiBorderedElement - позволяет использовать спрайты для оформления
    • TUiTextElement - предоставляет возможность вывода многострочного текста
  • uiComposite (стандартный) - набор классов для реализации составных элементов управления. В данный момент содержит только класс TUiCheckbox.
  • uiCompositeExt (расширенный) - расширяющий модуль для реализации собственных классов составных элементов. В данный момент содержит класс TUiConsole.
  • uiManager - обертка над вышеописанными модулями, обеспечивающая взаимодействие элементов между собой, а также, их загрузку из файла разметки и стилизацию при помощи файла стилей.

На данный момент консоль является основным элементом управления в игре. Класс TUiConsole основан на стандартном классе TUiTextElement и содержит вложенный элемент TUiEdit для ввода текста. Реализован набор простых методов для работы с консолью извне:
  • toggle() - открыть/закрыть консоль
  • log() - вывести отладочную информацию
  • clear() - очистить консоль

Благодаря реализованной чуть ранее в Perfect Engine возможности вывода форматированного текста, консоль позволяет выделять некоторые сообщения цветом. Напомню, что для активации форматирования достаточно указать цвет в выводимой строке в следующем формате:

Код:
[#ff0000ff]Красный текст[#], Обычный текст
Эта функция активируется в классе TUiTextElement специальным флагом formatted.
SaiLight вне форума Ответить с цитированием
Старый 28.08.2019, 21:15   #14
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию

Библиотека ECS

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

Сущности:
  • figureEntity - описывает квадратик (персонаж)
  • bulletEntity - описывает маленький квадратик (пулька)

Компоненты:
  • transformComponent - содержит позицию и размеры объекта
  • lifeComponent - содержит данные о "здоровье" персонажа
  • lifeTimeComponent - содержит данные о времени жизни объекта
  • damagerComponent - содержит данные о силе атаки
  • victimComponent - содержит данные о поврежденности объекта на текущий момент
  • renderComponent - содержит данные, необходимые для вывода объекта
  • physicComponent - содержит данные, необходимые для перемещения объекта
  • shootComponent - содержит данные для обработки выстрелов
  • ownerComponent - содержит данные о владельце объекта

Системы:
  • initSystem - обрабатывает события запуска/закрытия программы и начала/окончания игры
  • uiSystem - обрабатывает все игровые элементы управления
  • inputSystem - обрабатывает ввод с клавиатуры
  • controlSystem - обеспечивает управление игровым персонажем
  • lifeTimeSystem
  • renderSystem
  • physicSystem
  • damageSystem
  • shootSystem

События:
  • programStartEvent - возникает при запуске программы
  • programEndEvent - возникает при окончании работы программы
  • gameStartEvent - возникает при старте новой игры
  • gameEndEvent - возникает при окончании игры
  • gamePauseEvent - возникает при установке игры на паузу
  • gameUnpauseEvent - возникает при снятии игры с паузы
  • keyboardEvent - возникает при получении игровым окном сообщения с клавиатуры
  • mouseEvent - возникает при получении игровым окном события от мыши
  • keyMapsEvent - возникает в таймере и содержит в себе список всех нажатых управляющих клавиш
  • afterDrawEvent - возникает после вывода всех игровых объектов
  • collisionEvent - возникает при столкновении игровых объектов
  • changeControlledEvent - возникает при смене владельца объекта

Внутренние модули

1. Модуль Window. Так как программа создается, в большей степени, для саморазвития, нам важно, чтобы она, насколько это возможно, была оптимизированной. Модули VCL занимают слишком много места, а функционал, который нам может потребоваться, весьма скуден - только окно и оконные сообщения - вполне достижимо средствами WinAPI, чем и занимается данный модуль.

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

2. Модуль Global. Весь игровой процесс происходит внутри бесконечного цикла, инициирующего обновление игровых данных. Там же при помощи специальных функций засекается время, затраченное на последнее обновление игры - текущее игровое время всегда можно получить при помощи переменной time.now из модуля Global; в дальнейшем этот параметр будет задействован в реализации сетевого взаимодействия.

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

3. Модуль FileControl. Используется для контроля целостности игровых данных. Более подробное описание - ниже, в разделе вспомогательных утилит.

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

Для обеспечения взаимодействия с ECS-системой игры, класс TProgram снабжен специальным полем типа TEcsListener, умеющим перехватывать игровые события - сейчас это TProgramStartEvent и TProgramEndEvent.

Вспомогательные утилиты

1. AtlasGenerator - состоит из сторонней программы SprtiteSheetPackerStarling и конвертера AtlasConverter. SprtiteSheetPackerStarling позволяет соединить множество изображений в одну большую текстуру и создает xml-файл с разметкой этого изображения - в каких координатах находится каждая из его частей. Для применения этой разметки в движке Perfect Engine была написана программа-конвертер разметки AtlasConverter.

2. Crc32. Для контроля целостности игровых данных (защита файлов, необходимых для корректной работы программы, от измененй со стороны пользователя) был создан модуль fileControl. Основываясь на специальном файле fileControl.txt со списком путей ко всем файлам, которые необходимо защитить от изменений, модуль производит проверку контрольных сумм этих файлов и в случае несовпадения прерывает запуск программы. Контрольная сумма самого fileControl.txt вносится в код программы.

Вспомогательная утилита Crc32 позволяет автоматически сгенерировать fileControl.txt прямо в папке с программой и затем сохраняет контрольную сумму основного файла в буфер обмена.

----------

Управление:

WASD - перемещение
Space - выстрел
` - вызов консоли

Консольные команды (пока только для вида):

connect n - подключение к серверу
disconnect - отключение от сервера
clear - очистить консоль


Последний раз редактировалось SaiLight; 28.08.2019 в 23:14.
SaiLight вне форума Ответить с цитированием
Старый 06.11.2019, 21:37   #15
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию

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

Занимаясь изучением вопросов реализации сетевой поддержки для игры, а также, сопутствующими темами о лагокомпенсации и оптимизации, мы нашли англоязычную статью авторов Cheryl Savery и T. C. Nicholas Graham, в которой описана инновационная хронологическая модель программирования. По заверениям авторов, такая модель программирования обеспечивает встраивание времени как некоторой основополагающей сущности в сам принцип построения программы (или в данном случае многопользовательской игры), что дает широкие возможности для программирования сетевых взаимодействий между клиентами и значительно упрощает реализацию множества алгоритмов лагокомпенсации.

Данная модель была разработана специально для многопользовательских сетевых игр. В ходе её проектирования авторы реализовали некий фреймворк, так называемый Janus Toolkit, название которого аллегорически представляет возможности программистов получать значение игровых параметров из любого момента времени — настоящего, прошедшего или будущего, подобно персонажу римской мифологии Янусу, видящему прошлое и будущее. Этот фреймворк написан на языке С# с использованием сетевой библиотеки Lidgren.

По словам авторов статьи, многие разработчики, использовавшие Janus Toolkit в своих проектах, очень хорошо отозвались о его удобстве для реализации сетевых возможностей в играх. Некоторые принципы лагокомпенсации уже заложены в хронологическую модель изначально, такие как расчет пути (dead reconing) и методы отложенного ввода (delayed input techniques), а некоторые сложные алгоритмы, такие как плавные исправления (smooth corrections) или удаленная задержка (remote lag) реализуются с помощью простых выражений.

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

Поэтому мы сделали запись типа TTimelineState - состояние хронологического значения, - содержащую два поля: "value: TValue" и "time: Cardinal". Тип данных TValue дал возможность хранить в этом поле значения любого типа, что обеспечило нам реализацию любых хронологических типов. Далее нужно было решить, как структурировать хранимые значения - все состояния должны храниться в каком-то массиве или списке. Выбор варианта хранения во многом зависел от требований доступа к этим данным. Согласно описанным в статье принципам, эти требования можно сформулировать так:
  • Запись значений по абсолютному времени
  • Считывание значений по относительному времени (текущее время со смещением)
  • Считывание ближайших предыдущих и ближайших следующих значений по абсолютному времени

Поскольку хронологии различных типов данных будут иметь похожее внутреннее устройство, мы решили основывать их на базовом классе TTimeline, в котором хранится массив состояний states: TArray<TTimelineState>, а также, описаны методы записи и считывания значений.

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



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

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

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

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

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

Исходный текст статьи можно посмотреть здесь. А наш перевод - по этой ссылке.


SaiLight вне форума Ответить с цитированием
Старый 12.05.2020, 21:56   #16
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
По умолчанию

Рады снова опубликовать очередную порцию материала по разработке игры Galaxy Boom mini. С момента последней публикации мы много работали над системой сетевого обмена данными. Стоит сказать, что изначально это была простая сетевая библиотека, написанная еще задолго до старта разработки, когда мы собирали сведения по некоторым областям, с которыми нам придется столкнуться в процессе написания игры. Это были области графики (движок Perfect Engine 3), общей структуры (система ECS, парсинг JSON-файлов и RTTI-сериализация) и несколько других областей, в число которых входила область работы с сетью.

Тогда мы узнали основные понятия: TCP/UDP, сокеты, потоки..., а также, выбрали наиболее подходящую для наших целей библиотеку, реализующую базовый набор функций для сетевой разработки.

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

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

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

Библиотека состоит из трех уровней:
  1. Непосредственная реализация сокета и клинетского класса, которые используются как в реализации клиента, так и в реализации сервера (список клиентов).
  2. Системная реализация клиента и сервера (два разных модуля) с поддержкой общих возможностей, не привязанных к конкретной программе.
  3. Пользовательская надстройка над классами клиента и сервера для реализации возможностей, связанных с текущей программой. Здесь могут быть описаны обработчики дополнительных сообщений, и сюда же планируется в дальнейшем внедрение базовых механизмов работы с хронологиями.

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


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не разрешается отладка USB (Samsung Galaxy S4) Danila7 Java Мобильная разработка (Android) 1 18.09.2016 17:05
[Аркада] Galaxy Boom mini, Perfect Light SaiLight Gamedev - cоздание игр: Unity, OpenGL, DirectX 5 14.03.2016 20:19
проблемы с samsung galaxy ace II GT-I8160 (Android 4.1.2) Андрей201421 Мобильные ОС (Android, iOS, Windows Phone) 1 15.08.2014 20:06
Региональная блокировка Samsung galaxy SIII starsv Мобильные ОС (Android, iOS, Windows Phone) 4 24.02.2014 17:21
Galaxy Boom SaiLight Gamedev - cоздание игр: Unity, OpenGL, DirectX 17 24.12.2012 14:56