# Direct Enemy Control

### Introduction

This tutorial covers how to create enemy movement in a top down game with direct control over the enemy's input device. Compared to the [Enemy Pathfinding](https://docs.flatredball.com/flatredball/tutorials/top-down-entity/enemy-movement/enemy-pathfinding) tutorial, this tutorial shows how to directly control the input device manually. This approach is considered *low level* and is not recommended for beginners. If your game includes enemies which can pathfind through a map then the [Enemy Pathfinding](https://docs.flatredball.com/flatredball/tutorials/top-down-entity/enemy-movement/enemy-pathfinding) tutorial is recommended.

### New Project Setup

This project tutorial assumes a Top Down Standard starting point (using the wizard), but the steps here can be used to add an Enemy entity to any project. We assume that the game already has levels.

### Enemy Entity

We'll be creating a new Enemy entity for this tutorial. To do this:

1. Click the **Quick Actions** tab
2. Click the **Add Entity** button

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-c3e7f1ec232386e98f181d9675ec9414e4fe81d4%2F2022-03-img_6230b5fde30ba.png?alt=media)
3. Enter the name **Enemy**
4. Check **AxisAlignedRectangle**
5. Check **Top-Down** for the **Input Movement Type**
6. Leave the rest of the defaults and click **OK**

![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-35d0f9dd1df95773609fa767e4c1331d0c1eed54%2F2022-03-img_6230b8a8de03d.png?alt=media)

We will also change the color of the enemy rectangle to tell it apart from the player:

1. Expand the Enemy **Object** folder
2. Select **AxisAlignedRectangleInstance**
3. Select the **Variables** tab
4. Change **Width** to **16**
5. Change **Height** to **16**
6. Change **Color** to **Red**

![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-dc6312de14191a024576dd1e73e59dda4a669160%2F2022-03-img_6230b9313ef12.png?alt=media)

### Adding an Enemy to Level1

To add an enemy to Level1:

1. Expand the Screens folder, then expand Level1's **Objects** folder
2. Select the **EnemyList**
3. Click the **Quick Actions** tab
4. Click **Add a new Enemy to Enemy List**<br>

   <figure><img src="https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-209a5c5b0ab66aa9c2a5033a943b0db4767767f1%2F2022-03-img_6230b9bfbb45e.png?alt=media" alt=""><figcaption></figcaption></figure>
5. Modify the X and Y values for the new enemy so it is inside of the level boundaries by changing **X to 160** and **Y to -160**

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-40bab42924b2a40a54f56dadcd9721a86dee59a9%2F2022-03-img_6230ba2a14f07.png?alt=media)

### Setting the InputDevice

So far our Enemy instance is an entity with no behavior - it simply stays in the same spot when the game runs. First, we'll mark it as using Top-Down movement:

1. Select the **Enemy** entity
2. Click the **Entity Input Movement** tab
3. Set **Input Movement Type** to **Top-Down**
4. Set **Input Device** to **None (Can Assign in Code)**

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-b1721afd9b468275f5a80865b09e8f9efa19111d%2F2022-03-img_6230bae6a419f.png?alt=media)

Now our Enemy has the behavior of top-down movement, but it is not using an input device for movement. Custom input can be set by defining an input device class which inherits from **FlatRedBall.Input.InputDeviceBase**. To do this:

1. Open the project in Visual Studio
2. Create a new class called **EnemyInput**. Mine is in an Input folder.

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-11756af349fca9d53243c852bcc3a9bfd037ea61%2F2022-03-img_6230bbff0fb59.png?alt=media)

The EnemyInput class needs to inhert from the FlatRedBall.Input.InputDeviceBase class which provides virtual methods to control how the input device behaves. Although the InputDeviceBase class offers many virtual methods, the only two that the top-down movement logic uses are:

* GetDefault2DInputX
* GetDefault2DInputY

We can override these to return values between -1 and 1. In this case we'll return constant values to test the functionality, as shown in the following code snippet.

```csharp
internal class EnemyInput : FlatRedBall.Input.InputDeviceBase
{
    protected override float GetDefault2DInputX()
    {
        return 1.0f; // 1 means all the way to the right
    }
    protected override float GetDefault2DInputY()
    {
        return -.5f; // Negative values are down, so -.5 means halfway down
    }
}
```

Next we need to assign the EnemyInput on the Enemy. To do this:

1. Open the **Entities/Enemy.cs** file in Visual Studio
2. Modify the **CustomInitialize** as shown in the following snippet:

```csharp
public partial class Enemy
{
    private void CustomInitialize()
    {
        var input = new Input.EnemyInput();
        this.InitializeTopDownInput(input);
    }
    ...
```

Now we can run the game and see the enemy move down to the right.

<figure><img src="https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-74a63be91ccd98bddb3e75130a818662dc32e714%2F2022-03-15_10-27-50.gif?alt=media" alt=""><figcaption><p>Enemy moving down and to the right</p></figcaption></figure>

### Building the Enemy Input

This tutorial primarily shows how to create an EnemyInput class which can be used to control your enemy. So far the device returns constant values for GetDefault2DInputX and GetDefault2DInputY. A real game would use logic to determine what to return, such as the position of the Player, or how far along the enemy has moved along a patrol path.

At this point the rest of the implementation is up to you depending on your needs.&#x20;
