-
I'm trying to make right-click tooltip menus for my game and they work just fine, but the way it's implemented seems a bit messy.
// Right click inside of a rect:
if(sf::Mouse::isButtonPressed(sf::Mouse::Right)
&& sf::Mouse::getPosition(Screen).x >= statBox.getPosition().x
&& sf::Mouse::getPosition(Screen).x <= statBox.getPosition().x + statBox.getSize().x
&& sf::Mouse::getPosition(Screen).y >= statBox.getPosition().y
&& sf::Mouse::getPosition(Screen).y <= statBox.getPosition().y + statBox.getSize().y) {
ttBox.setPosition(sf::Vector2f(sf::Mouse::getPosition(Screen)));
ttTitle.setPosition(sf::Vector2f(ttBox.getPosition().x + 10.f, ttBox.getPosition().y + -.5f));
ttTitle.setString("The Tooltip");
drawTooltip = true;
}
Like I said this works but it isn't ideal. Isn't there a way to do "if object is hovered" or "if object is clicked"? My implementation just specifies a position on the screen equal to the space within corners of the box - it doesn't specifically state that you're clicking in the box if you understand what I'm saying? Sorry if this is confusing, I'll try to explain better if you don't understand.
Thanks in advance guys!
-
You can get or create the sf::Rect of the stat thingy and call rect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(window)))
-
How about wrapping sf::Mouse inside a mouse class.
#include "SFML/Window.hpp"
class MyMouse{
public:
MyMouse(const sf::Window& _window, int mouse_width, int mouse_height) :
window(_window)
{
//initialize box
mouse_box.width = mouse_width;
mouse_box.height = mouse_height;
}
sf::Vector2i getPosition(const sf::Window &relativeTo){
return sf::Mouse::getPosition(relativeTo);
}
//WRAP THE REST OF sf::Mouse FUNCTIONS
bool intersects(sf::FloatRect& other_box){
//update before comparing
mouse_box.left = sf::Mouse::getPosition(window).x;
mouse_box.top = sf::Mouse::getPosition(window).y;
return mouse_box.intersects(other_box);
}
private:
const sf::Window& window;
sf::FloatRect mouse_box;
};
You can use it like:
MyMouse mouse(window, 16, 16); //initialize
mouse.intersects( statBox.getGlobalBounds() ); //assuming statBox is a sf::Sprite
-
Personally I wouldn't do that. It's not the mouse's job to check for collision and doublicating parts of the sf::Mouse interface doesn't seem like the right way to go.
Usually you'll anyways have some logic part, that holds the 'collision' area. At best it will be stored directly as sf::Rect and thus you'll get instantly access to the contains() function of the rects.
-
I knew there'd be an easier way to do it, thanks for the help. I should be good from here.
-
You can get or create the sf::Rect of the stat thingy and call rect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(window)))
Actually I just tried this and I can't get it to work properly.
// Create tooltip:
sf::RectangleShape ttBox;
ttBox.setSize(120.f, 120.f);
ttBox.setFillColor(sf::Color(0, 0, 0, 175));
sf::FloatRect ttBoxRect(ttBox.getPosition().x, ttBox.getPosition().y, ttBox.getSize().x, ttBox.getSize().y);
// ...
if(sf::Mouse::isButtonPressed(sf::Mouse::Right)
&& ttBoxRect.contains(static_cast<sf::FloatRect>(sf::Mouse::getPosition(Screen)))) {
ttBox.setPosition(sf::Vector2f(sf::Mouse::getPosition(Screen)));
ttTitle.setPosition(sf::Vector2f(ttBox.getPosition().x + 10.f, ttBox.getPosition().y + -.5f));
ttTitle.setString("The Tooltip");
drawTooltip = true;
}
error: no matching function for call to 'sf::Rect<float>::Rect(sf::Vector2i)'|
-
Well you then didn't understand what static_cast<sf::FloatRect> stand for.
There's no implicit conversation from sf::IntRect to sf::FloatRect or the other way around. Neither does sf::FloatRect have a constructor that takes a sf::IntRect. So to get from a sf::IntRect to a sf::FloatRect one has to cast it, either explicitly with static_cast<T> or implicitly but component-wise (sf::FloatRect(intRect.x, intRect.y)).
So on line 11 you'll have to change the setPosition() code.
-
He just wrote what you told him to write, ie. a cast from Vector2i to FloatRect ;)
But the correct way to do it is not a cast, you must call window.mapPixelToCoord, so that it wtill works if you have a custom view applied.
-
He just wrote what you told him to write, ie. a cast from Vector2i to FloatRect ;)
Never mind my post above then... ::)
-
Am I being simple here by not seeing that Window/RenderWindow function in the documentation listings?..
-
If you use an old SFML 2, it is convertCoords.
-
Ah yes, I have that function. I should probably update SFML.
So I got it working correctly and it's certainly much cleaner than what I originally had. Do I really need to make an sf::FloatRect to pair with any sf::RectangleShape I make if I want it to be clickable though? Would you suggest I make a Clickable class, with sf::Rectangle, sf::FloatRect, sf::Color, sizes etc, so I can use the mouseclick check that I've gained from this thread with it?
Thanks for your help guys.
-
You can get the bounding rectangle of your shape with the getGlobalBounds method.