From 7bcbe94e5f995cb9142748513307082efc5cd9d0 Mon Sep 17 00:00:00 2001 From: Simon Holmberg Date: Sun, 30 Sep 2012 00:05:35 +0200 Subject: [PATCH] Yay, dynamic shadows! --- DepthsBelow/DepthsBelow/Camera.cs | 3 + DepthsBelow/DepthsBelow/Core.cs | 77 ++- DepthsBelow/DepthsBelow/DepthsBelow.csproj | 4 + DepthsBelow/DepthsBelow/Map.cs | 53 +- DepthsBelow/DepthsBelow/MouseInput.cs | 4 + .../DepthsBelowContent.contentproj | 7 + .../DepthsBelowContent/KryptonEffect.fx | 478 ++++++++++++++++++ 7 files changed, 596 insertions(+), 30 deletions(-) create mode 100755 DepthsBelow/DepthsBelowContent/KryptonEffect.fx diff --git a/DepthsBelow/DepthsBelow/Camera.cs b/DepthsBelow/DepthsBelow/Camera.cs index bd187f4..d41839d 100644 --- a/DepthsBelow/DepthsBelow/Camera.cs +++ b/DepthsBelow/DepthsBelow/Camera.cs @@ -42,6 +42,9 @@ namespace DepthsBelow public void Update(GameTime gameTime) { + if (!core.IsActive) + return; + float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f; MouseState ms = Mouse.GetState(); diff --git a/DepthsBelow/DepthsBelow/Core.cs b/DepthsBelow/DepthsBelow/Core.cs index 415469c..b924bd5 100755 --- a/DepthsBelow/DepthsBelow/Core.cs +++ b/DepthsBelow/DepthsBelow/Core.cs @@ -19,6 +19,8 @@ namespace DepthsBelow GraphicsDeviceManager graphics; SpriteBatch spriteBatch; + public Krypton.KryptonEngine KryptonEngine; + public Camera Camera; public static MouseInput MouseInput; @@ -39,6 +41,8 @@ namespace DepthsBelow graphics.ApplyChanges(); this.IsMouseVisible = true; + + KryptonEngine = new Krypton.KryptonEngine(this, "KryptonEffect"); } /// @@ -50,6 +54,13 @@ namespace DepthsBelow protected override void Initialize() { // TODO: Add your initialization logic here + + // Initialize lighting engine + this.KryptonEngine.Initialize(); + this.KryptonEngine.SpriteBatchCompatablityEnabled = true; + this.KryptonEngine.CullMode = CullMode.CullClockwiseFace; + this.KryptonEngine.AmbientColor = new Color(35, 35, 35); + Camera = new Camera(this); Squad = new List(); @@ -67,7 +78,22 @@ namespace DepthsBelow Map = Content.Load("maps/Cave.Level1"); // Load map objects - Map.ParseObjects(this); + Map.Initialize(this, KryptonEngine); + + // DEBUG: Test lights + var light = new Krypton.Lights.Light2D() + { + Texture = Krypton.LightTextureBuilder.CreatePointLight(this.GraphicsDevice, 512), + Range = (float)(200), + Color = Color.White, + Intensity = 1f, + Angle = MathHelper.TwoPi, + X = 17 * Grid.TileSize, + Y = 7 * Grid.TileSize, + Fov = MathHelper.TwoPi, + IsOn = true + }; + this.KryptonEngine.Lights.Add(light); // TODO: use this.Content to load your game content here Soldier.LoadContent(this); @@ -103,6 +129,9 @@ namespace DepthsBelow foreach (var soldier in Squad) soldier.Update(gameTime); + foreach (Krypton.Lights.Light2D light in KryptonEngine.Lights) + light.Position = Camera.ScreenToWorld(new Vector2(Mouse.GetState().X, Mouse.GetState().Y)); + base.Update(gameTime); } @@ -112,25 +141,43 @@ namespace DepthsBelow /// Provides a snapshot of timing values. protected override void Draw(GameTime gameTime) { + // Assign the matrix and pre-render the lightmap. + this.KryptonEngine.Matrix = Camera.Transform; + this.KryptonEngine.Bluriness = 1; + this.KryptonEngine.LightMapPrepare(); + GraphicsDevice.Clear(Color.Black); - // Start drawing using the Camera transform - spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, - Camera.Transform); + /* + * Draw game world + */ + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Camera.Transform); - // Draw the level - Map.Draw(spriteBatch); + // Draw the level + Map.Draw(spriteBatch); - // Draw units - foreach (var soldier in Squad) - { - var sr = soldier.GetComponent(); - if (sr != null) - sr.Draw(spriteBatch); - } + // Draw units + foreach (var soldier in Squad) + { + var sr = soldier.GetComponent(); + if (sr != null) + sr.Draw(spriteBatch); + } - // Draw mouse input visuals - MouseInput.Draw(spriteBatch); + spriteBatch.End(); + + /* + * Draw Krypton lighting + */ + this.KryptonEngine.Draw(gameTime); + + /* + * Draw HUD elements + */ + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Camera.Transform); + + // Draw mouse input visuals + MouseInput.Draw(spriteBatch); spriteBatch.End(); diff --git a/DepthsBelow/DepthsBelow/DepthsBelow.csproj b/DepthsBelow/DepthsBelow/DepthsBelow.csproj index c935820..a6a7b0d 100644 --- a/DepthsBelow/DepthsBelow/DepthsBelow.csproj +++ b/DepthsBelow/DepthsBelow/DepthsBelow.csproj @@ -146,6 +146,10 @@ {CD3F949D-54AA-4D38-99DB-92905A375D84} AStar + + {B1BFCB2A-C001-4DAC-BA7D-B68BF28757F3} + Krypton + DepthsBelowContent %28Content%29 Content diff --git a/DepthsBelow/DepthsBelow/Map.cs b/DepthsBelow/DepthsBelow/Map.cs index d410a77..b2de6e3 100755 --- a/DepthsBelow/DepthsBelow/Map.cs +++ b/DepthsBelow/DepthsBelow/Map.cs @@ -59,27 +59,50 @@ namespace DepthsBelow } - public void ParseObjects(Core core) + public void Initialize(Core core, Krypton.KryptonEngine kryptonEngine) { foreach (var layer in Layers) { var objectLayer = layer as MapObjectLayer; - - if (objectLayer == null) - continue; - - foreach (var mapObject in objectLayer.Objects) + if (objectLayer != null) { - if (mapObject.Type == "SquadStart") + // Parse objects + foreach (var mapObject in objectLayer.Objects) { - var soldier = new Soldier(core); - // HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91) - var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize); - var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos); - soldier.X = mapObjectGridPos.X; - soldier.Y = mapObjectGridPos.Y; - - core.Squad.Add(soldier); + if (mapObject.Type == "SquadStart") + { + var soldier = new Soldier(core); + // HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91) + var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize); + var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos); + soldier.X = mapObjectGridPos.X; + soldier.Y = mapObjectGridPos.Y; + + core.Squad.Add(soldier); + } + } + } + + var tileLayer = layer as MapTileLayer; + if (tileLayer != null) + { + // Prepare collision hulls for lighting engine + if (tileLayer.Name == "Collision") + { + for (int y = 0; y < tileLayer.Height; y++) + { + for (int x = 0; x < tileLayer.Width; x++) + { + MapTile mapTile = tileLayer.Tiles[y * layer.Width + x]; + if (mapTile != null && mapTile.LocalId != 0) + { + var hull = Krypton.ShadowHull.CreateRectangle(new Vector2(TileWidth, TileHeight)); + hull.Position.X = x * TileWidth + TileWidth/2; + hull.Position.Y = y * TileHeight + TileWidth / 2; + kryptonEngine.Hulls.Add(hull); + } + } + } } } } diff --git a/DepthsBelow/DepthsBelow/MouseInput.cs b/DepthsBelow/DepthsBelow/MouseInput.cs index b57cb28..10d9427 100755 --- a/DepthsBelow/DepthsBelow/MouseInput.cs +++ b/DepthsBelow/DepthsBelow/MouseInput.cs @@ -38,6 +38,10 @@ namespace DepthsBelow public void Update(GameTime gameTime) { + // Only capture input if the game window is in focus + if (!core.IsActive) + return; + MouseState ms = Mouse.GetState(); Vector2 mouseWorldPos = core.Camera.ScreenToWorld(new Vector2(ms.X, ms.Y)); KeyboardState ks = Keyboard.GetState(); diff --git a/DepthsBelow/DepthsBelowContent/DepthsBelowContent.contentproj b/DepthsBelow/DepthsBelowContent/DepthsBelowContent.contentproj index 3a6f708..63b1f25 100644 --- a/DepthsBelow/DepthsBelowContent/DepthsBelowContent.contentproj +++ b/DepthsBelow/DepthsBelowContent/DepthsBelowContent.contentproj @@ -99,6 +99,13 @@ TextureProcessor + + + KryptonEffect + EffectImporter + EffectProcessor + +