# Player Behavior

### Introduction

At this point we have a ship which is visible on Screen, but it doesn't do anything. This tutorial adds behavior to our Player Entity so that it can move, turn, and shoot.

### Adding Variables

For this game, the Player will continuously move forward at a constant speed. The Player object will be turned left and right with the keyboard or Xbox gamepad. Before we begin writing any code we'll add two variables to Player: **MovementSpeed** and **TurningSpeed**. To do this:

1. Select the Player entity
2. Select the Variables tab
3. Click the **Create a new variable** button\\

   <figure><img src="https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2FlFmz6ERMAQ1FFi60Pt52%2Fimage.png?alt=media&#x26;token=a330590d-0468-4230-a69c-2a7ddb368c35" alt=""><figcaption><p>Click the Create a new variable button to add a new variable</p></figcaption></figure>
4. Leave the defaults **Create a new variable** option and **float** type
5. Enter the name **MovementSpeed**
6. Click **OK**

![Create a variable called MovementSpeed](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2FCHjFD3WyaIhCuAkKvpF6%2F30_07%2014%2045.png?alt=media\&token=998fee4a-2bd6-4b2c-b0bd-07875765aed5)

Repeat the steps above to also add a **TurningSpeed** variable.

![Create a variable called TurningSpeed](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2FDk8Si44lPLvi6ocSqIer%2F30_07%2012%2026.png?alt=media\&token=abe6f929-1b34-4f0a-ba9c-00279e6646d0)

Next let's give the variables some default values:

1. Enter a value of 100 for **MovementSpeed**. This is the number of pixels the Player will travel in one second.
2. Enter a value of 3.14 for **TurningSpeed**. This is the maximum number of radians the Player will rotate in one second.

![Player with the two new variables](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2F0vbaFgJos9pe7yidllIO%2F30_07%2015%2050.png?alt=media\&token=0a96ba7e-8532-4ecd-a632-9df43220cf7e)

### Applying Movement

To apply movement we will need to write some C# code. To do this:

1. Open the project in Visual Studio (or switch to Visual Studio if you already have it open)
2. Open **Player.cs**. This is in the **Entities** folder in the **Solution Explorer**.

   ![Player.cs in Visual Studio](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-ec575554a52ab6156a77d048f6e5b15f8a571648%2F2021-03-img_604d0807644d9.png?alt=media)
3. Scroll to the **CustomActivity** method in Player.cs

Modify CustomActivity as shown in the following snippet:

```csharp
void CustomActivity()
{
   this.Velocity = this.RotationMatrix.Up * this.MovementSpeed;
}
```

If you now run the game you will see the ship move upward, then eventually move off-screen.

#### **What is "RotationMatrix.Up"?**

If you are unfamiliar with the RotationMatrix property, or with matrices in general then you may be wondering about the RotationMatrix.Up variable, and why we're using it. The RotationMatrix property contains information about how an Entity, Sprite, or any other PositionedObject is rotated. The Up property indicates you which way is "up" for the object given its current rotation. This value is in "object space" meaning that if the object rotates, then this value will rotate along with the object. This is especially convenient for this tutorial because this game will have the ships always moving forward. The code above will work regardless of which way the Player is rotated - something which we'll see in the coming sections.

### Assigning Input

The next step is to assign input logic so the Player can turn. We will add an object to our Player representing the input device. This could be a gampad, keyboard, or any other object. By using the I1DInput interface, we can write the code the same regardless of the actual hardware used to control the Player. Modify Player.cs as shown in the following snippet:

```csharp
public I1DInput TurningInput { get; set; }

private void CustomInitialize()
{
 // we'll default to using the gamepad if one is
 // plugged in. Otherwise, we'll use the keyboard
 if(InputManager.Xbox360GamePads[0].IsConnected)
 {
  TurningInput = 
    InputManager.Xbox360GamePads[0].LeftStick.Horizontal;
 }
 else
 {
  TurningInput = InputManager.Keyboard.Get1DInput(
    Microsoft.Xna.Framework.Input.Keys.Left, 
    Microsoft.Xna.Framework.Input.Keys.Right);
 }
}

private void CustomActivity()
{
 this.RotationZVelocity =
 // Negative value is needed so that holding "left" turns to the left
   -TurningInput.Value * this.TurningSpeed;
   this.Velocity = this.RotationMatrix.Up * this.MovementSpeed;
}
```

Note that all of the code we have written uses coefficients (**MovementSpeed** and **TurningSpeed**) defined in the FRB Editor. This means that you can modify these values in the Player Entity at any time if you want to tune how the game feels. For example, if you want the ship to turn faster, increase **TurningSpeed** to a larger value.

Also, keep in mind that the variables MovementSpeed and TurningSpeed can be modified both in the FRB Editor and also in code - so where should you make the change? Typically, these variables can be thought of as variables which a game designer might edit. Larger teams may include designers who are not as comfortable making changes in code. The FlatRedBall Editor provides a less-technical environment so that designers can make changes and see them in-game without venturing into complex C# code.

But you might be wondering if this is important in your case - after all you are likely just learning to use FlatRedBall, so you are a team of one. You are both the designer and programmer, so where should the changes be made? Even in this situation, the answer is the same - if you can make the changes in the FlatRedBall Editor, do so! This makes it easier to tune your game in one place instead of needing to hop around different code files.

![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2F6spzec3THyPy2uxrJNJN%2F30_07%2024%2059.png?alt=media\&token=1361cc60-3baa-4329-90c6-a65d3f3a44bc)

