diff --git a/Shared/SneakGame.cs b/Shared/SneakGame.cs index cce78a6..99c5b28 100644 --- a/Shared/SneakGame.cs +++ b/Shared/SneakGame.cs @@ -7,6 +7,9 @@ using System.Collections.Generic; namespace SemiColinGames { public class SneakGame : Game { + const int TARGET_FPS = 60; + const double TARGET_FRAME_TIME = 1.0 / TARGET_FPS; + readonly GraphicsDeviceManager graphics; RenderTarget2D renderTarget; @@ -19,6 +22,12 @@ namespace SemiColinGames { readonly History input = new History(2); readonly FpsCounter fpsCounter = new FpsCounter(); + readonly Timer updateTimer = new Timer(TARGET_FRAME_TIME / 2.0, "UpdateTimer"); + readonly Timer drawTimer = new Timer(TARGET_FRAME_TIME / 2.0, "DrawTimer"); + // Draw() needs to be called without IsRunningSlowly this many times before we actually + // attempt to draw the scene. This is a workaround for the fact that otherwise the first few + // frames can be really slow to draw. + int framesToSuppress = 2; Texture2D grasslandBg1; Texture2D grasslandBg2; @@ -32,7 +41,7 @@ namespace SemiColinGames { GraphicsProfile = GraphicsProfile.HiDef }; IsFixedTimeStep = true; - TargetElapsedTime = TimeSpan.FromSeconds(1.0 / 60); + TargetElapsedTime = TimeSpan.FromSeconds(TARGET_FRAME_TIME); IsMouseVisible = true; Content.RootDirectory = "Content"; } @@ -69,6 +78,7 @@ namespace SemiColinGames { // Updates the game world. protected override void Update(GameTime gameTime) { + updateTimer.Start(); input.Add(new Input(GamePad.GetState(PlayerIndex.One), Keyboard.GetState())); if (input[0].Exit) { @@ -97,10 +107,17 @@ namespace SemiColinGames { } base.Update(gameTime); + updateTimer.Stop(); } // Called when the game should draw itself. protected override void Draw(GameTime gameTime) { + drawTimer.Start(); + + if (framesToSuppress > 0 && !gameTime.IsRunningSlowly) { + framesToSuppress--; + } + // We need to update the FPS counter in Draw() since Update() might get called more // frequently, especially when gameTime.IsRunningSlowly. fpsCounter.Update(); @@ -140,20 +157,23 @@ namespace SemiColinGames { // Draw RenderTarget to screen. GraphicsDevice.SetRenderTarget(null); - GraphicsDevice.Clear(Color.Black); - spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, - SamplerState.PointClamp, DepthStencilState.Default, - RasterizerState.CullNone); - Rectangle drawRect = new Rectangle( - 0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); - spriteBatch.Draw(renderTarget, drawRect, Color.White); - - // Draw debug toasts. - Debug.DrawToasts(spriteBatch, font); - - spriteBatch.End(); + GraphicsDevice.Clear(Color.CornflowerBlue); + if (framesToSuppress == 0) { + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, + SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + Rectangle drawRect = new Rectangle( + 0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); + spriteBatch.Draw(renderTarget, drawRect, Color.White); + + // Draw debug toasts. + Debug.DrawToasts(spriteBatch, font); + + spriteBatch.End(); + } base.Draw(gameTime); + drawTimer.Stop(); } } }