Войти
ПрограммированиеФорумГрафика

Игровой движок. Создание с нуля.

Страницы: 1 2 39 10 Следующая »
#0
16:42, 24 окт 2009

Привет всем.

Заранее извиняюсь за слишком большое чтиво.  : \

Эпизод I.  Предисловие.

ПЕРЕД ТЕМ КАК ДАЛЬШЕ ЧИТАТЬ:


1. Да, очередной велосипедист.
2. Да, таких тем завались даже на этом форуме.
3. Нет, я УМЕЮ пользоваться поиском.
4. Спасибо, но идите Вы сами!... в гугл  : )
5. Да, вроде одна моя подобная тема гдето на форуме есть.
6. мож что ещё позже дополню.
7. Если после прочтения пп. 1-4 Вам больше нечего сказать - Вы ошиблись темой - это однозначно.

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


=====================================================================
Эпизод  II.  Постановка проблемы.

Итак, начну с описания ситуации:
Я написал графический движок. Он не супер мощный и не со всеми ультрамодными эффектами, шейдерами и прочим.. Обычный, пока ещё довольно таки простой движок. Тоесть графика у меня есть.

Вдоволь "наигравшись" с ним я теперь всерьёз настроен сделать на нём 3D игру (а именно Horror-action. Жанр не придуман сейчас на ходу - идея игры есть, игра вдоль и поперёк продумана уже мною, сюжет понравится довольно таки большому количеству людей, сюжет оригинален  - таких фильмов и игр не видел ещё, однако также ни чего революционного.).

Итак для создания игры мне нужно:
1. Графика
2. Физика
3. Ввод
4. Звук
5. Tools (типа редактора уровней, энтитей, можелей и т.д.)

Всё кроме физики у меня есть - самописное.  Я решил что я хоть и сумасшедший, но не настолько, чтоб писать ещё и физ. двиг, поэтому юзаю ODE.

Вот мы и подошли к сути:  теперь мне нужно всё это (графику, физику и т.д.) объединить в ИГРОВОЙ движок.
Над его структурой в полную силу думаю с вчерашнего дня.  Много идей мелькает в голове, но вследствие отсутствия опыта создания ИГРОВОГО двига, я не могу остановиться на одной из них. Поэтому прощу мне помочь в этом, помочь мне выбрать и поделиться своим опытом.

=====================================================================

Эпизод III. It has began...

Как я себе представляю игровой двиг:

Это нечто, которое:

1. Создаёт игровые сущности и удаляет их.
2. загружает игровые миры с файлов (имеется ввиду файл уровня грузим)
3. связывает графическое представление сущности с физическим.
4. связывает Entity и AI
5. Обрабатывает игровую логику.

далее спорные моменты, которые я не могу решить:
что есть Entity?  Это игрок, триггер, стул..    а стена, она Entity? Я имею ввиду обычную стену, которая тупо является Solid объектом и всё! В ней нет игровой логики.  Она к чему относится? если не она Entity, то что?  И в каком виде хранить? Хранить в игрвом двиге или достаточно засунуть в физический и графический?

вот я гружу ща Entity класса Player..    Entity player = EntityFactory.LoadEntity("блаблабла.xml");
а как мне стену грузить? она вроде не Entity.. тогда мне её не учитывать в игровом двиге?

Ещё задача:
у меня в ГРАФИЧЕСКОМ двиге есть камера.. ей можно свободно управлять, и вот мне для CutScene понадобится тоже камера... в игрвом двиге. Тоесть мне опять класс Camera обворачивать ещё одним классом Camera а стену обворачивать ещё одним классов StaticEntity? 

Ещё: у меня есть класс сцены в граф двиге.. получается мне нужно делать опять класс сцены в игровом? 

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


пока что я вижу структуру игрвого двига так:

CGameEngine:  CreateGameWindow(), LoadWorld(), CreateEmptyWorld(), DestroyWorld() (эпично xD), Release(), MainLoop()
CEntity: Update(dloat dt), ListenInput(...), Pulse() (AI),  от него может наследоваться Entity2D, и другие сущности типа  CPlayer
CGameWorld: AddEntity(CEntity entity), DeleteEntity(), Update()
CEntityFactory: LoadEntity(), SaveEntity(сохраняем всё в XML файл),  что ещё?

Дополните, пожалуйста.

#1
17:08, 24 окт 2009

К меня не возникло желания выйти после пп1-4, соответственно отпишусь.

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

По сути должно быть так, (ИМХО:):
-Любой объект в игре ентити.
-Ентити колектит в себе физику, графику, игровую логику и т.д. Если какой-либо части не надо (скайбоксу ни логики, ни физике не надо), то ее и нет.
-На уровне игры взаимодействие идет только с ентитями, ни чем иным.
-Ентити связаны в дерево. Корень - игра.

