How do you make a clickable sprite in SFML? - c++

I've been looking through the SFML documentation for making clickable sprites, but so far I haven't found anything.
Do you guys think you could help me out?

There is nothing like sf::ClickableSprite in SFML so far, and probably there will never be. (Current list of classes in SFML)
However, you can obtain this behavior with the sf::Sprite object and the events. The idea is simple - as soon as you get the sf::Mouse::isButtonPressed(sf::Mouse::Left) event, check if the mouse is in the sprite. If it is, perform the action. You can perform another action (maybe undo) when button is released.
There is sf::Sprite::getGlobalBounds() function which returns you the position and the dimensions of the sprite. There's also sf::Mouse::getPosition() function, which returns the current position of the mouse. You can use sprite.getGlobalBounds().contains(mousePos) to check whether the mouse is in the sprite.
If you're using views, you'll need to add the view's position to sf::Mouse::getPosition(window), since it gets the mouse position relative to window coordinates.
(thanks to Chaosed0 for additional notes.)

Related

how can i draw a sprite by left clicking?

i've tried to make a project, but i can't draw a sprite as i want. I mean that everything works when i just draw a sprite, but it stop working when i am trying to draw the sprite by clicking left mouse button. There's code i tried:
if(zdarzenie.type == Event::MouseButtonPressed && zdarzenie.mouseButton.button == Mouse::Left)
{
pocisk.setPosition(10, 10);
oknoAplikacji.draw(pocisk);
}
Btw, I am writing in Polish as if it would change something.
And yes, i have everything good besides that.
(and i am using 2.4.1 version of SFML)
I don't know what you are doing now because you didn't provide enough of your code and I actually don't understand your if statement but, it can just be :
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sprite.setPosition(sf::Mouse::getPosition());
renderTarget.draw(sprite);
}
By the way I strongly suggest that you do not use the draw function here but organize your code to have a draw method called in a render loop, because depending on where your code is in your program, the sprite could be drawn for only one frame and then erased since it's not updated.
From what I understand in your code in Polish, you have the right code to do what you want, but the problem comes from the fact that you draw the sprite only once.
The draw method is called every frame and it will erase everything on screen and then redraw them. Doing it only once, like in your code, will only draw it a single time then delete it the very next frame.
At that point multiple solution can be used. If its a GameObject clicking can activate the object to then draw it or a simple bool could be used has a switch in your draw to make it appear.

correct way of updating a QGraphicsView from QGraphicsScene

I have implemented a QGraphicsScene to contain instances of QGraphicsItem of a few different classes implemented by me. What I still don't understand is how the QGraphicsView associated with this scene is updated.
When I call addItem(QGraphicsItem) the scene seems to redraw displaying the newly added items.
When I change properties of my QGraphicsItem instances (e.g. calling setVisible(bool)) it seems that the view is not updated automatically.
I currently call QGraphicsScene::update() without any arguments to draw the new state. this works in most cases, however in some of them it fails ( QGraphicsItem's paint() method is not called. I set a breakpoint there but whether it is reached or not depends on the zoom level in the QGraphicsView. I have to zoom out to a certain level for it to get called again).
It doesn't work when I pass the bounding box of the changed item (scene coordinates) to QGraphicsScene::update(QRect). I can't see objects changing.
Can anybody give me a hint what is the correct way of implementing this? How do I notify the view correctly of changes in certain areas, what does the behaviour depend on. I think there's something wrong with my assumptions about coordinate systems. Thanks a lot for your explanations.

how to get Qt Mouse Position all the time

So I have been struggling with this question for quite some time. I have tried many things, none of them seem to work.
So, I want to make a game in Qt, and one of the things I need is that player(QRectItem for now) rotate always to the mouse position. I just need to get readings of that position all the time, so not when i click or when I drag, all the time.
How can I do that?
I set
this->setMouseTracking(true);
on a class that inherits for QGraphicsView class, also I have set focus on it.
Dont know if the problem is with overriding functions(dont know which one to override) or with focus.
void Game::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << QCursor::pos();
}
Did this but it does not work at all.
Btw, I am noob it Qt, this is my first project.
Thanks in advance! :)
P.S.
I have really done research, but if I have somehow missed topic with same or similar question that can solve this problem, just paste it and accept my apologies. :)
EDITED
You can install an event filter on your QApplication object, examine the received events for mouse movement events, convert the resulting position into your scene, and then use it to orient your rectangle.
Look at QObject::installEventFilter. Event filters are pretty easy to use. When a mouse event is received by an object, its coordinates are in that object's coordinate space, so you'll need to convert from that to your graphics scene coordinates. There will probably be several conversions to get that because you'll need to map the received position to your QGraphicsView using mapTo and then map the result of that to your scene using QGraphicsView::mapToScene.
This should get you pretty close. Let me know if you need more help.

MapView.zoomToBoundingBox() not zooming

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.

Move mouse without glutWarpPointer

I'm attempting to move the camera via gluLookAt in my OpenGL app similar to how the camera moves in a FPS game. It works, however, I would like to center the mouse after moving it, to disallow the mouse from ever reaching the edge of the screen. After doing some research, I found glutWarpPointer is a viable option, however, I get the sense that professional game developers only utilize the basic OpenGL commands, instead of something like glutWarpPointer, or glutSolidCube, or glutSolidSphere. Am I correct in assuming this?
In my WndProc function, I set the look for my gluLookAt under the WM_MOUSEMOVE message in my switch block. I also realize that SendInput would achieve what I want, but from my understanding SendInput would trigger another WM_MOUSEMOVE when the cursor goes to the middle of the screen, essentially reversing my original movement of the mouse, and not moving the camera's look at all.
Any ideas?
Edit: I don't think there exists a function that does not call a WM_MOUSEMOVE message. I think the proper route is to create a flag that determines whether the WM_MOUSEMOVE was invoked by a SetCursorPos, and if it was, do not change the camera's look.
Use SetCursorPos to relocate the mouse cursor if you're on Windows.