C++ SFML mouse movement - c++

I'm trying to detect mouse movement event and move it back to the middle of the screen using sf::RenderWindow pollEvent method and detect the event type sf::Event::MousePressed. The problem is when I'm detecing the mouse movment I need to move the mouse back to the middle of the screen and for that im using sf::Mouse::setPosition but I think (maybe I'm wrong) that function itself calling sf::Event::MouseMoved when it used, and im afraid it creates an infinite loop.
Exmaple of the way im doing that: (I know 0, 0 it's not the middle it is just and exmaple)
while (app.pollEvent(Event))
{
if(Event.type == sf::Event::MouseMoved)
{
sf::Mouse::setPosition(0 , 0));
}
}
Sorry for my bad english!
Thanks in advance!

Try using app.SetCursorPosition(x, y); instead.
Also, i would skip the check for events, since you will want the cursor to end in the middle at the end of each frame anyway.

Related

How to move an object with the mouse in c++?

I have a problem trying to create a script that moves an object with the mouse. The object is supposed to move when I hold the mouse button (which button does not really matter, so let us leave it there. I use SDL, so I have no trouble implementing this). I could of course have a variable moving = true when I start the move and then update position until moving = false, but this seems to be possibly messy. What I want is instead to be able to call a function grab_piece and then let the piece follow the mouse until I call the release function (I am creating a chess game, from where piece comes).
So the ideas, and relevant code this far: The idea is to assign a pointer to the mouse x and y positions and this would of course move the piece at the same time as the mouse. However, this seems tedious since shifting around pointers seems to be highly error prone. Is it possible to do this in a safe way? Otherwise I am open for other proposals.
Example code
SDL_Event e; //Event queue more or less
while (!quit) //Main loop, a little simplified
while (SDL_PollEvent( &e ) != 0){
if (e.type == SDL_QUIT){
quit = true;
}
if(e.type == SDL_MOUSEMOTION){
SDL_GetMouseState(&mouseX, &mouseY);
//do irrelevant things
} else if (e.type == SDL_MOUSEBUTTONDOWN){
//get mouse position
SDL_GetMouseState(&mouseX, &mouseY);
//get the board position
mouseBinPos = misc::screen2idx(mouseX, mouseY);
//location in the piece vector (hard coded)
currentPieceIdx = chess_board.getMappedPiece(mouseBinPos);
if (currentPieceIdx>=0){
chess_board.getPiece(currentPieceIdx)->grab_piece(mouseX, mouseY);
}
} else if ((e.type == SDL_MOUSEBUTTONUP)) {
//will release the piece and snap to nearest bin. Not implemented yet.
snap2bin(in args);
}
}
}
void Piece::grab_piece(int mouseX, int mouseY){
//Set pixel positions
setPixX(mouseX);
setPixY(mouseY);
}
All the variables are integers except the event queue, the board and the pieces which is a struct, user defined class and user defined class.
This is actually more a design issue, so I do not require executable code. More tips on how to do the design, if I should assign a pixX and pixY should be pointers to mouseX and mouseY and so on.
If anyone have an idea I would be happy. I have tried to describe the problem as good as possible, but if you have any questions please comment. I would describe further attempts if I had any, but I do not really know where to start. Also, this is not work, or school and I have been thinking about this for some days now and not found a good way to do it. So I am not just trying to get away easily.
Your ideas about pointers seem ill-defined, and are probably leading you down a path that isn't useful.
You need to use the same event loop as always when you're moving a piece. That means that MOUSEMOTION sometimes has to adjust the location of a piece, and sometimes not. That means that somehow you need to track the "moving a piece" state.
Here's the basic recipe:
On button down, save the idx of the piece that you've clicked on, maybe in a variable called "piece_being_dragged", or something. You also need to save the offset of mouse pointer to object center, so that the object doesn't recenter itself right on the pointer. You'll see what I mean when you get there.
On button up, zero the drag state variables, and handle the "done moving" logic.
On mousemotion, when piece_being_dragged is non-zero, look the piece up from the index, and set the new location based on the mouse pointer, and on the previously saved center offset.
Is this all a little messy? Yes. Is it necessary? Yes.

SFML flickering renderwindow?

