Sign in to follow this  

Simulation (game) loop in WPF

This topic is 2049 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I am working on a simulation software for basic physics using WPF. In my software I want to be able to show a simulation based on the input the user has provided (some shapes moving around). I need to implement some kind of simulation (game) loop but I need help figuring out how to do this properly. These are my requirements:[list]
[*]Run with the same speed independently of the hardware.
[*]Multiple runs of the simulation, given the same input, shall yield the same visual output.
[*]Ability to start, stop, pause and resume at any time.
[/list]
Not required but would be great:[list]
[*]Adjustable simulation speed: 0.5x real-time, 2x real-time, 10x real-time for example.
[/list]
I guess this can be split up into two questions: How do I create a simulation loop which meets my requirements? and how do I integrate it into my WPF software? Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
[quote]How do I create a simulation loop which meets my requirements?[/quote]
You will want to look into a fixed time-step loop for this. This will help keep your physics simulation deterministic on multiple runs. Also make sure the user input is calculated in at the correct time. This may require your timestep to be in sync with your input polling. i.e. Input being polled at 30hz would also require a 30hz physics update.

I haven't created a WPF application, so I'm not entirely sure how input is captured. I assume either direct polling or a windows message pump? If input is being captured through a win32 message, you may need to timestamp the input and then determine when its best to be applied to the physics update.

Here are some links to help you out.
[url="http://gafferongames.com/game-physics/fix-your-timestep/"]http://gafferongames...-your-timestep/[/url]
[url="http://lspiroengine.com/?p=378"]http://lspiroengine.com/?p=378[/url]

Share this post


Link to post
Share on other sites
Thanks will check out the links.

As for the input, right now the user inputs all the data before starting the simulation so the only input I need to check for once the simulation has started is if the user wants to stop, pause or resume.

Share this post


Link to post
Share on other sites
Having a set input for startup will definitely make things easier.

Those links I posted before provide code for a typical C++ game loop. In WPF, I'm not sure how much control you have over your game loop, since logic is usually updated based on callbacks. Hopefully those articles can still be applied to your project. Goodluck.

Share this post


Link to post
Share on other sites
I decided to try the loop in your first link (the "The final touch" version, I use stopwatch to get the time and timestep 0.2).

The problem is how to run the loop. I tried both options shown here [url="http://windowsclient.net/downloads/folders/controlgallery/entry2391.aspx"]http://windowsclient.../entry2391.aspx[/url].

[b]Game loop 1:[/b]

When I use CompositionTarget.Rendering I get an fps of ~60 (I used 1/frameTime). So I moved everything out from the while-loop into my event handler instead. I found some more info about using CompositionTarget.Rendering:

[quote]The [url="http://msdn.microsoft.com/en-us/library/system.windows.media.compositiontarget.rendering.aspx"]Rendering[/url] event is raised each time the application's scene is drawn. The rendering frame rate is the number of times the scene is drawn per second.[/quote]

[quote]You may discover that your custom drawing runs at different speeds on different computers. This is because your custom drawing is not frame-rate independent. Depending on the system you are running and the workload of that system, the [url="http://msdn.microsoft.com/en-us/library/system.windows.media.compositiontarget.rendering.aspx"]Rendering[/url] event may be called a different number of times per second.[/quote]

This is exactly what I don't want, Does it help that I use the fixed timestep code or should this approach be thrown out the window?

[b]Game loop 2:[/b]

I created a DispatcherTimer with default settings (priority = background, interval = 0) and using the same fps calculation I got an fps of > 1000. (I tried to set the fps to 100 but then I get 50 sometimes and 100 sometimes). The same event handler is used as in game loop 1.

Any thoughts about this approach?

I logged the x and y of my shape during two runs (without interpolation) using Game loop 1 and got this:

Run 1:
[CODE]150 500
153,99975 500
154,79964 500
154,79964 500
155,59951 500
155,59951 500
156,39936 500
157,19919 500
157,999 500[/CODE]

Run 2:
[CODE]150 500
153,99975 500
154,79964 500
154,79964 500
154,79964 500
155,59951 500
156,39936 500
157,19919 500
157,19919 500
157,999 500
[/CODE]

The same values appear in both runs but there are some duplicated values in run 1 that are not present in run 2 and the other way around. What should I make of this?

And btw there is a big jump from 150 to 153.99975, my log shows that Update() is called many times in the beginning, any idea why? Starting my stopwatch wrong?

Anyway I can see that interpolation really helps to get smooth movement.

I am quite confused, I hope someone can help me sort things out. Edited by dabo

Share this post


Link to post
Share on other sites
I briefly read through the Game Loops link you posted. I would probably stick with Game Loop 1 as it says "The Rendering event is raised once per frame".

You can either keep your physics updates outside of the rendering function or make sure to only increment a step if enough time has passed.

So now, even though the rendering event may be called more often on faster machines, this is where you can interpolate between the previous and current physics states. By doing this your rendering is now independent of your physics simulation.

Share this post


Link to post
Share on other sites
Thanks for your response.

I will go with game loop 1 then and see how it goes. I assume the slightly different output between run 1 and 2 is not a problem then.

Share this post


Link to post
Share on other sites

This topic is 2049 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this