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 float Speed { get; }
public float Seconds { get; }
public SpawnBallAfterDestroyComponent(float seconds)
public SpawnBallAfterDestroyComponent(float speed, float seconds)
{
Speed = speed;
Seconds = seconds;
}
}

View File

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

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(
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<CanCauseAngledBounceComponent>(a))
{
if (HasComponent<CanBeBouncedComponent>(b))
{
SendMessage(new AngledBounceMessage(a, b, hitOrientation));
}
}
}
private void CheckDestroy(Entity a, Entity b)
{
if (HasComponent<CanDestroyComponent>(a))

View File

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

View File

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

View File

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

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 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
)

View File

@ -18,6 +18,7 @@ namespace PongFE.Renderers
public override void Render(Entity entity, in Texture2DComponent textureComponent)
{
ref readonly var positionComponent = ref GetComponent<PositionComponent>(entity);
ref readonly var scaleComponent = ref GetComponent<ScaleComponent>(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
);