Здравствуйте, alx771103, Вы писали:
A>Привет всем!
A>Я в этом деле новенький, но хотел бы (чиста, хобби) написать свой игровой движок... А идеи как это сделать — закончились...
A>Как бы так разбить движок на модули, чтобы при переходе на другую платформу не пришлось переписывать почти всё с нуля?..
A>Если есть идеи (или, еще лучше, проверенные идеи), пожалуйста, поделитесь...
игровой движок для различных типов игр будет различен — имхо.
в одних играх нужен движок с элементами искусственного интеллекта, в других — нет.
Re: Архитектура ИГРОВОГО движка
От:
Аноним
Дата:
09.06.06 06:51
Оценка:
Здравствуйте, alx771103, Вы писали:
A>Привет всем!
A>Я в этом деле новенький, но хотел бы (чиста, хобби) написать свой игровой движок... А идеи как это сделать — закончились...
A>Как бы так разбить движок на модули, чтобы при переходе на другую платформу не пришлось переписывать почти всё с нуля?..
A>Если есть идеи (или, еще лучше, проверенные идеи), пожалуйста, поделитесь...
Если хочешь чего то написать, то возьми opensource движок и посмотри на его архитектуру и это будет ответы на твои текущии и буущие вопросы. см. http://www.devmaster.net/engines/
Здравствуйте, alx771103, Вы писали:
A>Попытаюсь конкретизировать...
A>Утверждение первое: Движок состоит из модулей. A>Утверждение второе: Модули общаются между собой.
A>Вопрос №1: Как его лучше разбить и организовать "общение"?
Сам движок явно должен быть представлен паттерном сингельтон, а общение между модулями можно организовать использую паттерн медиатор, чтобы в последствии было проще добавлять новые модули. Разбивать движок нужно в соответствии со здравым смыслом, т.е. на графическую часть, звуковую, скриптовую и какие вы там еще хотели?
Здравствуйте, <Аноним>, Вы писали:
А>Если хочешь чего то написать, то возьми opensource движок и посмотри на его архитектуру и это будет ответы на твои текущии и буущие вопросы. см. http://www.devmaster.net/engines/
+1
Автору темы имеет смысл начать с чего-то подобного + поиска хотя бы в данном форуме rsdn + поиска в онлайн-ресурсах по теме
Здравствуйте, alx771103, Вы писали:
FF>>а этот класс универсальный для всех платформ или есть несколько различных Platform'ов на все случаи жизни?. A>Есть интерфейс Platform, есть классы Win32Platform, ОкноPlatform, НезнаюЧтоЕщеPlatform, которые наследуются от Platform. Ядро — знает только Platform. A>Но! Ведь есть еще графический, звуковой модуль... Модуль устройств ввода... Они-то сильно привязаны к платформе... A>То есть, с одной стороны... Хочется, чтобы ядро и сервер не знали вообще ничего о платформе... A>С другой, платформа может оказывать влияние на работу ядра... A>Как это совместить?..
я не понял в чем проблема.. как платформа может влиять на работу ядра, если все низкоуровневые вещи вынесены в отдельные модули?.
что в ядро тогда входит?.
FF>>зависит от платформ..базовые функции(время, файлы), работа со специфичными для платформы вещами.. FF>>вот в этом Platform'е что уже есть?. A>Это мне и хотелось узнать... Навскидку: A>1. Получение системного времени (от него потом и плясать при вычислении разных deltaTime)
это да..
A>2. Обработка сообщений от платформы и интерпретация в сообщения ядра. Например, для Windows, активация/деактивация окна приводит, в зависимости от того, работает ли на этой машине dedicated сервер, к приостановке выполнения приложения. A>3. Обертка системы ввода/вывода (по поводу её необходимости есть сомнения).
а думаю по любому нужна.. особенно, если используются сильно отличающиеся системы ввода вывода..
A>4. Что еще?
звук, графика.. а вроде ничего больше нет.. ИИ не зависит..
по сути, чтобы абстрагироваться от платформы полностью (включая низкоуровневые библиотеки) нужно создать свой маленький АПИ, у которого, например, есть настройка "вид платформы"
FF>>имхо лучше обернуть.. FF>>по крайней мере, если кто будет это использовать, то не сделает чего нить, что не устраивает вас.. хотя для мелких проектов думаю это не важно.. A>Во втором случае (с "выводильщиками"), сделать что-то не так могут только эти самые "выводильщики", а они написаны мной и измнению не подлежат... A>Зато, когда завтра выйдет чудесная графическая библиотека "NextGeneration3DGraphicsAPI", в которой будут использоваться не треугольники, а кружочки, этот самый "выводильщик" будет преобразовывать треугольники в кружочки и отдавать их в API.
зачем создавать много "выводильщиков" на низком уровне, когда можно создать один, предоставляющий высокий уровень, и в нем преобразовывать в низкий?.
Здравствуйте, RomashkaX, Вы писали:
RX>Сам движок явно должен быть представлен паттерном сингельтон, а общение между модулями можно организовать использую паттерн медиатор, чтобы в последствии было проще добавлять новые модули. Разбивать движок нужно в соответствии со здравым смыслом, т.е. на графическую часть, звуковую, скриптовую и какие вы там еще хотели?
Здравствуйте, alx771103, Вы писали:
A>И куда потом ето девать?
1) При устройстве на работу в какую-нибудь игровую компанию Вы можете продемонстрировать этот пример.
2) Вы можете разместить исходники на Вашем сайте, а на форуме профессионально обсуждать вопросы создания игровой физики или AI. Почему профессионально? Потому что Ваши знания будут базироваться на опыте.
Встречный вопрос: "А что Вы потом будете делать с написанным движком?"
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>1) При устройстве на работу в какую-нибудь игровую компанию Вы можете продемонстрировать этот пример. КЛ>2) Вы можете разместить исходники на Вашем сайте, а на форуме профессионально обсуждать вопросы создания игровой физики или AI. Почему профессионально? Потому что Ваши знания будут базироваться на опыте. КЛ>Встречный вопрос: "А что Вы потом будете делать с написанным движком?"
Здравствуйте, alx771103, Вы писали:
A>Я призываю порассуждать на тему архитектуры!
Не хочу Вас обидеть, но такие обсуждения интересно (и продуктивно!) вести с человеком, который принимал участие в написании движка для какой-нибудь коммерческой игры. Или хотя бы с человеком, который спроектировал не одну программу.
Здравствуйте, neFFy, Вы писали:
FF>я не понял в чем проблема.. как платформа может влиять на работу ядра, если все низкоуровневые вещи вынесены в отдельные модули?. FF>что в ядро тогда входит?
Ядро, на мой взгляд — класс, содержащий основной цикл. Или основной цикл должен содержаться именно в той самой Platform?
FF>а думаю по любому нужна.. особенно, если используются сильно отличающиеся системы ввода вывода..
Поясните...
FF>звук, графика.. а вроде ничего больше нет.. ИИ не зависит.. FF>по сути, чтобы абстрагироваться от платформы полностью (включая низкоуровневые библиотеки) нужно создать свой маленький АПИ, у которого, например, есть настройка "вид платформы"
То есть этакий Framework и для каждой платформы свой?
FF>зачем создавать много "выводильщиков" на низком уровне, когда можно создать один, предоставляющий высокий уровень, и в нем преобразовывать в низкий?.
Ну, например, у меня есть объект класса Mesh и выводить его надо посредством отрисовки какого-то буфера точек. А есть еще объект класса ParticleSystem и выводить его надо совсем по-другому... И для Mesh, и для ParticleSystem есть свой "выводильщик" и он занет что и как нужно отдать низкоуровневой бибилиотеке...
Здравствуйте, alx771103, Вы писали:
FF>>я не понял в чем проблема.. как платформа может влиять на работу ядра, если все низкоуровневые вещи вынесены в отдельные модули?. FF>>что в ядро тогда входит? A>Ядро, на мой взгляд — класс, содержащий основной цикл. Или основной цикл должен содержаться именно в той самой Platform?
имхо в самой Platform..
для примера можно сравнить "основной цикл" в glut и DirectX..
FF>>а думаю по любому нужна.. особенно, если используются сильно отличающиеся системы ввода вывода.. A>Поясните...
ну если есть специфичные вызовы..
или например система предоставляет id'шники разных клавиш.. но при портировании эти id'шники на разных системах отличаются.. поэтому имхо лучше сделать свой какой нить enum, в котором будет набор всех нужных клавиш.. или что нибудь подобное..какой нить преобразователь.. об этом надо еще немного подумать..что то я криво сказал
в кратце: обертка над подсистемой ввода-вывода должна принимать какие либо данные от программы и преобразовывать их под платформу.. как и брать от платформы и передавать в программу данные, которые понятны во всех участках программы.. что то типа стандартизации
вообще зависит от количества поддерживаемых платформ и их различия..возможно и не стоит заморачиваться
FF>>звук, графика.. а вроде ничего больше нет.. ИИ не зависит.. FF>>по сути, чтобы абстрагироваться от платформы полностью (включая низкоуровневые библиотеки) нужно создать свой маленький АПИ, у которого, например, есть настройка "вид платформы" A>То есть этакий Framework и для каждой платформы свой?
вроде того.. маленький набор классов для удобной работы..
FF>>зачем создавать много "выводильщиков" на низком уровне, когда можно создать один, предоставляющий высокий уровень, и в нем преобразовывать в низкий?. A>Ну, например, у меня есть объект класса Mesh и выводить его надо посредством отрисовки какого-то буфера точек. А есть еще объект класса ParticleSystem и выводить его надо совсем по-другому... И для Mesh, и для ParticleSystem есть свой "выводильщик" и он занет что и как нужно отдать низкоуровневой бибилиотеке...
с другой стороны.. есть меш и есть массив частиц.. им вовсе не обязательно уметь рисоваться для разных низкоуровневых библиотек.. имхо логичней сделать отдельный "рисовальщик", который будет уметь работать на разных библиотеках.. да и количество изменяемого кода при портировании на другую платформу сильно меньше..
Прошу прощения за молчание — отпуск, знаете ли...
FF>имхо в самой Platform..
Но тогда под каждую платформу придется писать этот самый основной цикл... А это-то как раз делать и не хочется... Нет никаких идей как этого избежать?
FF>в кратце: обертка над подсистемой ввода-вывода должна принимать какие либо данные от программы и преобразовывать их под платформу.. как и брать от платформы и передавать в программу данные, которые понятны во всех участках программы.. что то типа стандартизации
Уупс!.. Мы про разные системы ввода-вывода говорим... Это всё я виноват ... Мне хочется знать, стоит ли оборачивать во что-то свое дисковый ввод-вывод?
FF>вроде того.. маленький набор классов для удобной работы..
Надо подумать... ...я все еще думаю... ...О!
То есть, на полную независимость от платформы может претендовать только сервер и клиент? Единственные модули, которые будут использовать другие, платформозависимые, модули для работы?
FF>с другой стороны.. есть меш и есть массив частиц.. им вовсе не обязательно уметь рисоваться для разных низкоуровневых библиотек.. имхо логичней сделать отдельный "рисовальщик", который будет уметь работать на разных библиотеках.. да и количество изменяемого кода при портировании на другую платформу сильно меньше..
Но тогда для каждого класса сцены придется код переписывать... Хотя в моем случае тоже самое... ДА, ты, наверное, прав... Намотал на ус...
Здравствуйте, alx771103, Вы писали:
FF>>имхо в самой Platform.. A>Но тогда под каждую платформу придется писать этот самый основной цикл... А это-то как раз делать и не хочется... Нет никаких идей как этого избежать?
а что такого сложного написать несколько "основных циклов"??.
в основном цикле:
— видео
— управление
— звук
— что еще??.
FF>>в кратце: обертка над подсистемой ввода-вывода должна принимать какие либо данные от программы и преобразовывать их под платформу.. как и брать от платформы и передавать в программу данные, которые понятны во всех участках программы.. что то типа стандартизации A>Уупс!.. Мы про разные системы ввода-вывода говорим... Это всё я виноват ... Мне хочется знать, стоит ли оборачивать во что-то свое дисковый ввод-вывод?
вот лично я не знаю как осуществляется ввод-вывод с карты памяти в SonyPS..
если под "платформой" понимаются вин/лин, то можно обойтись стандартной библиотекой..
вообще.. если существуют различия между системами ввода-вывода на разных платформах, то стоит обернуть в свое, чтобы работать со стандартизированным интерфейсом..
FF>>вроде того.. маленький набор классов для удобной работы.. A>Надо подумать... ...я все еще думаю... ...О! A>То есть, на полную независимость от платформы может претендовать только сервер и клиент? Единственные модули, которые будут использовать другие, платформозависимые, модули для работы?
для сервера свой платформозависимый кусочек, а для клиента свой.. абсолютно независимой может быть только логика игры
отступление:
под какие платформы вы ищите подход??. может с этого стоит начать?.
Здравствуйте, neFFy, Вы писали:
FF>а что такого сложного написать несколько "основных циклов"??. FF>в основном цикле: FF>- видео FF>- управление FF>- звук FF>- что еще??.
Плохо то, что код под разные платформы будет почти один и тот же, и если понадобится добавить что-то, придется много ковырять...
Вот что я надумал когда-то давно, и, по-моему, надумал правильно:
Есть интерфейс Platform, который полностью скрывает работу с платформой.
Есть класс Kernel, который реализует основной цикл.
Внимание мысль: Kernel может находиться только в двух основных состояниях: запущен (Running) и стоит (Stopped), кроме того, у него в состоянии Running может быть еще одно этакое "подсостояние" Suspended.
Некая функция MAIN должна создать объект нужной платформы, создать и передать ссылку на платформу объекту Kernel. И передать управление какому-то методу run класса Kernel. Соответственно, Kernel перейдет из состояния Stopped в состояние Running. Platform имеет возможность перевести Kernel в состояние Suspended и Stopped. Ну, и соответственно какие-то другие классы могут Kernel ТОЛЬКО в состояние Stopped.
ТО Kernel — класс, реализующий основной цикл, получился платформонезависимым.
Ну и как?
FF>для сервера свой платформозависимый кусочек, а для клиента свой.. абсолютно независимой может быть только логика игры
Вот именно эти кусочки я и хочу вынести в отдельные классы.
FF>отступление: FF>под какие платформы вы ищите подход??. может с этого стоит начать?.
Не "вы", а "ты": я — один.
По-моему, с этого начинать и не надо: Платформазависим — налево, независим — направо... От того, на какой платформе реализуется, платформонезависимый код не становиться зависимым...
A>По-моему, с этого начинать и не надо: Платформазависим — налево, независим — направо... От того, на какой платформе реализуется, платформонезависимый код не становиться зависимым...
Я не понял ты хочешь писать платформонезависимый код только под одну платформу? Если так то сразу скажу ничего кроме потери времени не получишь, при реальном портировании всплывут такие проблемы которые ты и представить не мог, и в тоже время многие вещи будут неоправданно усложнены.
Здравствуйте, FR, Вы писали:
A>>По-моему, с этого начинать и не надо: Платформазависим — налево, независим — направо... От того, на какой платформе реализуется, платформонезависимый код не становиться зависимым... FR>Я не понял ты хочешь писать платформонезависимый код только под одну платформу? Если так то сразу скажу ничего кроме потери времени не получишь, при реальном портировании всплывут такие проблемы которые ты и представить не мог, и в тоже время многие вещи будут неоправданно усложнены.
+1
хорошо бы еще создать проектик, реализующий работу с платформой по минимуму, и прописать его под несколько доступных платформ.. от результата и идти..
Здравствуйте, neFFy, Вы писали:
FF>Здравствуйте, FR, Вы писали:
A>>>По-моему, с этого начинать и не надо: Платформазависим — налево, независим — направо... От того, на какой платформе реализуется, платформонезависимый код не становиться зависимым... FR>>Я не понял ты хочешь писать платформонезависимый код только под одну платформу? Если так то сразу скажу ничего кроме потери времени не получишь, при реальном портировании всплывут такие проблемы которые ты и представить не мог, и в тоже время многие вещи будут неоправданно усложнены.
FF>+1 FF>хорошо бы еще создать проектик, реализующий работу с платформой по минимуму, и прописать его под несколько доступных платформ.. от результата и идти..
От себя могу добавить — посмотри архитектурный паттерн "Microkernel". Либо делай виртуальную машину, а на ее основе пиши всю основную логику. Цель при разработке кроссплатформенных систем минимизировать усилия при переносе кода на любую другую даже заранее неизвестную систему. Сделать как ты планируешь просто нереально... Задача в общем виде решается, но огромными усилиями — учти это.
Здравствуйте, alx771103, Вы писали:
FF>>а что такого сложного написать несколько "основных циклов"??. A>Плохо то, что код под разные платформы будет почти один и тот же, и если понадобится добавить что-то, придется много ковырять... A>Вот что я надумал когда-то давно, и, по-моему, надумал правильно: A>Есть интерфейс Platform, который полностью скрывает работу с платформой. A>Есть класс Kernel, который реализует основной цикл. A>Внимание мысль: Kernel может находиться только в двух основных состояниях: запущен (Running) и стоит (Stopped), кроме того, у него в состоянии Running может быть еще одно этакое "подсостояние" Suspended.
зачем Suspended?.
A>Некая функция MAIN должна создать объект нужной платформы, создать и передать ссылку на платформу объекту Kernel. И передать управление какому-то методу run класса Kernel. Соответственно, Kernel перейдет из состояния Stopped в состояние Running. Platform имеет возможность перевести Kernel в состояние Suspended и Stopped. Ну, и соответственно какие-то другие классы могут Kernel ТОЛЬКО в состояние Stopped.
A>ТО Kernel — класс, реализующий основной цикл, получился платформонезависимым. A>Ну и как?
как я бы сделал а что то уже было
есть стартовая функция main, в которой основной цикл.. которая создает
я бы не стал делать один класс Platform, который работает с платформой, а вынес бы каждую деталь (видео, управление, звук, етк..) в одтельные классы.. они бы все вместе предоставляли некий API(вроде WTL) для работы всех остальных низкоуровневых классов..
Например, Graph, Input, Sound/Audio.. каждый из этих классов был бы оберткой над различными низкоуровневыми библиотеками..
почему несколько?. например OpenGL не дает работы со звуком.. нужно OpenAl или SDL например.. да и для управления какой нить glut.. это в DirectX удобно, а вдруг что..
можно сделать Kernel, но имхо это некритично.. Kernel будет содержать в себе Sound и Input..А Graph..
имхо можно сделать класс "Сцена"/View, которая будет содержать в себе Graph и сама обрабатывать всё видео..
потом вынести работу с этими классами в отдельные потоки, и аналогами Running, Stopped будут критические секции.. имхо полностью останавливать цикл, чтобы обработать всю новую инфу не стоит..
не знаю точно.. но можно было бы попробовать создать свою подсистему обработки высокоуровневых сообщений..
например, игрок ткнул на юнит, сообщение создалось (юнит ид, состояние: ткнут ), в главном цикле выбрали сообщение и передали в Graph и Sound.. юнит выделился и сказал что нибудь но это не для экшенов