SFML community forums
Help => Graphics => Topic started by: GarrickW on June 14, 2011, 07:10:23 am
-
So I've managed to get my window detecting mouse input, and MouseMove.Y always properly returns coordinates, but MouseMove.X consistently returns 0, no matter where on the screen I click.
I am trying to click on a circle to reset it's color. Here are the relevant parts of code:
//This checks for mouse input.
else if(Event.Type == sf::Event::MouseButtonPressed)
{
for(int i = 0; i < (*GameBoard).theBoard.size(); ++i)
{
bool colliding = (*GameBoard).theBoard[i].CollidePoint(Event.MouseMove.X, Event.MouseMove.Y);
if(colliding)
{
(*GameBoard).theBoard[i].m_Circle.SetColor(sf::Color(20, 20, 200));
break;
}
}
}
And this:
bool Space::CollidePoint(int x, int y)
{
float xDist = abs(x - (m_X + m_radius));
float yDist = abs(y - (m_Y + m_radius));
float distance = sqrt(pow(xDist, 2) + pow(yDist, 2));
cout << "\nClick detected at: " << x << ", " << y << endl;
cout << "Center is at " << (m_X + m_radius) << ", " << (m_Y + m_radius) << endl;
cout << "Distance is: " << distance << "\n";
if(distance <= m_radius)
{
return true;
}
else
{
return false;
}
}
Now, it's possible that MouseMove.X is returning the proper value and I'm just not sending it properly to cout, but I doubt this is the issue, since none of the circles I click on want to respond to me. Anyone know what I'm doing wrong? I'm quite new to C++, coming from a background in Python; I fully expect to have made some simple mistake somewhere.
-
Since it's a mouse button event and not a mouse move event, try Event.MouseButton.X and Event.MouseButton.Y
EDIT:
Also, using pow to square stuff should be a mortal sin.
pow(x,2) <- bad
(x*x) <- good
using pow for this is like driving a small nail with a sledgehammer.
EDIT 2:
Also, another optimization tip for your future reference:
You can avoid the sqrt call for this kind of collision if you square the radius. Remember that the actual theorum is a*a + b*b = c*c. Note that theorum only has a sqrt if you try to solve for c, which is unnecessary.
// assuming x and y are the distance between the point and the circle center
// assuming r is the radius of the circle.
// bad:
return sqrt( (x*x) + (y*y) ) <= r;
// better:
return (x*x) + (y*y) <= (r*r);
-
Thanks for the tips! I changed MouseMove to MouseButton and it worked - the tutorial was rather confusing on that aspect, and I had the impression that MouseButton didn't have X and Y values.
I've also implemented your optimizations. A question regarding things like sqrt(x) and pow(x) - do they have additional overhead costs compared to x*x? Or are there other potentials for problems?
Also, small question - what is the use of the Shape.SetColor() method? I tried using SetColor(sf::Color(255, 255, 255)) on a circle that was of the color sf::Color(20, 20, 20), and basically nothing happened (using other colors, I notice the color changed only very slightly). I managed to work around by simply creating a new circle, but I'm sure that's not the best option.
-
the tutorial was rather confusing on that aspect, and I had the impression that MouseButton didn't have X and Y values
It was a bug in the tutorial :)
A question regarding things like sqrt(x) and pow(x) - do they have additional overhead costs compared to x*x? Or are there other potentials for problems?
sqrt is an expensive operation.
pow is expensive too, because it works with floating-point values/exponents; it's not as simple as multiplying x with itself an integer amount of times.
Also, small question - what is the use of the Shape.SetColor() method? I tried using SetColor(sf::Color(255, 255, 255)) on a circle that was of the color sf::Color(20, 20, 20), and basically nothing happened (using other colors, I notice the color changed only very slightly). I managed to work around by simply creating a new circle, but I'm sure that's not the best option.
SetColor changes the global color of the object. The global color is modulated (multiplied) with the object, so using (255, 255, 255) does nothing (white * color = color).
-
Ah, that clarifies things quite a bit. Thanks!