Skip to content

Commit c806f69

Browse files
Merge branch '2d-tutorial-bounty' into 27-conclusion
2 parents 4896c28 + b6e46d4 commit c806f69

File tree

25 files changed

+516
-29
lines changed

25 files changed

+516
-29
lines changed

articles/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@
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/
165167
- name: "Chapter 27: Conclusion and Next Steps"
166168
href: tutorials/building_2d_games/27_conclusion/
167169
- name: Console Access

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ Unlike sound effects, music is played through the [**MediaPlayer**](xref:Microso
149149

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

152-
- [bounce.wav](./files/bounce.wav) - For when the bat bounces off screen edges
153-
- [collect.wav](./files/collect.wav) - For when the slime eats the bat
154-
- [theme.ogg](./files/theme.ogg) - Background music
152+
- [bounce.wav](./files/bounce.wav){download} - For when the bat bounces off screen edges
153+
- [collect.wav](./files/collect.wav){download} - For when the slime eats the bat
154+
- [theme.ogg](./files/theme.ogg){download} - Background music
155155

156156
> [!NOTE]
157157
>
158158
> - *bounce.wav* is "Retro Impact Punch 07" by Davit Masia (<https://kronbits.itch.io/retrosfx>).
159159
> - *collect.wav* is "Retro Jump Classic 08" by Davit Masia (<https://kronbits.itch.io/retrosfx>).
160-
> - *theme.mp3* is "Exploration" by Luis Zuno ([@ansimuz](https://twitter.com/ansimuz)]).
160+
> - *theme.mp3* is "Exploration" by Luis Zuno ([@ansimuz](https://twitter.com/ansimuz)).
161161
162162
Add these files to your content project using the MGCB Editor:
163163

@@ -168,6 +168,7 @@ Add these files to your content project using the MGCB Editor:
168168
5. For each file that is added, check its properties in the Properties panel:
169169
- For `.wav` files, ensure the *Processor* is set to `Sound Effect`.
170170
- For `.mp3` files, ensure the *Processor* is set to `Song`.
171+
6. Save the changes and close the MGCB Editor.
171172

172173
Next, open the *Game1.cs* file and update it to the following:
173174

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
@@ -193,7 +193,7 @@ First, we will need to create a SpriteFont Definition. Open the *Content.mgcb*
193193

194194
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.
195195

196-
- [04B_30.ttf](./files/04B_30.ttf)
196+
- [04B_30.ttf](./files/04B_30.ttf){download}
197197

198198
### Update the SpriteFont Description
199199

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ Add the following override for the `Draw` method to the `GameScene` class:
294294

295295
### Updating the Game1 Class
296296

297-
With our scene system and scene classes in place, we can now simplify our main `Game1` class to just initialize the game and start with the title scene. Open the *Game1.cs* file and update it to the following:
297+
With our scene system and scene classes in place, we can now simplify our main `Game1` class to just initialize the game and start with the title scene. Open the *Game1.cs* file and replace its entire contents with this simplified implementation:
298298

299299
[!code-csharp[](./snippets/game1.cs)]
300300

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: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ To make our UI more responsive and engaging, we will add audio feedback that pla
342342

343343
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:
344344
345-
- [ui.wav](./files/ui.wav)
345+
- [ui.wav](./files/ui.wav){download}
346346
347347
Next, add this sound effect to your content project using the MGCB Editor:
348348
@@ -404,17 +404,20 @@ Gum is now fully initialized and we can use it in our scenes to add UI to our ga
404404

405405
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.
406406

407+
> [!NOTE]
408+
> 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.
409+
407410
First, open the *TitleScene.cs* file in the game project and add the following using declarations to the top of the `TitleScene` class:
408411
409-
[!code-csharp[](./snippets/titlescene/usings.cs?highlight=1,6-8)]
412+
[!code-csharp[](./snippets/titlescene/usings.cs?highlight=1,3,6-8)]
410413
411-
Next, add the following fields:
414+
Next, add the following fields to the `TitleScene` class:
412415
413416
[!code-csharp[](./snippets/titlescene/fields.cs)]
414417
415418
#### Creating the Title Panel
416419
417-
First, wew ill create a method that builds our main menu panel with start and options buttons. Add the following method to the `TitleScene` class:
420+
First, wew ill create a method that builds our main menu panel with start and options buttons. Add the following method to the `TitleScene` class after the fields:
418421
419422
[!code-csharp[](./snippets/titlescene/createtitlepanel.cs)]
420423
@@ -423,7 +426,7 @@ Our title panel includes two buttons positioned at the bottom corners of the scr
423426
> [!NOTE]
424427
> Notice how we use `Anchor` to position the buttons relative to the panel's edges, with the "Start" button anchored at the bottom left and the "Options" button anchored at the bottom right. Then the positioning of the elements is adjusted relative to its anchor point.
425428

426-
Each button registers a `Click` event handler to respond when the players selects it. We should implement the event handler method for these buttons next. Add the following methods to the `TitleScene` class:
429+
Each button registers a `Click` event handler to respond when the players selects it. We should implement the event handler method for these buttons next. Add the following methods to the `TitleScene` class after the `CreateTitlePanel` method:
427430

428431
[!code-csharp[](./snippets/titlescene/handlestartclicked.cs)]
429432

@@ -433,13 +436,13 @@ These handlers are called when the `Click` event is raised for each button. The
433436

434437
#### Creating the Options Panel
435438

436-
Next, we will create the options panel with sliders to adjust the volume for music and sound effects. Add the following method to the `TitleScene` class:
439+
Next, we will create the options panel with sliders to adjust the volume for music and sound effects. Add the following method to the `TitleScene` class after the `HandleOptionsClicked` method:
437440

438441
[!code-csharp[](./snippets/titlescene/createoptionspanel.cs)]
439442

440443
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.
441444

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

444447
[!code-csharp[](./snippets/titlescene/handlesfxsliderchanged.cs)]
445448

@@ -458,23 +461,23 @@ These handlers update our audio settings in real-time as the player adjusts the
458461

459462
#### Initializing the UI
460463

461-
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:
464+
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:
462465

463466
[!code-csharp[](./snippets/titlescene/initializeui.cs)]
464467

465468
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.
466469
467470
#### Integrating with the Game Loop
468471
469-
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:
472+
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:
470473
471474
[!code[](./snippets/titlescene/initialize.cs?highlight=27)]
472475
473476
Next, update the `LoadContent` method to load the sound effect that will be used as auditory feedback for the UI:
474477
475478
[!code[](./snippets/titlescene/loadcontent.cs?highlight=12-13)]
476479
477-
Next update the `Update` method to include Gum's update logic:
480+
Next modify the `Update` method to include Gum's update logic:
478481
479482
[!code[](./snippets/titlescene/update.cs?highlight=14)]
480483
@@ -500,25 +503,28 @@ With these changes, our UI system is now fully integrated into the scene's game
500503
501504
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.
502505
506+
> [!NOTE]
507+
> 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.
508+
503509
First, open the *GameScene.cs* file in the game project and add the following using declarations to the top of the `GameScene` class.
504510
505-
[!code-csharp[](./snippets/gamescene/usings.cs?highlight=2,7-9)]
511+
[!code-csharp[](./snippets/gamescene/usings.cs?highlight=2-3,8-10)]
506512
507-
Next, add the following fields:
513+
Next, add the following fields to the `GameScene` class:
508514
509515
[!code-csharp[](./snippets/gamescene/fields.cs)]
510516
511517
#### Pausing the Game
512518
513-
To pause the game, first we will create a method that makes the pause panel visible. Add the following method to the `GameScene` class:
519+
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:
514520
515521
[!code-csharp[](./snippets/gamescene/pausegame.cs)]
516522
517-
Next, update the `CheckKeyboardInput` method so that when the escape key is pressed, we pause the game instead of returning to the title scene:
523+
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:
518524
519525
[!code-csharp[](./snippets/gamescene/checkkeyboardinput.cs?highlight=6-10)]
520526
521-
Finally, update the `CheckGamePadInput` method so the game is paused when the start button is pressed:
527+
Finally, update the `CheckGamePadInput` method so that when the start button is pressed, it pauses the game:
522528
523529
[!code-csharp[](./snippets/gamescene/checkgamepadinput.cs?highlight=6-10)]
524530
@@ -530,31 +536,31 @@ Next, we will create a method that builds our pause panel with resume and quit b
530536
531537
#### Initializing the UI
532538
533-
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:
539+
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:
534540
535541
[!code-csharp[](./snippets/gamescene/initializeui.cs)]
536542
537543
Just like with the `TitleScene`, we first clear any existing UI elements from Gum's root before creating the UI elements for this scene.
538544
539545
#### Integrating with the Game Loop
540546
541-
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:
547+
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:
542548
543549
[!code-csharp[](./snippets/gamescene/initialize.cs?highlight=38)]
544550
545551
Next, update the `LoadContent` method to load the sound effect that will be used as auditory feedback for the UI:
546552
547553
[!code-csharp[](./snippets/gamescene/loadcontent.cs?highlight=27-28)]
548554
549-
Next, update 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:
555+
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:
550556
551557
[!code-csharp[](./snippets/gamescene/update.cs?highlight=3-10)]
552558
553559
Finally, add Gum's drawing call to the end fo the `Draw` method:
554560
555561
[!code-csharp[](./snippets/gamescene/draw.cs?highlight=9-10)]
556562
557-
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.
563+
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.
558564
559565
| ![Figure 20-12: The pause menu during the game scene with default Gum buttons](./images/pause-unstyled.png) |
560566
| :---------------------------------------------------------------------------------------------------------: |

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)