I come again to ask for help, based on the post SFML Views setCenter vs rotation.
It was to be something absurdly simple, but it's becoming a nightmare!
What I want is simple: move a view to the upper left corner of the global window and rotate it, but the axis should be at 0,0 and not at the center of the view, like the default.
The problem is that "setCenter" moves the view and "move" changes the center of the view. That is, one cancels the other.
I read a lot, I asked a lot, but so far no one gave me the solution.
If you look at the documentation of the sf::View class (https://www.sfml-dev.org/tutorials/2.0/graphics-view.php):
"Unlike drawable entites such as sprites or shapes, whose positions
are defined by their top-left corner (and can be changed to any other
point), views are always manipulated by their center -- this is
simply more convenient. That's why the function to change the
position of a view is named setCenter, and not setPosition."
It states that a view's origin is at its center. So if you want to fit the view to the upper left corner just do it with:
view.setCenter(view.getWidth() / 2, view.getHeight() / 2);
If you would like to center the corner of the window in the center of the view just do:
view.setCenter(0,0);
Now if you rotate the view, it always rotates around its center, so position the view appropriately before rotating it.
Let me know if you have further questions and if it helped.
Does the following work for you?
// This should set the view to the upper left corner with a size of 500x300
view.reset(sf::FloatRect(250, 150, 500, 300));
// Now you can rotate the view around its center:
view.setRotation(90);
// Don't forget to apply the view.
window.setView(view);
Hope this helps.
Fortunately I received support from a SFML forum user and the solution is in post https://stackoverflow.com/a/50069393/5074998.
Related
I understand that I can already create a minimap by modifying a view object, as outlined here, but what I want instead is a small rectangle that will have a box or an arrow representing the player, and other colored boxes that represent enemies or various objects. Is there a better way to do this than simply create a Minimap object that calculates where each enemy is and translates that into a representational object (box, arrow.. etc) that then gets drawn to the screen?
This is a general question more than anything, so I'm not really expecting sample code, even though it would be much appreciated. I'm outlining a minimap class now and I'll upload it here soon.
Here is what I'm doing in my draw loop:
minimap.setCenter(player.getPosition());
minimap.setViewport(sf::FloatRect(0.75f, 0.75f, 0.25f, 0.25f));
//Bottom right corner of screen
window.setView(minimap);
window.draw(player);
window.setView(view); //Return to default view
With a call to minimap.zoom(10); when the view is initiated.
Actually, I tried this:
window.setView(minimap);
sf::CircleShape object;
object.setRadius(200);
object.setFillColor(sf::Color::Blue);
object.setPosition(player.getPosition());
window.draw(object);
object.setFillColor(sf::Color::Red);
for (auto& e : enemies)
{
object.setPosition(e->getPosition());
window.draw(object);
}
window.setView(view);
And that worked. Obviously it would benefit from being in its own class, so that the circle didn't have to be recreated each loop etc..
If there's a better way to do this, be sure to mention it.
Here's a screenshot of the Minimap (Bottom Right):
I'm trying to zoom the map to a specific bounding box. I know I have to make the call AFTER the layout of the map is ready, so that is not the problem. The camera only gets centered on the bounding box, but it doesn't zoom as closely as possible, it just stays at whatever zoom level was set previously. What am I missing? How do I make it zoom as well?
The class MapController in the API allows to move and animate the map. Maybe you can look the zoomToSpanmethod.
I want to use sf::View in SFML in order to change the position of the view, such that the player sprite is always in the center of the screen. Thus I want to write a function which allows me to input a set of coordinates and thus center the screen around those coordinates. In addition I want to be able to set a limit to this, such that when the player reaches the side of the map, that axis of the camera stops following the player, as it has reached a "limit". How do I achieve this?
Thank you in advance.
The function you need is called sf::RenderWindow::setView .
Do something like this:
sf::RenderWindow window (sf::VideoMode(800,600),"Test");
sf::View view ();
view.setCenter (/*Set Center here*/);
window.setView (view);
After I rotate a CCLayer, my boundingBox grows, instead of rotating. Perhaps to be expected.
My issue is, I'm relying on a user touch on this layer. When the layer is rotated as in the figure on the bottom of the attached image, the clickable area increases because I'm calling:
if(CGRectContainsPoint(clickableLayer.boundingBox, touchLocation))
This causes an issue because this bounding box after rotation is covering up other things that are also clickable.
How do I only perform an action if the actual layer is touched? I want something to happen when just the green box is clicked, not the boundingBox of the layer.
Thoughts?
You can use CGMutablePathRef to detect transparent part:
Refer my answer in this thread.
Information about How to create CGPath:Here
For more information, Click Here
This thread got me to my answer: http://www.cocos2d-iphone.org/forum/topic/272336
I have created my own class by extending QGraphicsItem and I want to make it so that when someone does a wheel even while over this item, it scales.
This way, i can have multiple items in a scene, and scale each of them in and out as I please.
The problem is, I want the item to scale under the mouse cursor, much like google maps does. That is, a move forward will keep panning the image and scaling it, so taht the area in the vicinity around my mouse pointer is always in view.
void ImagePixmapItem::wheelEvent ( QGraphicsSceneWheelEvent * event ){
update();
qreal factor = 1.2;
if (event->delta() < 0)
factor = 1.0 / factor;
scale(factor, factor);
scaleFactor *=factor;
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height());
}
This is the code I am using to do the scale. The problem is, it always seems to be scaling from the top left corner. Well, this is undesirable, beacuse if I scale in or out too much, eventually my area of interest around the mouse pointer has moved off the screen, and I have to either scroll manually or pan to the location, zoom, pan, etc, until i get to the desired level.
I tried to use the QGraphicsItem::setTransformOriginPoint, but no matter what values I put in there, it still seems to scale and such from the top left.
What can I add to that code I posted to get the desired effect?
I have achieved similar functionality in my Image-Manipulation application (scaling the view and having the area under my mouse stay in place and visible) but I scale the whole graphics-view not a specific item, so I don't know if this code can solve your problem.
Anyway, this is what I do in the constructor of my subclassed QGraphicsView (after I set the scene):
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
I also use the above functions, after each call to:
MyGraphicsView->setTransform(transform);
I'm not sure if this can help you, but I hope so.