From 1c57a4a79ff8c87747e68ebf027ca18fd5a711e4 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sat, 18 Jul 2020 14:41:32 -0700 Subject: [PATCH] title screen --- PongFE/Components/GameStateComponent.cs | 15 +++ PongFE/Engines/GameStateEngine.cs | 153 ++++++++++++++++++++++ PongFE/Enums/Enums.cs | 6 + PongFE/Messages/ChangeGameStateMessage.cs | 15 +++ PongFE/PongFEGame.cs | 78 ++--------- PongFE/Renderers/CenterLineRenderer.cs | 10 +- PongFE/Renderers/TitleRenderer.cs | 47 +++++++ 7 files changed, 255 insertions(+), 69 deletions(-) create mode 100644 PongFE/Components/GameStateComponent.cs create mode 100644 PongFE/Engines/GameStateEngine.cs create mode 100644 PongFE/Messages/ChangeGameStateMessage.cs create mode 100644 PongFE/Renderers/TitleRenderer.cs diff --git a/PongFE/Components/GameStateComponent.cs b/PongFE/Components/GameStateComponent.cs new file mode 100644 index 0000000..acf9cc4 --- /dev/null +++ b/PongFE/Components/GameStateComponent.cs @@ -0,0 +1,15 @@ +using Encompass; +using PongFE.Enums; + +namespace PongFE.Components +{ + public struct GameStateComponent : IComponent + { + public GameState GameState { get; } + + public GameStateComponent(GameState gameState) + { + GameState = gameState; + } + } +} diff --git a/PongFE/Engines/GameStateEngine.cs b/PongFE/Engines/GameStateEngine.cs new file mode 100644 index 0000000..bc97d51 --- /dev/null +++ b/PongFE/Engines/GameStateEngine.cs @@ -0,0 +1,153 @@ +using Encompass; +using Microsoft.Xna.Framework.Input; +using PongFE.Components; +using PongFE.Enums; +using PongFE.Messages; + +namespace PongFE.Engines +{ + [Reads(typeof(GameStateComponent))] + [Receives(typeof(ChangeGameStateMessage))] + [Sends( + typeof(BallSpawnMessage), + typeof(PaddleSpawnMessage), + typeof(BoundarySpawnMessage), + typeof(GoalBoundarySpawnMessage) + )] + [Writes(typeof(GameStateComponent))] + public class GameStateEngine : Engine + { + private int PlayAreaWidth { get; } + private int PlayAreaHeight { get; } + + public GameStateEngine(int playAreaWidth, int playAreaHeight) + { + PlayAreaWidth = playAreaWidth; + PlayAreaHeight = playAreaHeight; + } + + public override void Update(double dt) + { + ref readonly var gameStateEntity = ref ReadEntity(); + ref readonly var gameStateComponent = ref GetComponent(gameStateEntity); + + if (gameStateComponent.GameState == GameState.Title) + { + if (Keyboard.GetState().IsKeyDown(Keys.Enter)) + { + EndTitle(); + StartGame(); + + SetComponent(gameStateEntity, new GameStateComponent(GameState.Game)); + } + } + + if (SomeMessage()) + { + ref readonly var changeGameStateMessage = ref ReadMessage(); + + if (changeGameStateMessage.GameState == gameStateComponent.GameState) + { + return; + } + + if (gameStateComponent.GameState == GameState.Game) + { + if (changeGameStateMessage.GameState == GameState.Title) + { + EndGame(); + StartTitle(); + + SetComponent(gameStateEntity, new GameStateComponent(GameState.Title)); + } + } + } + } + + private void StartGame() + { + SendMessage( + new PaddleSpawnMessage( + new MoonTools.Structs.Position2D(20, PlayAreaHeight / 2 - 40), + Enums.PlayerIndex.One, + PaddleControl.Player, + 20, + 80 + ) + ); + + SendMessage( + new PaddleSpawnMessage( + new MoonTools.Structs.Position2D(PlayAreaWidth - 45, PlayAreaHeight / 2 - 40), + Enums.PlayerIndex.Two, + PaddleControl.Computer, + 20, + 80 + ) + ); + + SendMessage( + new BallSpawnMessage( + new MoonTools.Structs.Position2D(PlayAreaWidth / 2, PlayAreaHeight / 2), + 500, + 16, + 16 + ), + 0.5 + ); + + // top boundary + SendMessage( + new BoundarySpawnMessage( + new MoonTools.Structs.Position2D(0, -6), + PlayAreaWidth, + 6 + ) + ); + + // bottom boundary + SendMessage( + new BoundarySpawnMessage( + new MoonTools.Structs.Position2D(0, PlayAreaHeight), + PlayAreaWidth, + 6 + ) + ); + + // right boundary + SendMessage( + new GoalBoundarySpawnMessage( + Enums.PlayerIndex.One, + new MoonTools.Structs.Position2D(PlayAreaWidth, 0), + 6, + PlayAreaHeight + ) + ); + + // left boundary + SendMessage( + new GoalBoundarySpawnMessage( + Enums.PlayerIndex.Two, + new MoonTools.Structs.Position2D(-6, 0), + 6, + PlayAreaHeight + ) + ); + } + + private void EndGame() + { + DestroyAllWith(); + } + + private void StartTitle() + { + + } + + private void EndTitle() + { + + } + } +} diff --git a/PongFE/Enums/Enums.cs b/PongFE/Enums/Enums.cs index eda8cf0..26e0523 100644 --- a/PongFE/Enums/Enums.cs +++ b/PongFE/Enums/Enums.cs @@ -23,4 +23,10 @@ namespace PongFE.Enums Player, Computer } + + public enum GameState + { + Title, + Game + } } diff --git a/PongFE/Messages/ChangeGameStateMessage.cs b/PongFE/Messages/ChangeGameStateMessage.cs new file mode 100644 index 0000000..16bc2e4 --- /dev/null +++ b/PongFE/Messages/ChangeGameStateMessage.cs @@ -0,0 +1,15 @@ +using Encompass; +using PongFE.Enums; + +namespace PongFE.Messages +{ + public struct ChangeGameStateMessage : IMessage + { + public GameState GameState { get; } + + public ChangeGameStateMessage(GameState gameState) + { + GameState = gameState; + } + } +} diff --git a/PongFE/PongFEGame.cs b/PongFE/PongFEGame.cs index 7c41a04..0131aa7 100644 --- a/PongFE/PongFEGame.cs +++ b/PongFE/PongFEGame.cs @@ -25,6 +25,7 @@ namespace PongFE RenderTarget2D GameRenderTarget { get; set; } DynamicSpriteFont ScoreFont { get; set; } + DynamicSpriteFont InstructionFont { get; set; } const int PLAY_AREA_WIDTH = 1280; const int PLAY_AREA_HEIGHT = 720; @@ -63,6 +64,12 @@ namespace PongFE 128 ); + InstructionFont = DynamicSpriteFont.FromTtf( + File.ReadAllBytes(@"Content/Fonts/SquaredDisplay.ttf"), + 48 + ); + + WorldBuilder.AddEngine(new GameStateEngine(PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT)); WorldBuilder.AddEngine(new InputEngine()); WorldBuilder.AddEngine(new PaddleMovementEngine()); WorldBuilder.AddEngine(new VelocityEngine()); @@ -84,77 +91,14 @@ namespace PongFE WorldBuilder.AddOrderedRenderer(new Texture2DRenderer(SpriteBatch)); WorldBuilder.AddGeneralRenderer(new CenterLineRenderer(SpriteBatch, WhitePixel), 0); WorldBuilder.AddGeneralRenderer(new ScoreRenderer(SpriteBatch, ScoreFont), 0); - - WorldBuilder.SendMessage( - new PaddleSpawnMessage( - new MoonTools.Structs.Position2D(5, 5), - Enums.PlayerIndex.One, - PaddleControl.Player, - 20, - 80 - ) - ); - - WorldBuilder.SendMessage( - new PaddleSpawnMessage( - new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH - 25, 5), - Enums.PlayerIndex.Two, - PaddleControl.Computer, - 20, - 80 - ) - ); - - WorldBuilder.SendMessage( - new BallSpawnMessage( - new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH / 2, PLAY_AREA_HEIGHT / 2), - 500, - 16, - 16 - ) - ); - - // top boundary - WorldBuilder.SendMessage( - new BoundarySpawnMessage( - new MoonTools.Structs.Position2D(0, -6), - PLAY_AREA_WIDTH, - 6 - ) - ); - - // bottom boundary - WorldBuilder.SendMessage( - new BoundarySpawnMessage( - new MoonTools.Structs.Position2D(0, PLAY_AREA_HEIGHT), - PLAY_AREA_WIDTH, - 6 - ) - ); - - // right boundary - WorldBuilder.SendMessage( - new GoalBoundarySpawnMessage( - Enums.PlayerIndex.One, - new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH, 0), - 6, - PLAY_AREA_HEIGHT - ) - ); - - // left boundary - WorldBuilder.SendMessage( - new GoalBoundarySpawnMessage( - Enums.PlayerIndex.Two, - new MoonTools.Structs.Position2D(-6, 0), - 6, - PLAY_AREA_HEIGHT - ) - ); + WorldBuilder.AddGeneralRenderer(new TitleRenderer(SpriteBatch, ScoreFont, InstructionFont), 0); var playAreaEntity = WorldBuilder.CreateEntity(); WorldBuilder.SetComponent(playAreaEntity, new PlayAreaComponent(PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT)); + var gameStateEntity = WorldBuilder.CreateEntity(); + WorldBuilder.SetComponent(gameStateEntity, new GameStateComponent(GameState.Title)); + World = WorldBuilder.Build(); } diff --git a/PongFE/Renderers/CenterLineRenderer.cs b/PongFE/Renderers/CenterLineRenderer.cs index 35af84b..6debaee 100644 --- a/PongFE/Renderers/CenterLineRenderer.cs +++ b/PongFE/Renderers/CenterLineRenderer.cs @@ -3,6 +3,7 @@ using Encompass; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using PongFE.Components; +using PongFE.Enums; namespace PongFE.Renderers { @@ -19,9 +20,14 @@ namespace PongFE.Renderers public override void Render() { - ref readonly var playAreaComponent = ref ReadComponent(); + ref readonly var gameStateComponent = ref ReadComponent(); - DrawDottedLine(playAreaComponent.Width / 2, 0, playAreaComponent.Width / 2, playAreaComponent.Height, 20, 20); + if (gameStateComponent.GameState == GameState.Game) + { + ref readonly var playAreaComponent = ref ReadComponent(); + + DrawDottedLine(playAreaComponent.Width / 2, 0, playAreaComponent.Width / 2, playAreaComponent.Height, 20, 20); + } } private void DrawDottedLine(float x1, float y1, float x2, float y2, int dash, int gap) diff --git a/PongFE/Renderers/TitleRenderer.cs b/PongFE/Renderers/TitleRenderer.cs new file mode 100644 index 0000000..56ceb95 --- /dev/null +++ b/PongFE/Renderers/TitleRenderer.cs @@ -0,0 +1,47 @@ +using Encompass; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using PongFE.Components; +using PongFE.Enums; +using SpriteFontPlus; + +namespace PongFE.Renderers +{ + public class TitleRenderer : GeneralRenderer + { + private SpriteBatch SpriteBatch { get; } + private DynamicSpriteFont TitleFont { get; } + private DynamicSpriteFont InstructionFont { get; } + + public TitleRenderer(SpriteBatch spriteBatch, DynamicSpriteFont titleFont, DynamicSpriteFont instructionFont) + { + SpriteBatch = spriteBatch; + TitleFont = titleFont; + InstructionFont = instructionFont; + } + + public override void Render() + { + ref readonly var gameStateComponent = ref ReadComponent(); + ref readonly var playAreaComponent = ref ReadComponent(); + + if (gameStateComponent.GameState == GameState.Title) + { + var titleDimensions = TitleFont.MeasureString("PongFE"); + var titlePosition = new Vector2( + (playAreaComponent.Width - titleDimensions.X) / 2, + (playAreaComponent.Height - titleDimensions.Y) / 4 + ); + + var instructionDimensions = InstructionFont.MeasureString("Press Enter to begin"); + var instructionPosition = new Vector2( + (playAreaComponent.Width - instructionDimensions.X) / 2, + playAreaComponent.Height * 2 / 3 + ); + + SpriteBatch.DrawString(TitleFont, "PongFE", titlePosition, Color.White); + SpriteBatch.DrawString(InstructionFont, "Press Enter to begin", instructionPosition, Color.White); + } + } + } +}