Недавно я начал работать над игрой 2D Tower Defense в SFML, и я собираюсь добавить несколько визуальных уловок и других функций, возникающих при наведении курсора мыши на определенные объекты (элементы меню, враги и т. Д.). Для этого мне нужно постоянно проверять, находится ли мышь над таким объектом, многие из которых могут перемещаться и иметь различные размеры и формы. Кто-нибудь знает быстрый и эффективный способ сделать это?
Метод грубой силы для решения этой проблемы заключается в простой проверке каждого объекта в игровом мире, пересекает ли позиция мыши их ограничивающий прямоугольник. Моя игра довольно проста, поэтому обычно было бы излишне оптимизировать ее здесь, но я также намереваюсь внедрить более сложные компоненты в других местах, и я хочу убедиться, что программа тратит как можно меньше ресурсов на графику.
Кроме того, я прочитал ряд различных решений, которые могут работать, например, отслеживание объектов в сетке / квадродереве и проверка только области, где находится мышь. Было также решение с помощью радиопередачи, но, насколько мне известно, в самом SFML его нет. Поскольку я предполагаю, что я не единственный, кто должен был это решить, я надеюсь, что есть какое-то решения для этого, что я пропустил. Есть идеи?
Заранее спасибо за помощь!
Я также пишу TD игру прямо сейчас, я начал ее в этом месяце, также используя SFML. это было также моей проблемой в прошлый день, и придумал эту идею. Я не знаю, является ли это стандартным способом сделать это, но это лучше, чем моя первая попытка протестировать все игровые объекты. и в надежде придумать лучшее решение, лол
у меня есть 3 области моего игрового окна, а именно:
КАРТА — место, где карта, враг и где вы строите башню
МАГАЗИН — где вы покупаете башни
ИНФОРМАЦИЯ — если вы нажмете врага или башню или что-то, информация появится в этой области
Затем я написал класс Boundary, который определяет границу области.
Пример:
Boundary shopBoundary;
Boundary mapBoundary;
Boundary infoBoundary;
Я также могу добавить еще одну Границу, если я хочу добавить еще одну область (может быть, область, где я могу нажать специальные бафы для башни?), тогда я просто сделаю это
Boundary buffsBoundary;
так вот как я делаю трюк
я создал перечисление, которое определяет местоположение мыши
enum AREAS { NONE, SHOP, MAP, INFO }
Areas mLoc = NONE;
я создал структуру, которая хранит ОБЛАСТИ, которые будут использоваться для именования этой области, и граничный объект для границы этой области.
struct _Boundary
{
Areas area;
Boundary boundary;
bool isMouseInside(const sf::Vector2i v) const
{
return boundary.isMouseInside(v);
}
}
std::vector<_Boundary> boundaries; // now put all your boundary to a container
теперь каждый раз, когда мышь двигается, мне нужно будет только проверить, где мышь использует только 3 итерации (для карты, магазина и информации)
if ( mouse moved )
{
for ( int a = 0; a < boundaries.size(); a++ )
{
if ( boundaries[a].isMouseInside(mousePos) )
{
mLoc = boundaries[a].area;
break;
}
}
}
с помощью этой петли я смогу отследить, куда бы ни направлялась мышь, проверив mLoc
из-за необходимости знать местоположение, когда происходит нажатие, это сужает игровые объекты, которые необходимо проверить, (если местоположение мыши находится в зоне магазина, а затем при нажатии происходит проверка только игровых объектов в этой области)
if ( mouse button pressed )
{
if ( click mouse left )
{
if ( mLoc == SHOP )
{
// the click has been occured in shop
// check the game objects relative to shop
}
else if ( mLoc == MAP )
{
// the click has been occured in map
// check the game objects relative to map
}
else if ( mLoc == INFO )
{
// the click has been occured in information
// check game objects relative to that area
}
}
}
Других решений пока нет …