win condition
							parent
							
								
									b2198f448b
								
							
						
					
					
						commit
						5eb92804f4
					
				|  | @ -0,0 +1,16 @@ | |||
| using Encompass; | ||||
| 
 | ||||
| namespace PongFE.Components | ||||
| { | ||||
|     public struct BallParametersComponent : IComponent | ||||
|     { | ||||
|         public int Speed { get; } | ||||
|         public double Delay { get; } | ||||
| 
 | ||||
|         public BallParametersComponent(int speed, double delay) | ||||
|         { | ||||
|             Speed = speed; | ||||
|             Delay = delay; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,16 +0,0 @@ | |||
| using Encompass; | ||||
| 
 | ||||
| namespace PongFE.Components | ||||
| { | ||||
|     public struct SpawnBallAfterDestroyComponent : IComponent | ||||
|     { | ||||
|         public float Speed { get; } | ||||
|         public float Seconds { get; } | ||||
| 
 | ||||
|         public SpawnBallAfterDestroyComponent(float speed, float seconds) | ||||
|         { | ||||
|             Speed = speed; | ||||
|             Seconds = seconds; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,17 @@ | |||
| using Encompass; | ||||
| using SpriteFontPlus; | ||||
| 
 | ||||
| namespace PongFE.Components | ||||
| { | ||||
|     public struct UITextComponent : IComponent | ||||
|     { | ||||
|         public DynamicSpriteFont Font { get; } | ||||
|         public string Text { get; } | ||||
| 
 | ||||
|         public UITextComponent(DynamicSpriteFont font, string text) | ||||
|         { | ||||
|             Font = font; | ||||
|             Text = text; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -5,35 +5,16 @@ using PongFE.Messages; | |||
| namespace PongFE.Engines | ||||
| { | ||||
|     [Reads( | ||||
|         typeof(SpawnBallAfterDestroyComponent), | ||||
|         typeof(IncreaseScoreAfterDestroyComponent) | ||||
|     )] | ||||
|     [Receives(typeof(DestroyMessage))] | ||||
|     [Sends( | ||||
|         typeof(BallSpawnMessage), | ||||
|         typeof(ScoreMessage) | ||||
|     )] | ||||
|     [Sends(typeof(ScoreMessage))] | ||||
|     public class DestroyEngine : Engine | ||||
|     { | ||||
|         public override void Update(double dt) | ||||
|         { | ||||
|             foreach (ref readonly var message in ReadMessages<DestroyMessage>()) | ||||
|             { | ||||
|                 if (HasComponent<SpawnBallAfterDestroyComponent>(message.Entity)) | ||||
|                 { | ||||
|                     ref readonly var respawnComponent = ref GetComponent<SpawnBallAfterDestroyComponent>(message.Entity); | ||||
| 
 | ||||
|                     SendMessage( | ||||
|                         new BallSpawnMessage( | ||||
|                             new MoonTools.Structs.Position2D(640, 360), | ||||
|                             respawnComponent.Speed, | ||||
|                             16, | ||||
|                             16 | ||||
|                         ), | ||||
|                         respawnComponent.Seconds | ||||
|                     ); | ||||
|                 } | ||||
| 
 | ||||
|                 if (HasComponent<IncreaseScoreAfterDestroyComponent>(message.Entity)) | ||||
|                 { | ||||
|                     SendMessage(new ScoreMessage(message.DestroyedBy)); | ||||
|  |  | |||
|  | @ -1,22 +1,39 @@ | |||
| using Encompass; | ||||
| using Microsoft.Xna.Framework.Input; | ||||
| using MoonTools.Structs; | ||||
| using PongFE.Components; | ||||
| using PongFE.Enums; | ||||
| using PongFE.Messages; | ||||
| using SpriteFontPlus; | ||||
| 
 | ||||
| namespace PongFE.Engines | ||||
| { | ||||
|     [Reads(typeof(GameStateComponent), typeof(PlayAreaComponent))] | ||||
|     [Reads( | ||||
|         typeof(PositionComponent), | ||||
|         typeof(GameStateComponent), | ||||
|         typeof(PlayAreaComponent), | ||||
|         typeof(UITextComponent) | ||||
|     )] | ||||
|     [Receives(typeof(ChangeGameStateMessage))] | ||||
|     [Sends( | ||||
|         typeof(BallSpawnMessage), | ||||
|         typeof(PaddleSpawnMessage), | ||||
|         typeof(BoundarySpawnMessage), | ||||
|         typeof(GoalBoundarySpawnMessage) | ||||
|         typeof(GoalBoundarySpawnMessage), | ||||
|         typeof(UITextSpawnMessage) | ||||
|     )] | ||||
|     [Writes(typeof(GameStateComponent))] | ||||
|     public class GameStateEngine : Engine | ||||
|     { | ||||
|         private DynamicSpriteFont TitleFont { get; } | ||||
|         private DynamicSpriteFont InstructionFont { get; } | ||||
| 
 | ||||
|         public GameStateEngine(DynamicSpriteFont titleFont, DynamicSpriteFont instructionFont) | ||||
|         { | ||||
|             TitleFont = titleFont; | ||||
|             InstructionFont = instructionFont; | ||||
|         } | ||||
| 
 | ||||
|         public override void Update(double dt) | ||||
|         { | ||||
|             ref readonly var gameStateEntity = ref ReadEntity<GameStateComponent>(); | ||||
|  | @ -42,8 +59,6 @@ namespace PongFE.Engines | |||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 if (gameStateComponent.GameState == GameState.Game) | ||||
|                 { | ||||
|                 if (changeGameStateMessage.GameState == GameState.Title) | ||||
|                 { | ||||
|                     EndGame(); | ||||
|  | @ -53,7 +68,6 @@ namespace PongFE.Engines | |||
|                 } | ||||
|             } | ||||
|         } | ||||
|         } | ||||
| 
 | ||||
|         private void StartGame() | ||||
|         { | ||||
|  | @ -137,12 +151,36 @@ namespace PongFE.Engines | |||
| 
 | ||||
|         private void StartTitle() | ||||
|         { | ||||
|             ref readonly var playAreaComponent = ref ReadComponent<PlayAreaComponent>(); | ||||
| 
 | ||||
|             var titleDimensions = TitleFont.MeasureString("PongFE"); | ||||
|             var titlePosition = new Position2D( | ||||
|                 (playAreaComponent.Width - titleDimensions.X) / 2, | ||||
|                 (playAreaComponent.Height - titleDimensions.Y) / 4 | ||||
|             ); | ||||
| 
 | ||||
|             SendMessage(new UITextSpawnMessage( | ||||
|                 titlePosition, | ||||
|                 TitleFont, | ||||
|                 "PongFE" | ||||
|             )); | ||||
| 
 | ||||
|             var instructionDimensions = InstructionFont.MeasureString("Press Enter to begin"); | ||||
|             var instructionPosition = new Position2D( | ||||
|                 (playAreaComponent.Width - instructionDimensions.X) / 2, | ||||
|                 playAreaComponent.Height * 2 / 3 | ||||
|             ); | ||||
| 
 | ||||
|             SendMessage(new UITextSpawnMessage( | ||||
|                 instructionPosition, | ||||
|                 InstructionFont, | ||||
|                 "Press Enter to play" | ||||
|             )); | ||||
|         } | ||||
| 
 | ||||
|         private void EndTitle() | ||||
|         { | ||||
| 
 | ||||
|             DestroyAllWith<UITextComponent>(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,55 @@ | |||
| using Encompass; | ||||
| using PongFE.Components; | ||||
| using PongFE.Enums; | ||||
| using PongFE.Messages; | ||||
| using SpriteFontPlus; | ||||
| 
 | ||||
| namespace PongFE.Engines | ||||
| { | ||||
|     [Reads(typeof(PlayAreaComponent))] | ||||
|     [Receives(typeof(GameWinMessage))] | ||||
|     [Sends(typeof(UITextSpawnMessage), typeof(ChangeGameStateMessage))] | ||||
|     public class GameWinEngine : Engine | ||||
|     { | ||||
|         public DynamicSpriteFont Font { get; } | ||||
|         private readonly string _playerOneWinText = "Player 1 Wins!"; | ||||
|         private readonly string _playerTwoWinText = "Player 2 Wins!"; | ||||
| 
 | ||||
|         public GameWinEngine(DynamicSpriteFont font) | ||||
|         { | ||||
|             Font = font; | ||||
|         } | ||||
| 
 | ||||
|         public override void Update(double dt) | ||||
|         { | ||||
|             if (SomeMessage<GameWinMessage>()) | ||||
|             { | ||||
|                 ref readonly var gameWinMessage = ref ReadMessage<GameWinMessage>(); | ||||
|                 ref readonly var playAreaComponent = ref ReadComponent<PlayAreaComponent>(); | ||||
| 
 | ||||
|                 string winText; | ||||
|                 if (gameWinMessage.PlayerIndex == PlayerIndex.One) | ||||
|                 { | ||||
|                     winText = _playerOneWinText; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     winText = _playerTwoWinText; | ||||
|                 } | ||||
| 
 | ||||
|                 var textDimensions = Font.MeasureString(winText); | ||||
| 
 | ||||
|                 SendMessage(new UITextSpawnMessage( | ||||
|                     new MoonTools.Structs.Position2D( | ||||
|                         (playAreaComponent.Width - textDimensions.X) / 2, | ||||
|                         playAreaComponent.Height / 4 | ||||
|                     ), | ||||
|                     Font, | ||||
|                     winText | ||||
|                 )); | ||||
| 
 | ||||
|                 SendMessage(new ChangeGameStateMessage(GameState.Title), 2); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -4,8 +4,13 @@ using PongFE.Messages; | |||
| 
 | ||||
| namespace PongFE.Engines | ||||
| { | ||||
|     [Reads(typeof(ScoreComponent))] | ||||
|     [Reads( | ||||
|         typeof(ScoreComponent), | ||||
|         typeof(PlayerComponent), | ||||
|         typeof(BallParametersComponent) | ||||
|     )] | ||||
|     [Receives(typeof(ScoreMessage))] | ||||
|     [Sends(typeof(GameWinMessage), typeof(BallSpawnMessage))] | ||||
|     [Writes(typeof(ScoreComponent))] | ||||
|     public class ScoreEngine : Engine | ||||
|     { | ||||
|  | @ -17,6 +22,26 @@ namespace PongFE.Engines | |||
|                 { | ||||
|                     ref readonly var scoreComponent = ref GetComponent<ScoreComponent>(scoreMessage.Entity); | ||||
|                     SetComponent(scoreMessage.Entity, new ScoreComponent(scoreComponent.Score + 1)); | ||||
| 
 | ||||
|                     if (scoreComponent.Score + 1 >= 2) | ||||
|                     { | ||||
|                         ref readonly var playerComponent = ref GetComponent<PlayerComponent>(scoreMessage.Entity); | ||||
|                         SendMessage(new GameWinMessage(playerComponent.PlayerIndex)); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         ref readonly var ballParametersComponent = ref ReadComponent<BallParametersComponent>(); | ||||
| 
 | ||||
|                         SendMessage( | ||||
|                             new BallSpawnMessage( | ||||
|                                 new MoonTools.Structs.Position2D(640, (int)MathHelper.RandomFloat(20, 700)), | ||||
|                                 ballParametersComponent.Speed, | ||||
|                                 16, | ||||
|                                 16 | ||||
|                             ), | ||||
|                             ballParametersComponent.Delay | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -32,7 +32,6 @@ namespace PongFE.Spawners | |||
|             AddComponent(ball, new BounceResponseComponent()); | ||||
|             AddComponent(ball, new CanBeTrackedComponent()); | ||||
|             AddComponent(ball, new CanBeDestroyedComponent()); | ||||
|             AddComponent(ball, new SpawnBallAfterDestroyComponent(message.Speed, 0.5f)); | ||||
|             AddComponent(ball, new IncreaseScoreAfterDestroyComponent()); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,17 @@ | |||
| using Encompass; | ||||
| using PongFE.Components; | ||||
| using PongFE.Messages; | ||||
| 
 | ||||
| namespace PongFE.Spawners | ||||
| { | ||||
|     public class UITextSpawner : Spawner<UITextSpawnMessage> | ||||
|     { | ||||
|         protected override void Spawn(UITextSpawnMessage message) | ||||
|         { | ||||
|             var entity = CreateEntity(); | ||||
| 
 | ||||
|             AddComponent(entity, new PositionComponent(message.Position)); | ||||
|             AddComponent(entity, new UITextComponent(message.Font, message.Text)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -26,6 +26,7 @@ namespace PongFE.Enums | |||
| 
 | ||||
|     public enum GameState | ||||
|     { | ||||
|         Init, | ||||
|         Title, | ||||
|         Game | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,15 @@ | |||
| using Encompass; | ||||
| using PongFE.Enums; | ||||
| 
 | ||||
| namespace PongFE.Messages | ||||
| { | ||||
|     public struct GameWinMessage : IMessage | ||||
|     { | ||||
|         public PlayerIndex PlayerIndex { get; } | ||||
| 
 | ||||
|         public GameWinMessage(PlayerIndex playerIndex) | ||||
|         { | ||||
|             PlayerIndex = playerIndex; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,20 @@ | |||
| using Encompass; | ||||
| using MoonTools.Structs; | ||||
| using SpriteFontPlus; | ||||
| 
 | ||||
| namespace PongFE.Messages | ||||
| { | ||||
|     public struct UITextSpawnMessage : IMessage | ||||
|     { | ||||
|         public Position2D Position { get; } | ||||
|         public string Text { get; } | ||||
|         public DynamicSpriteFont Font { get; } | ||||
| 
 | ||||
|         public UITextSpawnMessage(Position2D position, DynamicSpriteFont font, string text) | ||||
|         { | ||||
|             Position = position; | ||||
|             Font = font; | ||||
|             Text = text; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -69,7 +69,7 @@ namespace PongFE | |||
|                 48 | ||||
|             ); | ||||
| 
 | ||||
|             WorldBuilder.AddEngine(new GameStateEngine()); | ||||
|             WorldBuilder.AddEngine(new GameStateEngine(ScoreFont, InstructionFont)); | ||||
|             WorldBuilder.AddEngine(new InputEngine()); | ||||
|             WorldBuilder.AddEngine(new PaddleMovementEngine()); | ||||
|             WorldBuilder.AddEngine(new VelocityEngine()); | ||||
|  | @ -82,23 +82,29 @@ namespace PongFE | |||
|             WorldBuilder.AddEngine(new UpdatePositionEngine()); | ||||
|             WorldBuilder.AddEngine(new UpdateVelocityEngine()); | ||||
|             WorldBuilder.AddEngine(new ComputerControlEngine()); | ||||
|             WorldBuilder.AddEngine(new GameWinEngine(ScoreFont)); | ||||
| 
 | ||||
|             WorldBuilder.AddEngine(new BallSpawner(WhitePixel)); | ||||
|             WorldBuilder.AddEngine(new BoundarySpawner()); | ||||
|             WorldBuilder.AddEngine(new GoalBoundarySpawner()); | ||||
|             WorldBuilder.AddEngine(new PaddleSpawner(WhitePixel)); | ||||
|             WorldBuilder.AddEngine(new UITextSpawner()); | ||||
| 
 | ||||
|             WorldBuilder.AddOrderedRenderer(new Texture2DRenderer(SpriteBatch)); | ||||
|             WorldBuilder.AddGeneralRenderer(new CenterLineRenderer(SpriteBatch, WhitePixel), 0); | ||||
|             WorldBuilder.AddGeneralRenderer(new ScoreRenderer(SpriteBatch, ScoreFont), 0); | ||||
|             WorldBuilder.AddGeneralRenderer(new TitleRenderer(SpriteBatch, ScoreFont, InstructionFont), 0); | ||||
|             WorldBuilder.AddGeneralRenderer(new UITextRenderer(SpriteBatch), 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)); | ||||
|             WorldBuilder.SetComponent(gameStateEntity, new GameStateComponent(GameState.Init)); | ||||
| 
 | ||||
|             var ballParametersEntity = WorldBuilder.CreateEntity(); | ||||
|             WorldBuilder.SetComponent(ballParametersEntity, new BallParametersComponent(500, 0.5)); | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new ChangeGameStateMessage(GameState.Title)); | ||||
|             World = WorldBuilder.Build(); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,47 +0,0 @@ | |||
| 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<GameStateComponent>(); | ||||
|             ref readonly var playAreaComponent = ref ReadComponent<PlayAreaComponent>(); | ||||
| 
 | ||||
|             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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,35 @@ | |||
| using Encompass; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Graphics; | ||||
| using PongFE.Components; | ||||
| using PongFE.Extensions; | ||||
| using SpriteFontPlus; | ||||
| 
 | ||||
| namespace PongFE.Renderers | ||||
| { | ||||
|     public class UITextRenderer : GeneralRenderer | ||||
|     { | ||||
|         private SpriteBatch SpriteBatch { get; } | ||||
| 
 | ||||
|         public UITextRenderer(SpriteBatch spriteBatch) | ||||
|         { | ||||
|             SpriteBatch = spriteBatch; | ||||
|         } | ||||
| 
 | ||||
|         public override void Render() | ||||
|         { | ||||
|             foreach (ref readonly var entity in ReadEntities<UITextComponent>()) | ||||
|             { | ||||
|                 ref readonly var uiTextComponent = ref GetComponent<UITextComponent>(entity); | ||||
|                 ref readonly var positionComponent = ref GetComponent<PositionComponent>(entity); | ||||
| 
 | ||||
|                 SpriteBatch.DrawString( | ||||
|                     uiTextComponent.Font, | ||||
|                     uiTextComponent.Text, | ||||
|                     positionComponent.Position.ToXNAVector(), | ||||
|                     Color.White | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit 59014c7a9e7c3c90b902c8025d907a33a0ffb75c | ||||
| Subproject commit b4a5a4c66adb1fe268954acdfb6839bd21189b1d | ||||
		Loading…
	
		Reference in New Issue