title screen

main
Evan Hemsley 2020-07-18 14:41:32 -07:00
parent 3251bcf7fd
commit 1c57a4a79f
7 changed files with 255 additions and 69 deletions

View File

@ -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;
}
}
}

View File

@ -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<GameStateComponent>();
ref readonly var gameStateComponent = ref GetComponent<GameStateComponent>(gameStateEntity);
if (gameStateComponent.GameState == GameState.Title)
{
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
{
EndTitle();
StartGame();
SetComponent(gameStateEntity, new GameStateComponent(GameState.Game));
}
}
if (SomeMessage<ChangeGameStateMessage>())
{
ref readonly var changeGameStateMessage = ref ReadMessage<ChangeGameStateMessage>();
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<PositionComponent>();
}
private void StartTitle()
{
}
private void EndTitle()
{
}
}
}

View File

@ -23,4 +23,10 @@ namespace PongFE.Enums
Player,
Computer
}
public enum GameState
{
Title,
Game
}
}

View File

@ -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;
}
}
}

View File

@ -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();
}

View File

@ -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<PlayAreaComponent>();
ref readonly var gameStateComponent = ref ReadComponent<GameStateComponent>();
DrawDottedLine(playAreaComponent.Width / 2, 0, playAreaComponent.Width / 2, playAreaComponent.Height, 20, 20);
if (gameStateComponent.GameState == GameState.Game)
{
ref readonly var playAreaComponent = ref ReadComponent<PlayAreaComponent>();
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)

View File

@ -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<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);
}
}
}
}