Если бы я думал о том, записаться ли на такой курс - в первую очередь хотел бы посмотреть на содержание курса. Какие темы сколько времени будут рассматриваться, для какого уровня аудитории будет курс, в каком формате будет проходить и т.д. Если бы этой информации не было предоставлено - однозначно прошёл бы мимо.
Если же речь идёт о книге - достаточно оглавления и нескольких отзывов. https://vk.com/beezoya
Предлагаю растянуть создание игры для будущего конкурса не на 1 месяц, а хотя бы на 3. А на счет бюджета
Не могу доказать, но мне субъективно кажется, в таком случае до финиша дойдёт ещё меньше проектов, чем обычно. И из всех, которые дойдут будет только 1 нормальный, на который эти 3 месяца были полноценно убиты. https://vk.com/beezoya
Вообще планирую сам себе писать музон и купить ради этого десятый ризон (или более новый, если успеет к тому моменту выйти), а то с торрента качнуть можно тока древнейшую пятую версию. Но, если время не позволит (или частично не позволит), буду иметь ввиду. https://vk.com/beezoya
Пишу игру, в ней будут объекты. Для создания объекта у меня есть LUA скрипт, который вызывается сразу при создании объекта и формирует наш объект так, как требуется; возможно, вызывая в процессе какие то другие функции, функции из движка и т. д, не суть. На входе эта луа функция принимает аргумент - таблицу, содержащую данные произвольной топологии. Эта таблица содержит дополнительные данные, для создания объекта. Также движок должен позволять луа скриптам создавать другие объекты, передавая при этом произвольные параметры через таблицу. Алгоритм такой:
1) идёт итерация игрового цикла, выполняется какой-то скрипт, которому приспичило создать объект
Код
function someLuaFunction() local position = {6, 3, 2} Core.EntitiesManager.createEntity("testCube", position) end
здесь первый параметр - имя создаваемого объекта, второй - та самая таблица произвольной топологии, для разных объектов может иметь разный вид. Для простоты примера пусть будет тупо позиция.
2) вызывается функция из С++ (Core.EntitiesManager.createEntity), которая создаёт пустой объект, затем по имени объекта ищет подходящий скрипт для создания объекта с соответствующим именем, ищет в нём функцию onCreate и вызывает, ПЕРЕДАВ В НЕЁ идишник объекта И полученную таблицу. Упрощённо говоря:
Код
void EntitiesManager::createEntity( lua_State* params) { object = new чото там int id = objBuffer.push_back(object); luabridge::luaRef ref = достать из params первый аргумент - строку: имя объекта и найти по этому имени подходящий скрипт для создания // Как достать второй аргумент - таблицу из params и послать её на вход onCreate()? ref (id, ..); }
3) функция onCreate из нужного скрипта вызывается, имея на входе идишник и таблицу
Код
function testCube.onCreate(id, position) Core.EntitiesManager.setObjPosition(id, position); Core.ThrowError("луа психанул и кинул исключение без веской причины, наслаждайтесь"); end
Собсно вопрос - как реализовать пункт 2) Тобишь, как достать из lua_State аргумент-таблицу произвольной топологии и ничего в ней не меняя послать в функцию в луа в качестве аргумента
Перегуглил весь гугел - ничего не нашёл, а свободного времени мало чтобы досконально во всём разбираться...
Добавлено (05 Декабря 2018, 01:25) --------------------------------------------- Можно конечно обойти проблему так: 1) просим движок создать объект и возвратить идишник 2) НАПРЯМУЮ вызываем скрипт создания нужного объекта в луа
Но: 1) Это злостный костыль 2) это 2 строки луа кода вместо одной. (ну, тут можно обернуть в отдельную функцию) 3) всё равно хочется узнать ответ на вопрос в топе ибо могут в дальнейшем возникнуть похожие ситуации - всё время костылить чтоль?
Впрочем, работать такой подход будет чуть быстрее
Добавлено (05 Декабря 2018, 23:54) --------------------------------------------- Нашёл ответ на свой вопрос сам: пришлось всё-таки разбираться и ковыряться в луа стеке.
Итак: Вот пример функции, которая решила создать объект
Код
a = function () if zz == nil then local h = Core.Vector2(400.0, 300.0); zz = Core.EntitiesManager.createEntity("testEntity", h); end end
создаём юзердату-позицию, вызываем Core.EntitiesManager.createEntity, которая возвращает юзердату-идишник.
Вот сбайнденная Core.EntitiesManager.createEntity в движке:
Код
int createEntity(lua_State* state) { lua_settop(state, 2); // Получаем тока 2 аргумента - имя объекта и таблица, остальное убиваем из стека const char* objName = luaL_checkstring(state, 1); // Достаём первый аргумент - имя объекта lua_remove(state, 1); // Убираем первый аргумент чтоб не мешался. Теперь в стеке только таблица StorageId id = context.entitiesManager().createEntity(objName, state); // Создаём объект luabridge::push(state, id); // Возвращаем идишник объекта (то что в луа скрипте присваивается переменной zz ) return 1; // Указываем, что вернули одно значение }
А вот как выглядит непосредственно функция создания объекта
Код
void Entity::runCreateScript(StorageId id, lua_State* state) { context.entitiesManager().getObjectsDataRef()[id.uid] = luabridge::newTable(context.sharedVariables().runtimeState); if (idOnCreate_ >= 0){ if (!state){ refs_[idOnCreate_](id); } else{ // Интересующий код начинается здесь // Сейчас в стеке лежит только таблица refs_[idOnCreate_].push(state); // Пихаем в стек функцию testEntity.onCreate // Сейчас в стеке лежит таблица, затем функция luabridge::push(state, id); // Пихаем в стек идишник // Сейчас в стеке лежит таблица, затем функция, затем идишник lua_insert(state, 1); // перемещаем идишник в начало стека // Сейчас в стеке лежит идишник, затем таблица, затем функция lua_insert(state, 1); // перемещаем функцию в начало стека // Сейчас в стеке лежит функция, затем идишник, затем таблица
int code = lua_pcall(state, 2, 0, 0); // вызываем функцию, передав идишник и таблицу if (code != 0){ const char* error = luaL_checkstring(state, -1); throwString("Entity::runCreateScript %s", error); } } } }
Вот так выглядит код вызванного testEntity.onCreate
Код
testEntity.onCreate = function(id, pos) Core.Messaging.printMessage("ggg "..pos.x, "error"); end
Это да, но можете посоветовать что-нибудь конкретное? Что-нибудь для совсем-совсем новичка.
А ну значт так, скажу как чувачок, начинавший с с++ и ни на что в итоге не перешедший. По самому языку с++ могу порекомендовать книжло А. Хортона "Вижуал студия чото там - полный курс", отличная книга, изначально язык учил по ней.
Затем стоит попытаться чото наварганить. Но чтоб было не сложно. Берёшь библиотеку SFML - это обёртка для OpenGL, но простая как валенок, и для 2д заточена.
После поймёшь как делать игры, сможешь поглотить более серьёзный материал, например, по алгоритмам, методам, паттернам и прочей лабуде. (Вот например архиполезная книжица http://www.gameprogrammingpatterns.com/contents.html)
Ну и наконец, поняв всё это мракобесие, можно садиться за серьёзное программирование - берёшь и изучаешь сырой DirectX, openGL или Vulcan, делаешь игру на нём.
Либо путь 2) Берёшь движок Unreal - там с++ скриптовый. Но тут я ничо не скажу, ибо изобретаю свой велосипед и пишу всё с нуля сам на своём полуфабрикатном уродливом двигле. https://vk.com/beezoya
Hobo_Gus, пасибка. Ну, ждать ещё навскидку ~ 1.5 года надо. Но это не точно.
Добавлено (19 Ноября 2018, 08:24) --------------------------------------------- Короче, я тут немного ленился, но время от времени чото поделывал. В общем: Закончил писать код по GUI (ну или почти закончил, мелкие правки и доделки буду реализовывать по ходу дела).
А ещё, начал внедрять в игру скриптовый язык Lua. Я уже даже загрузил конфиг игры на луа скрипте! Сейчас разрабатываю модульную систему. Игра будет загружаться помодульно, модули будут загружаться в определённом порядке, порядок будет прописан в отдельном луа файле. Проще говоря, модуль = мод. Пользователи легко смогут создавать свои моды. В системе, которую я придумал, возможности по моддингу будут не хуже, чем в игре CortexCommand (и даже лучше). В луа скрипты будет вынесен почти весь высокоуровневый геймплейный код, а в движке будет такой контент, как, например, обобщнный алгоритм поиска пути, рейтрейсинг, обнаружение и расчёт столкновений, обобщённый функционал для обработки ИИ и т.д. Короче, в движке будут реализованы нетривиальные и сложные задачи, которые нужно решать быстро (каким бы шустрым ни был интерпретатор луа, всё равно он будет работать в 10-100 раз медленнее кода на с++). Взаимодействие с объектами будет осуществляться с помощью колбеков. Например, ударили гоблина, вызывается колбэк из луа типа obj_goblin.getHit(selfId, damageSourceId, attackerId, damage) Все скрипты будут работать в глобальной видимости. Чтобы убрать коллизию имён, все колбэки, относящиеся к определённому объекту будут иметь свой "класс" (obj_goblin, gui_testButton, ...). Хранить все скрипты в глобальной видимости нужно для того, чтобы не плодить все утилитные глобальные луа функции для каждого луа стейта, а то жирно будет для каждого объекта инициализировать свой отдельный луа стейт со всеми приблудами!
И ещё - этот проект будет фигурировать в моей магистерской дисертации, а тема диссертации - ИИ в играх. То есть придётся сделать врагам хороший качественный ИИ. А раз так, то будут внедрены элементы стратегии. Игрок не только будет рубить всё подряд, но и сможет управлять своими отрядами, а враг будет также формировать свои отряды и координировать их действия для того чтоб задавить игрока по-умному. Но игра вовсе не будет заставлять вас использовать свои мозги. Не хотите - будет куча режимов игры для чистого мочилова.
Добавлено (01 Декабря 2018, 15:27) --------------------------------------------- Реализовал модульную загрузку игры через луа, теперь буду пилить взаимодействие с луа в рантайме А ещё вот эта статься вдохновила меня на создание травы в игре. https://habr.com/company/pixonic/blog/431340/
И у меня появилась пара мыслей насчёт системы здоровья. В общем, здоровье будет ключевым фактором. Чем меньше здоровья - тем медленнее мы двигаемся, тем ниже наш урон и тем хуже мы блокируем. Максимальный уровень запаса сил не сможет быть больше, чем процентное количество оставшегося здоровья (как в игре kingdom come). Также магия будет тратить запас сил. Чтобы восстановить здоровье - надо будет грызть бинты, а если мы хотим поддержать запас сил - будут специальные конфеты с укропом, дающие заряд бодрости! Ну и добавим к этому, что, повредив определённые конечности или лишившись их, мы получим дополнительные штрафы к эффективности действий. Например, если нам отрубили голову (а как известно, мозг ХНК находится несколько в ином месте), мы потеряем способность видеть. Чтобы восстановить потерянную конечность - можно будет воспользоваться подорожником.
Добавлено (10 Декабря 2018, 00:09) --------------------------------------------- Текущая версия игры: 0.0.13, движок в целом реализован на 50-60% (без учёта шейдеров и луа скриптов) С прошлого момента сделано:
Главное меню - отдельный игровой режим, меню выбора уровня - отдельный игровой режим, каждый игровой уровень - отдельный игровой режим. Каждый игровой режим имеет свой lua код, в частности функции, вызывающиеся при входе и при выходе из игрового режима, а также функции, вызывающиеся каждый кадр. Всё взаимодействие с движком будет через игровые режимы.
Каждый игровой объект И текущий игровой режим смогут слать и реагировать на любые сообщения в любой момент выполнения программы, передав в качестве аргумента таблицу произвольной топологии. Подпиской на реагирование на некоторое сообщение является наличие соответствующей функции с с подходящим именем в таблице объекта. Пример: Убили игрока? Игрок при уничтожении шлёт сообщение, которое ловится всеми врагами - и они начинают танцевать от счастья. Или например оно ловится игровым режимом - и тот меняет игровой режим на чёрный экран с надписью красными буквами "Он ушёл, но обещал вернуться"
Ну а также луа скрипты были присобачены к гуйне. Нажали кнопку - выполнился скрипт. Сдвинули ползунок - выполнился скрипт. Через луа можно создавать и уничтожать объекты и гуйню.
в версии 0.0.14 будет собственно реализовано главное меню, генерирование тестовой сцены, окошко настроек и т.п. ЧЕРЕЗ луа скрипты, попутно будет доделан необходимый для этого байндинг с движком, которого пока не хватает. То есть, движок избавится от всего тестового хардкода.
в версии 0.0.15 будет куча мелких правок. Ничего нового скорее всего добавлено не будет, цель - просто почистить двигло, привести всё в порядок и решить непонятки. Возможно, разве что, запихну bsp деревья. А может, и не запихну. Щас у меня сцена бьётся на области фиксированного размера. Короче, обдумаю вопрос.
затем пойдёт версия 0.1.0. С этой версии начнётся работа над скелетными мешами, скелетными анимациями, смешиванием и генерированием анимаций...
Тут форум неактивный, кроме того, обычно внимание уделяют проектам которые близки к завершению, либо идея уж очень оригинальная, ибо 99% проектов сдыхают на этапе зарождения. Так шо забей и просто делай. https://vk.com/beezoya
Заранее рендеришь дерево на большом расстоянии, сохраняешь результат. Далее все деревья на расстоянии, большем некоторой величины рисуешь полученными спрайтами вместо мешки. Можно банально объекты заменять. Типа если дерево отдалилось достаточно - убирать дерево и ставить туда спрайт. Если наоборот - убирать спрайт и ставить дерево.
Добавлено (11 Мая 2018, 00:04) --------------------------------------------- В обливионе так деревья рисуются. Можно делать промежуточные фазы. Допустим, на средних расстояниях рисовать упрощённую модель дерева упрощёнными шейдерами
от этот варик подойдет для стратегии, где город видно целиком
Ну я ето писал с задней мыслью об авиасимуляторе. Летаешь высоко, видишь далеко. С фпс и рпг (но рпг разные бывают) понятно - много невидимых треугольников, которые можно отсечь на цпу, отсекая сразу всю мешку, да и сложность моделей там (обычно) будет на порядок-два выше.
В открытых мирах ещё решают Лоды. Некоторые объекты вообще можно заменить на спрайты. Допустим, бальшой-бальшой злющий лес в 100500 километрах можно заинстансировать спрайтами за 1 дров кол - и никто не заметит особой разницы. Можно делить на лоды ландшафт. Вблизи тесселировать, на среднем плане рисовать как есть, а на дальнем - убирать большую часть треугольников. https://vk.com/beezoya
На количество дровколов влияет разнообразие объектов. Теоретически все однообразные объекты на сцене можно заинстансировать за 1 дров кол. Так что один из способов уменьшить ко-во дров колов - уменьшить это разнообразие. Вариант 1: уменьшить количество уникальных объектов. Допустим, что на сцене 20 персонажей и все разные, а ты хоба - и заюзал для первых 10 одну мешку, для вторых 10 - вторую мешку, и в итоге вместо рисования каждой мешки отдельно ты инстансируешь их сразу по 10 особей Вариант 2: зафигачивать несколько мешек в одну. Допустим у тебя есть город. Он состоит из множества зданий. А ты хоба, вместо того чтоб рисовать каждое здание отдельно взял и в 3д максе слепил всё вместе в 1 неразрывный объект и возрадовался.
Ну я кароч в юнити не умею, но я думаю что он ну просто обязан внутри себя юзать инстансинг (иначе он был бы архимедленным), а значит подобные манипуляции вполне могут помочь. https://vk.com/beezoya
sfabrikan, ты не давал чёткого однозначного ответа, будешь ли помогать или нет. И если будешь - то мне нужна будет реальная помощь, а не по мелочи 2 раза в месяц. Если готов - пожалуйста. С тобой я готов по честному поделиться процентами от дохода, если оный будет. В работу будет входить моделирование, текстурирование, и отчасти анимирование. Ну а если поможешь со звуками ещё - будет отлично. Ну и возможно, под моим руководством, луа скриптинг объектов тоже сможешь делать. Если сделаешь весь графон, полностью поможешь со звуками и поможешь со скриптингом и если меня будет всё устраивать - дам 40%.
На мне будет висеть создание музыки и написание движка, и все окончательные решения принимаю я.
Добавлено (12 Апреля 2018, 00:51) --------------------------------------------- Актуализировал шапку. В принципе, относительно общих идей геймплея изменений почти нет. Так что особо ничего нового там(в шапке) не появилось.
Добавлено (17 Апреля 2018, 21:23) --------------------------------------------- Сделал свой генератор карт нормалей, настройки для него загружаются через простенький скрипт, для которого забацал парсер. С настройками можно играться и получать разный результат. Считаются нормали, в принципе, в лоб, так что до серьёзных программ не дотянет. Но зато свой!
(чото имгур убил качество картинки в ноль)
+ прикрутил кавити - это короче штука, которая прибивает спекуляр. Ищется в точках, где нормали смотрят друг на друга, образуя "ямы". Ну типа в этих ямах будет прибиваться освещёнка. На скрине это белые точки (ибо для кавити юзается альфа канал - чтоб зря не пропадал)
Добавлено (21 Апреля 2018, 01:12) --------------------------------------------- поддержка карт нормалей прикручена
Добавлено (21 Апреля 2018, 18:28) --------------------------------------------- прикручена трипланарка (на кубиках незаметна) и селфиллюм
Добавлено (22 Апреля 2018, 23:35) --------------------------------------------- С текстурированием полностью закончено. Также был починен инстансер (оказалось что он крашился при > 1 типе геометрии) + мелкие изменения в движке.
Следующая цель: - система частиц - вывод текста - поддержка нескольких языков
Добавлено (09 Мая 2018, 22:57) --------------------------------------------- короче система частиц. Делятся на 2 типа: экранные без теста глубины и мировые с тестом глубины Каждый тип делится на 4 подтипа: непрозрачные с простейшим альфа тестом, прозрачные сортируемые по дальности, аддитивные прибавляющие цвет и антиаддитивные, отнимающие цвет (да, в игре будут затемняющие источники света и частицы; мне кажется, с помощью этого можно будет достичь забавные эффекты)
следующий этап - написание системы гуйни и реализация текстовой гуйни. Ну хотя бы чтоб фпс вывести на экран)
Добавлено (28 Сентября 2018, 11:35) --------------------------------------------- Прогресс с предыдущего поста: 1) Куча правок улучшений и доделок рендер движка 2) Поддержка нескольких языков 3) Улучшение системы частиц. Частицы теперь анимируются конечным автоматом с вероятностными переходами 4) Система вывода звука на основе OpenAL 5) Вывод музыки. Музыка состоит из слоёв. Каждый слой играет одну и ту же мелодию, но по разному. Первый слой - спокойная музыка, второй - неспокойная, третий слой - боевая музыка и т.д. Слои переключаются между собой плавно и грузится в отдельном потоке. 6) Сиситема GUI. Гуйня в проекте немного нестандартная. Пока что реализованы: 6.1.1) Текст. Ну текст как текст, можно задавать размер шрифта, цвет, отдельные слова автоматом переносятся по строкам. 6.1.2) Иконка. Может находиться в нескольких состояниях (имеет несколько кадров). При приближении курсора мыши начинает рычать, краснеет и дрожит 6.1.3) Кнопка. убегает от курсора мыши и орёт при этом как резаный негр 6.1.4) Чекбокс. Плюётся в направлении курсора мыши мерзкой жижей, издавая неприятные звуки 6.1.5) Инпутбокс. Когда пользователь вводи буквы начинает злиться - краснеет, начинает испускать пар и начинает вышибать буквы прямо из середины введённого текста. Осталось реализовать: 6.2.1) Ползунки, вертикальный, горизонтальный, горизонтальный с набором фиксированных строковых значений; полоска здоровья. Ползунки будут регулярно заклинивать и испускать при движении искры 6.2.2) Раскрывающийся список. Элементы в раскрывающемся списке будут самовольно меняться местами 6.2.3) Фрейм. Служи для группировки других гуёв между собой. Можно вкладывать внуртрь других фреймов и перетаскивать мышой по экрану
В ближайшее время буду: -доделывать гуйню -реализовывать интеграцию lua скриптов в игру.
Разницы особой нету, но загрузить систему и вызвать просадку фпс в ртс будет значительно проще
Ну во первых это одна из сложнстей. То что в РТС надо делать 30 раз в секунду, в пошаговой можно убить целую секунду на ход. Во-вторых, в РТС всё двигается одновременно, в пошаговых все двигаются по очереди. Соответственно, алгоритмы будут разными. В РТС обычно важенее скорее общий умный ИИ, чем интеллект отдельных юнитов ибо там всё равно каша. В пошаговых Индивидуальный и общий ИИ обычно сильнее разделены и важенее ИИ каждого отдельного юнита(зависит от ситуации).
Вообще в любой РТС стратегии будет 3 уровня ИИ 1) ИИ отдельного юнита, самый низкий уровень, поди сюда, атакуй туда, подпрыгни и пукни заклинание. 2) ИИ отряда. общая команда атаковать, отступать, найти путь туды, построить формацию вот таким вот образом 3) Общий ИИ. Развить такие-то технологии, попытаться подружиться с тем-то, захватить такие-то ресурсы, сформировать такой-то общий план нападения на другого злюку. В пошаговых могут отсутствовать некоторые пункты. Например, в режиме боя пункт 2 постольку-поскольку, а пункт 3 вообще не нужен. В режиме перемещения отряда как в героях, пункт 1 не нужон.
Ну кароч раз такой вопрос вообще встал, да ещё имеется ввиду какаято унылая хрень-конструктор, то вангую 100% нада пилить тетрис а не стратежку. https://vk.com/beezoya