The question is... what is the origin point for this circle?
I would expect the origin to be the center point of the circle -- ie, if you setPosition(100,100), the
center point of the circle would be at 100,100. But after a quick experiment, I found out that is not the case.
It turns out the origin of the circle is the upper-left corner of the bounding box for the circle. So setPosition(100,100) puts the
upper-left corner of the bounding rect at 100,100. This is a little clunky.
This means if all of your circles have the same X coordinate, they will align to the left, rather than on their center.
Fortunately, you can change this with the setOrigin function. By doing
shape.setOrigin(radius,radius);
you can move the origin to the center of the circle. After you do this... circles with the same X coord will align on their center.
To stack 2 circles on top of each other with no overlap, you'd need to space them out on the Y axis by the sum of their radii. Or, if you want a little overlap, you could put them a bit closer together.
Here's some changes to your program with all of this employed, and a few other cleanups. All my notes are commented:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
// convenience function to generate a white circle that is origined on the center
sf::CircleShape createSnowmanCircle(float radius)
{
sf::CircleShape shape(radius); // create the circle with the given radius
shape.setOrigin(radius,radius); // move the origin point to the center
shape.setFillColor(sf::Color::White); // make it white
return shape;
}
int main()
{
sf::RenderWindow window(sf::VideoMode(800,600), "Snowman :)");
// Move the creation of these circles outside the loop. They do not need to be created
// and destroyed each time the loop runs -- that is inefficient.
// Just create them once and keep them alive for the duration of the program
//
// Also... I changed this to an array. Any time you find yourself naming things
// foo1, foo2, foo3, etc... you're probably doing it wrong. Reconsider.
sf::CircleShape snowman[3] = {
createSnowmanCircle(50),
createSnowmanCircle(75),
createSnowmanCircle(100)
};
// Put the head at 200,100
snowman[0].setPosition(200,100);
// Build the upper and lower body in relation to the head:
for(int i = 1; i < 3; ++i)
{
sf::Vector2f pos = snowman[i-1].getPosition(); // get the previous portion's position
pos.y += snowman[i-1].getRadius(); // offset Y coord by previous portion's radius
pos.y += snowman[i ].getRadius(); // and this portion's radius
pos.y -= 20; // subtract a bit so the portions overlap a bit
snowman[i].setPosition(pos);
}
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed) window.close();
}
window.clear(sf::Color::Black);
for(auto& i : snowman) // draw all portions of the snowman in a loop
window.draw(i);
window.display();
}
return 0;
}
|