You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Learn the advantages of using the Content Pipeline to load assets and go through the processes of loading your first asset
4
4
---
5
5
6
-
Every game has assets; images to represent the visual graphics to players, audio to provide sound effects and background music, fonts to render text with, and much more. These assets start out as raw files (e.g. *.png* image files or *.mp3* audio files), which you'll need to load into the game to use.
6
+
Every game has assets; images to represent the visual graphics to players, audio to provide sound effects and background music, fonts to render text with, and much more. These assets start out as raw files (e.g. *.png* image files or *.mp3* audio files), which you'll need to load into the game to use.
7
7
8
8
## Loading Assets
9
9
@@ -116,12 +116,14 @@ After changes have been made in the MGBC Editor, ensure that you save the change
116
116
Save the changes and then close the MGCB Editor.
117
117
118
118
## Understanding Content Paths
119
+
119
120
The folder structure you create in the MGCB Editor directly affects how you load content in your game. When you perform a build of your game project, the *MonoGame.Content.Builder.Tasks* NuGet package reference will:
120
121
121
122
1. Compile the image into an optimized format in the **content project's** output directory (typically *ProjectRoot/Content/bin/Platform/Content*) as an *.xnb* file.
122
-
2. Copy the compiled assets to your **game's** output directory (typically *ProjectRoot/bin/Debug/net8.0/Content* or *ProjectRoot/bin/Release/net8.0/Content*).
123
+
2. Copy the compiled assets to your **game's** output directory (typically *ProjectRoot/bin/Debug/net8.0/Content* or *ProjectRoot/bin/Release/net8.0/Content*).
123
124
124
125
For example, if your content project contains:
126
+
125
127
```sh
126
128
Content/
127
129
├── images/
@@ -169,18 +171,30 @@ The [**Game**](xref:Microsoft.Xna.Framework.Game) class provides the [**Content*
169
171
1.`T` Type Reference: The content type we are loading.
170
172
2.`assetName` Parameter: A string path that matches the content path of the asset to load. As mentioned in the [Understanding Content Paths](#understanding-content-paths) section, the content path is relative to the [**ContentManager.RootDirectory**](xref:Microsoft.Xna.Framework.Content.ContentManager.RootDirectory), minus the extension. For instance, we added our image to the *images* folder in the content project, the content path for it will be `"images/logo"`.
171
173
172
-
Let's update the game now to load the image file using the [**ContentManager**](xref:Microsoft.Xna.Framework.Content.ContentManager). First, open the *Game1.cs* file in your project and replace the contents with the following:
174
+
Let's update the game now to load the image file using the [**ContentManager**](xref:Microsoft.Xna.Framework.Content.ContentManager). Open the *Game1.cs* file in the game project and perform the following:
175
+
176
+
1. Add a new [**Texture2D**](xref:Microsoft.Xna.Framework.Graphics.Texture2D) field to store the logo texture in:
177
+
178
+
```cs
179
+
privateTexture2D_logo;
180
+
```
181
+
182
+
2. In [**LoadContent**](xref:Microsoft.Xna.Framework.Game.LoadContent), loadthelogotextureusingthecontentpipeline:
3. In [**Draw**](xref:Microsoft.Xna.Framework.Game.Draw(Microsoft.Xna.Framework.GameTime)), drawthetextureusingthe [**SpriteBatch**](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch):
177
189
178
-
- The `_logo` member was added to store a reference to the logo texture once we load it.
179
-
- In [**LoadContent**](xref:Microsoft.Xna.Framework.Game.LoadContent), the logo texture is loaded using [**ContentManager.Load<T>**](xref:Microsoft.Xna.Framework.Content.ContentManager.Load``1(System.String)).
180
-
- In [**Draw**](xref:Microsoft.Xna.Framework.Game.Draw(Microsoft.Xna.Framework.GameTime)), the logo is rendered using the [**SpriteBatch**](xref:Microsoft.Xna.Framework.Graphics.SpriteBatch).
Copy file name to clipboardExpand all lines: articles/tutorials/building_2d_games/12_input_management/index.md
+55-39Lines changed: 55 additions & 39 deletions
Original file line number
Diff line number
Diff line change
@@ -789,7 +789,7 @@ That's it for the `GamePadInfo` class. Next, let's create the actual input mana
789
789
790
790
## The InputManager Class
791
791
792
-
Now that we have classes to handle keyboard, mouse, and gamepad input individually, we can create a centralized manager class to coordinate all input handling. The `InputManager` class will be static, providing easy access to all input states from anywhere in our game.
792
+
Now that we have classes to handle keyboard, mouse, and gamepad input individually, we can create a centralized manager class to coordinate all input handling. The `InputManager` class will be a [**GameComponent**](xref:Microsoft.Xna.Framework.GameComponent) like we discussed previously in [Chapter 05](../05_game_components/index.md).
793
793
794
794
In the *Input* directory of the *MonoGameLibrary* project, add a new file named *InputManager.cs* with this initial structure:
795
795
@@ -798,45 +798,57 @@ using Microsoft.Xna.Framework;
798
798
799
799
namespaceMonoGameLibrary.Input;
800
800
801
-
publicstaticclassInputManager
801
+
publicclassInputManager : GameComponent
802
802
{
803
803
804
804
}
805
805
```
806
806
807
807
### InputManager Properties
808
808
809
-
The InputManager class needs properties to access each type of input device. Add these properties:
809
+
The `InputManager` class needs properties to access each type of input device. Add these properties:
> The `GamePads` property is an array because MonoGame supports up to four gamepads simultaneously. Each gamepad is associated with a PlayerIndex (0-3).
830
830
831
+
### InputManager Constructor
832
+
833
+
The `InputManager` needs a constructor that accept a [**Game**](xref:Microsoft.Xna.Framework.Game) parameter due to inheriting from the [**GameComponent**](xref:Microsoft.Xna.Framework.GameComponent) class. Add the following constructor:
834
+
835
+
```cs
836
+
/// <summary>
837
+
/// Creates a new InputManager.
838
+
/// </summary>
839
+
/// <paramname="game">The game this input manager belongs to.</param>
840
+
publicInputManager(Gamegame) :base(game) { }
841
+
```
842
+
831
843
### InputManager Methods
832
844
833
-
First, we need a method to initialize our input devices:
845
+
First, override the `Initialize` method so that we can ensure that the states for each input devices are initialized:
834
846
835
847
```cs
836
848
/// <summary>
837
849
/// Initializes this input manager.
838
850
/// </summary>
839
-
publicstaticvoidInitialize()
851
+
publicoverridevoidInitialize()
840
852
{
841
853
Keyboard=newKeyboardInfo();
842
854
Mouse=newMouseInfo();
@@ -849,14 +861,14 @@ public static void Initialize()
849
861
}
850
862
```
851
863
852
-
Next, we'll add a method to update all input states:
864
+
Next override the `Update` method so that the states of the input devices are updated:
853
865
854
866
```cs
855
867
/// <summary>
856
868
/// Updates the state information for the keyboard, mouse, and gamepad inputs.
857
869
/// </summary>
858
870
/// <paramname="gameTime">A snapshot of the timing values for the current frame.</param>
859
-
publicstaticvoidUpdate(GameTimegameTime)
871
+
publicoverridevoidUpdate(GameTimegameTime)
860
872
{
861
873
Keyboard.Update();
862
874
Mouse.Update();
@@ -868,73 +880,78 @@ public static void Update(GameTime gameTime)
868
880
}
869
881
```
870
882
871
-
> [!TIP]
872
-
> By centralizing input updates in the `InputManager`, we ensure all input states are updated consistently each frame. You only need to call `InputManager.Update` once in your game's [**Update**](xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime)) method.
873
-
874
883
### Implementing the InputManager Class
875
884
876
885
Now that we have our input management system complete, let's update our game to use it. Instead of tracking input states directly, we'll use the `InputManager` to handle all our input detection. Open *Game1.cs* and make the following changes:
877
886
878
-
Let's update the input code in our game now to instead use the `InputManager` class to manage tracking input states which inputs are active. Open the *Game1.cs* file and perform the following:
887
+
1. Add the `MonoGameLibrary.Input` using directive so we can access the `InputManager` class:
888
+
889
+
```cs
890
+
usingMonoGameLibrary.Input;
891
+
```
879
892
880
-
1. First we need to set up the `InputManager`. In [**Initialize**](xref:Microsoft.Xna.Framework.Game.Initialize), add this initialization code just before `base.Initialize()`:
893
+
2. Addafieldforthe `InputManager` class:
881
894
882
895
```cs
883
-
InputManager.Initialize();
896
+
private InputManager _input;
884
897
```
885
898
886
-
2. Next, in [**Update**](xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime)), weneedtoensureinputstatesareupdatedeachframe. Addthefollowingasthefirstlineofcodeinsidethe[**Update**](xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime)) method:
// Create and add the input manager component to the game's component collection
903
+
_input=newInputManager(this);
904
+
Components.Add(_input);
890
905
```
891
906
892
-
3. Next, removethe `if` statementin[**Update**](xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime))thatchecksfor the gamepad back button or the keyboard escape key being pressed and then exits the game.
907
+
4. In[**Update**](xref:xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime)), removethe `if` statementthatchecksfor the gamepad back button or keyboard escape key being pressed and then calls exit. We're going to move this to the individual handle input methods in a moment.
893
908
894
-
4. Finally, update the game controls to use the `InputManager`. Replace the `HandleKeyboardInput`, `HandleMouseInput` and `HandleGamePadInput` methods with the following:
909
+
5. In [**Update**](xref:xref:Microsoft.Xna.Framework.Game.Update(Microsoft.Xna.Framework.GameTime)) movethe `base.Update(gameTime)` callfrombeingthelastlineofthemethodtothefirstlineofthemethod. Wedothisbecausegamecomponentsareupdatedduringthe `base.Update(gameTime)` callandwewanttoensurethatinputisupdatedbeforewestarthandlinginputchecks.
0 commit comments