I'm hoping someone can help me out, I'm using SFML 2.1 and when I draw my renderWindow it just keeps flickering, now I know SFML uses two buffers so i'm sure one is not getting drawn at all but I can't understand why.
Here is my loop
while(!quit)
{
rs.Canvas.pollEvent(gameEvent);
colour += 1;
rs.Update(colour);
if(gameEvent.type == sf::Event::Closed)
quit = true;
rs.Canvas.clear( sf::Color(colour,0,0) );
rs.Canvas.draw( sprite );
rs.Canvas.display();
if(colour >= 300)
quit = true;
}
the rs.Canvas has these set
Canvas.setVerticalSyncEnabled(true);
Canvas.setFramerateLimit(60);
Can anyone see why my renderWindow would flicker?
From the SFML 2.0 tutorial, under the section Controlling the framerate:
Never use both setVerticalSyncEnabled and setFramerateLimit at the same time! They would badly mix and make things worse.
http://www.sfml-dev.org/tutorials/2.0/window-window.php#controlling-the-framerate
In the comments of your post, you state that you were calling clear twice on the window. This would effectively treat your window as if it were single buffered. I understand that the effect of this could create some screen tearing, but on my end I am not getting a glaring flicker effect. Make sure to remove your a call to either setting the framerate or to using the vertical sync, just to be sure.
Basically I was calling
rs.Canvas.clear
twice. I removed the second call and everything then worked fine

SDL_GetMouseState doesn't work to get initial mouse position

Is there a way to get initial position of mouse in SDL 2.0 ? I try to get mouse coordinates by SDL_GetMouseState(&mouse_x,&mouse_y), however I get the result I expected only after using the function SDL_PollEvent() and also I can't see a value other than (0,0) if the mouse has not been moved at least once since begining of the program.Although I don't check SDL_MOUSEMOTION and connect SDL_GetMouseState() to it, I get mouse coordinates only when mouse is moved.So what's wrong? Or is SDL_GetMouseState() suitable to do so?
Edit : Why, Why is there no any answer?
Try calling SDL_PumpEvents() before SDL_GetMouseState().
The SDL updates the position of the mouse internally in SDL_PrivateSendMouseMotion, which is called by various mouse related functions in the same file.
These functions are called in the event loop processing function WIN_WindowProc in response to the mouse events dispatched by Windows.
Thus, if you do not move the mouse, no event is dispatched and the SDL does not know where the mouse is. The solution is to wait for a mouse event before requesting the position and to find a workaround until this event.
I know it's late, but just chipping in with a resolution I found.
If you get zero coordinates, call SDL_GetGlobalMouseState(&x, &y) then offset x and y by the window.x and window.y coordinates.

glutWarpPointer makes multiple calls to the glutPassiveMotionFunc call back

I'm implementing a FPS style mouse look to "fly" around my scene.
I've got the right camera rotation and everything, my only problem is that when I try to warp the mouse to the middle of the screen, it performs multiple calls to the glutPassiveMotionFunc call back. So instead of teleporting the mouse, its moving it there over a few movements. These movements get processed and move the camera back to the original position.
How do I check that the mouse was actually moved and it was not triggered by the glutWarpPointer function.
I've tried to not process a movements if the pointer is in the middle of the screen but this doesn't help.
I want my program to run on Linux and Windows so I cannot use OS specific functions.
I wouldn't call this a great solution, but it should work:
bool isWarpingPointer = false;
void MyPassiveMovementCallback()
{
if (isWarpingPointer)
{
return;
}
//proceed normally
}
//elsewhere
isWarpingPointer = true;
glutWarpPointer();
isWarpingPointer = false;

C++/SFML Positioning Sprite Issue

I have a class named 'Player' where I handle movements, level ups etc in a game I am attempting to create. In the main loop in the main source file I have the keyboard events (Left/Right.) I want the movements to be able to know when your character is venturing past where it's allowed. To answer the problem I placed two if statements.
I am only having issues with this if statement:
else if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Right)) {
if (Player.getX() > 1279) {
Player.move(640,0);
}
Player.move(0.1,0);
}
No compiling issues. The only issue is, unlike the other if statement, this one doesn't return the sprite to the wanted position. If I lower the if statement to something like 1000, the sprite disappears from the screen.
Any help appreciated.
Player.move(640,0);
Your moving your player 640 pixel on the X-axis. This means that when the player gets to x > 1279, i.e. at the right end of your world, you move the player further to the right. So it disappears.
You might want to use setPosition instead of move here, or simply don't move the player, etc...