>CEntity: Update(dloat dt), ListenInput(...), Pulse() (AI)

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

В общем случае идея понятна, я надеюсь. Попробуй в такой схеме написать что-нить совсем простое. Там вылезут косяки архитектурные, будешь фиксить;)

#2
17:27, 24 окт 2009

 L 
Зря ты эту тему создал ;-)
Сейчас прибежит куча деятелей, и начнут спорить о преимуществах и недостатках онанизма правой и левой рукой O_o
И каждый будет прав.

#3
17:29, 24 окт 2009

Hawk
> Сразу вопрос - что есть сцена в рендере? Куча объекто с разными свойствами
> материалов и тп? Т.е. просто список всех объектов, которые рендерятся?
нет сцена хранит всякие настройки сцены, террайн, небо, окиян и сценеграф с остальными объектами.  В сценеграфе объекты являюзся узлами сцены. Узлы могут быть дочерними узлами другого узла или иметь свои дочерние узлы.  Собсно их трансформация так и объявляется - иерархически.

Hawk
> В корне не верно. Ентити только апдейтится.
да, действительно, спасибо..  я вот тут думаю, как быть с инпутом...  у меня чтобы работал инпут нужно Entity унаследовать от интерфейса IInputListener,
потом в инпуте зарегистрировать слушателя  и раелизовать метод  ListenInput(...)  при нажатии кнопки или движении мыши, внутри энтити вызывается эта функция , через которую я могу прочитать кнопки и сдвиг осей мыши. 

И вот проблема: когда юзер нажиает кнопку W, Character должен пройти вперёд, а на сколько??  у меня скорость движения перса установена как 0.5 метра/сек..    значит мне нужно знать TimeElapsed между кадрафи (грубо говоря ФПС нужно знать) чтобы рассчитать на сколько вперёд пройти!  Как это хэндлить?

Первое самое просто что пришло в голову: при обновлении системы ввода, передавать в неё и DeltaTime и когда она какому либо слушателю передаёт нажатые кнопки, передавать и DT.  Как вам?

Hawk
> Там вылезут косяки архитектурные, будешь фиксить;)
гы, так  я и пишу здесь, чтоб побольше узнать и поменьше потом фиксить  (ой, мне хватило переписываний в граф двиге!)

#4
17:30, 24 окт 2009

Nikopol
да ничо, надеюсь хоть какуюто часть отправил назад предисловием а с остальной.. ну что ж, в споре рождается истина, как грится...

ахаха, левой лучше - развивается правое полушарие мозга! Развивается творческий потенциал гвахаха  %) 

#5
17:52, 24 окт 2009

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

почему ОДЕ?

#6
18:03, 24 окт 2009

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

L
>И вот проблема: когда юзер нажиает кнопку W, Character должен пройти вперёд, а на сколько?? у меня скорость движения перса установена как 0.5 метра/сек.. значит мне нужно знать TimeElapsed между кадрафи (грубо >говоря ФПС нужно знать) чтобы рассчитать на сколько вперёд пройти! Как это хэндлить?

На апдейте плеера опрашиваешь подсистему ввода, на основании нажатых клавиш/поврнутой мыши строишь вектор скорости и скорость вращения. Отдаешь в физику. Все! За этим-то физика и нужна:) Никаких времен кадра, никакого геморроя. Просто достаточно в начале следующего фрейма взять координаты у физ представления.

L
>гы, так я и пишу здесь, чтоб побольше узнать и поменьше потом фиксить (ой, мне хватило переписываний в граф двиге!)
всего сразу не удумаешь, иначе б была отличная дока "Как дизайнить игровой двиг, чтоб всем было зае.. хорошо!" Каждая система пишется с учетом потребностей, ограничений и т.п. Возможно в движке, который должен держать 10000 юнитов в кадре никакая физика и не нужна (ну это я абстрактно)

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

#7
18:07, 24 окт 2009

Сори, пришлось писать ищо раз.
 L 
>В сценеграфе объекты являюзся узлами сцены. Узлы могут быть дочерними узлами другого узла или иметь свои дочерние узлы. Собсно их трансформация так и объявляется - иерархически.
Иерархия ток для партикл системов нужна, да для объектов, которые не имеют физического представления. Всем другим рулит именно физика сцены.

#8
18:19, 24 окт 2009

redbox
> игровое приложение это система работающая с множеством объектов, причем многие
> из этих объектов повторяются. значит для начала нужен счетчик ссылок :)
ну эт слишком понятно чтоб спрашивать.. вот я и не спрашивал  : )

redbox
> почему ОДЕ?
потомучто  C#,  а Newton юзал  - не понравился а PhysX к сожалению нету нормального враппера.. все мега старые!!  Если располагаете новым или знаете где его найти - то поделитесь, буду премного благодарен.

