• Препарируем движок MagicEngine

    Posted on by admin

    Чтоже такое MagicEngine который я использую в своей разработке.

    Некоторое время назад, лет 5-6 когда я только начинал программировать я начал писать этот движок. Он эволюционировал по следующей схеме: DOS(защищенный режим)->WinAPI->SDL->GLUT->самопальная система для создания окон(OpenGL)->Кросплатформенный с использованием glfw и OpenGL . Изначально движок разрабатывался как 2Д что сохранено по сей день, его цель — легкое создание 2Д игр.


  • Монстры

    Posted on by admin

    Добрался я до реализации монстров в своем маленьком проектике. Задача простая. Я хочу сделать чтобы небыло уровней, тоесть игрок имеет непрерывный геймплей который постепенно изменяется. При этом возникает сложность с тем что нельзя сделать заранее заданную карту по принципу «тут поставим 20 мобов таких, тут 10 таких, тут бос левел закончен».  Игра может длиться  неограниченное время и должна постепенно усложняться. Значит надо чтобы мобы появлялись динамически.

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

    Значит надо делать чтото другое.

    Покачто мысль дошла только до эмиттера мобов.

    Т.е. создаем неки невидимый объект за пределами экрана. На каждый кадр он получает управление и решает — надоли создавать нового монстра. У него должны быть ограничения — неможет быть более N одинаковых монстров одновременно, вероятность появления моба M и другие условия, которыми можно управлять генерацией мобов.

    Но чтоже такое сам моб. Моб — это самостоятельный объект незнанющий ничего об эмиттере. После его создания он должен двигаться по заранее заданному алгоритму (например по направлению к игроку) и выполнять указанные действия. Он должен понимать ситуацию попадания в него.

    Об попаданиях позже, за сим все. Может  у кого есть более интересные идеи по реализации монстров в аркаде?


  • Реализация стрельбы в стуктуре сигнал-слот

    Posted on by admin

    Вот и добрался я до реализации стрельбы в своей маленькой игрушке.

    Взаимодействие различных объектов, в игровом движке MagicEngine, построено на сигналах. Каждый объект имеет некоторые слоты, которые могут получать параметры и сигналы.

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

    Система сигналов построена так, что сцены получают сигналы верхнего уровня — от видео драйвера и перенаправляют их объектам сцены.

    В такой схеме сцена обязана получать сигнал нажатия мышькой чтобы уметь правильно выделить объект, на который было произведено нажатие мышкой. При нахождении такого объекта он становится активным и ему посылаются все остальные сигналы (движение мышки, нажатие кнопок) кроме сигнала нажатия кнопки мыши, потомучто при нажатии мыши мы могли хотеть сделать чтото другое, например нажать другую кнопку меню. Фактически это означает что объект «корабль» не может получить сигнал нажатия мыши и произвести выстрел на прямую. Поэтому для реализации стрельбы был использован промежуточный сигнал, что, кстати, очень удобно. Теперь появилась возможность посылать этот сигнал нескольким объектам. Конечно это осложняет задачу hot-seat, но она решается с привязыванием сигналов к игроку.

    Итак, реализация стрельбы в архитектуре сигнал-слот.

    Имеется два объекта: Hero(это кораблик которым управляет игрок) и Ammo( это собственно говоря и есть сам выстрел, картинка выстрела).

    По логике вещей при выстреле игрока объект Hero должен создать новый объект типа Ammo, который должен привязаться к сигналу нового кадра, и забыть про него. Дальнейшие действия выпущенного снаряда решаются самим объектом Ammo, к примеру именно он будет определять столкнулся ли он с врагом и посылать врагу сигнал hit(попадание).

    Для реализации этого были сделаны следующее:

    • Был перегружен объект scene (сцена) чтобы получить контроль над сигналом нажатия мышки (mouse_press). При получении этого сигнала посылается сигнал shoot(выстрел) с которым связан слот on_shoot(при выстреле) объекта Hero.
    • При получении сигнала shoot объект Hero его обрабатывает (к примеру смотрит — а остыло ли оружие, есть ли еще заряды) и создает (или не создает) новый объект типа Ammo который сам связывается с сигналом нового кадра.
    • Для того, чтобы можно было стрелять несколько раз пока один снаряд еще летит — было решено завести счетчик выстрелов и создавать объекты по этому счетчику, можно конечно было воспользоваться концепцией 300 пуль, но пока что в этом нет особой необходимости, да и сами сцены неумеют скрывать неиспользуемые объекты)


  • Блокирование спамеров

    Posted on by admin

    В целях блокирования спамеров пришлось покопаться в настройках WordPress, заодно и подтюнил слегка.

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

    Заодно поигрался с темкой и подключил древовидные каменты, теперь можно отвечать на коментарии, как мне этого не хватало)


  • Генерация классов

    Posted on by admin

    Последовал совету Hyborg и написал генератор классов из xml в cpp с помощью xslt.

    Впринципе xslt оказался достаточно простым для человека который ни разу с ним не работал.

    пример xml  описания

    результирующий файл

    сам конвертер

    Приветствуются мысли о том, как можно это сделать проще 🙂


  • Perfomance Counters

    Posted on by admin

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

    Но сейчас пойдет речь не об общем варианте счетчика, а об одном специализированном: счетчик  FPS.

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

    На данный момент думаю реализовать так: считать время за которое отрисуется  150 кадров. При скорости в 30 фпс это дает обновление  раз в 5 секунд.

    Еще была идея считать время отрисовки 1 кадра, но по моему тут будет слишком большой оверхед,  хотя такой счетчик былбы удобен, если вести статистику по последним N кадрам — для определения моментов, в которые произошло «замирание».

    Итак счетчик FPS:

    Будет содержать 1 параметр: кол-во кадров для которых надо рассчитать время и 1 слот — новый кадр. Строить его надо явно на основе уже имеющегося scorefield, который переименовать в counter )


  • Ближайшие планы

    Posted on by admin

    Итак, решил составить список ближайших планов по разработке.

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

    Что должно в нее войти: кораблик, который умеет стрелять по нажатию мышки и двигаться в разные стороны. Монстров добавим в следующей версии.

    На данный момент наиболее интересно именно получить что-то, пусть и не особенно играбельное)

    Что для этого осталось сделать:

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

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


  • Мысли об удобстве

    Posted on by admin

    Возникала мысль создать набор макросов для повышения удобства написания кода и выдирания параметров.

    Дело в том, что каждый объект имеет некоторый формат данных, которые он умеет читать из конфигурационных файлов. например картинка умеет читать название загрузчика и имя файла который надо загрузить, текстовый объект умеет читать цвет текста, шрифт, его размер и сам текст. На данный момент это реализовано прямым кодом. Есть у объекта некий метод load который вычитывает все эти параметры. Минусы очевидны — нет простого способа получить список параметров для документации и каждый раз надо писать похожий код.

    Надо сделать чтото типа макросов: REGISTER_CONFIG_VARIABLE(type, name, optional, default value). Как вариант сделать это в отдельном классе, который вместить во все классы объектов, чтобы небыло лишнего внешнего интерфейса и далее писать:

    CREATE_CONFIG_PARSER(TextObject)

    REGISTER_CONFIG_VARIABLE(type, name, optional, default value)

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


  • Для чего все это

    Posted on by admin

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