@fedoraman

Как грамотно обработать нажатия в самописном игровом движке?

В общем, понадобилось извратиться и написать на C++ движок для 2D-игрушки. В движке надобно обрабатывать нажатия мыши, определяя, в хитбокс какого виджета попало нажатие (виджет - что угодно, что можно нарисовать: кнопка, юнит на экране, етц.), и каким-либо образом вызывая обработчик. Сейчас загвоздка в том, чтобы придумать, как и в каком виде правильнее присобачить обработчики, чтобы это выглядело гламурно и не приводило к лишней писанине или рефакторингу, когда написал много кода и увидел, что всё фигня и надо по новой.

В данный момент у меня в голове крутится два варианта:
  • Сделать в базовом классе чистые виртуальные методы onClick, onMouseIn, етц. и реализовывать их в производных классах. Недостаток: для кнопок, например, придётся на каждое поведение наследовать отдельный класс. Это точно нормально? Я так делал, когда в лихой юности писал двухкнопочные приложения на Delphi, но не уверен, что это не приведёт к печальным последствиям в виде кода-спагетти ближе к сроку сдачи.
  • Передавать в виджет обработчик при его создании. Недостаток: непонятно, как это реализовать, т.к. нужно будет либо передать какой-то метод класса, что не особо осуществимо, либо аналогичную функцию, принимающую указатель на обрабатываемый виджет, что, кажется, не совсем ООП-шно.


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

Короче, нужен волшебный в своей простоте паттерн или просто похлопывание по плечу от человека с опытом, объясняющего, почему я неправ и написать один из этих двух вариантов будет хорошо. Ещё раз, пишу на C++.
  • Вопрос задан
  • 132 просмотра
Пригласить эксперта
Ответы на вопрос 1
dollar
@dollar
Делай добро и бросай его в воду.
При клике по экрану игры происходит поиск всех элементов, которые могут принимать клики. Если клик попал во что-то, то происходит поиск всех дочерних элементов, которые могут принимать клики. И так далее, пока не клик не попадет к конкретную кнопку. Это общая схема. Как вы это сделаете - дело вкуса. Здесь важно не столько ООП, то есть наследование классов, сколько реализация иерархии элементов самого интерфейса (GUI или HUD), то есть наследование объектов. В самих объектах нужны ссылки на дочерние и родительские элементы, примерно как в DOM браузера.

Далее нюансы. Например, элемент может иметь одновременно собственный обработчик и дочерние элементы. Можно сделать так, что если есть собственный обработчик, то дочерние - игнорируются. Либо можно сделать так, что если клик не попал по дочерним, то вызывается собственный обработчик. Всё имеет плюсы и минусы. Опять же - как удобно, так и делайте.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы