paddle bounce

main
Evan Hemsley 2020-07-17 22:53:22 -07:00
parent f347780019
commit 3251bcf7fd
12 changed files with 121 additions and 12 deletions

View File

@ -0,0 +1,6 @@
using Encompass;
namespace PongFE.Components
{
public struct CanCauseAngledBounceComponent : IComponent { }
}

View File

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

View File

@ -4,10 +4,12 @@ namespace PongFE.Components
{ {
public struct SpawnBallAfterDestroyComponent : IComponent public struct SpawnBallAfterDestroyComponent : IComponent
{ {
public float Speed { get; }
public float Seconds { get; } public float Seconds { get; }
public SpawnBallAfterDestroyComponent(float seconds) public SpawnBallAfterDestroyComponent(float speed, float seconds)
{ {
Speed = speed;
Seconds = seconds; Seconds = seconds;
} }
} }

View File

@ -7,13 +7,11 @@ namespace PongFE.Components
public struct Texture2DComponent : IComponent, IDrawableComponent public struct Texture2DComponent : IComponent, IDrawableComponent
{ {
public Texture2D Texture { get; } public Texture2D Texture { get; }
public Vector2 Scale { get; }
public int Layer { get; } public int Layer { get; }
public Texture2DComponent(Texture2D texture, int layer, Vector2 scale) public Texture2DComponent(Texture2D texture, int layer)
{ {
Texture = texture; Texture = texture;
Scale = scale;
Layer = layer; Layer = layer;
} }
} }

View File

@ -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<AngledBounceMessage>())
{
if (HasComponent<BounceResponseComponent>(message.Bounced))
{
ref readonly var bouncedPositionComponent = ref GetComponent<PositionComponent>(message.Bounced);
ref readonly var velocityComponent = ref GetComponent<VelocityComponent>(message.Bounced);
ref readonly var bouncedScaleComponent = ref GetComponent<ScaleComponent>(message.Bounced);
ref readonly var bouncerPositionComponent = ref GetComponent<PositionComponent>(message.Bouncer);
ref readonly var bouncerScaleComponent = ref GetComponent<ScaleComponent>(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));
}
}
}
}
}

View File

@ -7,6 +7,7 @@ namespace PongFE.Engines
{ {
[Reads( [Reads(
typeof(CanCauseBounceComponent), typeof(CanCauseBounceComponent),
typeof(CanCauseAngledBounceComponent),
typeof(CanBeBouncedComponent), typeof(CanBeBouncedComponent),
typeof(CanDestroyComponent), typeof(CanDestroyComponent),
typeof(CanBeDestroyedComponent) typeof(CanBeDestroyedComponent)
@ -14,6 +15,7 @@ namespace PongFE.Engines
[Receives(typeof(CollisionMessage))] [Receives(typeof(CollisionMessage))]
[Sends( [Sends(
typeof(BounceMessage), typeof(BounceMessage),
typeof(AngledBounceMessage),
typeof(DestroyMessage) typeof(DestroyMessage)
)] )]
public class CollisionEngine : Engine public class CollisionEngine : Engine
@ -25,6 +27,9 @@ namespace PongFE.Engines
CheckBounce(message.EntityA, message.EntityB, message.HitOrientation); CheckBounce(message.EntityA, message.EntityB, message.HitOrientation);
CheckBounce(message.EntityB, message.EntityA, 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.EntityA, message.EntityB);
CheckDestroy(message.EntityB, message.EntityA); CheckDestroy(message.EntityB, message.EntityA);
} }
@ -41,6 +46,17 @@ namespace PongFE.Engines
} }
} }
private void CheckAngledBounce(Entity a, Entity b, HitOrientation hitOrientation)
{
if (HasComponent<CanCauseAngledBounceComponent>(a))
{
if (HasComponent<CanBeBouncedComponent>(b))
{
SendMessage(new AngledBounceMessage(a, b, hitOrientation));
}
}
}
private void CheckDestroy(Entity a, Entity b) private void CheckDestroy(Entity a, Entity b)
{ {
if (HasComponent<CanDestroyComponent>(a)) if (HasComponent<CanDestroyComponent>(a))

View File

@ -26,7 +26,7 @@ namespace PongFE.Engines
SendMessage( SendMessage(
new BallSpawnMessage( new BallSpawnMessage(
new MoonTools.Structs.Position2D(640, 360), new MoonTools.Structs.Position2D(640, 360),
300, respawnComponent.Speed,
16, 16,
16 16
), ),

View File

@ -25,13 +25,14 @@ namespace PongFE.Spawners
AddComponent(ball, new PositionComponent(message.Position)); AddComponent(ball, new PositionComponent(message.Position));
AddComponent(ball, new VelocityComponent(velocity)); 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 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 CanBeBouncedComponent());
AddComponent(ball, new BounceResponseComponent()); AddComponent(ball, new BounceResponseComponent());
AddComponent(ball, new CanBeTrackedComponent()); AddComponent(ball, new CanBeTrackedComponent());
AddComponent(ball, new CanBeDestroyedComponent()); AddComponent(ball, new CanBeDestroyedComponent());
AddComponent(ball, new SpawnBallAfterDestroyComponent(0.5f)); AddComponent(ball, new SpawnBallAfterDestroyComponent(message.Speed, 0.5f));
AddComponent(ball, new IncreaseScoreAfterDestroyComponent()); AddComponent(ball, new IncreaseScoreAfterDestroyComponent());
} }
} }

View File

@ -26,12 +26,13 @@ namespace PongFE.Spawners
{ {
AddComponent(paddle, new ComputerControlComponent()); 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 PlayerComponent(message.PlayerIndex));
AddComponent(paddle, new PaddleMoveSpeedComponent(400)); 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 CollisionComponent(new MoonTools.Bonk.Rectangle(0, 0, message.Width, message.Height)));
AddComponent(paddle, new CanCauseBounceComponent()); AddComponent(paddle, new CanCauseAngledBounceComponent());
AddComponent(paddle, new Texture2DComponent(WhitePixel, 0, new System.Numerics.Vector2(message.Width, message.Height))); AddComponent(paddle, new Texture2DComponent(WhitePixel, 0));
} }
} }
} }

View File

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

View File

@ -68,6 +68,7 @@ namespace PongFE
WorldBuilder.AddEngine(new VelocityEngine()); WorldBuilder.AddEngine(new VelocityEngine());
WorldBuilder.AddEngine(new MotionEngine()); WorldBuilder.AddEngine(new MotionEngine());
WorldBuilder.AddEngine(new CollisionEngine()); WorldBuilder.AddEngine(new CollisionEngine());
WorldBuilder.AddEngine(new AngledBounceEngine());
WorldBuilder.AddEngine(new BounceEngine()); WorldBuilder.AddEngine(new BounceEngine());
WorldBuilder.AddEngine(new DestroyEngine()); WorldBuilder.AddEngine(new DestroyEngine());
WorldBuilder.AddEngine(new ScoreEngine()); WorldBuilder.AddEngine(new ScoreEngine());
@ -107,7 +108,7 @@ namespace PongFE
WorldBuilder.SendMessage( WorldBuilder.SendMessage(
new BallSpawnMessage( new BallSpawnMessage(
new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH / 2, PLAY_AREA_HEIGHT / 2), new MoonTools.Structs.Position2D(PLAY_AREA_WIDTH / 2, PLAY_AREA_HEIGHT / 2),
300, 500,
16, 16,
16 16
) )

View File

@ -18,6 +18,7 @@ namespace PongFE.Renderers
public override void Render(Entity entity, in Texture2DComponent textureComponent) public override void Render(Entity entity, in Texture2DComponent textureComponent)
{ {
ref readonly var positionComponent = ref GetComponent<PositionComponent>(entity); ref readonly var positionComponent = ref GetComponent<PositionComponent>(entity);
ref readonly var scaleComponent = ref GetComponent<ScaleComponent>(entity);
_spriteBatch.Draw( _spriteBatch.Draw(
textureComponent.Texture, textureComponent.Texture,
@ -26,7 +27,7 @@ namespace PongFE.Renderers
Color.White, Color.White,
0, 0,
Vector2.Zero, Vector2.Zero,
textureComponent.Scale.ToXNAVector(), new Vector2(scaleComponent.Width, scaleComponent.Height),
SpriteEffects.None, SpriteEffects.None,
0 0
); );