### Adding Bullet Sprite

Next we will add a file and Sprite to the Bullet entity. This process is essentially the same as when we added PNG files and a Sprite to our Player Entity so you may find these steps familiar. To add the PNG:

1. Download the following [file](https://github.com/flatredball/FlatRedBallDocs/blob/main/.gitbook/assets/migrated_media-Bullet1.png) to your computer: ![Bullet1.png](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-fba742e2bfb8d231fe834e45ffa269df41adb240%2Fmigrated_media-Bullet1.png?alt=media)
2. Expand the **Bullet** entity in Glue
3. Drag+drop Bullet1.png onto the Files folder in the Bullet

<figure><img src="https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-b94fb3b3da97b9d85788b7078b9a12c193e55d60%2F2016-01-2021_March_13_141331.gif?alt=media" alt=""><figcaption></figcaption></figure>

To add a Sprite to the **Bullet** entity:

1. Select the **Bullet** entity in Glue
2. Click the **Quick Actions** tab
3. Click the **Add Object to Bullet** button

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-a7510a12723710a3b51440052a6659ab7577947a%2F2021-03-img_604d30bc42574.png?alt=media)
4. Select the Sprite type
5. Click OK

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

Now we can set the Sprite's Texture:

1. Expand the **Bullet** Entity's **Object** folder
2. Select the newly-created **SpriteInstance**
3. Select the **Variables** tab
4. Set the **Texture** drop-down to **Bullet1**

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

### Shooting

The next step is to add firing bullets. We'll be using the BulletFactory which we created in an earlier tutorial to create a new bullet and automatically add it to the GameScreen's BulletList. For more information on factories, see the [page](https://docs.flatredball.com/flatredball/glue-reference/factory) on this topic. Next we will need to define a bullet speed. To do this:

1. Click the Bullet entity in Glue
2. Click the Variables tab
3. Click the **Add New Variable** button

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-c5f7e8587c0b0e9e58d1d3c83461699e95b4eb4c%2F2021-03-img_604d334e219f9.png?alt=media)
4. Leave the defaults
5. Set the variable name to **MovementSpeed**

   ![](https://951240982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_fye9Ufg3vzJxwX5Hk%2Fuploads%2Fgit-blob-9097530a7009fb804c84afd352e65a61c9b66762%2F2021-03-img_604d33b6286ff.png?alt=media)
6. Set **MovementSpeed** to 300

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

Now we can use BulletFactory to create bullets when the player shoots. To do this:

1. Go to Player.cs in Visual Studio
2. Modify the Player.cs code so that it contains the following code:

```csharp
public I1DInput TurningInput { get; set; }
public IPressableInput ShootingInput { get; set; }

private void CustomInitialize()
{
 // we'll default to using the gamepad if one is
 // plugged in. Otherwise, we'll use the keyboard
 if(InputManager.Xbox360GamePads[0].IsConnected)
 {
  TurningInput = 
   InputManager.Xbox360GamePads[0].LeftStick.Horizontal;
  ShootingInput = InputManager.Xbox360GamePads[0].GetButton(
   Xbox360GamePad.Button.A);
 }
 else
 {
  TurningInput = InputManager.Keyboard.Get1DInput(
   Microsoft.Xna.Framework.Input.Keys.Left, 
   Microsoft.Xna.Framework.Input.Keys.Right);
  ShootingInput = InputManager.Keyboard.GetKey(
   Microsoft.Xna.Framework.Input.Keys.Space);
 }
}

private void CustomActivity()
{
 this.RotationZVelocity =
  // Negative value is needed so that holding "left" turns to the left
  -TurningInput.Value * this.TurningSpeed;
 this.Velocity = this.RotationMatrix.Up * this.MovementSpeed;

 if (ShootingInput.WasJustPressed)
 {
  // We'll create 2 bullets because it looks much cooler than 1
  Bullet firstBullet = Factories.BulletFactory.CreateNew();
  firstBullet.Position = this.Position;
  firstBullet.Position += this.RotationMatrix.Up * 12;
  // This is the bullet on the right side when the ship is facing up.
  // Adding along the Right vector will move it to the right relative to the ship
  firstBullet.Position += this.RotationMatrix.Right * 6;
  firstBullet.RotationZ = this.RotationZ;
  firstBullet.Velocity = this.RotationMatrix.Up * firstBullet.MovementSpeed;

  Bullet secondBullet = Factories.BulletFactory.CreateNew();
  secondBullet.Position = this.Position;
  secondBullet.Position += this.RotationMatrix.Up * 12;
  // This bullet is moved along the Right vector, but in the nevative
  // direction, making it the bullet on the left.
  secondBullet.Position -= this.RotationMatrix.Right * 6;
  secondBullet.RotationZ = this.RotationZ;
  secondBullet.Velocity = this.RotationMatrix.Up * secondBullet.MovementSpeed;
 }
}
```

Notice that we are using the RotationMatrix of the MainShip to adjust the initial positions of the bullets, as well as their velocity

If you run the game you should be able to fly, turn, and shoot.

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

### Conclusion

Although we have a long way to go, this is a big milestone for Rock Blaster. You can now see how the game feels for the very first time. Since relevant coefficients are set in Glue, you can change the values to make the game feel differently. Now that we can shoot bullets we'll need something to shoot at. The next tutorial will add Rock entity instances to the GameScreen.
