arrow-left

All pages
gitbookPowered by GitBook
1 of 4

Loading...

Loading...

Loading...

Loading...

Top Down Basics

Input Device

hashtag
Introduction

This tutorial provides information on how to change the input device used by the entity. By default the entity uses the first Xbox game pad if one is available, otherwise the entity uses the keyboard. Sometimes this functionality is not desired, such as if the game supports multiple players or AI-controlled entities.

hashtag
IInputDevice

The Top Down entity code interacts with the IInputDevice interface, which provides a standard set of values for controlling game objects. Both the Xbox360GamePad and Keyboard implement this interface, so if the default implementation for this interface meets your game's needs, you can use these objects as-is. Otherwise, your game can implement its own IInputDevice to change how the top down entity is controlled. First we'll look at how to customize the input to use different keyboard keys.

hashtag
Changing Input Keys

As mentioned earlier, our Player entity defaults to using an Xbox gamepad if one exists. If not, it uses the keyboard. Even though we won't customize this code, we can see its implementation by looking in Player.Generated.cs and searching for InitializeInput.

Ultimately, these calls make their way to calling CustomInitializeTopDownInput. Since this is a partial method, we need to add it ourselves to our Player if we want to customize the input. To do this:

  1. Go to Player.cs

  2. Add the following code to the Player.cs file

The player will now move around with the IJKL keys (rather than the default WASD). Note that this will also override input even if you have an Xbox gamepad plugged in. If this is not desired, we can change the input if it's using the keyboard. This is an example of how to keep the input device, but only change the movement code conditionally:

This code could contain further updates to change desired input based on other input devices such as Xbox360GamePad.

hashtag
Changing Input Device

The code in the section above modifies which keys are used from the keyboard. It could be expanded to also handle other input devices like Xbox gamepads. However, instead of changing which keys are used when using the keyboard, you may want to change which input device is being used by your player. This is typically done in the GameScreen. This allows the GameScreen to initialize input, especially if your game allows the player to pick which input device to use. For example, to force the player to always use an Xbox gamepad, modify the following code in the GameScreen's CustomInitialize:

hashtag
Creating Multiple Players

If your game followed the previous tutorials, then your GameScreen has a PlayerList with a single Player named Player1. In this setup, the GameScreen will always have at least 1 player, but can have more. A quick way to support multiplayer without any UI is to detect the number of Xbox gamepads plugged in. If more than 1 is plugged in, we can create additional players very easily. The following code will create one player per Xbox gamepad plugged in. Notice that we only create additional players if we have two or more gamepads since the first player is automatically created.

To see more than one player you must have at least two gamepads plugged in to your computer. Also, keep in mind that the players will initially overlap so you must move one to see both.

partial void CustomInitializeTopDownInput()
{
 this.MovementInput = InputManager.Keyboard.Get2DInput(
    Microsoft.Xna.Framework.Input.Keys.J, // Key for left movement
    Microsoft.Xna.Framework.Input.Keys.L, // Key for right movement
    Microsoft.Xna.Framework.Input.Keys.I, // Key for up movement
    Microsoft.Xna.Framework.Input.Keys.K);// Key for down movement
}
partial void CustomInitializeTopDownInput()
{
 if(this.InputDevice is Keyboard keyboard)
 {
   this.MovementInput = keyboard.Get2DInput(
     Microsoft.Xna.Framework.Input.Keys.J, // Key for left movement
     Microsoft.Xna.Framework.Input.Keys.L, // Key for right movement
     Microsoft.Xna.Framework.Input.Keys.I, // Key for up movement
     Microsoft.Xna.Framework.Input.Keys.K);// Key for down movement
 }
}
void CustomInitialize()
{
 // Forces the player to use the first Xbox gamepad:
 Player1.InitializeTopDownInput(InputManager.Xbox360GamePads[0]);
}
void CustomInitialize()
{
 var connectedGamepads = InputManager.Xbox360GamePads
   .Where(item => item.IsConnected)
   .ToArray();

 for(int i = 0; i < connectedGamepads.Length; i++)
 {
   // By default the FlatRedBall project includes one instance of a player, so we don't
   // need to create one for index 0
   if(i > 1)
   {
     // create the player:
     var player = new Player();
     PlayerList.Add(player);
   }
   PlayerList[i].InitializeTopDownInput(connectedGamepads[i]);
 }
}

CurrentMovement

hashtag
Introduction

The CurrentMovement property controls the values used by the top down entity in response to input. The CurrentMovement property can be assigned in code in response to various conditions in your game such as:

  • Collision with different terrain (such as walking through mud)

  • Responding to power-ups (such as collecting a power-up which increases speed)

  • Responding to special moves or input which changes the character's movement variables (such as holding down a run button)

hashtag
Defining Movement Values

Movement values can be defined in the FRB editor or code. If your game has a limited set of movement values, these can be defined in the FRB editor. To do so:

  1. Select an entity

  2. Click the Entity Input Movement tab

  3. Verify that your entity is using the Top Down option for Input Movement Type

The Top Down tab displays all movement values for the selected entity.

hashtag
Assigning Movement Values

You can assign the current movement values in code through the CurrentMovement propety. For example, the following code assigns the movement to FastMovement or Default depending on the state of an Xbox360GamePad:

