SFML community forums

Help => Graphics => Topic started by: smurf on December 05, 2023, 07:17:13 am

Title: View, Viewports and getting mouse location
Post by: smurf on December 05, 2023, 07:17:13 am
The common recommendation for making games is to have separate Update() and Render() methods.

In Update(), I get all inputs (including mouse x y coordinates) and do all updates.

Problem is in the Render() method, I end up changing the view/viewport a few times because there is a HUD and game area at least. It means that the mouse coordinates (specifically the world mapped version of them) I grabbed in the Update() function are not correct by the time the Render() function changes the view stuff around.

So now it seems like I'm forced to put some of my Update() code inside the Render() function because this is where I will finally have the right inputs.

I really don't want to mix the update and the render logic like this though. What am I missing?
Title: Re: View, Viewports and getting mouse location
Post by: eXpl0it3r on December 05, 2023, 11:25:30 am
This more a question of state management. You inputs don't change within the frame, so Update() fetches the current input states and stores that information, either directly as input states or derives the necessary information for the view change. That information is then read in Render() to adjust the view.
So yes, it's not a completely isolated process, but you'll have to share some state information between Update() and Render()
Title: Re: View, Viewports and getting mouse location
Post by: smurf on December 05, 2023, 02:49:59 pm
Thanks!
I'm doing that now - the input mouse coordinates are globally accessible in the player object.
No problem adjusting the views based on these coordinates and even calling MapPixelToCoords() a few times during Render, to make the right things happen visually.

The issue is when I want to actually do something, like fire a bullet, which is definitely Update and not Render logic. But I cannot fire the bullet until I'm halfway through the Render function because this is when I've got the right view set up for calling MapPixelToCoords() and actually firing the bullet in the proper direction ad the proper angle.

Editing to give an example

During the Update() method, I grab the mouse coords. Lets say its 243, 150. This is global state accessible from anywhere no problem so far.

Mouse button is clicked, so, still in the Update method, I fire a bullet toward 243,150 coordinates.

Rest of Update method completes.

Now Render method starts
Change View/Viewport to render the Hud. Now that same mouse coord maps to -543, 280 world coordintes.
Change View/Viewport to render the game area. Now that same mouse coord maps to 20943,10080 world coordintes. I should have fired the bullet towards 20943,10080 but could not have known that until this point in the Render method!

Title: Re: View, Viewports and getting mouse location
Post by: eXpl0it3r on December 06, 2023, 10:14:18 am
During the update phase you should be able adjust the necessary views and thus, you should also be able to convert to mouse position to world coordinates, for both UI and game "world". I guess in that case, you then wouldn't even need to adjust the view during the render phase.
Title: Re: View, Viewports and getting mouse location
Post by: smurf on December 06, 2023, 06:56:53 pm
I must be missing something.

From what I see, you can't convert screen coords to world coords until you set the View to a Window/RenderTarget. So I actually have to do graphics work in my Update function. Something like this:


Update Method:
RenderWindow.SetView(new View( .. world view / viewport details) );
Vector2i mousecoordsWorld = RenderWindow.MapPixelToCoords(getMouseCoords());
// do world updates such as shoot bullets

RenderWindow.SetView(new View( .. HUD view / viewport details) );
Vector2i mousecoordsHud = RenderWindow.MapPixelToCoords(getMouseCoords());
// do hud updates such as updating button states and detecting clicks...
 


Render Method:
RenderWindow.SetView(new View( .. world view / viewport details) );
// render world

RenderWindow.SetView(new View( .. HUD view / viewport details) );
// render Hud
 


And I don't see how I can avoid adjusting the view in the Render phase because the Update phase has left it in the wrong view state.

On top of it, the Update method is actually called several times for every Render method (accurate physics sometimes requires this), so it ends up being a lot of view switching. Hopefully its fast at least.
Title: Re: View, Viewports and getting mouse location
Post by: kojack on December 07, 2023, 09:07:36 am
You don't need to use setView, you can use the second form of mapPixelToCoords that takes a view as the second parameter. That way nothing in the render window is changed by the update.

Title: Re: View, Viewports and getting mouse location
Post by: eXpl0it3r on December 07, 2023, 10:41:09 am
As kojack said, you can pass the view as second parameter: https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1RenderTarget.php#a2d3e9d7c4a1f5ea7e52b06f53e3011f9