Skip to content

Commit 2e419ef

Browse files
Proof to ch 20 plus pull in latest
2 parents b352245 + 4a1d4ca commit 2e419ef

File tree

27 files changed

+631
-35
lines changed

27 files changed

+631
-35
lines changed

articles/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@
162162
href: tutorials/building_2d_games/24_shaders/
163163
- name: "25: Packaging Your Game for Distribution"
164164
href: tutorials/building_2d_games/25_packaging_game/
165+
- name: "26: Publishing Your Game to itch.io"
166+
href: tutorials/building_2d_games/26_publish_to_itch/
167+
- name: "Chapter 27: Conclusion and Next Steps"
168+
href: tutorials/building_2d_games/27_conclusion/
165169
- name: Console Access
166170
href: console_access.md
167171
- name: Help and Support

articles/tutorials/building_2d_games/14_soundeffects_and_music/index.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ Unlike sound effects, music is played through the [**MediaPlayer**](xref:Microso
152152

153153
Before we can add audio to our game, we need some sound files to work with. Download the following audio files:
154154

155-
- [bounce.wav](./files/bounce.wav) - For when the bat bounces off screen edges
156-
- [collect.wav](./files/collect.wav) - For when the slime eats the bat
157-
- [theme.ogg](./files/theme.ogg) - Background music
155+
- [bounce.wav](./files/bounce.wav){download} - For when the bat bounces off screen edges
156+
- [collect.wav](./files/collect.wav){download} - For when the slime eats the bat
157+
- [theme.ogg](./files/theme.ogg){download} - Background music
158158

159159
> [!NOTE]
160160
>
@@ -171,6 +171,7 @@ Add these files to your content project using the MGCB Editor:
171171
5. For each file that is added, check its properties in the Properties panel:
172172
- For `.wav` files, ensure the *Processor* is set to `Sound Effect`.
173173
- For `.mp3` files, ensure the *Processor* is set to `Song`.
174+
6. Save the changes and close the MGCB Editor.
174175

175176
Next, open the `Game1.cs` file and update it to the following:
176177

articles/tutorials/building_2d_games/16_working_with_spritefonts/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ First, we will need to create a SpriteFont Definition. Open the *Content.mgcb*
200200

201201
Next, right-click the following TTF font and choose "Save Link as..." and save it in the same folder as the *04B_30.spriteFont* file we just created.
202202

203-
- [04B_30.ttf](./files/04B_30.ttf)
203+
- [04B_30.ttf](./files/04B_30.ttf){download}
204204

205205
### Update the SpriteFont Description
206206

articles/tutorials/building_2d_games/17_scenes/index.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ The key changes here are:
118118
With the scene architecture in place, the game can now be updated so that it is broken down into scenes. We will create two scenes; a title scene and a gameplay scene. First, however, we need to add an additional SpriteFont Description that will be used during the title scene to display the title of the game. Open the *Content.mgcb* content project file in the MGCB Editor and perform the following:
119119

120120
1. Right-click the `fonts` folder and choose `Add > New Item...`.
121-
2. Select `SpriteFont Description (.spritefont)` from the options
121+
2. Select `SpriteFont Description (.spritefont)` from the options.
122122
3. Name the file `04B_30_5x` and click `Create`.
123123

124124
| ![Figure 17-1: The *04B_30_5x.spritefont* file created in the MGCB Editor](./images/font_added.png) |
@@ -134,7 +134,7 @@ Next, open the *04B_30_5x.spritefont* file in your code editor and make the foll
134134
The title scene serves as the game's initial starting point; the first impression the player gets when they launch the game. For our game, the title scene will display the text for the title of the game and a prompt to inform the player what action to take to start the game. We will use a simple trick for the title text in order to draw it with a drop shadow to add a bit of visual flair.
135135

136136
> [!NOTE]
137-
> As the following screens are specific to our game and are not reuable bits, these will be added to your game project.
137+
> As the following screens are specific to our game and are not reusable bits, these will be added to your game project.
138138
>
139139
> Although, if you do end up making screens that are completely reusable, there is nothing wrong with putting them in your Game Library, it is completely up to you.
140140
@@ -320,9 +320,11 @@ With our scene system and scene classes in place, we can now simplify our main `
320320
[!code-csharp[](./snippets/game1.cs)]
321321

322322
> [!NOTE]
323-
> Feel free to check your homework and compare the original `Game1` class with the updated version, as well as checking the `GameScene` class did not lose any functionality (it has not but you have to be sure!). Refactoring code to be cleaner and more organised is a careful task.
323+
> Feel free to check your homework and compare the original `Game1` class with the updated version, as well as checking the `GameScene` class did not lose any functionality (it has not, but you have to be sure!). Refactoring code to be cleaner and more organised is a careful task.
324324
325-
The `Game1` class is now much simpler as most of the game logic has been moved to the appropriate scene classes. It:
325+
The `Game1` class is now much simpler as most of the game logic has been moved to the appropriate scene classes.
326+
327+
The updates include:
326328

327329
1. Sets up the game window with the constructor parameters.
328330
2. Overrides the `Initialize` method to set the title scene as the starting scene.

articles/tutorials/building_2d_games/17_scenes/snippets/gamescene.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System;
33
using Microsoft.Xna.Framework;
44
using Microsoft.Xna.Framework.Audio;
5-
using Microsoft.Xna.Framework.Content;
65
using Microsoft.Xna.Framework.Graphics;
76
using Microsoft.Xna.Framework.Input;
87
using MonoGameLibrary;

articles/tutorials/building_2d_games/20_implementing_ui_with_gum/index.md

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ In this chapter you will:
1414
* Handle input from keyboard, mouse, and gamepads
1515
* Integrate the UI system with our existing game architecture.
1616

17+
> [!IMPORTANT]
18+
> While GUM is used in this tutorial it is only one of many UI libraries available to the MonoGame community, some notable others are [EmptyKeys](https://github.com/EmptyKeys/UI_Engines), [GeonBit.UI](https://github.com/RonenNess/GeonBit.UI), as well as entire Game Frameworks/Engines like [Nez}(https://github.com/prime31/Nez) that have their own built in UI systems.
19+
>
20+
> Check out the [MonoGame Resources](https://monogame.net/resources/) page, as well as [awesome-monogame](https://github.com/aloisdeniel/awesome-monogame) from [Alo�s Deniel](https://github.com/aloisdeniel) for even more community offerings.
21+
1722
## What is Gum?
1823

1924
Gum is a powerful UI layout engine and framework. It provides a flexible, efficient system capable of producing virtually any UI layout you might need in your games. While originally developed alongside the FlatRedBall game engine, Gum has evolved to work seamlessly with multiple platforms, including MonoGame, which we will be using in this tutorial.
2025

21-
> [!IMPORTANT]
22-
> While GUM is used in this tutorial it is only one of many UI libraries available to the MonoGame community, some notable others are [EmptyKeys ](https://github.com/EmptyKeys/UI_Engines), [GeonBit.UI](https://github.com/RonenNess/GeonBit.UI), as well as entire Game Frameworks/Engines like [Nez}() that have their own built in UI systems.
23-
>
24-
> Check out [awesome-monogame](https://github.com/aloisdeniel/awesome-monogame) from [Aloïs Deniel](https://github.com/aloisdeniel) as well as the [MonoGame Resources](https://monogame.net/resources/) page for even more community offerings.
25-
2626
### Why Use Gum?
2727

2828
Creating a UI system from scratch requires solving many complex problems:
@@ -360,7 +360,7 @@ To make our UI more responsive and engaging, we will add audio feedback that pla
360360

361361
First, download the UI sound effect by right-clicking the following link and saving it as `ui.wav` in the game project's `Content/audio` folder:
362362
363-
* [ui.wav](./files/ui.wav)
363+
* [ui.wav](./files/ui.wav){download}
364364
365365
Next, add this sound effect to your content project using the MGCB Editor:
366366
@@ -422,11 +422,14 @@ Gum is now fully initialized and we can use it in our scenes to add UI to our ga
422422

423423
With Gum added and initialized in our game, we can now implement UI elements for our title scene. We will create panels for both the main menu and options menu, implement the necessary event handlers, and integrate everything with our existing title scene.
424424

425-
First, open the `TitleScene.cs` file in the game project and add the following using declarations to the top of the `TitleScene` class:
425+
> [!NOTE]
426+
> When adding these sections one by one, you may see compiler errors until all sections are in place. This is normal, as some parts of the code will reference fields or methods that haven't been added yet. Once all sections are complete, these errors will resolve.
427+
428+
First, open the *TitleScene.cs* file in the game project and add the following using declarations to the top of the `TitleScene` class:
426429
427430
[!code-csharp[](./snippets/titlescene/usings.cs?highlight=1,3,6-8)]
428431
429-
Next, add the following fields:
432+
Next, add the following fields to the `TitleScene` class:
430433
431434
[!code-csharp[](./snippets/titlescene/fields.cs)]
432435
@@ -463,7 +466,7 @@ Add the following method to the `TitleScene` class:
463466

464467
This panel includes a text label, two sliders for adjusting audio volumes, and a back button for returning to the main menu. The panel is initially invisible since we start on the main menu. Both the "Music Volume" slider and the "Sound Effects Volume" slider register events to be called when the value of the sliders change and when the value change has been completed. The "Back" button registers a click event similar to the ones from the main menu.
465468

466-
Now we should implement the event handlers for these controls:
469+
Now we should implement the event handlers for these controls. Add the following methods to the `TitleScene` class after the `CreateOptionsPanel` method:
467470

468471
[!code-csharp[](./snippets/titlescene/handlesfxsliderchanged.cs)]
469472

@@ -482,23 +485,23 @@ These handlers update our audio settings in real-time as the player adjusts the
482485

483486
#### Initializing the UI
484487

485-
Now that we have implemented the methods that will create both the main menu panel and the options menu panel, we need to implement the main UI initializations method that will call them. Add the following method to the `TitleScene` class:
488+
Now that we have implemented the methods that will create both the main menu panel and the options menu panel, we need to implement the main UI initializations method that will call them. Add the following method to the `TitleScene` class after the `HandleOptionsButtonBack` method:
486489

487490
[!code-csharp[](./snippets/titlescene/initializeui.cs)]
488491

489492
This method first clears any existing UI elements from Gum's root container to prevent duplication, then calls our panel creation methods to build the complete interface.
490493
491494
#### Integrating with the Game Loop
492495
493-
Finally, we need to integrate our UI initialization, update, and draw with the scene's lifecycle. First, add the call to `InitializeUI()` in the `Initialize` method:
496+
Finally, we need to integrate our UI initialization, update, and draw with the scene's lifecycle. First, add the call to `InitializeUI()` in the `Initialize` method by updating it to the following:
494497
495498
[!code[](./snippets/titlescene/initialize.cs?highlight=27)]
496499
497500
Next, update the `LoadContent` method to load the sound effect that will be used as auditory feedback for the UI:
498501
499502
[!code[](./snippets/titlescene/loadcontent.cs?highlight=12-13)]
500503
501-
Then update the `Update` method to include Gum's update logic:
504+
Next modify the `Update` method to include Gum's update logic:
502505
503506
[!code[](./snippets/titlescene/update.cs?highlight=14)]
504507
@@ -524,25 +527,28 @@ With these changes, our UI system is now fully integrated into the scene's game
524527
525528
Now that we have setup the UI for the title scene, we will add a pause menu to our game scene. This UI will start invisible but will be shown when the player presses the escape key. For consistency, we will implement the UI for the game scene in the same order that we implemented the UI for the title scene.
526529
530+
> [!NOTE]
531+
> When adding these sections one by one, you may see compiler errors until all sections are in place. This is normal, as some parts of the code will reference fields or methods that haven't been added yet. Once all sections are complete, these errors will resolve.
532+
527533
First, open the *GameScene.cs* file in the game project and add the following using declarations to the top of the `GameScene` class.
528534
529-
[!code-csharp[](./snippets/gamescene/usings.cs?highlight=2,7-9)]
535+
[!code-csharp[](./snippets/gamescene/usings.cs?highlight=2-3,8-10)]
530536
531-
Next, add the following fields:
537+
Next, add the following fields to the `GameScene` class:
532538
533539
[!code-csharp[](./snippets/gamescene/fields.cs)]
534540
535541
#### Pausing the Game
536542
537-
To pause the game, first we will create a method that makes the pause panel visible. Add the following method to the `GameScene` class:
543+
To pause the game, first we will create a method that makes the pause panel visible. Add the following method to the `GameScene` class after the fields:
538544
539545
[!code-csharp[](./snippets/gamescene/pausegame.cs)]
540546
541-
Next, update the `CheckKeyboardInput` method so that when the escape key is pressed, we pause the game instead of returning to the title scene:
547+
Next, update the `CheckKeyboardInput` method so that when the escape key is pressed, instead of returning to the title scene, we now pause the game:
542548
543549
[!code-csharp[](./snippets/gamescene/checkkeyboardinput.cs?highlight=6-10)]
544550
545-
Finally, update the `CheckGamePadInput` method so the game is paused when the start button is pressed:
551+
Finally, update the `CheckGamePadInput` method so that when the start button is pressed, it pauses the game:
546552
547553
[!code-csharp[](./snippets/gamescene/checkgamepadinput.cs?highlight=6-10)]
548554
@@ -552,33 +558,45 @@ Next, we will create a method that builds our pause panel with resume and quit b
552558
553559
[!code-csharp[](./snippets/gamescene/createpausepanel.cs)]
554560
561+
Now we should implement the event handlers for these controls. First, we will implement the handler for the "Resume" button. Add the following method to the `GameScene` class after the `CreatePausePanel` method:
562+
563+
[!code-csharp[](./snippets/gamescene/handleresumebuttonclicked.cs)]
564+
565+
This method plays the UI sound effect for auditory feedback and then hides the pause panel so that the game can resume.
566+
567+
Next is the handler for the "Quit" button. Add the following method to the `GameScene` class after the `HandleResumeButtonClicked` method:
568+
569+
[!code-csharp[](./snippets/gamescene/handlequitbuttonclicked.cs)]
570+
571+
This method as well plays the UI sound effect for auditory feedback, then quits the game by changing scenes back to the title scene.
572+
555573
#### Initializing the Game UI
556574
557-
Now that we have implemented the method to create the pause panel, we can implement the main UI initializations method that will call them. Add the following method to the `GameScene` class:
575+
Now that we have implemented the method to create the pause panel, we can implement the main UI initializations method that will call them. Add the following method to the `GameScene` class after the `CreatePausePanel` method:
558576
559577
[!code-csharp[](./snippets/gamescene/initializeui.cs)]
560578
561579
Just like with the `TitleScene`, we first clear any existing UI elements from Gum's root before creating the UI elements for this scene.
562580
563581
#### Integrating with the Game Loop for the GameScreen
564582
565-
Finally, we need to integrate our UI initialization, update, and draw with the scene's lifecycle. First add the call to `InitializeUI()` in the `Initialize` method:
583+
Finally, we need to integrate our UI initialization, update, and draw with the scene's lifecycle. First add the call to `InitializeUI()` in the `Initialize` method by updating it to the following:
566584
567585
[!code-csharp[](./snippets/gamescene/initialize.cs?highlight=38)]
568586
569587
Next, update the `LoadContent` method to load the sound effect that will be used as auditory feedback for the UI:
570588
571589
[!code-csharp[](./snippets/gamescene/loadcontent.cs?highlight=27-28)]
572590
573-
Next, add the following to the beginning of the `Update` method to include Gum's update logic and to only update the game if it is not paused, pausing will prevent any other Game update logic running. We will use the visibility of the pause menu to determine if the game is paused or not:
591+
Next, modify the `Update` method to include Gum's update logic and to only update the game if it is not paused. We will use the visibility of the pause menu to determine if the game is paused or not:
574592
575593
[!code-csharp[](./snippets/gamescene/update.cs?highlight=3-10)]
576594
577595
Finally, add Gum's drawing call to the end fo the `Draw` method:
578596
579597
[!code-csharp[](./snippets/gamescene/draw.cs?highlight=9-10)]
580598
581-
WIth these changes, the pause menu is now fully integrated into the game scene's game loop. Gum updates its controls during the `Update` method and draws them during the `Draw` method. If the game is paused, as determined by the `IsVisible` property of the pause menu, then updating the actual game logic is skipped.
599+
With these changes, the pause menu is now fully integrated into the game scene's game loop. Gum updates its controls during the `Update` method and draws them during the `Draw` method. If the game is paused, as determined by the `IsVisible` property of the pause menu, then updating the actual game logic is skipped.
582600
583601
| ![Figure 20-12: The pause menu during the game scene with default Gum buttons](./images/pause-unstyled.png) |
584602
| :---------------------------------------------------------------------------------------------------------: |

articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/createpausepanel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ private void CreatePausePanel()
2626
_resumeButton.Visual.X = 9f;
2727
_resumeButton.Visual.Y = -9f;
2828
_resumeButton.Visual.Width = 80;
29-
_resumeButton.Click += HandleResumeClicked;
29+
_resumeButton.Click += HandleResumeButtonClicked;
3030
_pausePanel.AddChild(_resumeButton);
3131

3232
var quitButton = new Button();
@@ -35,7 +35,7 @@ private void CreatePausePanel()
3535
quitButton.Visual.X = -9f;
3636
quitButton.Visual.Y = -9f;
3737
quitButton.Width = 80;
38-
quitButton.Click += HandleQuitClicked;
38+
quitButton.Click += HandleQuitButtonClicked;
3939

4040
_pausePanel.AddChild(quitButton);
4141
}

articles/tutorials/building_2d_games/20_implementing_ui_with_gum/snippets/gamescene/usings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using Gum.DataTypes;
23
using Gum.Wireframe;
34
using Microsoft.Xna.Framework;
45
using Microsoft.Xna.Framework.Audio;

articles/tutorials/building_2d_games/21_customizing_gum_ui/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ While MonoGame natively uses [**SpriteFont**](xref:Microsoft.Xna.Framework.Graph
135135

136136
First, download the *.fnt* file by right-clicking the following link and saving it as *04b_30.fnt* in the game project's *Content/fonts* folder:
137137

138-
- [04b_30.fnt](./files/04b_30.fnt)
138+
- [04b_30.fnt](./files/04b_30.fnt){download}
139139

140140
Next, add this font file to your content project using the MGCB Editor:
141141

Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)