diff --git a/PongFE/Components/CanCauseAngledBounceComponent.cs b/PongFE/Components/CanCauseAngledBounceComponent.cs new file mode 100644 index 0000000..a390078 --- /dev/null +++ b/PongFE/Components/CanCauseAngledBounceComponent.cs @@ -0,0 +1,6 @@ +using Encompass; + +namespace PongFE.Components +{ + public struct CanCauseAngledBounceComponent : IComponent { } +} diff --git a/PongFE/Components/ScaleComponent.cs b/PongFE/Components/ScaleComponent.cs new file mode 100644 index 0000000..75be731 --- /dev/null +++ b/PongFE/Components/ScaleComponent.cs @@ -0,0 +1,16 @@ +using Encompass; + +namespace PongFE.Components +{ + public struct ScaleComponent : IComponent + { + public int Width { get; } + public int Height { get; } + + public ScaleComponent(int width, int height) + { + Width = width; + Height = height; + } + } +} diff --git a/PongFE/Components/SpawnBallAfterDestroyComponent.cs b/PongFE/Components/SpawnBallAfterDestroyComponent.cs index d8dcd68..912596e 100644 --- a/PongFE/Components/SpawnBallAfterDestroyComponent.cs +++ b/PongFE/Components/SpawnBallAfterDestroyComponent.cs @@ -4,10 +4,12 @@ namespace PongFE.Components { public struct SpawnBallAfterDestroyComponent : IComponent { + public float Speed { get; } public float Seconds { get; } - public SpawnBallAfterDestroyComponent(float seconds) + public SpawnBallAfterDestroyComponent(float speed, float seconds) { + Speed = speed; Seconds = seconds; } } diff --git a/PongFE/Components/Texture2DComponent.cs b/PongFE/Components/Texture2DComponent.cs index c0e596f..2fedab0 100644 --- a/PongFE/Components/Texture2DComponent.cs +++ b/PongFE/Components/Texture2DComponent.cs @@ -7,13 +7,11 @@ namespace PongFE.Components public struct Texture2DComponent : IComponent, IDrawableComponent { public Texture2D Texture { get; } - public Vector2 Scale { get; } public int Layer { get; } - public Texture2DComponent(Texture2D texture, int layer, Vector2 scale) + public Texture2DComponent(Texture2D texture, int layer) { Texture = texture; - Scale = scale; Layer = layer; } } diff --git a/PongFE/Engines/AngledBounceEngine.cs b/PongFE/Engines/AngledBounceEngine.cs new file mode 100644 index 0000000..5df4e71 --- /dev/null +++ b/PongFE/Engines/AngledBounceEngine.cs @@ -0,0 +1,48 @@ +using System.Numerics; +using Encompass; +using PongFE.Components; +using PongFE.Extensions; +using PongFE.Messages; + +namespace PongFE.Engines +{ + [Reads( + typeof(PositionComponent), + typeof(VelocityComponent), + typeof(ScaleComponent), + typeof(BounceResponseComponent) + )] + [Receives(typeof(AngledBounceMessage))] + [Sends(typeof(UpdateVelocityMessage))] + public class AngledBounceEngine : Engine + { + public override void Update(double dt) + { + foreach (ref readonly var message in ReadMessages()) + { + if (HasComponent(message.Bounced)) + { + ref readonly var bouncedPositionComponent = ref GetComponent(message.Bounced); + ref readonly var velocityComponent = ref GetComponent(message.Bounced); + ref readonly var bouncedScaleComponent = ref GetComponent(message.Bounced); + + ref readonly var bouncerPositionComponent = ref GetComponent(message.Bouncer); + ref readonly var bouncerScaleComponent = ref GetComponent(message.Bouncer); + + var bouncedY = bouncedPositionComponent.Position.Y + bouncedScaleComponent.Height / 2; + var bouncerY = bouncerPositionComponent.Position.Y + bouncerScaleComponent.Height / 2; + + var speed = velocityComponent.Velocity.Length(); + var horizontal = velocityComponent.Velocity.X < 0 ? 1 : -1; + var diff = bouncedY - bouncerY; + var scale = (float)diff / (bouncerScaleComponent.Height / 2); + var rotation = scale * System.Math.PI / 4; + + Vector2 newVelocity = new Vector2(speed, 0).Rotate((float)rotation) * new Vector2(horizontal, 1); + + SendMessage(new UpdateVelocityMessage(message.Bounced, newVelocity)); + } + } + } + } +} diff --git a/PongFE/Engines/CollisionEngine.cs b/PongFE/Engines/CollisionEngine.cs index 15c1fae..692f259 100644 --- a/PongFE/Engines/CollisionEngine.cs +++ b/PongFE/Engines/CollisionEngine.cs @@ -7,6 +7,7 @@ namespace PongFE.Engines { [Reads( typeof(CanCauseBounceComponent), + typeof(CanCauseAngledBounceComponent), typeof(CanBeBouncedComponent), typeof(CanDestroyComponent), typeof(CanBeDestroyedComponent) @@ -14,6 +15,7 @@ namespace PongFE.Engines [Receives(typeof(CollisionMessage))] [Sends( typeof(BounceMessage), + typeof(AngledBounceMessage), typeof(DestroyMessage) )] public class CollisionEngine : Engine @@ -25,6 +27,9 @@ namespace PongFE.Engines CheckBounce(message.EntityA, message.EntityB, message.HitOrientation); CheckBounce(message.EntityB, message.EntityA, message.HitOrientation); + CheckAngledBounce(message.EntityA, message.EntityB, message.HitOrientation); + CheckAngledBounce(message.EntityB, message.EntityA, message.HitOrientation); + CheckDestroy(message.EntityA, message.EntityB); CheckDestroy(message.EntityB, message.EntityA); } @@ -41,6 +46,17 @@ namespace PongFE.Engines } } + private void CheckAngledBounce(Entity a, Entity b, HitOrientation hitOrientation) + { + if (HasComponent(a)) + { + if (HasComponent(b)) + { + SendMessage(new AngledBounceMessage(a, b, hitOrientation)); + } + } + } + private void CheckDestroy(Entity a, Entity b) { if (HasComponent(a)) diff --git a/PongFE/Engines/DestroyEngine.cs b/PongFE/Engines/DestroyEngine.cs index 52bcc3d..64e0697 100644 --- a/PongFE/Engines/DestroyEngine.cs +++ b/PongFE/Engines/DestroyEngine.cs @@ -26,7 +26,7 @@ namespace PongFE.Engines SendMessage( new BallSpawnMessage( new MoonTools.Structs.Position2D(640, 360), - 300, + respawnComponent.Speed, 16, 16 ), diff --git a/PongFE/Engines/Spawners/BallSpawner.cs b/PongFE/Engines/Spawners/BallSpawner.cs index 0eaa862..a52ff5b 100644 --- a/PongFE/Engines/Spawners/BallSpawner.cs +++ b/PongFE/Engines/Spawners/BallSpawner.cs @@ -25,13 +25,14 @@ namespace PongFE.Spawners AddComponent(ball, new PositionComponent(message.Position)); AddComponent(ball, new VelocityComponent(velocity)); + AddComponent(ball, new ScaleComponent(message.Width, message.Height)); AddComponent(ball, new CollisionComponent(new MoonTools.Bonk.Rectangle(0, 0, 16, 16))); - AddComponent(ball, new Texture2DComponent(WhitePixel, 0, new Vector2(message.Width, message.Height))); + AddComponent(ball, new Texture2DComponent(WhitePixel, 0)); AddComponent(ball, new CanBeBouncedComponent()); AddComponent(ball, new BounceResponseComponent()); AddComponent(ball, new CanBeTrackedComponent()); AddComponent(ball, new CanBeDestroyedComponent()); - AddComponent(ball, new SpawnBallAfterDestroyComponent(0.5f)); + AddComponent(ball, new SpawnBallAfterDestroyComponent(message.Speed, 0.5f)); AddComponent(ball, new IncreaseScoreAfterDestroyComponent()); } } diff --git a/PongFE/Engines/Spawners/PaddleSpawner.cs b/PongFE/Engines/Spawners/PaddleSpawner.cs index 02713db..ed25edf 100644 --- a/PongFE/Engines/Spawners/PaddleSpawner.cs +++ b/PongFE/Engines/Spawners/PaddleSpawner.cs @@ -26,12 +26,13 @@ namespace PongFE.Spawners { AddComponent(paddle, new ComputerControlComponent()); } + AddComponent(paddle, new PositionComponent(message.Position)); + AddComponent(paddle, new ScaleComponent(message.Width, message.Height)); AddComponent(paddle, new PlayerComponent(message.PlayerIndex)); AddComponent(paddle, new PaddleMoveSpeedComponent(400)); - AddComponent(paddle, new PositionComponent(message.Position)); AddComponent(paddle, new CollisionComponent(new MoonTools.Bonk.Rectangle(0, 0, message.Width, message.Height))); - AddComponent(paddle, new CanCauseBounceComponent()); - AddComponent(paddle, new Texture2DComponent(WhitePixel, 0, new System.Numerics.Vector2(message.Width, message.Height))); + AddComponent(paddle, new CanCauseAngledBounceComponent()); + AddComponent(paddle, new Texture2DComponent(WhitePixel, 0)); } } } diff --git a/PongFE/Messages/AngledBounceMessage.cs b/PongFE/Messages/AngledBounceMessage.cs new file mode 100644 index 0000000..631e5a2 --- /dev/null +++ b/PongFE/Messages/AngledBounceMessage.cs @@ -0,0 +1,19 @@ +using Encompass; +using PongFE.Enums; + +namespace PongFE.Messages +{ + public struct AngledBounceMessage : IMessage + { + public Entity Bounced { get; } + public Entity Bouncer { get; } + public HitOrientation HitOrientation { get; } + + public AngledBounceMessage(Entity bouncer, Entity bounced, HitOrientation hitOrientation) + { + Bouncer = bouncer; + Bounced = bounced; + HitOrientation = hitOrientation; + } + } +} diff --git a/PongFE/PongFEGame.cs b/PongFE/PongFEGame.cs index 1d58f4e..7c41a04 100644 --- a/PongFE/PongFEGame.cs +++ b/PongFE/PongFEGame.cs @@ -68,6 +68,7 @@ namespace PongFE WorldBuilder.AddEngine(new VelocityEngine()); WorldBuilder.AddEngine(new MotionEngine()); WorldBuilder.AddEngine(new CollisionEngine()); + WorldBuilder.AddEngine(new AngledBounceEngine()); WorldBuilder.AddEngine(new BounceEngine()); WorldBuilder.AddEngine(new DestroyEngine()); WorldBuilder.AddEngine(new ScoreEngine()); @@ -107,7 +108,7 @@ namespace PongFE WorldBuilder.SendMessage( new BallSpawnMessage( new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH / 2, PLAY_AREA_HEIGHT / 2), - 300, + 500, 16, 16 ) diff --git a/PongFE/Renderers/Texture2DRenderer.cs b/PongFE/Renderers/Texture2DRenderer.cs index 24ee2d3..a36598a 100644 --- a/PongFE/Renderers/Texture2DRenderer.cs +++ b/PongFE/Renderers/Texture2DRenderer.cs @@ -18,6 +18,7 @@ namespace PongFE.Renderers public override void Render(Entity entity, in Texture2DComponent textureComponent) { ref readonly var positionComponent = ref GetComponent(entity); + ref readonly var scaleComponent = ref GetComponent(entity); _spriteBatch.Draw( textureComponent.Texture, @@ -26,7 +27,7 @@ namespace PongFE.Renderers Color.White, 0, Vector2.Zero, - textureComponent.Scale.ToXNAVector(), + new Vector2(scaleComponent.Width, scaleComponent.Height), SpriteEffects.None, 0 );