encompass-cs-docs/content/pong/ball/bouncing/collision_response.md

2.9 KiB

title date weight
Collision Response 2019-05-28T20:39:54-07:00 800

Now the ball needs to bounce off of the paddle. What does that mean? If there is a horizontal collision, we reverse the horizontal velocity. Otherwise we reverse the vertical velocity.

In PongFE/Engines/BounceEngine.cs:

using System.Numerics;
using Encompass;
using PongFE.Components;
using PongFE.Messages;

namespace PongFE.Engines
{
    [Reads(
        typeof(BounceResponseComponent),
        typeof(VelocityComponent)
    )]
    [Receives(typeof(BounceMessage))]
    [Sends(typeof(UpdateVelocityMessage))]
    public class BounceEngine : Engine
    {
        public override void Update(double dt)
        {
            foreach (ref readonly var message in ReadMessages<BounceMessage>())
            {
                if (HasComponent<BounceResponseComponent>(message.Entity) && HasComponent<VelocityComponent>(message.Entity))
                {
                    ref readonly var velocityComponent = ref GetComponent<VelocityComponent>(message.Entity);

                    Vector2 newVelocity;
                    if (message.HitOrientation == HitOrientation.Horizontal)
                    {
                        newVelocity =
                            new Vector2(-velocityComponent.Velocity.X, velocityComponent.Velocity.Y);
                    }
                    else
                    {
                        newVelocity =
                            new Vector2(velocityComponent.Velocity.X, -velocityComponent.Velocity.Y);
                    }

                    SendMessage(new UpdateVelocityMessage(message.Entity, newVelocity));
                }
            }
        }
    }
}

Let's create that UpdateVelocity behavior.

In PongFE/Messages/UpdateVelocityMessage.cs:

using System.Numerics;
using Encompass;

namespace PongFE.Messages
{
    public struct UpdateVelocityMessage : IMessage, IHasEntity
    {
        public Entity Entity { get; }
        public Vector2 Velocity { get; }

        public UpdateVelocityMessage(Entity entity, Vector2 velocity)
        {
            Entity = entity;
            Velocity = velocity;
        }
    }
}

In PongFE/Engines/UpdateVelocityEngine.cs:

using Encompass;
using PongFE.Components;
using PongFE.Messages;

namespace PongFE.Engines
{
    [Receives(typeof(UpdateVelocityMessage))]
    [Writes(typeof(VelocityComponent))]
    public class UpdateVelocityEngine : Engine
    {
        public override void Update(double dt)
        {
            foreach (ref readonly var message in ReadMessages<UpdateVelocityMessage>())
            {
                SetComponent(message.Entity, new VelocityComponent(message.Velocity));
            }
        }
    }
}

In PongFEGame.cs:

    WorldBuilder.AddEngine(new BounceEngine());
    WorldBuilder.AddEngine(new UpdateVelocityEngine());

That's it for defining our collision behavior!