Виталий Новичков@Wohlstand
Инженер-Программист С++
Информация
- В рейтинге
- Не участвует
- Откуда
- Москва, Москва и Московская обл., Россия
- Зарегистрирован
- Активность
Специализация
Фулстек разработчик, Разработчик игр
Старший
C++
Git
Cmake
Linux
Bash
Unix
ООП
Базы данных
Они бы имели право жаловаться на Телегу, если бы Телега разрешила, например, рекламу Макдональдса или KFC, и тут БК был бы прав. Но, Телега запретила всю категорию, и под неё попали все конкуренты Бургера, без исключений. Так что, им не чего волноваться. В итоге, просто зря потратят деньги на пошлины и адвокатов, в конечном итоге ничего и не добившись.
И не удивительно, просто я сам лично вспомнил мало примеров, а их тьма, и с этим я полностью солгасен! Да даже Qt чёткий тому пример, разрабатываемый компанией Digia, и живущий как СПО, но при этом компания делает деньги на поддержке и на коммерческих лицензиях.
А как же случаи, когда и открытый свободный код, и при этом всё равно заказывается у поставщика? То есть, поставщик разрабатывает и продаёт, но при этом спокойно отдаёт свои исходные коды в народ. Чаще всего в таких случаях, исходники даются бесплатно и свободно, а вот бинари и официальная поддержка поставщика продаются за деньги, на чём, собственно, поставщик и зарабатывает. Кроме всем известного RedHat, есть ещё несколько примеров, например, некая DAW (забыл её название), которая в собранном виде продаётся за деньги, а исходники открыты, на, пожалуйста, если хочется ковыряться в коде и собрать самому, бери и собирай. Иначе если хочешь, чтобы всё подали на блюдечке - "плати денежку, и мы всё организуем индивитуально для Вас".
В любом случае, если речь идёт о задачах для бизнеса, требующего повышенной безопасности (особенно в такой чувствительной сфере как финансовой, привлекающей немало киберворишек), то здесь важна не закрытость-открытость кода, а именно обеспечение надёжности системы от взломов. Также, ничто не отменяет тот факт, что ключи шифрования, используемые в системе, должны быть надёжно защищены, и, по возможности, изолированы от интернета аппаратно, например, работать через USB-модуль, с которого физически невозможно извлечь закрытый ключ (если же в нём нет уязвимостей, конечно же).
Если говорить в общем, открытые коды удобны для возможности независимых специалистов по безопасности исследовать код и выявить возможные уязвимости в коде прежде, чем они будут использованы кибер-воришками, и таким образом, прежде чем внедрять решение в бизнес, оно должно быть отполировано народом задолго до. У закрытых систем независимо опретелить реальный уровень надёжности, не представляется возможным, и поэтому, у таких систем есть только два статуса - взломана или невзломана.
В физике координаты крайне рекомендуется именно с плавающей точкой. Это очень важно, что если объект движится с маленькими скоротями, то это будет чётко видно. При отрисовке координаты надо соответственно выравнивать. Хотя, зависит от типа и жанра игры. Для платформеров и экшнов нужны именно с плавающей точкой, либо числа с фиксированной точкой, но чтобы были дробные единицы. Иначе смена скоростей будет резкой и жёстко ограничена.
В терминологии OpenGL это текстура, выделяется текстура определённой размерности, и дальше задаётся цель отрисовки прямо в эту текстуру. Текстуру можно просто один раз загрузить из сырых данных, а можно прямо в неё же рисовать сцену, а потом накладывать куда-нибудь ещё: на полигоны, на поверхностью объёмных фигур, и т.п. Только рендер в текстуру используеся чаще всего для разного рода экранов-камер, зеркал, и т.п. Либо для отображения нескольких игровых сцен (например, в режиме двух игроков), и т.п.
Ну это и есть двойная буферизация, когда рисование сцены производится в отдельный буфер, а не прямо на отображаемую поверхность.
Мне кажется, или вы не используете двойную буфферизацию... В случае с GDI, надо выделить текстуру, на ней рисовать свою сцену, и дальше эту текстуру отрисовывать как единое целое. В случае с OpenGL, механизм двойной буферизации встроен (его лишь надо включить на начальном этапе инициализации). Необходимо лишь нарисовать сцену как нужно, и дальше вызвать обмен буферов (либо запросить перерисовку, в зависимости от терминологии интерфейса).
А вообще, лучше всего обощить графический интерфейс какой-нибдуь абстрактной обёрткой, и в ней реализовывать взаимодействие с каждым из графических интерфейсов. То есть, по умолчанию использовать OpenGL, если он доступен и работает. Тут и плавность графики, и быстрая отрисовка. Если же OpenGL не работает, то соответственно, нужно задействовать модуль программной отрисовки, где ни о какой плавности точно не может бы и речи.
В любом случае, самый стандартный способ выдержка времени между кадрами, это рассчёт разницы между временем, затраченным на цикл игры, и желамой длительности одного кадра, которая используется в виде задержки между текущим и следующим кадром. (если значение меньше нуля, пропускать задержку, лучше игра пусть лагает, но не зависнет никогда).
Я пишу кроссплатформенный софт, и работаю в основном на Linux. Windows загружаю иногда либо на виртуалке, либо на втором компьютере, чтобы отлаживать специфичные для Windows баги или стабилизировать работу там.
А OpenGL как? Он есть почти везде, и я использую именно его первым делом. Без вертикальной синхронизации (не зависимо от используемого графического интерфейса) никогда не удастся отрисовать идеально плавно, потому что если частота монитора не совпадает с обновлением графики игры, картинка будут резаться пополам, чего будет видно на динамических сценах (особенно если фон движится вправо-влево). В QNX, как я покопал, OpenGL есть.
Время, которое ждать, используя
SDL_Delay()/usleep()/Sleep().Метод вертикальной синхронизации поможет точно, здесь плавность обеспечивается на аппаратном уровне.
P.S. Библиотека, чей код я взял за основу для себя, чтобы жёстко выдерживать заданную частоту (которая крайне важна для сообщества спидраннеров): https://gitlab.com/torkel104/libstrangle
Для плавности нужно делать следующее:
Замерять время, за которое отработала физика-логика, обработка событий, и, собственно отрисовка
Взять желаемую длительность кадра (например, 16 миллисекунд), вычесть из неё время, затраченное на обработку всего, и если разница больше нуля, использовать как задержку
Если включён режим вертикальной синхронизации, никакие задержки самому делать не нужно, это всё будет обеспечено графическим драйвером. Важно лишь настроить физику так, чтобы она шла в постоянной частоте (либо шаг физики прямо соотнести с частотой развёртки монитора, чтобы на разных частотах был разный шаг физики), не зависимо от того, какая частота выстроена на мониторе (60 герц, 75 или, 80 и больше)
У меня для жёсткого выдерживания строгой частоты используется особая логика, которая подразумевает учёт времени, которое необходимо спать, и в учёт берутся "недосып" и "пересып", которыми следующий такт выравнивается. Всё равно идёт не идеально ровно, какой-то кадр идёт дольше, какой-то быстрее, но суммарная частота за секунду равна заданной.
Благодарю за замечания!
Статью подкорректирую и местами перефразирую: часть формулировок действительно ошибочны, а часть - совершенно не правильно объяснено, хотя мысль я пытался подать правильную.
Отвечаю по каждому из замечаний:
Так и есть, с VB я в серьёз никогда и не работал, максимум делал пару-тройку экспериментов, пока был ребёнком, а потом взял лишь за необходимостью портировать код игры на C++.
Всё верно, поскольку вывод я сделал по исследуемому мною коду и по поведению, которое я обнаружил в нём.
Всё верно. Я по факту не правильно страктовал свою мысль. Про обращение к переменным и функциям внешних модулей я лишь хотел обозначит то, что для доступа к публичным модулям из других не надо делать никаких предварительных деклараций, включений заголовков, импортов, и т.п. и что неявное определение таких ссылок функций и переменных в VB это основная особенность. В чистом C (до стандарта С99) возможно вызывать какую-нибудь функцию, не добавляя никаких предварительных деклараций. Однако, это очень плохой тон, и, в зависимости от компилятора и его флагов, можно получить соответствующее предупреждение "implicit declaration of function", или даже ошибку вовсе.
Возникает путаница в коде (особенно для человека, сильно теряется наглядность и множество неоднозначностей), и в C, и C++ чётко происходит ошибка, если помимо глобального поля, без ключевого слова "struct" попытаться определить локальную переменную с этим типом, будет ошибка "error: expected ‘;’ before ‘ko’":
Так и есть, просто если специально не указывать, будет работать именно как
ByRef, и это вызвало путаницу, поскольку я не догадывался об этом изначально.Понял, хотя я и замечал, что и для логики, и для побитовых операций в коде использовались одни и те же ключевые слова "And" / "Or", но чтобы они были побитовыми жёстко, не догадался.
Так и есть, в С++ это 0 и 1, а в VB используется COMBOOL со значениями 0 (0x0000) и -1 (0xFFFF).
Я в коде чётко использовал либо && / ||, либо & / |, в зависимости от ситуации.
Я мало видал использование классов в VB-проектах, но при этом знал, что они были, и они были с собственными уникальными особенностями, не свойственными другим языкам. Перефразирую.
Та и есть, BRST в качестве носителя. Я ругался, по факту, на интерфейс IDE и на фактическое поведение созданных программ при приёме и выдаче текстовых данных, запрос путей к файлам, и т.п. Пока под капотом работает юникод, стандартные интерфейсы, используемые конкретно в VB6, используют именно локалезависимые ANSI-кодировки. Соответственно и нужно использовать расширенные возможности и нестандартный подход, чтобы нормально принимать и выдавать нормальные юникодные строки. В C/C++ стандартных способов работы с текстом большое множество. Самые базовые фукнции также локалезависимы. При этом имеется множество альтернативных функций, принимающих и работающих с юникодом, как стандартных (в т.ч. платформозависимых), так и сторонних. UTF8 мне нравится тем, что он позволяет создавать по большей части лаконичный код, который бы корректно работал с системными интерфейсами, не зависимо от того, на каком языке строчка. Так и есть, что для посимвольной работы с UTF8 много хитростей и сложностей, требующих сканировать всю строку и парсить биты, чего мне и приходится делать, когда я реализую функцию отрисовки текста на экране, для подсчёта посимвольной размерности строки, и т.п. UTF32 в этом плане гораздо удобней, потому что одно значение - один символ. Фреймворк Qt внутри себя и использует UTF32 под капотом QString, чем он чрезвычайно удобен. UCS-2 всё же не идеален, поскольку у него присутствует такое понятие как суррогатные пары, которые позволяют закодировать один символ двумя единицами.
Игра там появилась благодаря моему другу из Китая, который собственно и создал пакет. Мы с ним через QQ общались, и я ему помог настроить сборку (там были некоторые проблемы из-за лишних флагов). Также друг создал и другую игру на этом же движке, пакет называется
thextech-adventuresofdemo, альтернативная игра, но на базе того же движка.Ну, по факту она и есть частичная, только работает на простых типах: целочисленные, числа с плавающей точкой и булевы. Что остновано на классах, и так само себя инициализирует, поэтому для них и первый шаблон.
P.S. А так, сначала я создал первый шаблон для всего, однако, понадобилось упростить инициализацию для простых типов, и решил сделать по проще - просто второй шаблон, который отличается от первого тем, что в конструкторе проходится по элементам и назначает им значение по умолачини. В общем, можно упростить и использовать один шаблон на всё, используя значение по умолчанию для последнего поля шаблона и в конструкторе условно выполнять или не выполнять инициализацию. Однако, как я помню, я пытался так сделать, но не получилось, и решил, что проще будет просто два шаблона держать.
У меня игра уже имеет сборки под Android, так что, на мобилках тоже живёт (и не только на мобилках - на планшетах и умных телевизорах). Сама игра изначально не подразумевает работу в вебе концептуально, это однопользовательская игра (если не считать локальный мультиплеер) для прохождения различных эпизодов или отдельных уровней, опубликованных сообществом на форуме (или на Discord-серверах). Форумы как раз и есть основная площадка конкретно данного сообщества.
Главная идея именно возможность играть автономно, без интернета совсем. Также, это критично важно для сохранения истории, ведь, наши будущие внуки и правнуки потом смогут играть в эти игры. DOS-игры как раз самые живучие в этом плане, и всё благодаря проекту DosBox, который позволяет им работать даже на ARMах. Всё, что создавалось онлайн, веб, очень быстро умирает, если теряет аудиторию и прибыль, что ествественно вынуждает компанию-владельца гасить сервера (в The Matrix Online уже точно не поиграешь, лишь надежда на реверс-разработчиков, которые параллельно пилят альтернативный сервер, чтобы воскресить игру, но пока ещё очень и очень сыро). Можно лишь хранить исходники игры, что, пусть каждый сам соберёт себе сервер и запустит сие чудо. Куда проще запустить сборку автономного приложения в таком случае. По факту, игра будет ориентирована на сисадминов, которые готовы развернуть у себя игру на сервере, чтобы поиграть.
Ред.: Забыл упомянуть ситуацию с гибелью Adobe Flash. Хоть это и действительно очень убогая в плане безопасности и стабильности технология, но на её базе было построено большое количество крупных проектов, которые ныне полностью погибли (кроме тех единиц, кто успел перенести свою империю на HTML5).
Можно потом отдельно создать сетевую игру (это как раз в планах), чтобы пользователи могли играться между собой по интернету или в локалке, сообщество как раз очень жаждет эту возможность с самого 2010го года. Эндрю пытался создать режим сетевой игры, но он получился очень сырым и некачественным. В итоге, так не вышел из беты.
Что по поводу создания кода пользователями (не программистами C++), то уже давно в планах добавить скриптовую подсистему на lua, чтобы участники сообщества смогли создавать собственную логику различным объектам не вклиниваясь в код самой игры.
Немного про мой основной проект
При этом, мой основной проект является игровым движком для игр-платформеров, который предполагает создание всей игровой логики на lua. Сам движок реализует лишь базовые элементы физики, графики, аудио, управления, и конечно же механизм сцен (главное меню, карта мира, уровни, и др.), и т.п. Изначально тот проект планировался в качестве замены SMBX методом обратной разработки и с реализацией гибкой и универсальной концепции (моя основная идея проекта - создать движок, который позволял бы создавать новые игры с нуля, сохраняя некоторую похожесть на SMBX и обратную совместимость с наработками, какие были созданы для него). Однако, с тех пор как я создал TheXTech, я решил переориентировать проект на разработку новых проектов, без оглядки на прошлое. TheXTech для обратной совместимости (в т.ч. багов, на которых сообщество обожает строить уровни), а новый движок для новых проектв, созданных с нуля.
Теперь поставил в план, что как только допилю некоторые фичи и выпущу очередную стабильную версию набора, начну большую перестройку всего, потому что с 2014го года накопилось чрезвычайное количество костылей, которых я создал по неопытности, и хочу полностью от них избавиться. Ибо из-за них полно преград для развития.
P.S. Я ещё слыхал, что некто задумал выпустить порт "Super Mario Bros. X Java Edition", перенеся код игры на язык Java, однако, проект отменили. Подробностей не нашёл, только упоминание факта.
Ну, никто никому не запрещает реализовать задумку, если есть желание и широкие навыки и понимание современных веб-технологий, пожалуйста, решение имеет право на жизнь. :-)
Я сам был вебером, пока учился в универе, однако, мне веб сильно надоел тем, что было (на тот момент) полно неудобных инструментов разработки (это сейчас мы имеем JetBrains, VisualStudio Code, Atom, и кучу всевозможных фрэймворков и под JavaScript, и под PHP, т.п.), а также, по вебу у меня не было масштабных серьёзных проектов. Мой первый настоящий масштабный проект был начат именно на C++.
Почему я для себя выбрал C++?
Мне этот язык полюбился за его широкие возможности, и особенно за то, что он среди тех, которые умеют создавать монолитные, лёгкие и независимые исполняемые файлы (системные библиотеки не считаются). Я пробовал и смотрел много разных решений, но ни одно из них мне не понравилось, поскольку либо результат получался громоздским и тяжеловесным, либо зависел от кучи ещё более тяжеловесных бибилотек и сред исполнения, и т.п. И как раз мне подвернулось в универе изучить C++. Сначала я его не особо использовал, кроме как для решения лаборатоных работ и курсовых. Однако, к 2014 году у меня созрела идея создать проект, который вроде бы как хобби, но благодаря нему, я начал профессиональную карьеру программиста C++, и мне это сыграло на руку.
Через Emscripten легко собирается для работы в браузере через WebAssembly. Недостаток работы из браузера, это невозможность легко добавлять в игру свои ресурсы или эпизоды без полной пересборки игры с созданием пака ресурсов. Создать возможность "выгрузки" даёт лишь временный эффект, "выгруженные" данные будут летать в воздуже, а если их объём гигабайт? (Есть такие эпизоды тяжёлые). Веб-версия хороша в качестве демки, при этом, игра полноценная и её можно пройти целиком.
Очень интересное объяснение, действительно, я абсолютно не правильно сказал на счёт "интерпретируется". Благодарю за подробности! Такой комментарий вообще заслуживает быть полноценной статьёй. А так, я и подозревал, что код при исполнеии уже хранится в преобразованной форме концептуально больше похожий на Java или .NET, а вовсе не на bash и т.п., с которыми его сравнивали.
В Вики-разделе репозитория есть ссылки на сборки под разные платформы, в т.ч. и под винду (x86_64, ARM64 и x86).
У китайцев есть несколько подобных игр, и они даже вместо GDI запилили использование DirectX 9 там. Среди игр прошлого полно VB-игр от самих Microsoft (пакет Best Of Windows Entertainment Pack), там по большей части логические и карточные игры, если не считать Chip's Challenge, представляющую из себя бродилку с головоломками. При этом, они были созданы с более старыми версиями VB, по моей памяти, это где-то версия 3 (работало прямо на борту Windows 3.1).