From fd4bf85d1ca483c96eebe7171e410a1ea8ad0540 Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Thu, 19 Nov 2020 14:44:12 -0500 Subject: [PATCH] add basic shmup game --- Shared/Shared.projitems | 2 ++ Shared/ShmupScene.cs | 76 +++++++++++++++++++++++++++++++++++++++++ Shared/ShmupWorld.cs | 33 ++++++++++++++++++ Shared/SneakGame.cs | 6 ++-- Shared/Textures.cs | 3 ++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 Shared/ShmupScene.cs create mode 100644 Shared/ShmupWorld.cs diff --git a/Shared/Shared.projitems b/Shared/Shared.projitems index 83545d6..251e65a 100644 --- a/Shared/Shared.projitems +++ b/Shared/Shared.projitems @@ -17,6 +17,8 @@ + + diff --git a/Shared/ShmupScene.cs b/Shared/ShmupScene.cs new file mode 100644 index 0000000..65d4829 --- /dev/null +++ b/Shared/ShmupScene.cs @@ -0,0 +1,76 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; + +namespace SemiColinGames { + public sealed class ShmupScene : IScene { + + const float DESIRED_ASPECT_RATIO = 1920.0f / 1080.0f; + + private readonly Color backgroundColor = Color.DarkBlue; + + private readonly GraphicsDevice graphics; + private readonly RenderTarget2D sceneTarget; + private readonly SpriteBatch spriteBatch; + + public ShmupScene(GraphicsDevice graphics) { + this.graphics = graphics; + + sceneTarget = new RenderTarget2D( + graphics, 1920 / 4, 1080 / 4, false /* mipmap */, + graphics.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); + spriteBatch = new SpriteBatch(graphics); + } + + ~ShmupScene() { + Dispose(); + } + + public void Dispose() { + GC.SuppressFinalize(this); + } + + public void Draw(bool isRunningSlowly, IWorld iworld, bool paused) { + ShmupWorld world = (ShmupWorld) iworld; + graphics.SetRenderTarget(null); + graphics.Clear(backgroundColor); + + // Draw scene to sceneTarget. + graphics.SetRenderTarget(sceneTarget); + graphics.Clear(backgroundColor); + + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, + SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + spriteBatch.Draw(Textures.SilverBlue1.Get, Vector2.Floor(world.Player.Position), Color.White); + spriteBatch.End(); + + // Get ready to draw sceneTarget to screen. + graphics.SetRenderTarget(null); + + + // Letterbox the scene if needed. + float aspectRatio = 1.0f * graphics.Viewport.Width / graphics.Viewport.Height; + Rectangle drawRect; + if (aspectRatio > DESIRED_ASPECT_RATIO) { + // Need to letterbox the sides. + int desiredWidth = (int) (graphics.Viewport.Height * DESIRED_ASPECT_RATIO); + int padding = (graphics.Viewport.Width - desiredWidth) / 2; + drawRect = new Rectangle(padding, 0, desiredWidth, graphics.Viewport.Height); + } else { + // Need to letterbox the top / bottom. + int desiredHeight = (int) (graphics.Viewport.Width / DESIRED_ASPECT_RATIO); + int padding = (graphics.Viewport.Height - desiredHeight) / 2; + drawRect = new Rectangle(0, padding, graphics.Viewport.Width, desiredHeight); + } + + // Actually draw to screen. + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, + SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + spriteBatch.Draw(sceneTarget, drawRect, Color.White); + spriteBatch.End(); + } + } +} diff --git a/Shared/ShmupWorld.cs b/Shared/ShmupWorld.cs new file mode 100644 index 0000000..b78bdb5 --- /dev/null +++ b/Shared/ShmupWorld.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; + +namespace SemiColinGames { + public sealed class ShmupWorld : IWorld { + public struct ShmupPlayer { + // Center of player sprite. + public Vector2 Position; + } + + public ShmupPlayer Player; + + public ShmupWorld() { + Player = new ShmupPlayer(); + } + + ~ShmupWorld() { + Dispose(); + } + + public void Dispose() { + GC.SuppressFinalize(this); + } + + public void Update(float modelTime, History input) { + float speed = 150f; + Vector2 motion = Vector2.Multiply(input[0].Motion, modelTime * speed); + Player.Position = Vector2.Add(Player.Position, motion); + } + } +} diff --git a/Shared/SneakGame.cs b/Shared/SneakGame.cs index 05d0946..87af97b 100644 --- a/Shared/SneakGame.cs +++ b/Shared/SneakGame.cs @@ -64,11 +64,13 @@ namespace SemiColinGames { private void LoadLevel() { world?.Dispose(); - world = new SneakWorld(GraphicsDevice, Content.LoadString("levels/demo.json")); + // world = new SneakWorld(GraphicsDevice, Content.LoadString("levels/demo.json")); // world = new TreeWorld(); + world = new ShmupWorld(); scene?.Dispose(); - scene = new SneakScene(GraphicsDevice, ((SneakWorld) world).Camera); + // scene = new SneakScene(GraphicsDevice, ((SneakWorld) world).Camera); // scene = new TreeScene(GraphicsDevice); + scene = new ShmupScene(GraphicsDevice); GC.Collect(); GC.WaitForPendingFinalizers(); diff --git a/Shared/Textures.cs b/Shared/Textures.cs index 671c7db..b8e14ee 100644 --- a/Shared/Textures.cs +++ b/Shared/Textures.cs @@ -40,6 +40,9 @@ namespace SemiColinGames { // UI sprites. public static TextureRef Heart = new TextureRef("sprites/semicolin/heart"); + // Ship sprites. + public static TextureRef SilverBlue1 = new TextureRef("sprites/dylestorm/SilverBlue-1"); + // Backgrounds are indexed by draw order; the first element should be drawn furthest back. public static TextureRef[] Backgrounds = new TextureRef[] { new TextureRef("backgrounds/szadiart/pf4/background1_day"),