Hawk
> На апдейте плеера опрашиваешь подсистему ввода, на основании нажатых
> клавиш/поврнутой мыши строишь вектор скорости и скорость вращения. Отдаешь в
> физику. Все! За этим-то физика и нужна:) Никаких времен кадра, никакого
> геморроя. Просто достаточно в начале следующего фрейма взять координаты у физ
> представления.
а, блин, ну да.. я ж физдвиг отдельно апдейтю.. он и посчитает сам  : )

Hawk
> Иерархия ток для партикл системов нужна, да для объектов, которые не имеют
> физического представления. Всем другим рулит именно физика сцены.
ну вот предположим едит горящая машина!  Она является также физическим объектом! но к ней нужно прицепить партикл. и А теперь вопрос, если ты говоришь, что объекты, ИМЕЮЩИЕ физ. представление, НЕ должны быть в сценеграфе, то как я прицеплю систему частиц к этому объекту?

#9
20:42, 24 окт 2009

 L 
> ну вот предположим едит горящая машина! Она является также физическим
> объектом! но к ней нужно прицепить партикл. и А теперь вопрос, если ты
> говоришь, что объекты, ИМЕЮЩИЕ физ. представление, НЕ должны быть в сценеграфе,
> то как я прицеплю систему частиц к этому объекту?

Дык он вроде и сказал что иерархия для партиклов НУЖНА :))
Нод к которому прицеплена машина, и его потомок - нод к которому прицеплен эмитттер, или даже несколько. Так как кроме партиклов наверянка к такой машинке ещё понадобится прицепить что-нить, например истоники света для фар и освещения "огнём" всего вокруг, источник звука горяшего пламени если у тебя звук 3д... конечно это должно быть в сценеграфе рендера/звукового движка, но это всё не надо пихать в физику, так как всё это просто привязано к машине и не имеет физического представления можно сказать что "горящая машина" это игровой объект, а привязанные к нему партиклы, истоники света, звуки и прочее это своего рода атрибуты описывающие каким образом этот игровой объект будет представлен игроку. Вроде об этом Hawk тебе и говорит

#10
22:06, 24 окт 2009

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

 L 
> CEntity: Update(dloat dt), ListenInput(...), Pulse() (AI),
тут тоже ощущение что одно и тоже описано разными словами, чтобы список не выглядел таким пустым.
Не бойся простой структуры. Простота это плюс а не минус движка. L 

И еще у тебя список методов класса Engine:
> LoadWorld(), CreateEmptyWorld(), DestroyWorld()
а если у тебя еще есть отдельный класс World то зачем его методы отдаешь классу Engine?

#11
22:15, 24 окт 2009

Megabyte-Ceercop
> LoadWorld(), CreateEmptyWorld()
> второе заменяется первым, это позволит просто настраивать шаблон пустого мира,
> добавлять в него все необходимые базовые объекты без изменений кода, и вообще
> написания этой ненужной функции.
да, спасибо, снёс 2


Megabyte-Ceercop
> тут тоже ощущение что одно и тоже описано разными словами, чтобы список не
> выглядел таким пустым.
> Не бойся простой структуры. Простота это плюс а не минус движка.
а эт уже давно убрал..  (мне выше сказали)


Megabyte-Ceercop
> а если у тебя еще есть отдельный класс World то зачем его методы отдаешь классу
> Engine?
а чем ему ещё заниматься? : )  у меня сейчас движок что делает:  CreateGameWindow(...), SetCustomWindow(это например игра внутри редактора),  инициализирует подсистемы, апдейтит подсистемы и World..  + есть MainLoop в котором выполняется игровой цикл до посинения  выхода из программы.

#12
0:10, 25 окт 2009

 L 
мне нравится система примененная в Unity.
есть GameObject - просто контейнер для компонентов (List<Component> говоря на C#)
есть Componentы - графические, физические, логические, сетевые. Componentы соединяются между собой входами и выходами.
Весь "игровой мир" - просто список (или дерево) GameObjectов.

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

#13
0:24, 25 окт 2009

 L 
> что есть Entity?
Так используй наследование же. целая иерархия получится.
Грубо говоря так:
Совсем общая абстрактная ентити
Статический объект | Существо | Транспорт
                                    |
                    Игрок | Монстр | NPC

Стена тоже ентети, статическая.

> а как мне стену грузить?
Что из разных классов то одно за другим,
А иерархию рекурсивным спуском.

Ну и используй сразу Компоновщик для ентети.
P.S. Голосую за пункт 1.

#14
3:12, 25 окт 2009

Зачем mainloop???
Гораздо проще в цикле делать обновления

while(Game.Update()){};
Страницы: 1 2 39 10 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.