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