-
Notifications
You must be signed in to change notification settings - Fork 0
/
PhysicsDemo.cs
182 lines (146 loc) · 5.63 KB
/
PhysicsDemo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Physics.DemoGames;
using Physics.DemoGames.BaseGames;
using Physics.DemoGames.Particles;
using static Physics.Constants;
namespace Physics
{
public class PhysicsDemo : Game
{
#region Singleton Access for Demo Games
private static Game _game;
public static Rectangle GetScreenBounds() =>
ScreenBounds;
public static GraphicsDevice GetGraphicsDevice() =>
_game.GraphicsDevice;
public static void ExitGame() =>
_game.Exit();
#endregion
/// <summary>
/// The bounds of the demo game's screen.
/// </summary>
public static Rectangle ScreenBounds { get; private set; }
private static readonly BaseDemoGame _SCurrentGame =
new ParticleFrictionDemo();
//new ParticleDragDemo();
/// <summary>
/// The graphics device manager for the demo game.
/// </summary>
private GraphicsDeviceManager _graphics;
/// <summary>
/// The sprite batch for drawing in the demo game.
/// </summary>
private SpriteBatch _spriteBatch;
/// <summary>
/// The time since the last step, or the <see cref="Constants.MS_PER_FRAME"/>
/// </summary>
private int _deltaTimeNextStep = MS_PER_FRAME;
/// <summary>
/// Create a new instance of the demo.
/// </summary>
public PhysicsDemo()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
#region init
/// <summary>
/// Initializes the demo.
/// </summary>
protected override void Initialize()
{
_game = this;
_SCurrentGame.Initialize();
base.Initialize();
}
/// <summary>
/// The load content method, responsible for instantiating all of the demo's content.
/// </summary>
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
ScreenBounds = GraphicsDevice.Viewport.Bounds;
_SCurrentGame.LoadContent(this);
}
#endregion
#region Drawing
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Current <see cref="GameTime"/> object.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin();
// draw calls
_SCurrentGame.Draw(_spriteBatch);
_spriteBatch.End();
base.Draw(gameTime);
}
#endregion
#region Updating
/// <summary>
/// Delta Update method, intended to be used for physics calculations.
/// </summary>
/// <param name="deltaTime">the delta time to apply to the physics simulations.</param>
private void DeltaUpdate(float deltaTime) =>
_SCurrentGame.DeltaUpdate(deltaTime);
// ! remove
private void TopDownDemo(Particle particle) =>
particle.AddForce(Force.GenerateFrictionForce(particle, 10 * Constants.PIXELS_PER_METER));
/// <summary>
/// The demo's update method, which is called every frame.
/// </summary>
/// <param name="gameTime">The current <see cref="GameTime"/> object.</param>
protected override void Update(GameTime gameTime)
{
CheckAndDoDeltaUpdate(gameTime);
_SCurrentGame.Update(gameTime);
base.Update(gameTime);
}
#endregion
#region Delta Time
/// <summary>
/// Creates the delta update method for the demo.
/// </summary>
/// <param name="gameTime">The current frame's <see cref="GameTime"/> object.</param>
private void CheckAndDoDeltaUpdate(GameTime gameTime)
{
if (Waiting(gameTime)) return;
var deltaTime = GetDeltaTime(gameTime);
ClampDeltaTime(ref deltaTime);
CreateDeltaTimeNextStep(gameTime);
DeltaUpdate(deltaTime);
}
/// <summary>
/// Clamps the delta time to the max delta time.
/// </summary>
/// <param name="deltaTime"></param>
private static void ClampDeltaTime(ref float deltaTime) =>
deltaTime = deltaTime > MAX_DELTA_TIME ? MAX_DELTA_TIME : deltaTime;
/// <summary>
/// Creates the next step for the delta update method.
/// </summary>
/// <param name="gameTime"></param>
private void CreateDeltaTimeNextStep(GameTime gameTime) =>
_deltaTimeNextStep = MS_PER_FRAME + (int) gameTime.TotalGameTime.TotalMilliseconds;
/// <summary>
/// Gets the delta time for the current frame.
/// </summary>
/// <formula>
/// TotalMilliseconds - <see cref="_deltaTimeNextStep"/> / 100
/// </formula>
private float GetDeltaTime(GameTime gameTime) =>
((float) gameTime.TotalGameTime.TotalMilliseconds - _deltaTimeNextStep) / 100;
/// <summary>
/// Returns if our demo's delta updates are waiting for the next frame.
/// </summary>
/// <param name="gameTime"></param>
/// <returns></returns>
private bool Waiting(GameTime gameTime) =>
(int) gameTime.TotalGameTime.TotalMilliseconds < _deltaTimeNextStep;
#endregion
}
}