---
title: "Input Handling"
date: 2019-05-23T13:38:42-07:00
weight: 10
---

In Pong, the paddles move when the player moves the joystick on their controller up or down.

We currently have a MotionEngine that reads MotionMessages and moves the PositionComponents they reference.

So... it makes sense that we could have an InputEngine that sends MotionMessages, yeah?

Create a file: **PongFE/Engines/InputEngine.cs**

```cs
using Encompass;
using Microsoft.Xna.Framework.Input;
using PongFE.Messages;

public class InputEngine : Engine
{
    public override void Update(double dt)
    {
        var keyboardState = Keyboard.GetState();

        if (keyboardState.IsKeyDown(Keys.Down))
        {
            SendMessage(new MotionMessage(
        }
    }
}
```

*record scratch*

Uh oh. **SendMessage** emits a message, as the name suggests, and we can use it to send out a MotionMessage. But it needs a reference to our paddle entity.

At this point, you might be tempted to attach our paddle entity as a property on InputEngine. This would be a *terrible mistake*. We *absolutely never* want to have our game state directly attached to the state of an Engine.

What we want instead is to have a component that the InputEngine can use to look up the appropriate entity. This is a concept I refer to as *tagging*. Essentially, we use a Component to designate that an Entity is a certain kind of object that we want to be able to reference.

Create a file: **PongFE/Components/PlayerInputComponent.cs**

```cs
using Encompass;

namespace PongFE.Components
{
    public enum PlayerIndex
    {
        One,
        Two
    }

    public struct PlayerInputComponent : IComponent
    {
        public PlayerIndex PlayerIndex { get; }

        public PlayerInputComponent(PlayerIndex playerIndex)
        {
            PlayerIndex = playerIndex;
        }
    }
}

```

Why an *enum* instead of just an integer or something? When we write programs it is very easy to shoot ourselves in the foot. What if someone accidentally typed -1 in as a value or something? Enums structure our data to make it harder for us to make silly mistakes like this.

Let's add this component to our paddle entity.

In **PongFEGame.cs**:

```cs
    ...

    var paddle = WorldBuilder.CreateEntity();
    WorldBuilder.SetComponent(paddle, new PlayerInputComponent(PongFE.Components.PlayerIndex.One));
    WorldBuilder.SetComponent(paddle, new PositionComponent(new MoonTools.Structs.Position2D(5, 5)));
    WorldBuilder.SetComponent(paddle, new Texture2DComponent(PaddleTexture, 0));

    ...
```

Now we can go back to our InputEngine.

```cs
using Encompass;
using Microsoft.Xna.Framework.Input;
using PongFE.Components;
using PongFE.Messages;

namespace PongFE.Engines
{
    [Reads(typeof(PlayerInputComponent))]
    [Sends(typeof(MotionMessage))]
    public class InputEngine : Engine
    {
        public override void Update(double dt)
        {
            var keyboardState = Keyboard.GetState();

            foreach (ref readonly var playerInputEntity in ReadEntities<PlayerInputComponent>())
            {
                ref readonly var playerInputComponent = ref GetComponent<PlayerInputComponent>(playerInputEntity);

                if (playerInputComponent.PlayerIndex == PlayerIndex.One)
                {
                    if (keyboardState.IsKeyDown(Keys.Down))
                    {
                        SendMessage(new MotionMessage(playerInputEntity, new System.Numerics.Vector2(0, 10)));
                    }
                }
            }
        }
    }
}
```

Engines have total freedom to read anything in the game state that they desire. This gives Engines a lot of flexibility to do what they need to do. In this case, **ReadEntities<PlayerInputComponent>** lets us get a reference to each entity that has a PlayerInputComponent attached to it. From there, we can get the specific PlayerInputComponent for that Entity, check which PlayerIndex it contains, and then send a message to its entity if the Down key is pressed.

Also, remember when we had to declare **Reads** and **Receives** and **Writes** on our MotionEngine? Well, similarly, we have to declare **Sends** when our engine emits a certain kind of Message. Otherwise Encompass will get mad at us and crash the game for our own safety.

Let's add our PlayerInputEngine to the WorldBuilder.

In **PongFEGame.cs**:

```cs
    ...

    WorldBuilder.AddEngine(new InputEngine());
    WorldBuilder.AddEngine(new MotionEngine());
    WorldBuilder.AddOrderedRenderer(new Texture2DRenderer(SpriteBatch));

    ...
```

It doesn't matter which order they go in, because remember, Encompass figures it out automatically. I just prefer this order for some reason. Once we have a lot of Engines it stops mattering pretty quickly anyway.
