using System; using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace TimingTest { public class Game1 : Microsoft.Xna.Framework.Game { bool vsync = false; GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D spinner; double theta = 0; double spinSpeed = 0.005f; float screenWidth = 1280; float screenHeight = 768; const double MILLISECONDS = 1000.0; const double TARGET_SPEED = 60.0; //Logic tick rate in hertz const double dt = MILLISECONDS / TARGET_SPEED; double currentTime; double accumulator = 0.0; Stopwatch logicTimer = new Stopwatch(); public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.PreferredBackBufferWidth = (int)screenWidth; graphics.PreferredBackBufferHeight = (int)screenHeight; graphics.SynchronizeWithVerticalRetrace = vsync; logicTimer.Start(); currentTime = logicTimer.ElapsedMilliseconds; this.IsFixedTimeStep = false; //Setting IsFixedTimeStep to false makes Update and Draw run in lockstep as fast as your //system can do go. This allows me to control the update timing using the accumulator loop. //Using IsFixedTimeStep=true caps the framerate and introduces some other behaviors I'd like //to avoid. } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); spinner = Content.Load("Spinner"); //I'm using this image: http://i.imgur.com/5qkVH1d.png } protected override void Update(GameTime gameTime) { if (Keyboard.GetState().IsKeyDown(Keys.Escape)) this.Exit(); double newTime = logicTimer.ElapsedMilliseconds; double frameTime = newTime - currentTime; currentTime = newTime; accumulator += frameTime; while (accumulator >= dt) { theta = (theta + spinSpeed * dt) % (Math.PI * 2.0); accumulator -= dt; } } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); spriteBatch.Draw(spinner, new Vector2(screenWidth / 2, screenHeight / 2), null, Color.White, (float)theta, new Vector2(spinner.Width / 2, spinner.Height / 2), Vector2.One, SpriteEffects.None, 0f); spriteBatch.End(); } } }