hashtag
Movement Values and Inheritance

Derived entities can override movement values which are defined by their base entity. For example, consider an Enemy entity with two movement types: Idle and Walk.

A derived entity automatically inherits these movement values as shown in the FRB editor.

Notice that these values are read-only, but they can be overwritten by checking the Overwrite Values radio button.

The name of movement types cannot be changed when overwriting values; however derived entities can add additional movement variables which do not exist in their base.

At runtime the derived entity merges the overwritten values with the base values. For example, the Slime enemy has two movement values, but its Walk value has a max speed of 150 instead of 76.

circle-info

This merging occurs in the generated code for each entity. For example, the following shows what the code in Enemy.Generated.cs looks like. Notice that it merges the base TopDownValuesStatic with its own values.

Setup

hashtag
Introduction

This tutorial sets up an entity with Top Down controls. It provides a default implementation which requires no code. Later tutorials show how to interact with this plugin using code.

hashtag

Click the Add Movement Type button

Add Movement Type button
  • Modify the newly-added movement values as necessary

  • All movement values displayed in the FRB Editor
    Enemy with movement values
    Inherited values
    Overwritten walk variable
    MaxSpeed set to the overwritten value of 150
    Requirements

    The FRB Editor provides support for top-down entities through the Entity Input Movement tab. Any entity can be created as a Top Down entity; however, the most common setup is to have a Player entity which uses top down controls.

    Empty projects can use the Project Setup Wizard to create a top down player entity. Existing games can add top down controls to new or existing entities with a few clicks. This tutorial shows you how to do both.

    hashtag
    Project Setup Using the New Project Wizard Preset

    The simplest way to set your project up is to use the new project wizard. FlatRedBall automatically launches the wizard when creating a new project.

    To create a top-down project, select the Standard Top Down button.

    Now your game should be set up with a fully-functional top-down entity. You can verify this by clicking on the Player entity and then clicking on the Entity Input Movement tab. The Player should be marked as having Top-Down as its Input Movement Type.

    hashtag
    Alternative - Manually Creating GameScreen and Player Entity

    This section will explain how to manually add a GameScreen and Top-Down entity. You do not need to follow this section if you have used the wizard as shown in the previous step.

    1. Select the Quick Actions tab

    2. Click the Add Screen button

    3. Click OK to the default GameScreen name (all games should have a single GameScreen)

    To add a Player entity:

    1. Click the Add Entity button

    2. Name the entity Player

    3. Check:

      1. Circle under Collisions

      2. Top-Down under Input Movement Type

    4. Leave the rest of the defaults and click OK

    If you already have an entity created, you can make it a Top Down entity:

    1. Select the entity

    2. Click the Entity Input Movement tab

    3. Click the Top-Down option

    By default your GameScreen should have a list of Players (it was an option earlier when creating the Player entity). We recommend always creating a list of Players even if you intend to only have one player. This standard appears throughout FlatRedBall's documentation and can make moving from one project to another easier.

    If you did not add a PlayerList earlier by keeping the Include lists in GameScreen, or if you created your GameScreen after your Player, you can manually add a PlayerList by following these steps:

    1. Verify Player is selected

    2. Click the Quick Actions tab

    3. Click the Add Player List to GameScreen button

    You will also need a Player instance in the list. To do this, drag+drop the Player onto the GameScreen and it will be added to the Player list.

    hashtag
    Moving the Entity

    Now that the entity is marked as a Top Down entity and now that we have an instance of the entity in the GameScreen, we can run the game and see the player move. By default the entity uses a gamepad if one is connected. Otherwise, the entity will use WASD keys on the keyboard.

    var gamepad = InputManager.Xbox360GamePads[0];
    if(gamepad.ButtonDown(Xbox360GamePad.Button.B))
    {
        this.CurrentMovement = TopDownValues[DataTypes.TopDownValues.FastMovement];
    }
    else
    {
        this.CurrentMovement = TopDownValues[DataTypes.TopDownValues.Default];
    }
    if (TopDownValuesStatic == null)
    {
        {
            // We put the { and } to limit the scope of oldDelimiter
            char oldDelimiter = FlatRedBall.IO.Csv.CsvFileManager.Delimiter;
            FlatRedBall.IO.Csv.CsvFileManager.Delimiter = ',';
            System.Collections.Generic.Dictionary<string, global::TopDownExample.DataTypes.TopDownValues> temporaryCsvObject = new System.Collections.Generic.Dictionary<string, global::TopDownExample.DataTypes.TopDownValues>();
            foreach (var kvp in Entities.Enemy.TopDownValuesStatic)
            {
                temporaryCsvObject.Add(kvp.Key, kvp.Value);
            }
            FlatRedBall.IO.Csv.CsvFileManager.CsvDeserializeDictionary<string, global::TopDownExample.DataTypes.TopDownValues>("Content/Entities/Slime/TopDownValuesStatic.csv", temporaryCsvObject, FlatRedBall.IO.Csv.DuplicateDictionaryEntryBehavior.Replace);
            FlatRedBall.IO.Csv.CsvFileManager.Delimiter = oldDelimiter;
            TopDownValuesStatic = temporaryCsvObject;
        }
    }