diff --git a/Shared/Scene.cs b/Shared/Scene.cs new file mode 100644 index 0000000..141550a --- /dev/null +++ b/Shared/Scene.cs @@ -0,0 +1,110 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace SemiColinGames { + class Scene { + Color backgroundColor = Color.CornflowerBlue; + + readonly GraphicsDevice graphics; + readonly Camera camera; + + readonly RenderTarget2D sceneTarget; + readonly RenderTarget2D lightingTarget; + readonly BasicEffect lightingEffect; + + readonly SpriteBatch spriteBatch; + readonly SpriteFont font; + readonly Texture2D grasslandBg1; + readonly Texture2D grasslandBg2; + + public Scene(GraphicsDevice graphics, Camera camera, ContentManager content) { + Enabled = false; + this.graphics = graphics; + this.camera = camera; + + sceneTarget = new RenderTarget2D( + graphics, camera.Width, camera.Height, false /* mipmap */, + graphics.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); + lightingTarget = new RenderTarget2D( + graphics, camera.Width, camera.Height, false /* mipmap */, + graphics.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); + + lightingEffect = new BasicEffect(graphics); + lightingEffect.World = Matrix.CreateTranslation(0, 0, 0); + lightingEffect.View = Matrix.CreateLookAt(Vector3.Backward, Vector3.Zero, Vector3.Up); + lightingEffect.VertexColorEnabled = true; + + // TODO: handle unloading of resources when the level is done. + spriteBatch = new SpriteBatch(graphics); + font = content.Load("font"); + grasslandBg1 = content.Load("grassland_bg1"); + grasslandBg2 = content.Load("grassland_bg2"); + } + + public bool Enabled { get; set; } + + public void Draw(World world, Player player, LinesOfSight linesOfSight) { + graphics.SetRenderTarget(null); + graphics.Clear(backgroundColor); + if (!Enabled) { + return; + } + + graphics.SetRenderTarget(sceneTarget); + graphics.Clear(backgroundColor); + + // Draw scene to sceneTarget. + spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null); + + // Draw background. + Color bgBlend = Color.FromNonPremultiplied(new Vector4(1, 1, 1, 0.5f)); + Rectangle bgSource = new Rectangle( + (int) (camera.Left * 0.25), 0, camera.Width, camera.Height); + Rectangle bgTarget = new Rectangle(0, 0, camera.Width, camera.Height); + spriteBatch.Draw(grasslandBg2, bgTarget, bgSource, bgBlend); + bgSource = new Rectangle( + (int) (camera.Left * 0.5), 0, camera.Width, camera.Height); + spriteBatch.Draw(grasslandBg1, bgTarget, bgSource, bgBlend); + spriteBatch.End(); + + // Set up transformation matrix for drawing world objects. + Matrix transform = Matrix.CreateTranslation(-camera.Left, -camera.Top, 0); + spriteBatch.Begin( + SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null, null, transform); + + // Draw foreground tiles. + world.Draw(spriteBatch); + + // Draw player. + player.Draw(spriteBatch); + + // Aaaaand we're done. + spriteBatch.End(); + + // Draw lighting to lightingTarget. + graphics.SetRenderTarget(lightingTarget); + graphics.Clear(new Color(0, 0, 0, 0f)); + lightingEffect.Projection = camera.Projection; + linesOfSight.Draw(player, world.CollisionTargets, graphics, lightingEffect); + + // Draw debug rects & lines on top. + Debug.Draw(graphics, lightingEffect); + + // Draw sceneTarget to screen. + graphics.SetRenderTarget(null); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, + SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + Rectangle drawRect = new Rectangle( + 0, 0, graphics.Viewport.Width, graphics.Viewport.Height); + spriteBatch.Draw(sceneTarget, drawRect, Color.White); + spriteBatch.Draw(lightingTarget, drawRect, Color.White); + + // Draw debug toasts. + Debug.DrawToasts(spriteBatch, font); + + spriteBatch.End(); + } + } +} diff --git a/Shared/Shared.projitems b/Shared/Shared.projitems index 64ba46d..cb50e14 100644 --- a/Shared/Shared.projitems +++ b/Shared/Shared.projitems @@ -21,6 +21,7 @@ + diff --git a/Shared/SneakGame.cs b/Shared/SneakGame.cs index 1a1ec3e..a89a9ef 100644 --- a/Shared/SneakGame.cs +++ b/Shared/SneakGame.cs @@ -11,13 +11,7 @@ namespace SemiColinGames { const double TARGET_FRAME_TIME = 1.0 / TARGET_FPS; readonly GraphicsDeviceManager graphics; - RenderTarget2D sceneTarget; - RenderTarget2D lightingTarget; - BasicEffect lightingEffect; - - SpriteBatch spriteBatch; - SpriteFont font; bool fullScreen = false; bool paused = false; IDisplay display; @@ -30,10 +24,9 @@ namespace SemiColinGames { // 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; + int framesToSuppress; + Scene scene; Player player; World world; LinesOfSight linesOfSight; @@ -58,18 +51,6 @@ namespace SemiColinGames { Debug.Initialize(GraphicsDevice); - sceneTarget = new RenderTarget2D( - GraphicsDevice, camera.Width, camera.Height, false /* mipmap */, - GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); - lightingTarget = new RenderTarget2D( - GraphicsDevice, camera.Width, camera.Height, false /* mipmap */, - GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); - - lightingEffect = new BasicEffect(GraphicsDevice); - lightingEffect.World = Matrix.CreateTranslation(0, 0, 0); - lightingEffect.View = Matrix.CreateLookAt(Vector3.Backward, Vector3.Zero, Vector3.Up); - lightingEffect.VertexColorEnabled = true; - RasterizerState rasterizerState = new RasterizerState() { CullMode = CullMode.None }; @@ -81,18 +62,16 @@ namespace SemiColinGames { // Called once per game. Loads all game content. protected override void LoadContent() { base.LoadContent(); - spriteBatch = new SpriteBatch(GraphicsDevice); - font = Content.Load("font"); linesOfSight = new LinesOfSight(GraphicsDevice); - grasslandBg1 = Content.Load("grassland_bg1"); - grasslandBg2 = Content.Load("grassland_bg2"); LoadLevel(); } private void LoadLevel() { + framesToSuppress = 2; camera = new Camera(); player = new Player(Content.Load("Ninja_Female")); world = new World(Content.Load("grassland"), Levels.ONE_ONE); + scene = new Scene(GraphicsDevice, camera, Content); } // Called once per game. Unloads all game content. @@ -145,8 +124,12 @@ namespace SemiColinGames { protected override void Draw(GameTime gameTime) { drawTimer.Start(); + // Enable the scene after we've gotten enough non-slow frames. if (framesToSuppress > 0 && !gameTime.IsRunningSlowly) { framesToSuppress--; + if (framesToSuppress == 0) { + scene.Enabled = true; + } } // We need to update the FPS counter in Draw() since Update() might get called more @@ -160,62 +143,7 @@ namespace SemiColinGames { Debug.SetFpsText(fpsText); - // Draw scene to sceneTarget. - GraphicsDevice.SetRenderTarget(sceneTarget); - GraphicsDevice.Clear(Color.CornflowerBlue); - spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null); - - // Draw background. - Color bgBlend = Color.FromNonPremultiplied(new Vector4(1, 1, 1, 0.5f)); - Rectangle bgSource = new Rectangle( - (int) (camera.Left * 0.25), 0, camera.Width, camera.Height); - Rectangle bgTarget = new Rectangle(0, 0, camera.Width, camera.Height); - spriteBatch.Draw(grasslandBg2, bgTarget, bgSource, bgBlend); - bgSource = new Rectangle( - (int) (camera.Left * 0.5), 0, camera.Width, camera.Height); - spriteBatch.Draw(grasslandBg1, bgTarget, bgSource, bgBlend); - spriteBatch.End(); - - // Set up transformation matrix for drawing world objects. - Matrix transform = Matrix.CreateTranslation(-camera.Left, -camera.Top, 0); - spriteBatch.Begin( - SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null, null, transform); - - // Draw foreground tiles. - world.Draw(spriteBatch); - - // Draw player. - player.Draw(spriteBatch); - - // Aaaaand we're done. - spriteBatch.End(); - - // Draw lighting to lightingTarget. - GraphicsDevice.SetRenderTarget(lightingTarget); - GraphicsDevice.Clear(new Color(0, 0, 0, 0f)); - lightingEffect.Projection = camera.Projection; - linesOfSight.Draw(player, world.CollisionTargets, GraphicsDevice, lightingEffect); - - // Draw debug rects & lines on top. - Debug.Draw(GraphicsDevice, lightingEffect); - - // Draw sceneTarget to screen. - GraphicsDevice.SetRenderTarget(null); - 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(sceneTarget, drawRect, Color.White); - spriteBatch.Draw(lightingTarget, drawRect, Color.White); - - // Draw debug toasts. - Debug.DrawToasts(spriteBatch, font); - - spriteBatch.End(); - } + scene.Draw(world, player, linesOfSight); base.Draw(gameTime); drawTimer.Stop();