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

2.5 KiB

title date weight
Collision Dispatch 2019-05-28T19:06:03-07:00 700

Let's make the CollisionEngine. All it needs to do is read the CollisionMessages, determine what, if any, kind of collision occurred, and create more specific collision messages from them.

Right now the only collision responses we care about are bounces.

Let's create our Actor, PongFE/Components/CanCauseBounceComponent.cs:

using Encompass;

namespace PongFE.Components
{
    public struct CanCauseBounceComponent : IComponent { }
}

And our Receiver, PongFE/Components/CanBeBouncedComponent.cs:

using Encompass;

namespace PongFE.Components
{
    public struct CanBeBouncedComponent : IComponent { }
}

We'll also need PongFE/Messages/BounceMessage.cs:

using Encompass;
using PongFE.Components;

namespace PongFE.Messages
{
    public struct BounceMessage : IMessage, IHasEntity
    {
        public Entity Entity { get; }
        public HitOrientation HitOrientation { get; }

        public BounceMessage(Entity entity, HitOrientation hitOrientation)
        {
            Entity = entity;
            HitOrientation = hitOrientation;
        }
    }
}

In PongFE/Engines/CollisionEngine.cs:

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

namespace PongFE.Engines
{
    [Reads(
        typeof(CanCauseBounceComponent),
        typeof(CanBeBouncedComponent)
    )]
    [Receives(typeof(CollisionMessage))]
    [Sends(typeof(BounceMessage))]
    public class CollisionEngine : Engine
    {
        public override void Update(double dt)
        {
            foreach (ref readonly var message in ReadMessages<CollisionMessage>())
            {
                CheckBounce(message.EntityA, message.EntityB, message.HitOrientation);
                CheckBounce(message.EntityB, message.EntityA, message.HitOrientation);
            }
        }

        private void CheckBounce(Entity a, Entity b, HitOrientation hitOrientation)
        {
            if (HasComponent<CanCauseBounceComponent>(a))
            {
                if (HasComponent<CanBeBouncedComponent>(b))
                {
                    SendMessage(new BounceMessage(b, hitOrientation));
                }
            }
        }
    }
}

Now we are emitting proper collision messages every time an entity collides with another.

Don't forget to add our new engine in PongFEGame.cs

    WorldBuilder.AddEngine(new CollisionEngine());

Next, we'll make our game actually do something in response to the Bounce message.