From a329e3c79b36d9f21180ef5d4f1aad4f23908377 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Sun, 8 Sep 2024 15:05:40 +1200 Subject: [PATCH 01/29] Scene creation, asset importing, and player idle animation --- .../game-design/godot/2d Dungeon Crawler.mdx | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/content/docs/game-design/godot/2d Dungeon Crawler.mdx diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx new file mode 100644 index 0000000..e0f9b3a --- /dev/null +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -0,0 +1,83 @@ +--- +title: Making a 2D top down dungeon crawler +description: This page works through 2D top down dungeon crawler step-by-step +sidebar: + order: 5 +--- + + +This is a guide to making a 2-dimensional dungeon crawling game in [Godot](https://godotengine.org/). If you are unfamiliar with Godot, check out the [Godot basics](/game-design/godot/basics) doc as this tutorial assumes basic knowledge of navigating and using the Godot Engine. + +:::note[Version] +This guide is up-to-date with Godot 4.2 stable official release but will most likely work with any 4.x release. +::: + +We'll be making a game in which the player explores a multi-floor dungeon in a top-down perspective. This project will include: +- Movement +- Attacking +- Health loss & Gain +- Pickups (Coins & Potions) +- Enemies + +We will not be creating our own assets as part of this project, although you are of course welcome to! + +We'll instead be using a free asset pack by Ox72 on Itch.IO which [can be found here](https://0x72.itch.io/dungeontileset-ii) Just click *Download now* followed by *No thanks, just take me to the download* and download the file called *0x72_DungeonTilesetII_v1.7.zip* + + +## Making the project +Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing our assets. +First let's create a new folder, and call it something like 'Assets' + +Then, let's extract the assets from the folder we downloaded, and at them into our Assets folder. Mine looks like this, but it's fine if yours looks slightly different. + +TODO: Image here + +![Godot new project window](/src/assets/godot/3DGameGuide/3dgameprojectsetup.png) + +Let's also create two new top level folders called **Scripts** and **Scenes** + +TODO: Image here + + +To ensure our pixel art assets look crisp and not blurred we'll want to make one quick change. + +Using the buttons in the top left of the screen, select **Project -> Project settings** In this menu, select the **General** tab, and scroll until you see the **Rendering** header. Under this, select **Textures** + +Change **Default Texture Filter** from **Linear** to **Nearest** + +TODO: Settings image + + +## Creating the Player + +Great! Let's start by making a basic version of our player character that will let us move around. We'll worry about more complicated things like attacking later. + +Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. + +Give the **CharacterBody2D** a name like **Player** and give it two children: + +A **CollisionShape2D** and an **AnimatedSprite2D** + +Here's how my scene looks with no other modifications: + +TODO: Player scene basic img + +Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it something like **Player.tscn** + +Let's give ourselves something to look at. Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. +Click on **\** and create a new **Spriteframes** Click on the **Spriteframes** you created. This will open a new window at the bottom of the screen. + +This is where we'll create our player's animations. Rename the *General* animation to *Idle* and click the *Add frames from File* Button (The folder icon) + +Navigate to your *assets/frames* folder, and decide which character you want to be your player. I'll be using the Plague Doctor. Using Shift + Click select all the frames for your character labeled *Idle* (This should be four frames) then open them. + +TODO: Image + +You'll see them added to the animation timeline. We'll want to select two things in the timeline. The **Loop** Button (To ensure the animation loops) and the **Play on start button** (To ensure the animation plays automatically) +Let's also increase the FPS to 8 so that the animation plays a little faster. + +Hit play to test! You'll see the player now has an idle animation that loops! + + + + From 445b2077a08a501e8dcabc5854c9a6a069743175 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Mon, 9 Sep 2024 15:32:58 +1200 Subject: [PATCH 02/29] Player movement --- .../game-design/godot/2d Dungeon Crawler.mdx | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index e0f9b3a..1d5040f 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -64,7 +64,9 @@ TODO: Player scene basic img Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it something like **Player.tscn** -Let's give ourselves something to look at. Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. +### Animations + +Let's give ourselves something to look at! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. Click on **\** and create a new **Spriteframes** Click on the **Spriteframes** you created. This will open a new window at the bottom of the screen. This is where we'll create our player's animations. Rename the *General* animation to *Idle* and click the *Add frames from File* Button (The folder icon) @@ -78,6 +80,68 @@ Let's also increase the FPS to 8 so that the animation plays a little faster. Hit play to test! You'll see the player now has an idle animation that loops! +Let's add our characters walking animation. Add a new animation using the **Add animation** Button and call it something like "Walk" + +TODO: add animation button image + +Do the same thing we did to grab the frames for the idle animation, but this time, grab all the frames labeled "Run" it should again be 4 frames. We want this animation to loop, but we **don't** want it to autoplay. Let's also give this a framerate of 8 FPS. + +TODO: Walk anim image + +great! That's our animations all done! + +### Collision and Movement + +Now that we have something to look at, let's give our player a hitbox. Open the inspector for the **CollisionShape2D** we added, and add a new shape in the **empty** shape field. +It's a good idea to use a **CapsuleShape** as it will make us less likely to get stuck on corners. Position and adjust the capsule so that it's *slightly* smalle than the sprite for our player. +Mine looks like this: + +TODO: image CollisionShape2D + +Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player_movement" and make sure we're saving it +in our Scripts folder. We also need to make sure we **untick** the **template** box as we will not be using the template! This is because the template is designed for gravity based platformers. + +With our script created and attached, let's get to programming our movement! + +First, let's set up a variable to control our speed. + +```gdscript +@export var speed = 200 +``` + +The **\@export** tag will allow us to easily edit our speed variable, without needing to open the script! + +Then, we'll want to use Godots built in **_physics_process(delta):** function for our movement logic. Inside that we'll want to get the combined vector of all the inputs the player is pressing. + +```gdscript +func _physics_process(delta): + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") +``` + +We'll then multiply this vector by our speed, and then invoke Godots built in **move_and_slide()** function + +```gdscript +velocity = direction * speed + +move_and_slide() +``` + +giving us a final script that looks like this: + +```gdscript +extends CharacterBody2D + +@export var speed = 200 + +func _physics_process(delta): + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + velocity = direction * speed + + move_and_slide() +``` +For now our movement is controlled using the arrow keys, but we'll go over how to map it to whatever we want later in the guide. + + From 54dc043f085df93751093ce7f1eaf00582d2aacf Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Mon, 9 Sep 2024 16:28:46 +1200 Subject: [PATCH 03/29] Tilemap setup. and level creation --- .../game-design/godot/2d Dungeon Crawler.mdx | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 1d5040f..9f40be9 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -88,6 +88,8 @@ Do the same thing we did to grab the frames for the idle animation, but this tim TODO: Walk anim image +Finally, just select your idle animation again, to make sure this is what our player will start on. + great! That's our animations all done! ### Collision and Movement @@ -141,6 +143,81 @@ func _physics_process(delta): ``` For now our movement is controlled using the arrow keys, but we'll go over how to map it to whatever we want later in the guide. +Switch back to 2D view at the top of the screen. + +## Building a level + +Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "Floor 1" + +Save the scene in our Scenes folder. + +Give our root node a child node with the type **TileMap** this will handle the visuals and collision of our level. +In the inspector, create a new **Tile Set** for the **empty** **Tile Set** field. + +You'll notice two new tabs have appeared at the **TileSet** and **TileMap** we'll be working with both of these, but open the **TileSet** tab first. + +using the **+** button in the lower left, navigate to your assets, and load in the "atlas_floor-16x16.png" hit **Yes** when prompted. + +Do the same for the "atlas_walls_low-16x16.png" file, again hitting **Yes** when prompted. + +You can think of these two as palettes we'll use to paint our levels! Our dungeon will be made up from a series of tiles that we can arrange however we want! + +**Note: We won't be implementing the spikes/buttons/levers. So if you add these to your level they'll be purely decorative.** + +Next, we'll want to make sure our walls appear **ontop** of our floors! To do this we'll use layers! On the right, in the inspector for the **TileMap** you'll see a section called layers, with one already there! + +Call this one "Floors" and modify its **Z Index** field to be -1. + +Click **Add Element** to add another layer. Call this one "Walls" and set its **Z Index** field to be 1. + +Todo: layers image + +With our **Tilesets** setup we can now go to the **TileMap** tab. + +From here, if you click on a tile and then in the scene, you'll notice your able to paint them into the scene! This is how we'll create our levels! you can click between the floor and wall tilesets to get access to the different tiles. + +You'll also notice you can switch layers in the top righ of the **TileMap** section. Make sure you're in the right layer for what you're painting! Otherwise they won't appear right! It might be a good idea to do the floors first, followed by the walls. + +Spend some time and get familiar with painting and removing tiles! Aim to create a single room that we can use to test our game. + +**Tip: You can use the Rect tool to draw a rectangle of tiles all at once** + +TODO: rect tool image + +Here's what my room looks like: + +TODO: Basic Room Image + + +## Adding our player to the level + + +### Level collision + + +## Improving our player + +### Animtion switching + +### Input mapping + +## Health + +## Pickups + +### Coins + +### Potions + +## Enemies + +## Another floor + + +TODO: Link to docs +TODO: general cleanup pass +TODO: Add images + From 46e228aaafd6b84b9246757716a8f05d7a4965fc Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Sun, 15 Sep 2024 16:53:30 +1200 Subject: [PATCH 04/29] Collision for tileset --- .../game-design/godot/2d Dungeon Crawler.mdx | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 9f40be9..9f08cfd 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -188,19 +188,57 @@ Here's what my room looks like: TODO: Basic Room Image - ## Adding our player to the level +Now that we have a basic level set up, let's add our player to it so we can start to properly test our game! To do this, we'll just drag our player scene from the **Scenes** folder +in the file browser, into our **scene tree** as a child of the root node! Finally, we'll give the player a child of type **Camera2D.** here's what my scene looks like: + +[TODO: image] + +You should be able to move around! Though you'll quickly notice you're able to walk through walls, which isn't ideal, so let's fix that! ### Level collision +Click on your **TileMap** Node again, select **TileSet** at the bottom of the screen, and click on your Wall **TileSet** Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. +Under the **Physics Layers** drop down, click **Add Element.** + +Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop down, select **Physics Layer 0.** Here's how things look for me! + +[TODO: Image] +Think of the blue square that has appeared under the **Paint** tab as our brush that we'll use to paint collisions onto our **Tileset** with the blue square representing where exactly our player will collide. + + +You can click and drag the white diamonds to move them, and click on the edges to add new points. pressing F (Full) will make the collider occupy the whole square, and pressing C (Clear) will make it occupy none of it. + +So using this, try to create colliders for each tile that closely match their sprite. + +Tip: It'll be easiest to do them in batches of tiles that have the same collision! + +Here's how mine look: + +[TODO: Image] + +Now try playing your game again! You'll notice you actually collide with the walls! Great! ## Improving our player -### Animtion switching +Let's spend some time further improving our player. Let's implement some different controls (Well be doing WASD, but you can using any controls you like) +make sure our animation changes to our walking animation when we move, and make sure our sprite faces in the direction we're moving. + +We'll also be implementing attacking, but we'll do that in it's own section! ### Input mapping +### Animation switching + +### Sprite facing + +## Attacking + +### Weapon Scene + +### Adding our weapon to our player + ## Health ## Pickups From 487fe9737a1272aadd99180d35817f58c8bf3658 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Sun, 15 Sep 2024 17:21:31 +1200 Subject: [PATCH 05/29] Sprite animation based on movement --- .../game-design/godot/2d Dungeon Crawler.mdx | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 9f08cfd..b76f403 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -229,8 +229,107 @@ We'll also be implementing attacking, but we'll do that in it's own section! ### Input mapping +To change our inputs, we'll first need to set up our **Input Map** to do this, we'll navigate to **Project -> Project Settings** in the top left of the workspace. + +Then, open the **Input Map** tab. + +We'll add our new Inputs by typing a name for each of them in the **Add New Action** box and hitting add. + +I'll be calling mine "Up" "Down" "Left" "Right" and i'll also add one called "Attack" + +[TODO: Images] + +To add buttons to these, we'll hit the "+" to the right of each action, we'll then physically press the key we want to assign on our keyboard, and hit "Ok" + +For my **Attack** action i'll be using **Left Click* for which you'll want to physically click (once) inside the **Listening for input** box. + +Here's what my inputs look like: +[TODO: Image] + +If you're happy with your inputs, you can then hit **Close** at the bottom of the screen. Let's navigate back to our **player_movement.gd** script. This can be done by opening our **player** scene, clicking on the **CharacterBody2D** and clicking the **Script** tab at the top of the screen. + +To change our inputs, all we need to do is change the predifined inputs to what we called ours! + +**Note:** What you named your input actions *is* case sensitive + +So, "ui_left" becomes "Left" +"ui_right" becomes "Right" and so on! + +leaving that line line in our script looking like this: + +```gdscript + var direction = Input.get_vector("Left", "Right", "Up", "Down") +``` +if you run your game, you'll notice your inputs are now changed! + +We won't assign our Attack option just yet, but it's good we've created it already. + ### Animation switching +To change our animation depending on if we're moving or not, we'll only need to add a few lines to our script. But first, we'll need a reference to our **AnimatedSprite2D** in our script. + +We can do this easily, by **Clicking** and **Dragging** our **AnimatedSprite2D** into our script, making sure we hold **Ctrl** on the keyboard after grabbing it, but before dropping it. + +We'll want to drop it below + +```gdscript +@export var speed = 200 +``` +It should get added to our script looking like: + +```gdscript +@onready var animated_sprite_2d = $AnimatedSprite2D +``` + +if it doesn't look like this, delete the line and try again, making sure you're holding **Ctrl** on your keyboard after picking it up. + +Great! Let's get to changing our animation! + +Under where we set our velocity, we'll simply add a check to see if our velocity is anything other than 0 and change our animation based on that! + +We can check this simply with: + +**Note:** Why can't we just do velocity != 0? This is because velocity actually contains both our X (Horizontal) and Y (Vertical) velocity, so we need to make sure **Both** aren't zero. + +```gdscript +if velocity != Vector2.ZERO: +``` + +Then, we can play our run animation! + +```gdscript +if velocity != Vector2.ZERO: + animated_sprite_2d.play("walk") +``` + +and if we're not moving, let's play our idle + +```gdscript +else: + animated_sprite_2d.play("idle") +``` + +Giving us a movement script that looks like this: + +```gdscript +extends CharacterBody2D + +@export var speed = 200 +@onready var animated_sprite_2d = $AnimatedSprite2D + +func _physics_process(delta): + var direction = Input.get_vector("Left", "Right", "Up", "Down") + velocity = direction * speed + if velocity != Vector2.ZERO: + animated_sprite_2d.play("walk") + else: + animated_sprite_2d.play("idle") + + move_and_slide() +``` + +Play your game, and you'll notice your animation changes when you move! + ### Sprite facing ## Attacking From 4b1b1747f3b88bf5ee594773967d580be423f0a3 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Sun, 15 Sep 2024 17:39:58 +1200 Subject: [PATCH 06/29] Sprite facing --- .../game-design/godot/2d Dungeon Crawler.mdx | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index b76f403..9def7ed 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -332,6 +332,57 @@ Play your game, and you'll notice your animation changes when you move! ### Sprite facing +To flip our player based on the direction we're moving, all we really need to do is add another If to check only the **Horizontal** part of our velocity, as thankfully the **AnimatedSprite2D** node has a built in way to flip our sprite! + +I'll be adding this section **beneath** the animation section, but before the **move_and_slide()** function call. + +let's start by checking the Horizontal portion of our movement: + +```gdscript +if(velocity.x < 0): +``` +if our x velocity is less than 0 (moving to the left) we want to flip our sprite. + +```gdscript +animated_sprite_2d.flip_h = true +``` + +And if it's greater than 0, we'll unflip it + +```gdscript +elif(velocity.x > 0): + animated_sprite_2d.flip_h = false +``` + +giving us a movement script that looks like this: + +```gdscript +extends CharacterBody2D + +@export var speed = 200 +@onready var animated_sprite_2d = $AnimatedSprite2D + +func _physics_process(delta): + var direction = Input.get_vector("Left", "Right", "Up", "Down") + velocity = direction * speed + + if velocity != Vector2.ZERO: + animated_sprite_2d.play("walk") + else: + animated_sprite_2d.play("idle") + + if(velocity.x < 0): + animated_sprite_2d.flip_h = true + elif(velocity.x > 0): + animated_sprite_2d.flip_h = false + + move_and_slide() +``` +**Note:** Why didn't we juse use **else:**? - If we'd just used **Else:** our sprite would have jarringly flipped to face left whenever we stopped moving, or if we were just moving up and down. +This way the direction our sprite is facing doesn't change unless we move either left or right! + +Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! + ## Attacking ### Weapon Scene From dc1d4f8a1805b6002dd433dccc97c8ad0a5b2afa Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 20 Sep 2024 12:22:52 +1200 Subject: [PATCH 07/29] Weapon scene creation --- .../game-design/godot/2d Dungeon Crawler.mdx | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 9def7ed..1d2b965 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -241,7 +241,7 @@ I'll be calling mine "Up" "Down" "Left" "Right" and i'll also add one called "At To add buttons to these, we'll hit the "+" to the right of each action, we'll then physically press the key we want to assign on our keyboard, and hit "Ok" -For my **Attack** action i'll be using **Left Click* for which you'll want to physically click (once) inside the **Listening for input** box. +For my **Attack** action i'll be using **Left Click* for which you'll want to physically click *once* inside the **Listening for input** box. Here's what my inputs look like: [TODO: Image] @@ -383,10 +383,36 @@ This way the direction our sprite is facing doesn't change unless we move either Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! -## Attacking - ### Weapon Scene +Let's create a new scene for our weapon! +Give it a root node of just a **Node2D** with two children, a **Sprite2D** and a **Animationplayer** +Give the sprite a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** + +Here's how my scenetree looks: + +[TODO: Weapon scenetree] + +Let's start by picking a sprite for our weapon, so we can see what we're working with! +Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! + +Don't worry that it's pointing up, we'll rotate it when we add it to our player scene! It'll be helpful to keep all Transform values at 0 in this scene. + +Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. +Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. + +Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" +Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. + +We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. + +Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! + +Finally, scroll until you see the **Position** property. + +Phew! That was quite a few steps, but our animation track is created! + + ### Adding our weapon to our player ## Health From cf4a9bfd514618d5e66a2c53b065161046585212 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Wed, 2 Oct 2024 19:50:12 +1300 Subject: [PATCH 08/29] Finished weapon, first half of health system --- .../game-design/godot/2d Dungeon Crawler.mdx | 247 +++++++++++++++++- 1 file changed, 243 insertions(+), 4 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 1d2b965..1b2f156 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -52,7 +52,7 @@ TODO: Settings image Great! Let's start by making a basic version of our player character that will let us move around. We'll worry about more complicated things like attacking later. -Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. +Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** Give the **CharacterBody2D** a name like **Player** and give it two children: @@ -100,7 +100,7 @@ Mine looks like this: TODO: image CollisionShape2D -Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player_movement" and make sure we're saving it +Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player.gd" and make sure we're saving it in our Scripts folder. We also need to make sure we **untick** the **template** box as we will not be using the template! This is because the template is designed for gravity based platformers. With our script created and attached, let's get to programming our movement! @@ -188,7 +188,7 @@ Here's what my room looks like: TODO: Basic Room Image -## Adding our player to the level +### Adding our player to the level Now that we have a basic level set up, let's add our player to it so we can start to properly test our game! To do this, we'll just drag our player scene from the **Scenes** folder in the file browser, into our **scene tree** as a child of the root node! Finally, we'll give the player a child of type **Camera2D.** here's what my scene looks like: @@ -383,24 +383,38 @@ This way the direction our sprite is facing doesn't change unless we move either Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! +## The Weapon + ### Weapon Scene Let's create a new scene for our weapon! Give it a root node of just a **Node2D** with two children, a **Sprite2D** and a **Animationplayer** Give the sprite a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** +Name the root **Node2D** something like "Weapon" + Here's how my scenetree looks: [TODO: Weapon scenetree] +Make sure you save the scene, calling it something like "Weapon.tscn" + Let's start by picking a sprite for our weapon, so we can see what we're working with! Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! -Don't worry that it's pointing up, we'll rotate it when we add it to our player scene! It'll be helpful to keep all Transform values at 0 in this scene. +Don't worry that it's pointing up, we'll rotate it in a minute. Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. +Before we get to the attack animation, let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** + +Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** + +Here's how my sword scene and inspector look: + +[TODO: swordSceneInspector] + Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. @@ -412,11 +426,236 @@ Finally, scroll until you see the **Position** property. Phew! That was quite a few steps, but our animation track is created! +Great, now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. + +To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! + +The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) + +Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. + +Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. + +Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. + +Play it again, and you'll notice it's much faster! Now we just need to play this animation from a script! + +### Weapon Script + +Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" + +We'll need this script to do two things: + +1. Rotate around our player, facing the mouse. +2. Play the animation when we press our attack input. + +The first step will be nice and easy! In the **process** function, add the line +```gdscript +look_at(get_global_mouse_position()) +``` +This will cause this node to always face toward the position of the mouse! + +Next, we'll need to get a reference to our **AnimatedSprite2D** node, we'll do this the same way we did for the **animated_sprite_2d** node for the player' by clicking, dragging, and then holding ctrl before we let go of the click. + +your script should look like this: + +```gdscript +extends Node2D + +@onready var animation_player = $AnimationPlayer + +func _process(delta): + look_at(get_global_mouse_position()) +``` + +Great, now let's add a check to see if we've just used the **Attack** input action we created earler, and play the animation if we have. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! + +Making sure that the Input action name, and animation name match, including case sensitivity. +```gdscript +extends Node2D + +@onready var animation_player = $AnimationPlayer + +func _process(delta): + look_at(get_global_mouse_position()) + + if Input.is_action_just_pressed("Attack"): + animation_player.play("Attack") + +``` +Great! Let's get our weapon added to our player! ### Adding our weapon to our player +Navigate to your player secene. From the filesystem, drag in your weapon scene (Likely called something like **weapon.tscn**) and attach it as a child of the main +**CharacterBody2D** node. + +Play your game, and you should hopefully have a weapon that rotates around the player and stabs when you click it! If it doesn't seem to be rotating around the middle of the player sprite, feel free to adjust its position within the Player scene. + +You're also welcome to adjust the size of the weapon (Although, you're best to do this within the weapon scene itself) it's your game after all! + ## Health +### Player Health + +Let's start setting up our health system on the player side, we'll start by adding a new Node to our player, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** +give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." + +Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** + +Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! +In the timer's inspector, set its **Wait Time** field to 0.5s + +Great! this **Area2D** will be used to detect collision with enemies, potions, and coins! For now we'll just be setting it up to handle health, both healing and damage. + +Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" + +This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its funcitonality up into multiple scripts, but for our scope this is fine! +Let's break down what we need it to do: + +1. Track our health +2. Detect collisions with potions/enemies/coins +3. Change our health value +4. Update the UI + +Let's start by creating the variables we'll need, those being: + +1. The signal we'll use to talk to the UI +2. A max health, and current health value +3. A reference to the timer we created. +4. A boolean determining if we can take damage + +These should look something like this, using the same click + drag + ctrl method to get the reference to the **Timer** + +```gdscript +signal on_health_changed(new_health : int) +@export var max_health : int = 6 +@onready var damage_timer = $damageTimer +var health : int +var can_take_damage : bool = true +``` + +**Remember:** We can use the **\@export** to modify the max health value, without editing the script! + +**Note:** Why are we starting at 6 health? We're doing this because each point of health will represent half a heart to the UI, for a total of 3 full hearts! Using ints like this is safer than using a float, +because what if we somehow end up with 0.001 health! + +in our **_ready** function we'll want to set some default values, and emit the health_changed signal to send our starting health to the UI. + +```gdscript +func _ready(): + health = max_health + emit_signal("on_health_changed", health) +``` + +Right, let's get onto the most complicated function in the script, the function for taking damage! In this function, there'll be a few different possible outcomes. +1. We can't take damage as we're currently immune. In this case. Nothing happens +2. Otherwise we'll take damage. Emitting the signal to change the UI. +3. If we do take damage, we might be reduced to 0 hitpoints +4. If we are, we die! If we're not. We start our immunity timer. + +Great! Let's write that in gdscript: + +```gdscript +func take_damage(): + if can_take_damage: + health = health - 1 + emit_signal("on_health_changed", health) + + if health <= 0: + print("you died!") + else: + can_take_damage = false + damage_timer.connect("timeout", allow_damage()) + damage_timer.start() +``` + +**Note:** For now we'll just having dying print to the console and do nothing else, as we'll want some proper UI. + +You'll notice we connected our timer to a function called **allow_damage()** which doesn't exist, let's create that now. All it's going to do is set the **can_take_damage** boolean to **True** as unfortunately Godot doesn't let you assign a value to a variable directly via the **connect()** function. + +```gdscript +func allow_damage(): + can_take_damage = true +``` + +Next we'll do healing! This one is *much* easier. We just need to check if we have room to be healed (Our health is less than our max health). If we do, increase our health by 1. Then emit the signal to update the UI! We'll also want to delete the potion, so it can no longer be used. + +```gdscript +func heal(body): + if health < max_health: + health = health + 1 + emit_signal("on_health_changed", health) + body.get_parent().queue_free() +``` + +Finally, we need a function that calls our **heal** and **damage** functions based on what we've collided with. To check what type of object we've collided with, we'll be using **Groups!** These are something we'll assign to our enemies/potions/coins later. + +To check if something has collided with us, we'll need to the **on_body_entered** signal! To connect this, swap to the **Node** tab of the **Inspector** and click on the **Area2D** node in the **SceneTree** again. You'll see a list of all the signals we have available to us! +Click the **on_body_entered** signal and press **Connect** select the **Area2D (hitbox)** node and click **Connect** + +You'll see a new function appear in our script! On that'll be called whenever something enteres this **Area2D** + +In here, we can check the **Group** of what we've collided with! + +```gdscript +func _on_body_entered(body): + if body.is_in_group("enemy"): + take_damage() + elif body.is_in_group("health"): + heal(body) +``` +and that's it! Giving us a full script that looks something that this: + +```gdscript +extends CollisionShape2D + +signal on_health_changed(new_health : int) +@export var max_health : int = 6 +@onready var damage_timer = $damageTimer +var health : int +var can_take_damage : bool = true + +# Called when the node enters the scene tree for the first time. +func _ready(): + health = max_health + emit_signal("on_health_changed", health) + +func _on_body_entered(body): + if body.is_in_group("enemy"): + take_damage() + elif body.is_in_group("health"): + heal(body) + + +func take_damage(): + if can_take_damage: + health = health - 1 + emit_signal("on_health_changed", health) + + if health <= 0: + print("you died!") + else: + can_take_damage = false + damage_timer.connect("timeout", allow_damage()) + damage_timer.start() + +func heal(body): + if health < max_health: + health = health + 1 + emit_signal("on_health_changed", health) + body.get_parent().queue_free() + +func allow_damage(): + can_take_damage = true +``` + +**Note:** If you copy and paste the above, you'll still need to manually connect the **on_body_entered** signal! + +And that's the player side of health done! Let's move onto the UI side! + +### Health UI + ## Pickups ### Coins From 1aafdc3179fef5446f80e39f73836dfe2ddcf1a2 Mon Sep 17 00:00:00 2001 From: Lillian Hide-Tobin Date: Thu, 3 Oct 2024 21:43:31 +1300 Subject: [PATCH 09/29] First Iteration of health system --- src/content/docs/game-design/godot/2d Dungeon Crawler.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 1b2f156..f2bfb9d 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -30,7 +30,7 @@ First let's create a new folder, and call it something like 'Assets' Then, let's extract the assets from the folder we downloaded, and at them into our Assets folder. Mine looks like this, but it's fine if yours looks slightly different. -TODO: Image here +TODO: Image here ![Godot new project window](/src/assets/godot/3DGameGuide/3dgameprojectsetup.png) From 0f436c6cbcf09651e85a3a76e611718a19dca8f1 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Thu, 3 Oct 2024 21:44:28 +1300 Subject: [PATCH 10/29] Update 2d Dungeon Crawler.mdx --- src/content/docs/game-design/godot/2d Dungeon Crawler.mdx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 1b2f156..d5f9852 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -608,7 +608,7 @@ func _on_body_entered(body): and that's it! Giving us a full script that looks something that this: ```gdscript -extends CollisionShape2D +extends Area2D signal on_health_changed(new_health : int) @export var max_health : int = 6 @@ -664,12 +664,17 @@ And that's the player side of health done! Let's move onto the UI side! ## Enemies +### Enemy Scene + +### Enemy Scripting + ## Another floor TODO: Link to docs TODO: general cleanup pass TODO: Add images +TODO: Weapon active logic From 6df1c543dbbf0f03574fc15a56e3ffc620ed9846 Mon Sep 17 00:00:00 2001 From: Lillian Hide-Tobin Date: Thu, 3 Oct 2024 22:08:51 +1300 Subject: [PATCH 11/29] Fixed failed commit --- src/content/docs/game-design/godot/2d Dungeon Crawler.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index f2bfb9d..1bcd3d6 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -656,6 +656,12 @@ And that's the player side of health done! Let's move onto the UI side! ### Health UI +Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like UI. and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! + +Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whetever the size of our screen is, the health will always be pinned to the top left! + +Rename the node to something like "health_container" + ## Pickups ### Coins From 4759586d3826e1a06168a0df3abcf5db64d5a48e Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Thu, 3 Oct 2024 22:53:08 +1300 Subject: [PATCH 12/29] Finished Health System --- .../game-design/godot/2d Dungeon Crawler.mdx | 117 +++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 2c2bced..9af0d7f 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -656,11 +656,124 @@ And that's the player side of health done! Let's move onto the UI side! ### Health UI -Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like UI. and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! +Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whetever the size of our screen is, the health will always be pinned to the top left! -Rename the node to something like "health_container" +Rename the node to something like "health_container." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) + + Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points, and a "You died" message) + + Add a script to the root node, calling it something like "ui.gd" + + Let's think about what we need this script to do: + 1. Store our three different heart images + 2. Recieve signals from our player when we take damage + 3. Update our health UI. + + We'll set this up so that it automatically adjusts depending on the players **max_health** when the game is run, so you can easily have more (or less) than three hearts! + (Or, you could implement an item that increases your max hp!) + + Thankfull, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image + +Find these in yor filesystem, and drag in the references, it should look something like this: + +```gdscript +const UI_HEART_EMPTY = preload("res://Assets/frames/ui_heart_empty.png") +const UI_HEART_FULL = preload("res://Assets/frames/ui_heart_full.png") +const UI_HEART_HALF = preload("res://Assets/frames/ui_heart_half.png") +``` + +Let's also get a reference to our **health_container** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) +We won't set this variable here, as it'll be set by whatever the most health we've had so far has been. + +```gdscript +@onready var health_cont = $health_container +var maxHealth : int = 0 +``` +Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! + +1. If the health recieved is bigger than our highest health so far, make that our new highest health. Easy enough! + +```gdscript +func changed_health(newHealth : int): + if newHealth > maxHealth: + maxHealth = newHealth +``` + +2. we'll want to check if we have enough hearts currently to represent that, if we don't, we'll need to add some more. (We'll create the function for this last) + +```gdscript + if(maxHealth/2 > health_cont.get_child_count()): + for h in (maxHealth/2) - health_cont.get_child_count(): + add_heart() +``` + +3. we'll iterate through all the children our **health_container** node has, and assign an image based on the current health. + +This section may look complicated, but once you get your head around it, it's fairly simple! Spend some time looking over it, and thinking about the conditions for each heart to be drawn. +When I was figuring out how to program this, I found it useful to draw out the hearts on paper, at different levels of health! + +```gdscript +for i in health_cont.get_child_count(): + if (i * 2) + 1 < newHealth: + health_cont.get_child(i).texture = UI_HEART_FULL + elif (i * 2) < newHealth: + health_cont.get_child(i).texture = UI_HEART_HALF + else: + health_cont.get_child(i).texture = UI_HEART_EMPTY +``` + +giving us a full **changed_health** function that looks like this: + +```gdscript +func changed_health(newHealth : int): + if newHealth > maxHealth: + maxHealth = newHealth + + if(maxHealth/2 > health_cont.get_child_count()): + for h in (maxHealth/2) - health_cont.get_child_count(): + add_heart() + + for i in health_cont.get_child_count(): + if (i * 2) + 1 < newHealth: + health_cont.get_child(i).texture = UI_HEART_FULL + elif (i * 2) < newHealth: + health_cont.get_child(i).texture = UI_HEART_HALF + else: + health_cont.get_child(i).texture = UI_HEART_EMPTY +``` + +Not too bad! + +Let's add that **add_heart** function, which just creates and configures another child if we need one. + +```gdscript +func add_heart(): + var img : TextureRect = TextureRect.new() + img.expand_mode = TextureRect.EXPAND_FIT_WIDTH + health_cont.add_child(img) +``` + +Save the scene as something like "UI.tscn" + +Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that that the UI 'sticks' to the camera, rather than existing within the game) + +*Finally,* to get everything hooked up, we just need to connect that signal! Open up **hitbox.gd** + +First, we'll get a reference to our new **UI** scene. Put this with the other variable declarations. + +``` +@onready var ui : Control = $"../../CanvasLayer/UI" +``` + +Then, finally, before we call the signal the first time, connect the signal with: + +```gdscript +on_health_changed.connect(ui.changed_health) +``` + +Run your game! And you should have 3 hearts! Great! ## Pickups From fe9212d45ef731aee037d25ee92dddaf5042dd72 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 00:12:43 +1300 Subject: [PATCH 13/29] Coins/Potions --- .../game-design/godot/2d Dungeon Crawler.mdx | 189 ++++++++++++++---- 1 file changed, 147 insertions(+), 42 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 9af0d7f..f9e6168 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -147,11 +147,11 @@ Switch back to 2D view at the top of the screen. ## Building a level -Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "Floor 1" +Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "World" Save the scene in our Scenes folder. -Give our root node a child node with the type **TileMap** this will handle the visuals and collision of our level. +Give our root node a child node with the type **TileMap** this will handle the visuals and collision of our level. Call it something like "Level 1" In the inspector, create a new **Tile Set** for the **empty** **Tile Set** field. You'll notice two new tabs have appeared at the **TileSet** and **TileMap** we'll be working with both of these, but open the **TileSet** tab first. @@ -407,7 +407,7 @@ Don't worry that it's pointing up, we'll rotate it in a minute. Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. -Before we get to the attack animation, let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** +let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** @@ -415,31 +415,6 @@ Here's how my sword scene and inspector look: [TODO: swordSceneInspector] -Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" -Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. - -We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. - -Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! - -Finally, scroll until you see the **Position** property. - -Phew! That was quite a few steps, but our animation track is created! - -Great, now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. - -To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! - -The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) - -Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. - -Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. - -Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. - -Play it again, and you'll notice it's much faster! Now we just need to play this animation from a script! - ### Weapon Script Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" @@ -457,18 +432,21 @@ This will cause this node to always face toward the position of the mouse! Next, we'll need to get a reference to our **AnimatedSprite2D** node, we'll do this the same way we did for the **animated_sprite_2d** node for the player' by clicking, dragging, and then holding ctrl before we let go of the click. +We'll also want a variable that keeps track of if we're *currently* attacking, as we don't want the sword to destroy enemies when we haven't attacked. + your script should look like this: ```gdscript extends Node2D @onready var animation_player = $AnimationPlayer +@export var attacking : bool = false func _process(delta): look_at(get_global_mouse_position()) ``` -Great, now let's add a check to see if we've just used the **Attack** input action we created earler, and play the animation if we have. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! +Great, now let's add a check to see if we've just used the **Attack** input action we created earler, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! Making sure that the Input action name, and animation name match, including case sensitivity. ```gdscript @@ -476,6 +454,8 @@ extends Node2D @onready var animation_player = $AnimationPlayer +@export var attacking : bool = false + func _process(delta): look_at(get_global_mouse_position()) @@ -483,6 +463,40 @@ func _process(delta): animation_player.play("Attack") ``` + +### Sword Animation + +Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" +Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. + +We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. + +Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! + +Finally, scroll until you see the **Position** property. + +Phew! That was quite a few steps, but our animation track is created! + +Great, now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. + +To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! + +The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) + +Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. + +Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. + +Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. + +Play it again, and you'll notice it's much faster! + +We'll want to add another **Property Animation Track** this time to modify the **attacking** variable, to keep track of if our weapon is "Active" or not. + +Add a new animation track, select property, and you should see "attacking" right at the top! Add two keyframes, one right at the start, and one right at the end. The first we'll want to set the value to "on" (as we're now attacking) and the one at the end will set the property back to "off" (or unticked) + +And that's it! We'll come back later to add the code for destroying enemies. + Great! Let's get our weapon added to our player! ### Adding our weapon to our player @@ -501,6 +515,8 @@ You're also welcome to adjust the size of the weapon (Although, you're best to d Let's start setting up our health system on the player side, we'll start by adding a new Node to our player, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." +In the **Inspector** of the **Area2D** Navigate to the **Collision** section. Deselect all numbers under the **Layer** Section, and ensure *only* 2 is selected under the **Mask** Section. + Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! @@ -520,15 +536,17 @@ Let's break down what we need it to do: Let's start by creating the variables we'll need, those being: -1. The signal we'll use to talk to the UI -2. A max health, and current health value -3. A reference to the timer we created. -4. A boolean determining if we can take damage +1. The signal we'll use to talk to the UI when our health has changed +2. While we're here, a signal for when we've collected a coin, as it'll also talk to the UI +3. A max health, and current health value +4. A reference to the timer we created. +5. A boolean determining if we can take damage These should look something like this, using the same click + drag + ctrl method to get the reference to the **Timer** ```gdscript signal on_health_changed(new_health : int) +signal on_point_gained @export var max_health : int = 6 @onready var damage_timer = $damageTimer var health : int @@ -586,7 +604,7 @@ func heal(body): if health < max_health: health = health + 1 emit_signal("on_health_changed", health) - body.get_parent().queue_free() + body.queue_free() ``` Finally, we need a function that calls our **heal** and **damage** functions based on what we've collided with. To check what type of object we've collided with, we'll be using **Groups!** These are something we'll assign to our enemies/potions/coins later. @@ -596,7 +614,7 @@ Click the **on_body_entered** signal and press **Connect** select the **Area2D ( You'll see a new function appear in our script! On that'll be called whenever something enteres this **Area2D** -In here, we can check the **Group** of what we've collided with! +In here, we can check the **Group** of what we've collided with! Let's also add a check to see if we've collected a coin here, to save us some time later! ```gdscript func _on_body_entered(body): @@ -604,6 +622,10 @@ func _on_body_entered(body): take_damage() elif body.is_in_group("health"): heal(body) + elif body.is_in_group("coin"): + emit_signal("on_point_gained") + body.queue_free() + ``` and that's it! Giving us a full script that looks something that this: @@ -611,6 +633,7 @@ and that's it! Giving us a full script that looks something that this: extends Area2D signal on_health_changed(new_health : int) +signal on_point_gained @export var max_health : int = 6 @onready var damage_timer = $damageTimer var health : int @@ -621,11 +644,14 @@ func _ready(): health = max_health emit_signal("on_health_changed", health) -func _on_body_entered(body): +func _on_body_entered(): if body.is_in_group("enemy"): take_damage() elif body.is_in_group("health"): heal(body) + elif body.is_in_group("coin"): + emit_signal("on_point_gained") + body.queue_free() func take_damage(): @@ -644,7 +670,7 @@ func heal(body): if health < max_health: health = health + 1 emit_signal("on_health_changed", health) - body.get_parent().queue_free() + body.queue_free() func allow_damage(): can_take_damage = true @@ -660,7 +686,7 @@ Time to start making some UI! Let's make a new scene, of, as you may have guesse Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whetever the size of our screen is, the health will always be pinned to the top left! -Rename the node to something like "health_container." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) +Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points, and a "You died" message) @@ -684,11 +710,11 @@ const UI_HEART_FULL = preload("res://Assets/frames/ui_heart_full.png") const UI_HEART_HALF = preload("res://Assets/frames/ui_heart_half.png") ``` -Let's also get a reference to our **health_container** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) +Let's also get a reference to our **healthContainer** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) We won't set this variable here, as it'll be set by whatever the most health we've had so far has been. ```gdscript -@onready var health_cont = $health_container +@onready var health_cont = $healthContainer var maxHealth : int = 0 ``` Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! @@ -709,7 +735,7 @@ func changed_health(newHealth : int): add_heart() ``` -3. we'll iterate through all the children our **health_container** node has, and assign an image based on the current health. +3. we'll iterate through all the children our **healthContainer** node has, and assign an image based on the current health. This section may look complicated, but once you get your head around it, it's fairly simple! Spend some time looking over it, and thinking about the conditions for each heart to be drawn. When I was figuring out how to program this, I found it useful to draw out the hearts on paper, at different levels of health! @@ -755,6 +781,13 @@ func add_heart(): health_cont.add_child(img) ``` +Let's also while we're here, add an empty function for our point system, which we'll come back to later! + +```gdscript +func add_point(): + pass +``` + Save the scene as something like "UI.tscn" Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that that the UI 'sticks' to the camera, rather than existing within the game) @@ -763,7 +796,7 @@ Go back to your main level scene. Add a new child of type **CanvasLayer** and ad First, we'll get a reference to our new **UI** scene. Put this with the other variable declarations. -``` +```gdscript @onready var ui : Control = $"../../CanvasLayer/UI" ``` @@ -772,15 +805,84 @@ Then, finally, before we call the signal the first time, connect the signal with ```gdscript on_health_changed.connect(ui.changed_health) ``` +we'll also connect our point signal with: + +```gdscript +on_point_gained.connect(ui.add_point) +``` Run your game! And you should have 3 hearts! Great! ## Pickups +Let's get onto pickups! Our game will have two types of pickups: Coins, and Potions. Coins will give us a point, and Potions will heal us for half a heart! + +Thankfully the setup for the two will be extremely simple, and they won't even need a script! As all logic is handled by our hitbox script! + ### Coins +For coins, we'll create a new scene with a root node of **Staticbody2D** calling it something like "Coin" + +It should have a child of type **CollisionShape2D** + +We'll also want to add an **AnimatedSprite2D** to the root node. + +Here's how my scene looks: + +[TODO: coin scene] + +We'll add the animation the same way we did with our player! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** create a new **Spriteframes** + +Click on the new **Spriteframes** and add sprites from file. (The coin has four frames) Make sure to click **autoplay** (The 'A' in the pointy box) +and then assign a shape to the **CollisionShape2D** that loosely matches the coin. (I just used a circle) + +The coin as is is very small, so open the inspector for the root **Staticbody2D** and change the **Scale** values to 2. + +Now, all that's left to do is create a **Group.** With the root **Staticbody2D** still selected, navigate to the **Node** tab of the inspector, then to the **Groups** tab. + +[TODO: Groups img] + +In the box, type "coin" and click **Add** + +Then, click **Manage Groups** and select each Node, followed by **Add** to ensure that each node in the scene is in the group. + +Finally, we'll want to open the **Collision** tab on the inspector of the **Staticbody2D** setting the **Layer** to *only* 2, and deselecting all numbers under the **Mask** as we don't want our coin to be looking for collisions, or to be physically collided with! + +And that's our coin! The only script work we need to do is in our **UI** script! But first we'll need to add a UI element to track our points! + +Don't worry, we've done all the hard work of connecting signals earlier! This'll be nice and easy! + +Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it something like "pointContainer" + +Give it two children, a **TextureRect** and a **Label,** name the label something like **pointsLabel** + +In the inspector of the **TextureRect** set the **Expand Mode** to "Fit Width" and assign the first coin image to the **Texture** field using the **Load** Option + +Finally for UI setup, in the inspector of the **Label** write "0" in the **Text** field. You'll notice this is pretty small! Scroll down in the **Inspector** until you see **Theme Overrides.** in this section you'll find **Font Sizes.** Set this to something you think looks good! I went with 40px. + +Great! Now we just need to add two lines of code to our UI. and then our points are done! + +First, a reference to our label, same way we've been doing, this should be second nature by now! + +```gdscript +@onready var points_label = $pointContainer/pointsLabel +``` + +then, we'll finish the function we created earlier. + + +```gdscript +func add_point(): + points_label.text = str(int(points_label.text) + 1) +``` +This looks a little silly, but what we're doing is taking the current text in the label, converting it to a number, adding 1 to it, and then converting to *back* to a string. + +If you've set it all up right, you should notice this number going up each time you pick up a coin! Add a few instances of the coin scene to your level to test! + ### Potions +For potions the process is exactly the same! You should be able to do it on your own! Just follow the steps for creating the coin scene. Except in this case we'll just want a regular **Sprite2D** As the potion sprite isn't animated, and we'll want the group to be called "health" (make sure it matches the line we wrote in **hitbox.gd**) + ## Enemies ### Enemy Scene @@ -789,11 +891,14 @@ Run your game! And you should have 3 hearts! Great! ## Another floor +## Finishing up! + TODO: Link to docs TODO: general cleanup pass TODO: Add images TODO: Weapon active logic +TODO: destroying coins and potions From ef96d5657b30ded7c457be072f62fa9d27b8f2d5 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 01:10:47 +1300 Subject: [PATCH 14/29] Enemy Scene --- .../game-design/godot/2d Dungeon Crawler.mdx | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index f9e6168..73a64e0 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -202,6 +202,8 @@ You should be able to move around! Though you'll quickly notice you're able to w Click on your **TileMap** Node again, select **TileSet** at the bottom of the screen, and click on your Wall **TileSet** Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. Under the **Physics Layers** drop down, click **Add Element.** +Here you'll see the **Collision Layer** section, make sure **1** and **3** are selected. For the **Collision Mask** section, only **1** should be selected. + Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop down, select **Physics Layer 0.** Here's how things look for me! [TODO: Image] @@ -415,6 +417,8 @@ Here's how my sword scene and inspector look: [TODO: swordSceneInspector] +Before we move on, navigate to the inspector tab of the **Area2D** node and find the **Collision** tab, under **Layer** make sure nothing is selected. Under **Mask** Make sure *only* 2 is selected. + ### Weapon Script Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" @@ -562,6 +566,7 @@ in our **_ready** function we'll want to set some default values, and emit the h ```gdscript func _ready(): + damage_timer.connect("timeout", allow_damage) health = max_health emit_signal("on_health_changed", health) ``` @@ -584,7 +589,6 @@ func take_damage(): print("you died!") else: can_take_damage = false - damage_timer.connect("timeout", allow_damage()) damage_timer.start() ``` @@ -641,6 +645,7 @@ var can_take_damage : bool = true # Called when the node enters the scene tree for the first time. func _ready(): + damage_timer.connect("timeout", allow_damage) health = max_health emit_signal("on_health_changed", health) @@ -663,7 +668,6 @@ func take_damage(): print("you died!") else: can_take_damage = false - damage_timer.connect("timeout", allow_damage()) damage_timer.start() func heal(body): @@ -885,10 +889,36 @@ For potions the process is exactly the same! You should be able to do it on your ## Enemies +We've got a weapon, we've got health, we've got treasure to collect. What's missing? + +Something to fight! + +We'll be keeping our enemy fairly simple, it'll operate off a circular detection range, and walk toward the player if it enters that range, without taking into account walls (Though it will of course still collide with walls) + ### Enemy Scene +Let's get to making the scene! + +It'll need: a root **Rigidbody2D** (Called "Enemy") with three children: a **CollisionShape2D,** an **Area2D** (named "range") and an **AnimatedSprite2D** + +Additionally we'll want to give the **Area2D** a **CollisionShape2D** as a child. + +[TODO: Enemy scene image] + +First, in the **Inspector** of the **Rigidbody2D** we'll want to set the **Gravity Scale** to 0 (As we don't want it to have gravity) and under the **Collision** section, we'll want **Layer** **2** and **3** selected. With only **1** selected under **Mask** + +Let's skip down to setting up the **AnimatedSprite2D.** Create two animations, call the first "idle" and the second "move". Then, pick something to be your enemy! Selecting both the idle and move animation as we did for the player, using the **Add from file** button. + +You may want to speed the animations up as they're fairly slow by default, I found 10 fps to be good for both! You'll also want to make sure you set the **idle** animation to be autoplay! + +Set the **CollisionShape2D** that's a child of the root node to have a shape that generally matches the sprite. + +Finally, set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! + ### Enemy Scripting +### Destroying the enemy! +sword scene function ## Another floor ## Finishing up! @@ -897,8 +927,6 @@ For potions the process is exactly the same! You should be able to do it on your TODO: Link to docs TODO: general cleanup pass TODO: Add images -TODO: Weapon active logic -TODO: destroying coins and potions From 73802735c89f8c9eabf35bc8c564ca27adc3c10d Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 01:50:31 +1300 Subject: [PATCH 15/29] Finished Enemy --- .../game-design/godot/2d Dungeon Crawler.mdx | 145 +++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx index 73a64e0..12b5416 100644 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx @@ -25,6 +25,14 @@ We'll instead be using a free asset pack by Ox72 on Itch.IO which [can be found ## Making the project + +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing our assets. First let's create a new folder, and call it something like 'Assets' @@ -50,6 +58,13 @@ TODO: Settings image ## Creating the Player +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + Great! Let's start by making a basic version of our player character that will let us move around. We'll worry about more complicated things like attacking later. Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** @@ -147,6 +162,7 @@ Switch back to 2D view at the top of the screen. ## Building a level + Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "World" Save the scene in our Scenes folder. @@ -224,6 +240,13 @@ Now try playing your game again! You'll notice you actually collide with the wal ## Improving our player +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + Let's spend some time further improving our player. Let's implement some different controls (Well be doing WASD, but you can using any controls you like) make sure our animation changes to our walking animation when we move, and make sure our sprite faces in the direction we're moving. @@ -387,6 +410,13 @@ Test your game, and you'll notice your sprite now faces left or right depending ## The Weapon +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + ### Weapon Scene Let's create a new scene for our weapon! @@ -514,6 +544,13 @@ You're also welcome to adjust the size of the weapon (Although, you're best to d ## Health +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + ### Player Health Let's start setting up our health system on the player side, we'll start by adding a new Node to our player, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** @@ -819,6 +856,13 @@ Run your game! And you should have 3 hearts! Great! ## Pickups +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + + Let's get onto pickups! Our game will have two types of pickups: Coins, and Potions. Coins will give us a point, and Potions will heal us for half a heart! Thankfully the setup for the two will be extremely simple, and they won't even need a script! As all logic is handled by our hitbox script! @@ -889,6 +933,12 @@ For potions the process is exactly the same! You should be able to do it on your ## Enemies +:::note[Godot Documentation] +Godot Documentation for nodes discussed in this section: + +[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) +::: + We've got a weapon, we've got health, we've got treasure to collect. What's missing? Something to fight! @@ -913,12 +963,102 @@ You may want to speed the animations up as they're fairly slow by default, I fou Set the **CollisionShape2D** that's a child of the root node to have a shape that generally matches the sprite. -Finally, set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! +Set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! + +Finally, let's create a new **Group** and call it "enemy", and assign it to the root node of the scene. ### Enemy Scripting +Now let's get the enemy moving! + +Let's create some variables: +1. a boolean to keep track of if the player is in range +2. a reference to the player +3. a variable to control our speed + +It should look something like this, again getting the reference to the **AnimatedSprite2D** the usual way: +```gdscript +var in_range : bool = false +var target + +@export var speed : float = 50.0 +@onready var animated_sprite_2d = $AnimatedSprite2D +``` + +Then, we'll want to connect two signals from the "range" **Area2D** node, we'll want to connect both the "on_body_entered" and "on_body_exited" signals to the script we created! + +Let's write those functions. When the player enters the the range, we'll want to set our **in_range** boolean, and play our move animation + +``` gdscript +func _on_range_body_entered(body): + if(body.is_in_group("player")): + in_range = true + target = body + animated_sprite_2d.play("move") +``` + +and in the exited function, we'll want to do the inverse! + +```gdscript +func _on_range_body_exited(body): + if(body.is_in_group("player")): + in_range = false + animated_sprite_2d.play("idle") +``` + +Now, in the **_process()** function, we'll want to check if our player is in range, if they are, move toward them. We'll also want to flip our sprite based on where the player is in relation to the enemy. + +```gdscript +func _process(delta): + if(in_range): + position = position.move_toward(target.position, speed * delta) + if(target.global_position.x < global_position.x): + animated_sprite_2d.flip_h = true + else: + animated_sprite_2d.flip_h = false +``` + +and that's it! The last thing we need to do is head over to our **Player** scene, create a group called "player" and add the root node of the scene to it. + +Add an enemy to the scene, and you should notice that if you get close to it, it'll walk toward you, and take health away whenever it touches you! + +Although there's one problem... We can't destroy it! + ### Destroying the enemy! -sword scene function + +Head to your weapon scene and open the **weapon.gd** script. We'll just need to make some slight modifications to check if the sword is colliding with enemies when we attack. + +First, let's get a reference to the **Area2D** node. + +```gdscript +@onready var area_2d = $Sprite2D/Area2D +``` +Then, in our **_process()** function, if we're attacking, we'll want to get all the bodies we're colliding with and check if they're enemies. + +```gdscript +if attacking: + for body in area_2d.get_overlapping_bodies(): + if body.is_in_group("enemy"): + body.queue_free() +``` + +leaving the **_process():** function looking like this: + +```gdscript +func _process(delta): + look_at(get_global_mouse_position()) + + if Input.is_action_just_pressed("Attack"): + animation_player.play("Attack") + + if attacking: + for body in area_2d.get_overlapping_bodies(): + if body.is_in_group("enemy"): + body.queue_free() +``` + +Test it out, and hopefully you'll find you can now destroy the enemies! + ## Another floor ## Finishing up! @@ -931,4 +1071,3 @@ TODO: Add images - From 73fdeffc001fdd0c21d08e7d30987fab11e2e8b9 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 12:55:28 +1300 Subject: [PATCH 16/29] Formated files for pages, added image s --- astro.config.mjs | 26 +- .../godot/dungeonCrawler/TextureFilter.PNG | Bin 0 -> 47265 bytes src/assets/godot/dungeonCrawler/addanim.PNG | Bin 0 -> 7303 bytes .../godot/dungeonCrawler/animlength.PNG | Bin 0 -> 19365 bytes .../godot/dungeonCrawler/animtimeline.PNG | Bin 0 -> 23683 bytes src/assets/godot/dungeonCrawler/assets.PNG | Bin 0 -> 11260 bytes .../godot/dungeonCrawler/basicroomimg.PNG | Bin 0 -> 39031 bytes src/assets/godot/dungeonCrawler/coinScene.PNG | Bin 0 -> 9487 bytes .../godot/dungeonCrawler/collshapeimg.PNG | Bin 0 -> 5903 bytes .../godot/dungeonCrawler/enemyscene.png | Bin 0 -> 10512 bytes src/assets/godot/dungeonCrawler/folders.PNG | Bin 0 -> 6455 bytes src/assets/godot/dungeonCrawler/groups.PNG | Bin 0 -> 13421 bytes src/assets/godot/dungeonCrawler/idleanim.PNG | Bin 0 -> 122218 bytes .../godot/dungeonCrawler/inittestscene.PNG | Bin 0 -> 70124 bytes .../dungeonCrawler/inputmappreinputs.PNG | Bin 0 -> 26002 bytes .../dungeonCrawler/inputswithbuttons.PNG | Bin 0 -> 38826 bytes src/assets/godot/dungeonCrawler/layersimg.PNG | Bin 0 -> 26696 bytes .../movementscriptsetpimage.PNG | Bin 0 -> 21222 bytes .../godot/dungeonCrawler/playerscenebasic.PNG | Bin 0 -> 14340 bytes .../godot/dungeonCrawler/recttoolimg.PNG | Bin 0 -> 3486 bytes .../dungeonCrawler/swordsceneinspector.PNG | Bin 0 -> 35203 bytes .../dungeonCrawler/tilesetphysicslayer.PNG | Bin 0 -> 145798 bytes src/assets/godot/dungeonCrawler/walkanim.PNG | Bin 0 -> 20233 bytes .../godot/dungeonCrawler/wallcolliders.PNG | Bin 0 -> 15851 bytes .../godot/dungeonCrawler/weaponscenetree.PNG | Bin 0 -> 11894 bytes .../godot/dungeonCrawler/worldScene.PNG | Bin 0 -> 18693 bytes .../game-design/godot/2d Dungeon Crawler.mdx | 145 +++++++- .../dungeoncrawler/0-scenesetup/index.mdx | 58 ++++ .../godot/dungeoncrawler/1-player/index.mdx | 112 ++++++ .../godot/dungeoncrawler/2-level/index.mdx | 88 +++++ .../3-playerimprovement/index.mdx | 177 ++++++++++ .../godot/dungeoncrawler/4-weapon/index.mdx | 141 ++++++++ .../godot/dungeoncrawler/5-health/index.mdx | 319 ++++++++++++++++++ .../godot/dungeoncrawler/6-pickups/index.mdx | 97 ++++++ .../godot/dungeoncrawler/7-enemy/index.mdx | 178 ++++++++++ .../godot/dungeoncrawler/8-levels/index.mdx | 96 ++++++ .../godot/dungeoncrawler/9-finish/index.mdx | 17 + 37 files changed, 1445 insertions(+), 9 deletions(-) create mode 100644 src/assets/godot/dungeonCrawler/TextureFilter.PNG create mode 100644 src/assets/godot/dungeonCrawler/addanim.PNG create mode 100644 src/assets/godot/dungeonCrawler/animlength.PNG create mode 100644 src/assets/godot/dungeonCrawler/animtimeline.PNG create mode 100644 src/assets/godot/dungeonCrawler/assets.PNG create mode 100644 src/assets/godot/dungeonCrawler/basicroomimg.PNG create mode 100644 src/assets/godot/dungeonCrawler/coinScene.PNG create mode 100644 src/assets/godot/dungeonCrawler/collshapeimg.PNG create mode 100644 src/assets/godot/dungeonCrawler/enemyscene.png create mode 100644 src/assets/godot/dungeonCrawler/folders.PNG create mode 100644 src/assets/godot/dungeonCrawler/groups.PNG create mode 100644 src/assets/godot/dungeonCrawler/idleanim.PNG create mode 100644 src/assets/godot/dungeonCrawler/inittestscene.PNG create mode 100644 src/assets/godot/dungeonCrawler/inputmappreinputs.PNG create mode 100644 src/assets/godot/dungeonCrawler/inputswithbuttons.PNG create mode 100644 src/assets/godot/dungeonCrawler/layersimg.PNG create mode 100644 src/assets/godot/dungeonCrawler/movementscriptsetpimage.PNG create mode 100644 src/assets/godot/dungeonCrawler/playerscenebasic.PNG create mode 100644 src/assets/godot/dungeonCrawler/recttoolimg.PNG create mode 100644 src/assets/godot/dungeonCrawler/swordsceneinspector.PNG create mode 100644 src/assets/godot/dungeonCrawler/tilesetphysicslayer.PNG create mode 100644 src/assets/godot/dungeonCrawler/walkanim.PNG create mode 100644 src/assets/godot/dungeonCrawler/wallcolliders.PNG create mode 100644 src/assets/godot/dungeonCrawler/weaponscenetree.PNG create mode 100644 src/assets/godot/dungeonCrawler/worldScene.PNG create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx create mode 100644 src/content/docs/game-design/godot/dungeoncrawler/9-finish/index.mdx diff --git a/astro.config.mjs b/astro.config.mjs index 943009d..fb993f3 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -71,10 +71,28 @@ export default defineConfig({ label: "About", link: 'game-design/index' }, { - label: "Godot", - autogenerate: { - directory: 'game-design/godot' - }, + label: "Godot", items: [{ + label: "3D Intro", + link: "game-design/godot/3d" + },{ + label: "3D Game", + link: "game-design/godot/3dgame" + },{ + label: "Basics", + link: "game-design/godot/basics" + },{ + label: "Setting up C# For Godot", + link: "game-design/godot/projectsetup" + },{ + label: "Survivors-Like", + link: "game-design/godot/survivors" + },{ + label: "Universal Features", + link: "game-design/godot/universal" + },{ + label: "Top-down Dungeon Crawler", + link: "game-design/godot/dungeoncrawler/0-scenesetup/" + }], collapsed: true }], }, diff --git a/src/assets/godot/dungeonCrawler/TextureFilter.PNG b/src/assets/godot/dungeonCrawler/TextureFilter.PNG new file mode 100644 index 0000000000000000000000000000000000000000..6ead191e2f5ec3bdbf4f31b79f7bc064ad7a8575 GIT binary patch literal 47265 zcmb@u2{>EZ`#-7!ZK>)&wZ_v?QMATW8fmGj8e3D1sVZuSIaElrTC`QP)I1e6lhiDT z6jiO6Ac(O_NRSkfkdV8b^FQbNy}$e1=YQ{W?|zSF@dO)Q0 ztNMv;UAsqI+eu>Lh0aILz_sn8)Ahlr4aR}SjA@Ohk?=oOkU28<%X4$?pybRg5PoI7 z#TlpHf4-La=KDC#veMabAJ+}1;hbJ@wEO|CkHt(->(~D}%!;JKBv1V3Fujm<5NYsV zM?%P1=GFf?%vWDexBqtoKmNB3$iQf<*-&Qe{FhvuYLwBo?dPw_d8C~$VqL6^O*PIY zPWZCJqyIXJpO_ZC$l7a9^jdjPkGOJT?*#h?Db&U!>h*seMLC8ScyOGpSWf3o27(=V zej$8goTG0;^4eJrEe}me{?9SlwjPXQ1n1rFzbKB65?0`y=QWmLU1+ykN|j#{65dL8 zjf9NhqKt47yw*?aJ-$5^*r0CP@2lMD<$KeixV;I-Pa6{CTqioKXtjp&8Ium=t#`VJ%#gvpLs))clF$ zOwG4jHOrDN&C7IjWSsMII}!PUPQlV!SP$KUO-Ejsf6nUM*|2p$jy53PDw)1#s5D#- z4d(7tNeIH8jnRS0nh8k%+v6ZZH%5YTLViy}y6v=Y_TJed}l+m*A z`Vx3grb>GvX0u{H4%{n3PMNyXdqmp4bxL(P

Ctz@LYAo|xc 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∨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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/animlength.PNG b/src/assets/godot/dungeonCrawler/animlength.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3c7aa1e3900e9edd9f46decdfc6b925c832b9371 GIT binary patch literal 19365 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 b@-_x1PQBW)t!}n>ch&W@jjy4#Zaw-xTo22m literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/animtimeline.PNG b/src/assets/godot/dungeonCrawler/animtimeline.PNG new file mode 100644 index 0000000000000000000000000000000000000000..22d14c1c3cf10a24c0b655ed2b1a06c8fd064f70 GIT binary patch literal 23683 zcmeFZ2UL?;yDyI8D5D6dD2NE?SP*Fn2vTDiMWm@nmmp$5YE){d7K(+U0zpIwihzI+ zY62ty1r@0gLQNou)R2TuC?Vm$13I5G^PPLn|K4@iI_s{J6&Ls>?7iRT`8~g%S{apy)pK0ZPHvwvLV<6CFI$G67dxAox4xJS<}@MDeVMZJ@Jc}=@$;6J}QoiIAV z$5#*|uw=gu{C~rZvsRvbd_vW{e`{*sZ?5t2UEZPp$B9dRP-f4D(p_yq!<$Px2^uhxATAJ;!9@!rQz>m-F{ZG9qEGjKHPmtd)e>5s%}Pt#qeIo*Z$wV zI1^~889aWkdYW!0B&@p>sui?v7h)-^FWrLro0wg2vXLG z2)yuzhc~;*Pm5h{@3ydt*ri*qz>_l{-#0T?%kutG&eP+ACF)fDsxS$78A-vy5ogO1 ze{$RrOAy)!Crm>fbjEk8xwCEOBw13M_kMyMb+%mmW`GXkmqrviFK6kM4X%jwINn9j zz=@cQ3f*LJ+0((VFTJCR4)@rkHHNYCT&yq^GRaWF-8yX<*f-c0CWsEV==Ia;4y5SV zcWmGnl6AmRGN!GrPc`8}o?q^QVb@eHGzIh}4nu#dY0%wUw%EYMz*1QlY>I)*UM_qaXM}amL=lc5f~Kki$Y}mx0_il`7_yc^Kz2AG?_K#`7ZKW55vVm;OQew z{cC#2w=97wBP=yOu4`h7-nW!)v5(^JO;A1m*y z+c!<%c=$1DovMrIYN~cg><(=yD1zBIK%k75S8DVgDKZwO+Xe35aDd^WDPZK*6~I*2 zF@#LL-uEIO!Dzo~QxUdL4Hd5Jb2KTwU{3xzf>B#i+l$7t%(q_JWL0y9W0Gr|@HUfx zksEMBm=8qB;B>^|cNN2AZ5&Z<4EWMN)nvMygv8?mm z#>Lzdj7&Ouhip3zI@xCv)I?{<<>?d$HUd|Wl=mvRa^lqhAroaQtw^|fdTThDP9o|; z5}Ss3gvZCn%u$dpk^3TlJ6|qI{zHCFJ!2my8Yg`nslQgtbN-0u(>dc8xZMcO2NF?O zwm(eSC+xYc(NUim+1j?tEb2EPa2R8wVt~8F$MosMnb90~AF5XO!lUzh2-yvJ?S&oY zAwE)qu%RZKIDGKT1E;6{3_^U)m@ySMUuXnTi_Pl~a+NYbI;U9UbP?n8vFbVjM+Eg0 z@iU`C3XQCgBu6%!CF>Mn%R06jA?UTXzcBFfp>ef9fnX9%6iN092p>Ms8e4{GU0qXwPmUp;xm&3Aj$ zMZkdgta6`*y`6Urq1H9P_*IXxiwqYxrZHm<6@a:k%vv0gB-n>g0da&qvZH8P! z!=fPiz<4^O{3`YX*%kM@qJn2j*6==yq%QY2Y6`HIVMg$yab*J!2Wwq%Mj8sS>yP?S z&;*aXex}itgMo~p zW-;Qa2a#l;gXN|V5cs9YUIO&9z%=3$2$kvz+l-D?6f_j-yI85(if8t8jo*zo3)$B(zk(~mH zWrr4;<5iEHs}^9-x&*k7Q?~p0_F`!)OTnXzgz6&5zUdK>q~Nokf;(YLRDKzl^#&M& z-;uEp?bFsV%9hs8uo6$ge9JI`e7FjE7uzK4b@!&mEqiAs&3u1=0AFU**+%F|r>fPDbgl5|O{|X3?pl_bm_FuhG{e#Gn7< zA%V&H!039+!k-9$_IZe89w0SAOI59iGws(?O;==R)a8Sq_nxzKG1hRf-@4xBiVN{Y z2`edhK)+U1*J5RX*X`Vi@+-yz%;(wvu@`5h(rm^yNB3SeJT{d>DI;Zw7h~*2NKn86tf$%L^9azs7&clPY;U^D%}CJvKtuIyzjCW2|tnZA$c2 z%4Cfloc)mW2!cgiB*ug=?^Pq6-@j2*GV3r~HBG*E*LTY^pAuL}V-@2CS5zc4t&byu z(6W@j+8P-Dj(oLEFJpSkGxhzLL87Ce}HZ(%8+^2m975Z_GF zA=IOL_c^AKyf=w*9rb=ll0B;em*(T!tWwpYn04#Cn?;=U7r)aEc0T=e4eOGEj%H1d zhs;*0o+2HUUT%G?jG#MBTQAfE)AxFmCf3}&AfQhgg!Rl)D(OwJE#4DCJ`U~J;a zlH1cWG0QI{+%Q)oh`}0fIgP@?8w~B1zQFfeyp&?|qr`naX64=UeRuSrmmMD`G(U9* zJ9G7oZPvY4uSJ#EM&Yt;n*1)aa;cJE3W59D)<&R*q=DUGFg4Y(}LC~_~O+M;yG*h zjz|7xfP2kI?ace#=$?K+-gP;mjC+C(u@&h_k%3SGi8hrpU0LJ76Q`VzJW?BdbW z4_o5a6=39XJ&+)x4TQZtNX`jc7x2;v>o!}~7<;@O3BwN2{r&iD?wy=l2jX~vhXo<4 zZ+{78o#s4udaDWcos@8zC&$^K#nnP2caA2?uv zbzL9pz4Rs)__hPMHY$|9m~K&St)bNI_Hm7v?p9sgN6eV2$)dbz(64uV^N$`ZWbZlZ zQxyjS$GLqBIC|6OdzRIAMT~V-@NBAj&-liec%88iD&6G|i*X@RK})i}I<3_)x_wQ( z?v$}YlhVcVq^f{%j&q?>Ug=_Zeq&Pr4wf_WdYMr{d~eSYPzuZJ(1o~>CuJHXS}K?r zJ1HgvF$>{AJcdy{y=eD_AedDP{ow+>mlC||mw2ZuZ`K{YLEWfyP zUJ?`F6r$eec9u@+VDo-wj!DB85cmb$dtGTvR~JJP*?Xfte-P@;j2a6x1JaZ~7&O?{ z5j&fI_+q9L+dMm&Ro_1=jplmO)%TIyY$+QIDLs&T#*_>*sO{w{AVF_%?gv zo5S+s(AQQnkXfRAX5w)9G)!ThV{)Lrfjbd5DTKK=tYj;yRxy{mr%3~zWz(+RacrS= zN}U=Qpxl@jc&;~~Ki9W9Ee0ZKtU3F32yfRJm~-P(*Kimwa;65dd-BJ^5@HcGjKdXH z85DrSfa7J0+=#7d-d8mGM`B||{BTpXNze$6kmjobqWZq&+m9;}xDF>-1P}kOFKfc1 zj?P|5i&Teawz$_rIZoqNx0Pw{5>M5&(-NIJ!V;jt3Lrdn^Yxb@3kt})Y5K5ejUA$K zJ}M1|VlhEDv`yO>*Vz}*^OR-l?bq+=0D@v1iCk7!(!-hVE*In1`*|n5 zqPe0Zq(+g>zRL&M_<|tTm%V#E_utw=m%%7{2e0>MS8fM7%El09<>1n{7*|0iqkwfo zKhuI=@U-nk%$Zb&TR??tEJ0pRIJP$$uoPOQd$V*M$9dflmT-9xIoVn0R>sC_Hr>JJD)BU`@Eupndf2U zU{4cwQrf5$)0-(PsHGrpdy|x%-=io}HBUGYVLF^FLZ!|(9-e+C5=$!@ZV*6MaD9$V zb;drW@k`zMfM?H)gR?L+y9O4|`dQEa+Lt z-Ur)rt~@WR+(X5L4xjVR(d>fIrl#&1v^4@dgGV1@#od_MkXcTO1iaugXA)^oGbL)P zzm7HswphsUJfQPwM{UTidI$Oyy7E)h9q%l%t|*e~&mPSmkE>2%rD#_xP~_z0ZRftp z=^xj)Ic48B;V={`hbG8sU^MC7>42QCv1{&EoB|ozc5GetEaMz{!iu96W7tDSJF{SgS9mx3fZyxVh1WYsYD`3;SrGxY5R~%)NB3 zf);w3oKRb+h~b`z zc8Wx-NK3sGBi*N`v7(JvK zu>3}AIqpfkcWIdvTU+iTCz})`rdpr8aFOb)2Q2)JXDZBGa@on zN|Ki+e0xrh!29;hs>@&>lY0~F2(K3A&g#$Ik>r!%kBeGc&v@^^x-yNVjCoYp@#CJ) z%&Jp&DvP#MSc&1H=APE0CAT&?CeR2SMqP`K{HA^CavCp^EEra?Z-IWo)573$Wr8ALpPh*tNlUxEYRJ? zop+xfcMJ5jEb~EN7XoG}!{tVliIyDuZYaNC5;UWSf>eOeFGek zVa4BsbrvuAF{6BWiWW3bB4lU~n{d*PLy@EyZCPz@t7omGih29V&UKFzg?Lqs1^#a! zWtWL(_l}J ztH>*lG8NJ|fKVb7wi)WqkK8cqKehl$Z`a#hpAJIUCkyd1DZ#o8&pmxSpT}3uz1ORL zp&}aYBte;4Op>S$it1n+BbG;p4Du|cq=Ff=A-XbkGG*Z#%1u%#=v(4|V#W+XMND4E zRVw)RGMuc9nzwWR4(FD*Q?UYTu5L64=qnZFTOVb+$C=na6AgRV0CBo$kvBGjTwbKZ zLkTjHotxwcvpJp%S@`_c0fms(>WeWJdNO#}w#m_hv4Ek%pT;axLp(E`5}Z%a8XSi9 zSq$SB+9|aGw0Ml@L94Ry;JE;M)LLs?%h#Gp*86K+tb6CmgLA{vedvU+SGY!NH8(N{ zWHbl(Q$87{B**E@kS)UF4ALv_+wGSxu^B|!EnoDT9PHT1UrG$$FJ>!+ng0~+VP$$$ zo-j(5s1lTe8*p_e<5Xf{?v?eSdtjr0ig3?KLh^(V7n^>VO-GwS7tBj=A(87cTv4`SQUO=}-aXN6-(#yJpd6Dp z%XN^}Y;)nT`b~YV+q?HZZJ#TP$`6diup;W2Cpzb)uFXivHb$15I3~K4( ze*L|pzqfOay>pxU3;)i^>OA?j{Fyf*#sa)b?lT?V;Fbe2C?5~M{@kd(&;3Jc^%VbZ z1o57JrwhBb{rxYb;%Ea!yOdusG#=idE|g@}^+>kZQ->yvOro$!*Y+MQ#t^cx@chw? zd@t1)*ELtpcPSAdm1FDXEHgf)|QW)Ar8P zDgFcUja*xnCI|NrfA8BN`z)*!D@4GM`Hp0~gHhs}9yv^@T%brsq|4|`#_r?maijNi z)2x!B#8Gj{oK8q7$#>Aip&w31*@C zn!)ls}bZKnXbt2bW8 z4E{65Nu{95HpIczIhbbRn@KAvaCL z8pS!Kw+MaWCYfB?$*7}yZo-Ze%y z_x=|}TqvpVN$4Hpif>D1p?=>hjwBbh%ssqDAGw6l&Fu|H=GvZaW9g?@fgV(CjATX& zrBmT7o|DIpXmr57vDtC`PI`ef+7SJVQT0Wfrm6xQmAUg5=#5&l#&U(w;>Yb(pW=E( zxl=iCp+p(8ZAj}k&UE(>>`tV4&nNS$7D1)Tl%;cuPIGT^8WxOJUem6bgK>a@X?X+_P1=Q|$=a-^-4q`X1CG1VEP)wPDvgkv&|m2iT~;Yo0Vp&l39 z%`#%dxh~;Tgeh`T-!l>8o0-0+%7q!`uU}E(-JbWfye0vwE2;2bsM}I0*z1vlpW_-4 zGwN+J{;Dfk_Lk5>Id{!Ig=v1s{E1TFE+m2+?0i$qy|)g%4ng7OpW4%h3*?%LyuGS& zRw8~)LEOx^c5YnOE0-XqVr379l&u+~W!+4h0;yZA=ZTQX7&NQQj&=Eq4@JquDhQ*P zt7}qX+cijE^!sj@Fl=8hel%szxTFq!X5T=OwAr~+I=Dt?^+f?&5<*_S&90Lep6;Y{ z`T4I;eFmM8I_gpEH*c#!^UTbQrIMNvM zZGIrTMy54qHwKQwzt-F1qZOnb%M2CQ3QNBK^YI$N=vHrCc zqF%Z!U)3g~DHh2n^y;G0XT}dr2|d&jG>GC{EKOFmynSJ?%;mIw7Qufae_x(yWNK*tSOY!HRlF$%wrE4n@l4Z%8m8tiWF_JCOI23oPBhz z-r`)H&DbtXbc&~#o%U;x)y-n7engUT^&aVl+s){%z6;DTlzAJXyZNDULT@d%fJog# zT&M8cK4u*eFMZ8L??TYd0i+I3h1@qB(s!fG+KE&I-NC6Bjf?_xU$E5NTCcRxU>XS-wRiR}Of8N!eqDcVS#f2#)Dx3;8!O1SEJqW)zBWt{ z#)BZBRdH;ASHCTE8&6F4ajh^a8h-BoKEny*{Nb^v#o>LM8&&MbZuvqz+s3)Ug@yu; zi|F4Z-NXaFa-OCq92MFpY@9+<^x;`a3L`|NhM*nEH=IR}Z`Wq1Ij3YAQqBsHIywc!k`rk_Qk|6qAz@aFx@ z;VxJPnryL3qhVgZ2YCc(ERS;#hIBAo6 zb3uu3w%+tRvC8&KdhS5GN#bD=XtyUG3=}B%i&d~65viHX2*(%7dqJGi{;|EbLJY6m z^OzY!hOD@kOYW#_`>Y;iIHckl1bMx0?$!Q;{U@Ac?6bn|#po8OX-|CVuZ=m`rPkoq z;K13ZWl~qw;;mG%l?8J9XU7)uZ**Re33D~?e)_h?*-60zS)}!fapbI?RLH0jR9dQC zclj!4|6rnUMlYVXx>`IO)9ibf4;tIyVJIK(Y@KuOezC!wV|_3cQ$?GX(14Q_Q^2Wd z&wq|RRkv+2dQNk@jU`!*S0y-$>GlbnC!1@jHtnw@X{X3eXZ9|dcV4Y`k3|qPa}HVu zLoGEg))NH`9wALENAbqXdB2aR9t&8Psjg!iEUxutVu)B&%@V01>Q3AV<>b=U^P0uo z$R^xrbf^+pDORH|gNztDsV-k4?Nw;^4x4kHun?)xKfbg6Ts4JJ4yvV}f@gz2Mqv+N z&vo6&)#;xqE)o^hJyjf=-zxNnLS%__P$8v;VYi%Vm_$P|k&NIkYwMe}Q;Ty9)$vO% zQ~f5?8O=_}rcRb)2!R}Y$j~+XGS^_yV8pwYrN>0AFkd#tqzx1mZ<2!f>QV>`O9DzV zkgHykunzBS$mcf$B)553BJ^(Ux>f@<(dI1WQ#wJbjI10P_Kan~#&%a|?z%Pq)*fa8 z3AlM{d$!K0)~e1}W1UP@c?HUuBG88(!1%ClHpxcp>JLY;x=Au9tAxwUMNlY?y>T?T z{hTGa(XJY9;bxyjTdDSKvsg?GlH^TOJj65LO|l{CfP z>84L}!rj@QwGLvg946c)B~k0p@5sUvmx3Ja{ZG5@Z1D#@0-+LRmiz@l^=Y>wtlRe3 zKJ2$n$h=|U+mgzKK6`qfq?_Qz9q20{n7;DDL=_OcysnRPwz9LAv@jDiwd*=%t= za$F(vtX8jN&u=)qcWr-TuMm37+|PSE?Gsn_;_yv9IZfN(9(E=wYUt*kMHH{_?`3!6 zvH;&+*BnXKCcEo_Qqr3JZw5S0k9U3wq}%ig@f&Gr%eqecd6%T2kdV!giEA=F66zJh zidywT_bG(gl9AM7yc;qX!!diSYG;tXaE>Ckdq_VK7tHqUxvfIXkoNO$O-2qs1$9oV z_Pf2y1NlGt0}lL1)-IXqHT$o&gNp5_69zGy>{~sv*AX{coKrVtgyY?asr3TCI;k`vJ=X{ z!$_U@Hb{+^7|)NYV@&G2RNffQ*7K_NlE0qj|JWsMJ(bb1$2LPJsTCSP#|}TcssETw zTAsOsgnxu5*j{j<7cEN%+jsuw4TyIm`NKD?cVDlZ@hC$TR5A%3+Ix!)8TB%tHwG%- zgDCFRt=n|j1tz5=Tw}@w7mGr&G7}yE+BOU|UeBX8V2_jfYoeUdDXaf-yJiHmYrZZ` zqJ#3qpJl9ZlytLl=5whGM^&J(!L;0YmccCaOP3(8NAnbh=h7>m;M+kz>%ZEbVMe61 zyz`osUV37aAtArJ1lCztSg8qyCSkkx$S(JsK?rK#_6VL^o=gbQV9e4QpU!zn{-+HU zz9YW_iI@vLRKPE>?Kny$>oTxGQ$_kcta^6;fcU1<>x$`>en=6a}*`BNY>L; zlW%piSftOH`!1##Tb-t3tDP!$afd8|O8}vw`zb1h*!d;VQzyS@o3{@k=I%+K8~xmp z+Bz~t_|IBHt9NpU|D#WsGs|aTTEhKHlcyoGW3~fC(~UW1%w-=Nf(7O}NB&*$J5|C~ z)%st)Y?tN`Zp_O-B!sxF!%4=AA2MTaw+5HW+EAesrC!vs-STeP1VMe%@<4P9&*YCo z_Q)Ru_Pg??xfc_^PDRhH55q$E`0j79cTTvZa}XnUjwF5cTo?V-*VemVc>T??Fh~&B zxi0Twqi))z_*}c4*E~QkE$PH{{}N|$c3%bw!i~`X`dsj|4z-Y=tH$g9%?MQ8y~;qX zzNu%}n-qCn4L|l;zS}#tAfuH9jx)ukLRfc%Rjc*b0sRq>=lR1ij`wQilRPRN;gz?? z+j<0j3@R0>+nbS2%XSM{L>c+gT+go6miD`|K<9fzb;)h%U0*L%U%+L@J>I(d(THwU zixdpoN>S0r&8|JadXewpmOuB;o$9D+A%-kS@SVA@zFvolU;V~}_kQ`=L+j5gNk-Hq z@vmN6_|4$XS=zBn&SlI4#9v$zm`N+wL3?)F{kZ5;Fc|*4z?(;`3oBQzp0eEd$GMu9 zh04&>b*-n_2Uo5ZfOP8j^#1c!;!0nB8GRMBvQzMOC)fw@q~+$Dw~=Dk*LXMUu52wj z?gpmYqKX)`w{K(mh9%e`6yAo|pR)9>>9KEF6HyAQA31i({F6ZO?ego=D{cGTYH48C zi%}HCphLhxwo1GrRI?pj( zH+`{gYVsw@qHo)`BR$&R%puKu!zJJq3Who}XR!^}lS0Ox+S|*1yN0D^p2#vbSWA+y z$lIxwdw)em$A40h%J25HM1dyH%tnpbw>QSVr8jmsTb56I1Vm_!mHU2fdqZoB!;Kx0 zy$nh`eR%<6CVARAU%yr-O^*k>+hb2lw+Ju5jVBovDJQuf$TP))$7D;MaQf; z$4j{xHr20XBf@p&bPiuGTKe=l8fI}h>GFkVP19|;zUNpmxi!hYy$OcBH#>~jq`NH) z779D?ZRl2^MQ^YJ#kRWYqu73SeO_nDLPcSlaU%^Aqi~~SnX;Hy-k)+fq;H-5w1T>= zk*od83sRGiI=Z~5EV(P_;aI*?ob~SK?#r!04s(VXgo$qk)fwBH{{cvUW%-gyg>5B| z4+p@qdKNuiek~TS2}MVBX>8c5@NAd5edV?Cb0x6U=s zq@9=-S27$$z6G-5&pHDW4o{s$Z=`rPecSUsH@;2Ipol#pkOYqpEfan10r4U3yIz8j zH^exbe`>Ejd7ff!6V0>`aEgIUwq7e&=*4(al6_2AG-#}l%X-X+6#Gafs9SUQyvxwR zdT{ccPybuwDMS{_9W@mYwS8=uvlD53O@Y79Xe_E9OZvr9iC1;vobSxrS)$2sAg33R9#@)FP{W!F#9DutlKu3M71HfEwI{Nm6(*|%SJBrBxAj~E;Q9< z_h?Ue<(0mt*T`Upqq3Xz7Qj+&9?4R`%>fRp`#=r^OB@kb!UU-ige3f4y!LBb{DYNyu;Ypqbc( zfR6j7oa&**JQOp61iENth122jIchx{dplFS{H-iCgNAO__OCA_Md|$VE~Bd#6GOV9 z8Xq)sn^PLEW7-}(G8#u3j>z@xbU$n5RrC5xNWt;e&g~y~HU8OQ`SR2S?)wPI!KNg= zf3W3)QLtChfQd*FRd!6bFn764E0B|Co--hj+mJBgkrHKROPBW^KGec|Ra@WK@boUb zybiGFX2>vJAj!geOn373IeS`Un(>Y5ixk~}OLsWA>`p(TbBUg4XGO^%WqW>?^GGzp zNy%+}T8f@jkal1YrCIzwP-3OMx#sR9J4(D_p0@7OZJ_te~=Za2qdAwV5ifGh+R*X=AZN^dSLI{ zbY92i**tcJoCA&`a!6RC1WY&8;*{ZNHF3S(An%goo&45c?AS1WoMtODrprEX>#t7L zEuecFyL6k>ffY|;2nQ(PcI8wDH`L{omPo%Tlol?`xlnZCx|O9%UqNnyZI27Z13O@o z1glRA7JY0kXz2Y9eohfIXuME^dZBI5nv$8g{uS75#Mw>a5fvW((r)pT5ezInPxMR% zB>1)b+v4HG=vL5u9ET{pEuBOTSfz_Tj7A+peD-3Sad>p6oq1Hy&s#(E7Fm@driNw` zRV|Og>}k5OnftL*nZ&y#Hj@hlnavlD9&Y;wMS&gYYl;;G4N(EXK~sCrLlajW^Utgg z9P`W$0mJ&c7t{Xhj+p27|K@B%(~rOY2V+Q7UEF<9Qz$-u@)w0vMY7(?j=1}R_OhF0 z{{gD-KjVg<+Km^pEea?dCcC5wT6HAqDN6<;K*xPQE$b zjEn2m@~*A~54y0weG>#9i*f%Pbi`Ec9f7xm;P)#dZcfSzOE(w3{iHAI#NUSilVzU} zy1fX*@wY$vap%18tKLo|5(6`G@UTt4bMC%B07cP4u`A0x?)yE~al0LGM-=q8U)de* z{6JSpoRwfBe_ik3&;r4Ad(b%tkWr<#TCZXxjW4~TG zD5?HKQ1;HYGXm?A{DLw>sLCtf>Nx>ou#+`Wz?OKDSbsR z(N_|J>~I2Q;A$HszBfs8h}I2oaq!1`qkwWkqa}dS)|ZN17yM=XSNVE@)RixygEQ?8 z->Y(6mPZr4s%*lsP`>l(j1BbNrOXW!xO!w>EOv}@rt-?-6HLzJ;vdP@ zG&r?94dP7kO~M*(5<;6?L!d4I`S<05y@tn=c|q<-DRBNg4VhO?8ove0&@9;sMbN46 z8G#IGXWUM-No!U-cPLkD5$vwPBI-YUoml(>IVaw>x-ve#)-1p>Sndqle$otEPHMoX z%T+Be)I!wldfA=R_8eDEXUtgTA8S=^{=kTcCmcgbDOAi!>p;JS=11w$>!feGXEgA$k8_H}uiigmFU>D= z*!fG*5zhzjbp8t$jG5Q9T3v_Iyjx!~t`RAiPMVk@!I6P%enu=M{{W)T{)&=Dd) zG0}ag!Fg^b9A3F7y_~bK^RH5P{zD4JEWG<8U>GxN-PO^M_-4(~^X zwN|Y91JTtL;8h<|Kd%kAF>TL7P_aLcJEy9}>8>{)3J1F>0_|??&o(mYV$MSrGDDn^ z{8!WZ&wyZL&Dc8Y0#fXO@oPDe?H3{nV|D(wgdWsa;#>VZQ+-onaQjE~0Wf3Ft&n+2 zC7Yd3eBvZ@Wb!_uaq76+pXMv)?WI>8R=VS{vjtV66;<7$SOFMIW()3J{>r) zS6cS?>9wZUTqB@T zR2*ovJT-b=GY0EE5=4&vMECS=;f~De15;oZOA=U002X(+AZtEjz0IC>qDbrjwvED^ z^$8o%f0Sn!oG+^+-{UbgS-aG`$h8Yk8@AnbKw1mZpfNsrW9Vatdi~mh=9|DbcLA4{ z+ey=Z>N}O;m7?r_)%?>xWZ`G;h(s#U?Vyt9h9@zC1QSZLUr?SgS(>0r%hmEnVbVId zJnQ(f3@qU6qu=F^vIOQ?YmFf6E@E{+FK7D3w<WeD&pPc&=1>pyXvK(iJ6zQee znAqVL8Kl2reqXH?!c@~lT<3^ff7^vmKfyi$DB`e+L4Crk5?UyI+K&t3nY)ZOZdlNk~&avO{Qnq=fu&`%2W)9B)sna#eaW1 zWAbq3Lw0hkhSKG_mMQO0i+_pLI7E)FG)htGws>F>ama=rPC2qzoQ&u4Fh|a;_w$Ye zz)CZr=u^s*xr0HyFz1Cr;(=8ygG$Z6S^sE4tQOqH0nqc279W?)%J^Ba!F8`r<25gJ zY5Gy3n=_dMvnvLsYrCqk9YJJcayxTIX`HPHFchSQ@IIJaLoo->h#2$Yr7!<7hY|e? zl`p#gB@-=9?%T?PN}CnFwY{use^2p=)OD9ZSMtb%MO!uB>JgGp3&tZe1kvkjWnIB2 zs$InusIL4QF)a=bG*Q}ld>&bxOs2tMoYROq*SDaB%s>|f<1pi_h2R+RfMJrb3XC%- zOf1G*i&M|8sBf8qp^R2-5j>ESDx$Lmxl?J^FZmDD9lu94EBcMqifJvQpuT&0Yk(Zvmaut0r40x>2I@2 zW@<4Q!qnoWE$HZMuVg~dokeG@>%DvMC)J&`ntQ?B27b>ocp>3-Egk)qSRGUIGbZhE zV&}I{j=nk9(M4fFS0jPb?5ED@hFj2(Yt9I?u!}f4Mc&p4PPqVa=XckulJkni#In?Z ztV(zlo34O3st9uG6|B_pR+hd|nZjNdPRgcn9-{ zwV!k@@pov*=awm`bgME{#|kJ3lNL-CB1ea&kASWHOgOk-0Lt;{KeY?QlFg$eQ2PAA z>KEi>d^K%NisO8Lu>d~q5O1XctG--}X^;`Gd>YSvoIXg+ygfxxt{> z2v|!mP?1&01?uphG6kBv#0&U&Mc411`<1!zm{)nqb=mP>^S;9gGpEV9OXDXik`oN& zU=RH`dkpFWg3j0b&0YiAq(t+?ueBBV3V^M+l7}kpD?Bmh2MmBud&6TEURKFVDXwP9 zoX&mGP4m)ezDV70`MVO`$GsQVk%WtFi9qjj7 zi3(mZU5X8r4$`R_Tv1qz z_pQqOA^Sh?$TkW|JI#yld|FK?@9B2uhGkuC27{mgi|1kVukKoa4ou}ZMwzY@Ikd?S zg!%v``~9y#-q0eV&O;Kl)&fY!c)mE&!UXv<&@eg8%7iy>D-kP7@#7c((s9rENf|YO z*Id#oXtsT;r!&s9Z$mj6oB+U#@GIzud;7eMoD z1r5TS%(w3GKiLS6ph2vkoac_l>jKMJg)2by!@pY2zOyFXk;tsN9F_W{%&@=57H@7-I923HwB9yZ;BU2beo}@~^nwt@A+HI^z(!Ngke(U1vOo z{}XZk@vP=-%FDqcngD&aMpoh+w+ql6f3En*)PD#{K-a(h6?J!K_SIca%*Jbi-Lct+ zw92M2KLkcIBkSdOL?CNMzW4y)!C*5*rxEr)ILy7~Gs&m9;u=rnbYUxND*c}IryLmr zz*PSh2eAj!VA)fn4O2r|*$m)(e$ZLEg|l>SxumsJ+9}FuN?TlfGf{Lf?80{*$4Krq zq5KDo_iq&QX1jw)+3T(7XnCERz~s!Zr|N5tuP~Z{oO=(GJJ6WsB?Y(n!mcB?6<^G_ zFQy1{MpWf+)0r#QWd=>QqH3G*82LE%XMe$%+4pAqPH6n(=;tZpc@TwoYZV7>;^oQL zam6j|J!2+RZC+@)j(~n^YXlhQdj9KTZF}eC7M|q(R3gu@rBZ(O96tVATQ>@#>-@a0 zA!Gv24QByK=&oPo6>Dd@$D9mYiWg|!rCPM-@#s?3@}hN0esPF1?mBL#f@!>k6H?v8 zY(^b~DDHnVJ(sX>3m9Ir5HF&eK7FZ2NI`n-DkM^{u;>5U|s|C+Ocgo8u zm{^i4d5DVo0q#SKAR-)5`(Ezi6@4Bir~KM>b1L0FVQNUW-`$|H8IaT05||lOx^8Ny zc51P7bySki+j|`$g#c5(;~(C`7|7v?`G8-opwgE#P1=}Wrhr3&{aq4u56sM{8|=Ux ziNkFcfis?2i&n^)T09S~AUkT}oBG`aK(y~5iRZ=+Hkxj?civTOYuy(V4jAb3)M9E2 zA{*e9XG%Z%a^GDU*{`eJ@YXe+}|4kSrx2~GS`&K1@^?afrSIP$OTCunb;g&umFStm|O%=0mnJ z-^H=ly~AT-(PTwHD`}X`hG@L5=^w)uRONVeyX_!!8*s+8Hn&5ifuRBYfC9yF^}iq) zFCsIz?nTc)@`UXFYFNO4|L+b9>Rqq#w|VTn5p4_<^i$1?gR2$T5yz{h@seKeRbiX) zawR|aOg!TO-=diQ_a)#7frw z0|q^85Cj%_%404=wTL|3?cI{(pX<&9O(4$JziAl|Z?3 zb_S$~G(D(|Ysh&((|+EEl51>yXLQ~5(7E)XFf*7Jf$+UfB3%poOjV94$gImj0OTd| zlhd1(0FD(VV-3|g?ZquzjIuD{6^VlfN=jJ#z>32xG698o>w$U;I3vUZy2JWR2Zf@> zo2GyE2_T0gby_17hN7T~OfsmcK+(**JX0M(v9eu`H(pR}G_qy_?|I3lKb{Q#gR zHpm@;5{e=%gn2a@F+*gtCI|uK)4W$JC!HJ7JYj;U9E|oi6^;LK4lxZLa7`R+RJqS{ zv4{8;DzfsZFyn1m-%CA|p)Lj5IpI<|7H(5zPKoiX2MYUe`zPMZuZ^YK34`|bYajP zICh2oI43hq1{JJ$Ik4-f2O?F(#-qq!D&}}Z!!b2Cu!-Ps@V9{*<7wLFE*_rE^~UTUrgsYSNM)TrB|7Rusrh=nYV-Ae+}Y23@elDZ~m;b_fplx z$Wo2W zmIH0JnyTjtP*uGJdG&Qv*UdmbTAO;+i3lm0F@O1cDb7T@R4q@~$5L z$$Xz}H?F)9CV?co&#M{r{yEORAa8nd?B@C^Ik@H*1FHVK-|3B zFUJO?V!PM>WC&qaeVegtZ%WmdOKpsQEjYESlJ+@V)XM&(4#dC09R>K>a3m zIj~Gi@=Yw~_lmG|7JZ)T1*{3G_tQ;vUTY*tRM~MyLiSrcl?q@LPE>;@#wI#F(dDq_ zouFlTBQ*UD1xaB%?OqR#=E7A;1(=9meFSHWG_5V>?emF<9ZHE`$|pUO{G_hiFSKD! zXa1~Z(DEq{a9G>z9Y2L@qH0~Z_3+%QEs18rC6XrcL;TOy?Sb5y+WB{5MY5qms|LWWR+=2zW z%l?zT@lTom-x|lfX7~T1yZhf^==6Kt0wuRS>Vpe-RLQql?z@Sqe_i2UzQ-}Es2LRW zTloUtz~0sJ6Jo8@>V+S>`KY%+Rsdedb^m9G|B(eB-~Zs^{QuYp-~aGM^r`>hPQHKR zN9f>uH`UK;&P&5L`QuN3@R0Yi>!<<;->$swi~rv}kQKxhs}ud} z%a*YjaKO=~2ubgYrSpaKswoM$0Pg?{-eIrc5mHX3RAT5;J)&k$GWFp-r(M#<#}?#$ zt);43MuTV4q)R^LJjz%7h4+YDgUyXQT7t_abLqLY0gyWIlEZOZIYnT1N^B#WMYV+s8(;=|@qku>IgiQWw&PD-AcJdeIZ z2WO&vm{GJ`yhr}!c}KX8m8Ha&O+3x1K0%5Rz%jkgKO@gCPf1wp zKapWUt!e{@r95eMUgIhQ4z!t0*o=(kQ~J$4%%bCdXnMOW8pmzV9|I{#61-9(#b)_p zOP^2A^l@z9lg#!!0SW_;)yfqq8hRnASUPaX*BX~+hX~l(@C>UStfIYKRbN|qh2i^EsO@AKJWIj| zXQ->&faf;eXc2+v?+WO!3k@G)8x5{gWSY2#aJYER<{{mjc`{Dg7f5+}I zC0S3)_iUYQ+jiP*|K{|QPdg_Gg-<&5oaT1f`DwNe%kxe=bwQ)8RwnCt-i4RvuIFf~ zJuI~ju;G>0!(FS_gd>idn_R+tWaIyx9QN2G`y9J``Smb7StmUU)13u}OzvgjwTCdo)@nvNHD053=U)mU(df4$v=xFV1(_;%u*EhDszI3y;8=HTdO3^>8 z^iunc*?FHNkeqSNOJUr!xnbPFbHhF-Ul}GGy(!f0mNC2R8;-yKZ`uk=C!cj|*m?hB zn|9diFt;oK004kuV|Lmr>@{hs82ZuurpVgdZfu~+sI)38Rvq1 z^V|Nk^`E%^VaYb7+im;WGPC)ME(&|>J1tDu_mE_}EFiXNR>s0o3qWVjouAY>aq?l| z@~dwM$Ded&bJ-`(U62I7wjFkbuU)uk+iCkDEz_w9lMYFE(@fd)t#{lj{Qq4JnaRE4 R5k~+3002ovPDHLkV1k~S6p;V` literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/assets.PNG b/src/assets/godot/dungeonCrawler/assets.PNG new file mode 100644 index 0000000000000000000000000000000000000000..9026add3882377d0330187691137b536ca507ef7 GIT binary patch literal 11260 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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/basicroomimg.PNG b/src/assets/godot/dungeonCrawler/basicroomimg.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c7840e568b198234aa9a760367c86995bb375f1c GIT binary patch literal 39031 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%0DS-><2EDgd{AKmX+Uj6G+V|JwbMy%&^_crlX2 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%0A>_W1a5;T<%X)mhc-L~Xb9a}F@I5MG=gKJA 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 E0h2Hho1&v297X$@G|4mj> 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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/folders.PNG b/src/assets/godot/dungeonCrawler/folders.PNG new file mode 100644 index 0000000000000000000000000000000000000000..cfab0dfdcc216d9314ddffa2cb676b87961d16bf GIT binary patch literal 6455 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 s{4bi$|9|vy;jD=>Y&(nc0|Pj6EO!8~gQ4r2qf` literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/groups.PNG b/src/assets/godot/dungeonCrawler/groups.PNG new file mode 100644 index 0000000000000000000000000000000000000000..ce724e0dcf03146aac0a6e2fc7ea151c07646a9d GIT binary patch literal 13421 zcmeHuXH=8l@~#PlE>$6b^d?I0ihzJ32vU_IB}ng8nzTqqKoFEJRZx-MYX~iLkRqW< z3B5OIfp7!A<~i$}b^rIS`|-M#Lh|l+X7UZ%_~;` z#@OG{1bEngpH``QVt)W!H6O`cDeSwkg8hJNDf>kB%9WC6;?ox(>}NtJMLpLmS4dkf z{sP(^znERQA_7!;Ap6wQXyYTk(^F*f($}xOUbZ$iHZApD0|0uvxS$|%IYs6Gasooa zpr8ljiqN1AW`R5S^z`_VuFU{D)8eb7qw{v?2JyPRL6}#C@Sa80&-LNW;gQY05pCaz zbGGz@mFyz@s+{<{XKFu+mc9Eu9Hud~TSfh6oA!eDM=$=w4&F2t6BDas7bQxJii+Y@ ziUL}gnwlzWW<$p=9uHqUu9UWY6wMf=lqb4AwB>hL=NMlrw$I_x$oGhlG=jn*)vWIlgT#{AxjNm{%r4dNJJqe5DrvvpM5b@jb zn?QxKxsBV$SsHLVJMN#%dCZ?QBPwJn`F|XYIbM=_Uip%y_ya%2jft!FVv!x8;}qd& zES9tbL@Dt?U}euWRruF&lkiG@b`?NbNeM@NO_@Q|Q~S{>-GGM>*2DDwu&w{iu77)M z4`=c{H)07QA3Rrw2a(6J-!zsZP@=phz!JnxNR&t}7mEv0Az)Do0CEP!u*(9d

9< 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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/idleanim.PNG b/src/assets/godot/dungeonCrawler/idleanim.PNG new file mode 100644 index 0000000000000000000000000000000000000000..da802cc0efab66162948371c83c1b1c2481f2f61 GIT binary patch literal 122218 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 @Z@IwCL(tS-s=QazXOx*?!>eT&B3HV3<(8zH|4% z0YM-oD<@JH_UXxvH1ha*iVNkz6Z5O|Xq2~jF7{7u-li|fS%#&$2v3$=Qm`i~`~nxk zmOi*RI!7XpzOTg#*V+`7EU;t9)_#gNS#L=cfurYjKO>zD2IJOChRJK0kkp9ywpR9~<9K z*D&X!6e**fWao1ose$_&4yn+iD@CG1V7t$!2@#&R7~4zI=nai_#c#ZA(~S+gS~T16 z$4qsTy8C4zL!~!9-uq=l30-bKXsDR#B~l+(YtX)g;++4sf9*@p`G);>w^F2aq@MFa z2;^${8bT_#+utDGds+~t!!d=oS1F1>ng*yBxFA{w@iab~dQ>&cJ7t|yu%2w7hxn!L z<>T14oOJ0n1Hk;F1+Ml~!@XKcupB*{au^3R(4r&R#84 za&~~GQd!++GrnW{dKvcO`X~eW`XP;l)YI{Z=I6&*>EVu`lZBMb>z+x{>w{$S&8-^$ z-PI!XMCg|fJ^<|N?{)RQTRcvI6>`&OZyq=ha&a;!kHpY54&VJ~sF+Esb%99YzV6~s~i1m^F zuBf~bU-@g__7@n_G4Zbtb>g~Q?PB56Q^lBEt7}|rxMbG8D41tStwPg`>4xbpIY+!< zUPp!dXzaBi2Xz+sNey;SYLb(JJ@hQx&*a#Saw;GC`E^n4Y|k`wR+FMDYHZrd|Ww!D*0)Bj!?zFi|SG9OLLMw4vVfHx|M3Q@{-n1Mbq*2}{#*zV!`Oi|vPU z<%$InUXgwliV1fcEdZL~TiQ@#dF`F}d@-eQ7t(=g_9nn4oA%iw)mcx)gXKYRN|1u7 z(nh&_^am?PJCDHD;+CTHD{itRv-JX(jOyBR=@BU3x300Md%Kd_`PwSVrP9G3UzlKZ z^|0H8)ih~pjm18}Xi4XvwnAg9^&F2~yUQNomplY{lIUHj@ltjN5Z;kYwkIX@-{|OH ztAr!A-(9?hK_R7h7!EYhu?phJX64}hU=02zkvWyfXr!9QxvxQ9-&=9Bs`LX^SDK@$ zggjQe@M$sE;!DKgm2rVwV()e{>JE<`dd%aMP`%|=;NoZC{^#LEt$RjPyl#KIqPNH{ z#c45?t;O7RGnf@!3nf^p-Tne)z4WI{3%C!(EUcJ&{eoLp17a9>E zBI|&I^ZfZUGP1%BKB|MqgSi2f`535A#m(O`J?_~6j#;!{&ziB`O=MzxzDjO1KC}hH zFa}tEsgysp@PDo;(X?8Fd)1m~Y$eJY)SHwiFTOv`FKxPRidZ;YOEs3e)l9Q5 zv!2EG`M!Eb;LpoZlq*++X~{<6{`Kl$`uQ;4cu$C-f9xXPVgcCe?n2VRQftOPsE2}B zLN|&j5E*XN_8EF|ZYivRRGI@jqh&p0e6x}Mdv9GP8ybNly{NM1v>RKcq$&KCs6%IA zz0gS^6->4Z2j&fcgoGtrN;Yvxzih+mmbin)Ib4e8BU z`_whLiXx#TOXP92@7ss=u}lJ~V4Ols45<3DI^MpFAm_&^pphtzp5&t??g>J-qqmWi zd;9y)+KyCu&)x6=8;pCy%TIBGI8c<*Vt%TG{|LAi z->Am&HOL!blD_6IUG_yIwO^q;U?*aih_s*=PzE+(W}<;x=daU!$|t7~cOH&5TD7eL z0~wh|4d}#?)WZ!%uoD@&QD&6^^Y{0W4H+H)26gaFXx=|~4WKheygsagjA1GjhM{PS zK}B7<@-n}ufQpY#wp|wm6ID#d8oidC<2!NCgkps;R1A_b?}iu@Qv1%iwT6J4>F*Ml zbLUHh;4ntEswUxAxEPMrIZec4iC~~YXqN}(a=~-${hmv?o3uh^f&C4vu1pc7?95-n zx1yG1onSLnlhmLhCzn%iF%kT^tcr@RsQ6U;YDWF}1?4*4z{^YV6+6a(nK>*{e(=ET zsMYCg-l9gmCw5pkqZMNS1rg8{ldoqtSUhy3%Wr%Y_3m{6bgG$pwnEd_u_~jt zoKQK@R#BC<)Gk8WNH|{)V5N9R+(&*@>j*hHmGUru`6H6V_pT^u-OH$d@EZ|VXjtPD*G2re!o%uyg-%rHx$!-BaX66JsxT^^rYRB(JkpDvno)Kz!1|Q?_z#0aJnIskWMl zK!j_8A0(q62Ot;Yj1`O_10AX~G%pJJ0xhLGP&R#ieWhjPMGT26qEpiHdhLXg%YBK%hd2-ZJ_qUsvBVuytRf1-d>wXn6EVh*0=k1Gvb3X zIA}NG(P&RkuF1-YxKOs))>CH6I9?xX1Pd>B`aNg-VXR^rI}J7lIdyluE3@CZeNwK; ziX{k1C=INm_I$iXYm-m(WBig|$NwrhqxcJw@_iry&9j^0K+eH{*2X2W=2K^KC(2?Xabqj9opuO{BU$P8I-Qq*m} z0Cz_+qT6@DinZVu0j}wGnejxd4T&VE?;4S6mHV-vczjI<$aYD;`Ps3xcI2gaaE`7L z8K0@TQCG+wPyIFpY%C>Qf^^Z)NER1{aTr!)wX?ZN%4lyS?=$jEuIn)F%{<>HsxfQ9 z&wcS9b84$^D%hd#q*K-E!*9cmUWe3b5z(|+-l;fGnBzC*Wol9(J)st)M(YX2?EisL z_PyGZ(3ke$(Z&7(24m9euRt60M2BvH!{>ZzL7?R>d8*;lvex3tbN^s;i8-?N*v#qv zTOH{Pg2f)pRCkR<*O#BhG<=`mbG5$MHc}R4AHz8Ei%yd7(st}$GpUj-9|`GSe;?Sy z?T*r+!+|^}dDT^UW?f`~pSWXql)aL|Yx?+=%U)pYH=BuJ7HoH|MPkTMbho(I+Px`D zg7ix-xBCNXZ%af6QExJMfw(3wI4`#i7khnOS~^5sIj`s)S+r1l3pEGzasil>-$_JA ztd=jxBWFJ17FP3ZL0WoL^*2DQHsa&-h_ktFm@joY zA!P}41YU;!$fn~U)ny#222Jz*)RVhAi$&O-Yovl)TM8a=xJ!gt7;VpgmH`bl1PsL@|(*1S*C!n#*UXiI#0&mU0NUH6NW&pAKo|{Ts zNF(F)sbLXG+bSEety=zuq5b2`q@uNDSn74LqgC7VYlLXI_>98kr02mxGLs?E5n^*E zDkJD)eSTkcoX*3gz|o$Mle_)PP9AEhr-FT8BWIJD!c-@N8)fXwT9RCYxE8{~!m1DK zd=irRgST{mlQDbC^3X-aGk8DUc0>szfPNEhw4Y+hGDkYmEm;;PnVLbKTr`8U^oFo4 zB};e1d*|)tt}rANIuS?EzjgWMHZ%!?vB)AxLq?%3*$O&rEi?^1^HY=>Q$DX|U5O*0 zG!i`Xe0a$%;4c0=&_>?Vd%HY!!YKS##_EPv)`#DT8IeZ5P7HYu%8aNCWCLgzpptfs z;hrKlV13Zf#RK*UzGaAL`w-KoWhS2yqOQ+dif3x0uBlfA20A!mFw@Z0F~0L@tk;Bu z$w?Z?zKTXsERzA($G|lGFkKV z1T9R&$P#a8(dF&2x4)tW1d~lBb#_N=zt_#@(s~i|F8TF9aFPDN`a&IB4)|G*qf(8} z5S^!|gD~0gVnAfiU5=S2BHq>E=Q84?je}uYd&@~D`4aO@PH285wA$#-v88H_tA!a`)LusBCwd)i<@3*{CIozdv@iB^D}`cE-%sNfbWEaL zofe%aVtqM#@PH;7r|>!=p@uOqjR!V;UcY%kMp$(Tr9sct+h5pO@YHZ@F=r(O8@D{kplmcaM0tCQNHNWg zPAc}ix3qtbi#o5Lq^%9Tg~Qs5>~m+j=n#VR6}m)s$5edL1*a>O?gZbHrzio z|2857Q);z%O)Hi&P7TIOnzdt~u42W6{;k{mm(#_$f|yh%5AL-j#U!mpBv0PS8s9s2 z9}HslXDC0-uw9#YA^#HL0?P*J>;W_ymc@w0?W&IUN-%?h=1$i}O1`%SZ|z3N`wW5K zP251qT@CALY89<**VW-t#Bs+%y%wFh$gh=4SvjeOQ=mT~3sh)majzn^8V$2#1!~91 zx?6hJ;Vue?Ge?myo8j1kWyUfv=*RRG`R2-~oaLBRlZyhz)Ktf7i_RM^*i5WTwu`Nd zR`VR}Xdw_Y1Ei6ORzjTDKB7E+v{P7OVRAh8{G1c4oBClFj}S3yAEdaRx9smwW&bkk zxlw{6%lnRU8)_@2aulYoW7$f5n6ylDQ_@-s10QDJPn;)um7hUyRU&d8N-RyX?S%o= zoxD|jAppz#5^G7HzwDR=#!ZBkr5_1TT>Pe89RwnCah6$n1foBA&B)w0xb8ob%U;9A zhJuEsTJ}ti`V|_&wuxCuV>SDsY>+{7+#5=^rwbM5vGM95hiyi^uPhcTfHFboX;-dm z{@cK#sb+*Emei^r%Ca}ZVUuTto=Yj%Jk@5zAIDR2gQjL^nfV__4wzTnE^%PU@Ect} zQ)xK(9Duu`kI`pd^@(PCp36#TWyJ?wsz|=CeCkcgcfJ==wCG&}$lRN!N!#;mO~^qs z5=PEfvP&Ag$eli>~pHS0jM0#4QQh18zJo z`_Q-ig|FmbN6$ezz=2aEC`d#+MQtSkH{6co$3lPI&=Lajq|ZvLbon;{6yJ;X%M@_Q zEPJ%vG{`kV+#fX)5Xa<5zD(IW$ciB8q(i(zE^BP4rv&(sfP&7P-7giDYYA$#Py$HZ zNaL;YmoLku9kmkcT|{0@-aLMs#ILRcbKaKS`QIyl*CIUX=v1S9nce)mg)Yq?xVa~mO$Lima!yePmMUJ+H08a0=g_d%5MwY zPikj&rLk%L!SgPI9otI13OLc8$EXkH^kMW}8vsHIsjkU!>G^neaf!L6i2ftvK;Ub_ z{JBz>FSoe*>*)=H`gASz1dx3$9T%LA0q^Ju`YzO&Ls4;Y3NKLR9$`f z91m?-*GRK&(@BZY7L+?(ZxV7dGjY|~n?jP(8raZjB@rN;dYYv`7y{J1?F*TDEFh|Z zdjzYMZc5qY+|C+@4~_Sd0Xv=J2Ygfw7MJr=+dr&^ ztysEU_xKP$nr?M}Tzt+CAbi$F^Jsijvy7^1(^Y^~+-^+QRlU*7(jNYi3Us|a|6Hln zJT^DvtR#Xr^fMQm0!>|eK3i{_0kgJ^a}riFG>igO#ZqYwDt3ssVCea&T%*~V)$k+3wQ9fA9WNQ-N-yJJ>zI^Ac8M16WX0rY1-6o!0zp8K>b>t)HiXv`Tg|RC;f=T z_yL1^NFo8d69K#Sxwkc)B*+x#Yk7if_C72B`wmdr=5i2Kqeyz<2Q=g62mJ^ioTvuJ zPgY1_y)*+iz!&Y`Q_-JuH;@ZiyUf>V%S`h1DhbsnNW9D4I{Et;YmUo=8c66+K?3c} zYxt{c=Uhfb;~MKWAG1&Nu{_#)z(zSko1A(w7Y3h$agkqJJG%#20khs8P_D2(M5Ssq z(xvoVR=B?s2mqgnSK9J;m~TU7g)yH#te@1;`Q+$rmlk|DP_nqw*ftG-l_I|nK-QEq zb`VjE1a%kO4XX=@AIbrjH&`2jYf~%(_0f@#UmAP5k$fDO^ZZz$5Zbl=-9$%z*g+s| z%Ll-R^n)dl`Vgu4HH7MchQ@9LcS?BY63|X(`r%tj@-kVK3VL7328>5JCKOFVrfH6b zoE-D$vnw*VkC;?@^YSOpl6hJv_g%vJ^t$dzu@v^}<>s3>TeoVOZH9O+VBnVu*KhLiMKGh*WmmIU~# zL09nWd&AdAUi#*2m=d^#ptrAI1%}!^^J{zd>mR3qNORZVqdAc*c+A7`u!)OH4F<{O zm3a>CoZ5>z$B?Y{q5Ih@Ix{sJ1UI)rt-_$Aw3N_y;d~Dwkpzc{^082q@c?Au(Kly= z!-!cFZ|{PNoe@kP=`a$1Z`J9ONxDQ~I%gLHHAg&OH~c7q*>c@C*F>w+-02AhNzMXl zB5UrYL#?HP3G|XmKj^T zYw2SoB1s)kR-b2?ki&FT3|z-OxF19tpb&U@gIM-P9xst3ds#cx8~YV#*4am}40*jn zwD=;tFX6K_myJxJ*ta>Ud9oHPnr@4R_=X|#qAx1%yx78IZ|h{>$r4%%6|G@`FJ>TV zp#K(*GBuW3H%$IP5PD00{zYGAtT!qD?TAcBZ$iMtKMN!)ZqvX*9*4od2S|qjB~NEd z-Om`}{p*o|2Pac&>l)hW!814XZq6E5o?y#2D>^(+2ksgMx-ZNR4|F2c zPDfLogvSOAK|ru{)?ZxjBxiRAFT=$GI&W5r?;fTOM6+FlU)=;Vo{FYxYm$r2MjC*2 zC3{`iZ{I>niCjuI7QW+WwFDwF!y~HlGs`F_CD48XC)C1kFxP{J4DQ0ez1VEc_*SpRMpxdiM>R$WoN{m+&od#S#TZdj< zy0yNxAZ-Bq+3xEO$Y?r%{ay1Gq#>->WF}uC$|orwzpY+UezZQmST_dBZ6Pzivi$5r z*X@O%ddJ-_totq;XvO_#Y0*;(88$Fo1Pr2|sJ75URmJdSu3i4m$^kmJm94Bz9#t$n z;>DCiHp!kBMlytmOYu$rXkmen42tlxMZZm+nDU%;ifj-n{uXp)lQ_&cDEaF@=E<0fZ{ z92nAr*0Udx;edx04^Q$!3U(d z1Ay?je%$pjU{LltFL^2e7p?@bRJDZ;o!|5HsMV?|+>(TE; zr)&ZmOy?W^1(U#~rQWZ9sl1h-)sFPA5KgK1~(;;1fNj+I#`5XgoWeJ0dMgSj+yzzpOn-84psh>nfMK9_{|jgUkP{r zJ3Zz9lJ}e%gn|`ozvp(cOAjE)m^RbmmhUigj=y3j*^2>yV7u*G=7Hnn_nBSQAD&y~ zyJO3Ld4oKxRtabubA#1^OaA4X767J_6s!VThy|EqfSN4E9&caL=}{2O5{`xf2r&}M zknlf|C2?RdAOewHYm7C_!!czs##|1Lc-~f@r@K%?>v2J9M7Z+_XfOeA{R7hg9+BU? z1XfG^$nZ3U*R^KfPP?y_7*b{r+>?hB^4?ke3t4CToDAq7IR(_1KUoz6-?j|!ZGOK8 z7(jJ=I||g4`@gbmQXv7sYlCk`zBInYp!V22LP&SpR_!fnZ~>r6`B&GW(+o%7Q|oq@ z@_Zui4RfML+BppcO6OdIkz{$a#1#N(4=4Sv%#R$@CwI{ZEV=V!odyUD> z0GU+7%NAxHfQ!gisACLB7e~4A76D3~MgT&&siJSVeprP-P>)5}m7f8e%mw`HHl{g? zRojf7+TeLAP-OA|&JlSVAozM=m8i9lV@2+){B4wW@sju*QBkdn?#w$1Qk6ZY{hr9J z!kAU%k0auxvvvuM$AxEcLE|aGOIrZoNW|NoUy7O%BdrXzgcH?cfS0*Qn#KlZEZ+a9(U=Aj|<1I%5ZV3UDVyL}frT%`U)PWEk+0 z*VI`jN7eBl+zO4wG{*P`M=KA6z8~o=txvOCJF%B)OOJM1y2BtVv7X5rH&BfpT69%E zy{(r^-M?!BCWHt8R5>6676M>PjJ=pf3trx*_b{pTXAk9Pfco%UA^UV z4_RISOr{eI;G*`?pxb;a1}tWOLSP<%kL1hVoN7Xs#QVN;@b@~_R1=> znnYyOYLRu=gtbgPEfAOey_8J=`Zh`mg$xZq0oxDL1H=d^|Ky8y=pCY8ctXlM?&!22hH6!@N^Ipq&vvKuZ0epJv%{%WF@kgu!d( zWN?~=JU~3#JGvj(ov)}eO`nPUXkDC+F&c+iioRU|{g}uJ<-79u)cT@d(h$~0!{fH~ zHu4(I>;)bhDb30cpNs@o0ER8`xgF~VS$&iL(=zZui-|)EsL{YOEB(jaJ1^>07l{@p zlXw^VJp&$zOLm?_y@8ry008i2_+q!MPv!v5&fm%efJ{|)sdJkBkNR`VvG}EnsfodN zKV-#e_O~LnU0L04bqXSe!hTd`wC_%hGK9y3wlJV2O3;`H;M?}j)0u1~73Xxbn`lI_ ztOh0bO{P18O`DQ_3b}33;3m4h1?ZDAA}%wP$_loDTP!!Sc{GkgujEq;h%WILCh>rM z$h_*yKtVeZfH}i}s-8Dt)F;OR4|XXRU%tS$#?)luCRalq^Ub&Kso2J)v#T+I8(W_3 zIeG6uf>`jsf(AKoZ(Gn)`?IpY0|B;Vk-_?uYLn+>p$oN;VptI;StX~6-^f**dnZ6n zE_}^67RJY5U%y-q7`*ZUaS35qaxkR%LyTc(Ey0&V#(|`B``Jl6qqy3dkN0>p*CFhT z=WQ1=-WinPdw_Htse0wI62=BV1D&aF-~HRBmrPi`FiQgX?g}jZfc|+oDL&X)U@V|) z#CV56!Y7$%W6TfnYr9N1k8d8Sy)G^{VVSE0){L^U6W9W712cCNuzC+5{Bf!V(uDU3 z!Gj>>w14>?TYZ0C+=K$jPPBN1MGeEm72UxY_A=wJDT~BR6@c>lH+UDe0T611R4tta za`J2IwuSNm$RJ#a!4EjX|CNV){fBlYEeGe7!1Kia|N1M3R00>o|A#CF+nZulm8^ zVzJ05UO@;l+{yHJ+dL9)b2$R=HT8dsDHM{e0D9GmSWn9Co!`DlM3N?A5M6op4TcaL zZ44=Y66G|-)&%;6Jp^%fwC14NnQk99uwJd#C%psoC{%V7qK~JH|ALVU6h>XOxKy$u zTK~#19?w`!AUwC*hA_`q=+wJB2LO2Ge3AW}F1^#RxZu&+#Dke0$?r!ke4oJTP&bI) zN1**d)zitS&{P1b%Ky%$im3vD_7o6&VcxW;f}DZ@#;5~JCLEl2)He-d@7Yn`G`9qu z-k8Ff9KWMkS|FM=$hQXoxdUwy!!x5^fV)6fxf=m6cMlhQ2mrOw>ZR2Xfvo~;RP<<9 z>-eC2-JKP#DNro-NMzvu*v(n5;OJiMHl-(-zofg@G^sacAq#q%ND3d>H0x9yhAMvf5-RX_ycmf4mvVy^+Z6wHg3G&^5Ny;Em& z*-y0i#&!{EZjzr9ClGmV&BzZ^Bz=2-)kRIq3i2NPDWPif8VgTh0l>MEasvnBJBzB% z)ovt0Fm^zU#E6h(La%-r7Zx{`?UerV(?L{wi0oi7wk?oZBvpWfkF#7&<6b3W0yUx{ zdf-o}Z(5)N)9`PMWhO4!ThZ@6!_OovP*7zd{0${RYmuO+)iG9Xm7GcX{l@0aS3Q*< z`Q4iaZw9*+`)!^Vjj1he`&bm43?{MZopF>uDi!%kMCj>H7kP$n3@SO((% zUMv<2z$mxLzI5w(de8jFnt?00^LZa&B%*_+8o3H{;wY7VbG`F29G2G8vFB_9 z?=pDxN9E#w739PP4HDRXDmF1!S5Ow`a_y@9cy4f--yYEfu?Nm;xYgdLF`d0MB_oU1 zq8>wsuViKp1--+h-iHXi~5_bI?%yOV^?}-)=gw#;>JYI#AUAzw-T_lXt2Bqhv*!s z4)(!Mfu{@p<%1_idm0!7>=5=$_&hGc=W#0G3b0V*z%+aa?f-oU$eLS{9aoD0h5Pbp zCPtcTaiYz(FZJmeJx%IdQBm@Fv;9GoRs?YMN)rkLq<}3ANkUx7~8PGSumspo`V|ps9b4d;}*xJ%WkTP%J@d0{iw2&n#V{s81H(q>3H@E3r2+z+OO(qxguud0ot*GU)T{PTj5PF`XnIPgqHa!)>#RLhE# z$BX>$k@Iiv4<7Xhk@T`z{c{)tVgH}X3>f!cVp4~I!u20HtUuJ$|I4(*e~@1P zCmE{$j~SDYdznfSG3(EXP|H8H?tl3(u>PSgnw9WGjEp~y)4$ZQK*rlkILCcML1XaC zmH#QZ71Cbg@G11l$W;7ap%UO&{uZO`UD4oe>;=`-=KRZT1}5mYIgD(})3rC+H5Mia z|F|)KAh|W%YGcf&dga!;=zos!Ke?lMV#b{$Hx{)wPJhfBp&JmKa801{vClx!p7Wzi zM0bnO2Od5F9CccWwf1K0>*+ANpYD#B9gC}kK7za?!aC{Uo$WPGg*z^Byl)SQydQoD z{_O1hg{|-XAVjv*?8{N~-e9qTS)o49TjYnb1R)*g@3zV zw34}A-$wj-X-D!6W-r=Ks_T!ca^&o?_fJ5$Z%DiOLh9ic; z_CJ{YYg7Ym_K5)t(1VZG5DXZ4t78oCiDUHq*lnFoeShat%6#+j$;D}+9InZAkgX-ztw=u?I~v9 z?T~%j$*RyxbIFk8fmhE4W*UvZ*xhB*&W%NdM&!FfsyHgQBZXO02RS*Ee6<*pCOwI= zQa*?;P0ly{-t?CeoD!ZAl@gbdn39^3k&=^Q9rWEjL(-lqjn6ECcCi@-PzATRpP{V; zoJgbKn*(V~p$~xRq{IML(9jd0AFv5zZ+<}IPpU@Bh4J3NR}ldkjLQ0nYQJmoM6V=E zME$n}A2NV0`_6w8&+&6@@%bV5hl4ZXa~Ne$b9Un^izXh)P@zYcuk5L@`?+>H?$Hv( z=_ePu2WSc9^2PL5i}bGYx7rG+aNt4ncm_ZYeyeUq5NF!`vWtOa){7ma=Edbn=*8CI z*lJdS)>;ol#r<&MZnjK2i3-T2cP5Vese|9IA7vDR{w!Ar`q(O|t9*-rmmFNq2{W$4 z?=qj}i!UC39Q(cTP!Cg&Opi@ZSWj8cQ17|kE4>K)5=|qtt{L7e_fxo>xu_rJ`JwrM z%Ar&jedpB=J-ZrtpiW*_y}|fKEjOtda2p;VU|b)o3Br4K-x51o(O*O8Rb^%z#Nm7< zsyO+yE^h%UXthS^$Y0GMirXPaq&|Lx+u)h#StmJ59`^4>*iQ}c&9$<-A&QeNvgtw* zVh_thrHnm|`wbLrO(7gS2Xt{~$f8;YA0f+Jiny418?c)@{)z>4DD-7QpB1PNc1>b( z0h=bi*_U^?LHY*W_&5lmj(ji!eP2HeMA@OEF8k>Gue&V$5k8=mFO66t{CmB-?9FR~ zsJOWf`}>BK=FwuFTh@~sWfTvcVt;{OAI#v{r{)+qn5~=+nMwcN2>GAJRb|>pyx8n) z?{{&>GU)8V(w9ISH>uAtV={r%P=HzLNn#hS8u#^JM-pU%73g(%06ardI>45eIXdB> z-WO_Gu>(WP-0n`h^4Z1`6zSWp{@@6Z(!dyFTVG9U&!vd$h3dPdtJ5H(|7^_BfjZ2 z#(&LSmZ9GPW=?L-N1PIzJ@wT& z-Hjt#;B&;&w##h-Y5((w9T%q-{wJ;4@Sf(*MpDX8?|^ZjJ?=NEmPsWWyaNDR6To8g z+wGqyucWXkE9GmOP=Cr0rMM>3s_`=at}3p^e?5dsN_dLuZ6CL^43YD}K0A?9uHheM zzR@w!G-;v74Y^6&p?*tqdxtdqLSij!Qb1+{>x#LD{Z3`$g^hk2(LWD0A=&n$^FW#> z0I{h4L}BaqyA}L3c#iceehQ3$*Esi!Y7BPm-1h0C)|r{y-R199X(#k9f1dDZ6QVk- zit17^TZ3mw9RW8p@7-J)5TgPaDT6w*3%u(*kJi7-->k<8Ru(Oj-TI7E%19jq=dJ9; z=>M&#a`Th5NUA&)v%Y(*;Pkz1G)ExLD0mx!5ae{^4-lf!b#W=H#KPhtL4~|EbZU z`KZ9aVM_Buyz}sXa|ognzScD2#G%eT;Hvr@w76ip)DmUoC;yU+n0z2Kr9Y$w==f95#+3 ztX480ZcvLDx0S_kXy+|);57`x{|H9AIX5gHF*%w zb>49j2VER9H_C40b)p`3+)kxmEWYjpn2c|`{zp{$PVFxHh{R^1wfK&10pqrjZsbnD zmmhzNOncfYO)mf^doL9Jj&wV;qZVbHMiiEs@svjmufMod2mcf_5cy8vTP(=E7Y9#2 zSwmQoZ2$6R`u(sLt0f{O9{Yr+vXD)jyMel8R`LMyTg&*M8((tN(V`K2{m^ZdKFAj&gW5cIdZ_Sb>Kvf$ zudzR2d)(`@4cB#?Et9Z&{QAEKFVuSV(?~FU3S`9%Y#*S$IdOYx9EESVy<=}BML(oJ zmiN#2{#%mCg-jD-osY$T+7~fA#+i?D|A*_HN_3@iCo&=K4Z)>w zd)qSgtT0u~7ZuyJlB;jUL%)s2Rs(-66TF{L6JoH7*UMF2--}%7WQ4crZJ9pJC zjy!Nt?)tlq&hd#)B)JC0+|K&P4&(a9=*I?RWT25jD1-p&65@HW)qH+*i@L%IJfByP z{QMec%Ss|1>DO#KJ#7D8(3|V(KE&dgAX_7JP17aJhVJsdc=EF8P3W&0aUeq?>v%@lRT1-lRZ+7 zQ#?|SQ$5m-(>&6T$t5DCdiiYVYo|Q-b05(et!_16uWy0aU|ZVhu)NOssGvY^+}oRV zULXha|9U-w9*Iu%fGRraROpnKS5XaEA++wKJXv3O`NITbLf1iv$6M{p+Ug&l!$KkxV^Or0E-snq!=?%cg<86uB z@Ng^$gM>642ItVWkzwRS4%e>Yq}o+>m``KphHa{hJAI{Tqn_eDERkW$iGl)b_=&zT zEu;ll^qyYh@p8ZC8A~ci(Z=M~H_<@&j@pAzp5v3iKQiQuk7RTkQ{d-b6V~2P$2~f- zxMY$-cW*RIQU-Q_Vwth0<3{V1n~P_Me6w#<;ArE&-yUV|+owg1Vx32Sxh zd;qqU@UwJmSc-(+azKPWuOBNRe*IuNRMgLjoZxWrt>$hz_mTBlu^NS_&xNP4g|laP zx57zicPK!OT#!*D##!kfGX4vSBKaJJ!=a_E^g`J*NA=56ui`!Ani2dA55eV7^0^QX zbc>|#bWCYqQ;<(A+UNfBJwvdu-7zc(Q%xcU8<^6gMynM4tzWYk;WvGo&HA&909eoa zCB7>$GOw8a%)p7c$2?U0aS8pGln-0#OPv}K{LOu9)mZCrYv0Wd#PM!GWO2zt8q_*!B08i>!My z?yw+(ZpLmytx(ZZJeeU;NQokCB}T!*LMr>}wie^qg9Wk^mD5^D0{6SPAU^BOrG@aY zBlptn! zws5*tE9e`}Ir|oj6(E~L>jW-;&E_^YFqL3^eqwt1&D$>@N(qNh<}uySe-vE z8R#(d73GV#IwK|1=wX%PdhvgX!I#-dT}jQVm;B6&Fl&*>I!X*1JL<>q<3W409$TVB zy|*pG%Lcixh#CG(`w{n}{Nrtl3gN$sIm|OD;}-FXj(qHSq~~ZL(7pHp`UEFhCzDDG z@#!rgK7#~+qFQeES;Y&o*T0x0H`Yp2`b;6Myn((8jZOtauQAuR&Xu3W1zvzL0R+l) z1KUx*xq@M~1vzljLFd93(-CXOyIAmF+z{~19BixR%gj&QaLCWU>H~m5r~oTiZnwzc z=V#%EK{v#es5A15=}uIMK8xj~n(w?eqIo#IC7s0C!Fs1OP~FEdw%smh=--5J6fQ-W z^E4Q~A&F%jHIE&osQ~u!kW!mKJW(;$b51SUaP`)3>;0n~_reJVTWT5HY7u-)+`Of@ z4qJ0>dEUT3_~q9BquMEwx@! zy|iq-pfQ|XFfV|Q-~6ry==eCIBEf|4!%js*a~gSc^od{To#iBI>^t_r#T(6@o_fDp z>nlfA8lis6y3P&eOOyZO>Dm+DFA-qJjlH$XHw>H}RE6Z1+J&)hGBZ`q*~^o75>jN` zxy={&zr6p^x5zCYXF1XpGrI7ES*7)p%G!(lT%Q}5Dq2SXD-Ja8iJ^R`>4;n}W`?OQ zuV^VJnc#w4$5XfIvL^X}PU#Y-;l7@3fN4HqxLhd`L6rkv&q6;!E|MH=HE*qJAAahi zUs;ZWw!cQ}d~?Vn?RQ8f4OC$M-49+ecgw8?-RSX3zo#Rw=*VQSl2nb3miIV)w9)L6 zfQ@7LJ1tXz6}*^}^rN|IbV~>uf3H0M1d;B~B2%$WNDfGl*l@J6`JI9E9h|=QA81KL zWv+yzIrlpA1+eZGOkhWi$SV5c6xMNBunB&+V{K~5C?|&ke*R|E3wu zPrCEgE1o7^_}Y?o%oBym>?icR2H*s;Oz{TH2V@83-i1o$;C$~iCCBmFUmCOO$`8&T zRVYR7aWTqA5minb#0E(oLw7B7H>Lel@? z8kGSud4K^iRu(LK=QugpiART{)4sKL#0^k{C%4B;b}V+?w?@`+b?JNjm#Tq=1B`sK zur5|0n|G57yOV)Sl%^x~fr;&@X5u(b+?c$N`dy|+!#o(64!w>Y8s_ri#6^Wfv=3t7 z?^(R@#nNb|ewnvn{Hw3T+7ZffH)CJ0Xc?yzvGuO}4ooC|2mMZ+0h3L@#&X&Ybm76( z*Z;A2yg*|T#Xkwys8*w+crT`V;*h%N->q}}O!6mUcEzC@W$!Q;dy-F_v9XyX6^qFjc{q(K7gxCwaWWzko+vxH;1e@56VZ}I z*Q^pgK4#RD_>IuJs5@U-|L=!O0mFlC@uD(4lZoh}P6s(QSlIHdObV#ttC@cv=aVnJ z@4$_~>WGhwf-Lvs?lQtJ`Jw&uPZq6?6K_7n1IgOoATWPY?_^*k5Y-*!4X4RD?0myD z%2Y>#Uh+Z)PxW{$gwdGSQbl20as`Rl)4+HDP3-#`fydKo%F=@kF*VzY-Y#NTV&oN` z{)zwEH{i*K>u>{snErRo?e~g4B7)P$=)@sCgw%ww-%1_52EWM;d~z6co2RP~t4xY_ zmK5RzV0t8WoKCk~(cXvse^tFjay5Bf{N-0&Axrc>W3Z#~UpN(_YWB&Be1@LEg!y%@B zdP$0KEXu&Vd@(WU+pW$YI)RVsEV7N&eme)sgY(c}2rmn+&J;0j#jPzGbE0^^U(U3=@M%P^dSlCZFNn)iw8BCJqK!%|_MO zXanY0J1blOtf-RM{I#~v7(i@>e`1(191sx^_N4gY{L#_iLx$g{s_*0ItNv*69bxKm z8(c@*?{}HwPt+Zd_=8n)@U~7XRHOQx&*O!zf#wJ}Au&Z{OCgMJI7oHkyyf`;^(hy<_37r^js0NCUdcOy=GYNso0|i(Y&<|<+1G(P- z4++|+e-C5Sg>sw~oxk(M6h9cSa?yI4iTEVw2L7_cah>abk| zZUX$B_SkQ4*T_3{(C&o;dR>h3w+)K_q3%ErM>d-_D8mgEWA%6#h^g9VaQEM_L;xF< z0qdYhr+wQ)8|vPsAGrpG5W4W+@A-8DcHzJu$c@%f$p+U1U^k_PSwFQD6($R}cC-KP z!~D-uHXZvw%3p<&8f9gPK_ixpsf^>ksP~bM#eFXV28s<>K5jCK*P~ghy}^#wcxxpq z;EzQ6fn;O~#>Tw8s=kfBJ?liJhu&VC2dPw8A&Fs(UE4ZyRF5F1U)LTY$6M>74fMU z|KgUbK^Jj+YtM0mWag9v4apNMEb2_-501x-ZIl6OhtXn}*z zGUl^?;IlZ8GKg2m$GrlM)q|9yjpy6G|yqu_; zlwMO>lc;nrqRJcCNp&ZXWGZ?Mxy7Z-dEL9=YSTp|J*H#oAr_r3dAk=z5PgiH!2LwvlWQ6JCGVo`P3Ti`wXrfXO^E1|2^h}5xklhM8wjoNweNq8 zpM18*=WM$1zGn*U2TCb?Vi$A8_*{Mu?uNyXafqyStv2@HrIU<~aml2aPs;)}? z4(db(Wl=eiPqKX&)3D*wz|H%0qu^G??+`|B z^I-e=ir-=Ts--|b2DPnAsH+QDL^y{fEKF7v80*GfewPjPf9`Gcy83w|w~4)xxNrLk z|NhEn*Tc`R533X|w5Tq>xfIxCS1t)9a_q@rkXd zQ?6xrecVivYK^7|_fF9fexFpK%sJNHt~)XBkAMMk%fzHsBB z-oPr9t5u(Y=tj(e5GCRS>sXdykj*-Us_}!x1abV8J-JvF8~? zWOSr8@NpL46{L-QuxX5awr_-p>3j@h-r5=4m833vl|@PikkXe5 zvB$C9FD+2A1-7++aVqEi{$cn=L!`c+pwL#rXmZR-`s2n@fo6mMPl{hFQQk{o1X-&OWTnm_X$_p2aO0xnE1aiOMiUpIu5dpY+e`4$Vk@vceA>1;!`^ z6}@d?L4msv*CdaO0?Qqed!fv>Wo$eVUm*SC3`Ztb@ngmjf}cXYYvVd-u6sLNs_IF+!#o4o|SHb_ZRVfRSCEY@|biJ$XDJ74R{PB(^k^xhgvzrc>$ z1NJS1)6+RWDdcc2yt-K=O1uqd75?+MG(#n7#Mi>8T472kh>qJ+UNmWBcnSYq3`a2*NA4?2~J3=;Pa}3 zgX_9}atxCT58))_-(5Q~w-A%Ir5vsqeJ47LYVg>@176+4$C2{A8rmcEXV0VF4`Qn~ zm~vRLOEP>e<`qs8q$#|gl&3j`bzVq&GB5>8om!S`_7t;_ITCG;vnD%xHrPi^4w`b_ z0!_r}w{CX_H+p$Y`HOc16407FN+zhzlv6PrE4FoZm^kvTUw)>H|1CDSfPx~aKzs|K z_=g3m`T;ce)xsic)zrMF=L40e2?4LJX05RT0=w0$a@C5f`PimJjFgzK;=%q)k^RRO zwB`L?$#yM1y!!802gx>Ce58!tsX*JGK7k@VgaWR2KcDVnQEz7@Af{%6#5JvuXH)@a z=T?(Od4WsV({B5p0J&a1gE4{uS)UM3@+QgC`Nzr!9t(s^-Mr6!S<5DojH^eSK{28p9^L_ZUFI8JsSUxz)0TS zKz#7pzj!5*p0}Vewr8$(Jz9e+beVj?amo?lC zIAsk#8^B^3n&I%7kQU_|o6o5$W)2@fO$*!St?N7M?AfQy>o})7o@%F?eRfv}Q?39% zsi(rFovoZLsmjo0vNk<_Wg(Tf?`+T&BhbE_D?eQJt2fYLq*|T!I^3s{jAp zjpmO9evU<*9gtluRufEGtw<;Z`5&SMoUZU*taR1?b+VTsikH0dLUV^bR zn2SmmLlbm59Kl=cqMT|%gMQ>2I(Z@HA{X(SZwhI4tpi-hFKgyN_hNNmryTJ;4Fol_ zwlYXcrJKFl>n5Y-JZYZuzq~DvoX33P|620>!o?m83+Q<>SD{o&Kf)T$ZVE2E`JmNw#WHSJ(2K=@BP<*kssK- z`~#8EPvdQb4Rw3%uyW^|T?zESYn+}yd?(o!=XBn)@FCKs&P6Ba+5nJxJw@b9o&NexzWuXtBu)o8Gl~lYSr8c=8Ws?e_?PA7IX4PahKPyPc3w#+ zg+ugDnHe`?V+$sKkW%SeDBHHCw|2ee890qK2JPBP{KK_ZhLY0J`Mh6~XF6E4gvt2D zYUm~o10Mftcc@iq_F{Z5uy=`=n29+UP8-Gk6u*?CFx(b%e5EgW$t6=PlMS&e_h6p# zM`wA8;aG<182yU;V%k`tuJ>bucS(vp&ciR}!@3&$CKSb6{L5)Vy1GLNkfW3z8wFMz zlo!l=d^{RH5V5nF?p$UV`o0K`ds$sGVMe{SBO*b2IuNRLwKY{J7r-|$UE0CXV!$tJ zuIU~F68t4MU21sbo69{6t32>J%<16kf-UQwBK=5quC2!M521P5RyR(p$o-uArx1~* zsp`YMkIgS>@)!AO3)9DBl*VLUr)cGh&iuQDlaRQQjH1Gn%h=$1rAxf8km@Y{$#r5^!4r0!>(xzIdHMM`nfFq&j;w~O2 zu)yP`1aVLp7QS{}fB!q?(ND!Jk5VHL93SR;u3Cb($16nB1+$M*(sSj}eGMl+;V8WD z>7?TN{yk-Yb5x_?OEg-hXg(yniewEiTJci}hxaqxK6#Wc++fzoJI>6n2%0C8*DFu= zgs9s^p<2y`b36NSN2gs?K35xRSOJ%@$sOXnR5K1FJG&=mM1=g)F(3-xU`FzC@XDT1zFh)Qyex1ssPHLL{poRmB1hl3e$6QUE&nj6)mZ4u>=YgH!radVk0-B7Ax!$?dZ{680*l*Z9y5I0>pUboctjlcB*;wD*t*{ju4*41k$SsDH zu8=206xN`qGl-rroDCYPeZEuU>uIO2C^nP48?!IZYy-eetak!}Jur1a$^~9UTpS`9 zlF?{-M7QtExN05tz#t|0Kz9!kz}|n^sv^JSvu)kBd6qm*Ns@<&i9dK*6jS9XvF{vAGkd|l-4#b{yjrMrrL8pmobvozwi>f?oO9T(=2wP)z@7($ zS}COTit8eZLP_+2v0sqe4ySVobWZouMm#nkgu4(WGfoysWx~oi{;AAo{$lc9nY+6= z3`NyUv`R=Bndt5pL}Jl>faggw;at|%B-W5f+X7Z@SvA+eAZ8+J_Iy~)qYe(1se!MO zb8R&-Pv8M0&;`e0@`7sEm_AkD`$cQXLrG?GN1Mo$InR-y+;{52`k$ymybe@kpprcdH|6SakXH-=wgqz~!1U?M* z-Qx-S;;ek&dn%7$af$??do~{;P91zeHx3-Q=uI3js(Qs0*?}8=h5@=ch<~h zg?`olVZ?dks`ZXw6&=SE$2-i23O@MWey0zs^UZ&Hj(doIoxovmD5*yqz^*rteXIJq z_Xz}3fghli<`~%VvW z@E4!=^h+u#jpyNfL+ae5V_Z~X&DBpdF{TbbO7#5dlnW1NUISv%jRO)7n$~DrB;O{9cmUF z$`~ul+@RdAVC%N0Jy5<$P+o`f?d6)n)rgAQ_+oX3B7X-siGY6L3AMgFo`byM>i{{^K1AZ{MwjI$|>?F$zs?+#N0sErMcA{Zvh4d?-io zd5~O7Gx|GQ5e3`=luduyR@nU1jQ%&+fgHBud6@XL&;y+3_^-qCmAyDvRl>&^{6s4? z+z83wlp{J3-VwF%@n75FSl9%FhYc_yLP7>f;D&ip`zL-@1YHqJM7hp9hRI)eCXCzf&z7bFMORR)Z=k55If`U*v_>?$)*9rNzmMlJZC?>1_i2BFSW^!N%@7m+Fz1;lEzo`aGgyr!4k=lO1*GQwQ9PW zxw^1Q1v7>Ds}s5y;-} z5t!4zl46ilE#cx(k0y>AX8sN!(mTGeF7im1aXgT6dHtgo#`aOiqOtT1vOdQA?{i7z z(Dz^l4tOP;QA7>O>^!TF(hBf*pINvRrPjm2w}AXv{2L-2ScaTZ6<8UhpJAJ{45?4x z?AWP~7}*R}q;!YXKYvfHq9jx2K$g_!RMPU^QDl%hSTWTX##rWYPb{YIN=#}n?dfLl zuk1yVKNG%SfU&1v1po7UJ^P}~fXW8X(p0VZ=J8ZY_fyY_In=Z|UVCSkdgtQv5}EzD zl1@60Nts-&eC;uoiF68&V3uSN!R=PF!iND8=^d^5ve0%@9;#V;ufsUpFXzu2HMlPK zC3*nZu2B@!*_tAaoF=;(@Wa|pwvthx?+l7UouX*3wwpWiXAjIv$VYQNvJ)JXc<;_k ze46)su??Rv&|Qv6nmkGAEZ`1ye(N0U9O4}69OfME9N`Rcz9@krqfy5Y=r|O0V|KM= z6{M1fM1oE?J5d@|K`3%gno>o~2gc-!&&>AFue+sd-DpDhr^SD#wcvocGwe74T~*`a zy4W32JC3IB<)p-!Pu!hwQyq#q0i-2|7l!o~MvAA${31}Dg;zV~^dAP1wi{u62gr4S zBGjs@A)ZxlH>`?Q&4k40vl_KjI z$a&z`tfB}VPEGs=cX9wfyX#~9(WR}XnXw#IEtTo zf&nKUm;rvg2_5Yw8qjt!5u)?*QqK9dLV~dZjK@Cxg6Xy4uKTJS}Oa zD}lDZc^8Pha=+@UaM+GB;v3GD5~|CS^m-@kwxWSY&inC*gk2ws3N0)B)atWJO^2w$ zt-4!uKe0Oa>H6QeQl5 z;22WGOa9)#$exBsQ=aOIp1J$CvqA?dA_Z>%&Hu&{TwF1jMeJ6a$T_M-^wB5p{S@wy z?!$L_m>QnRKOE5dj84-P1T-kaUl!5=6fmJQ;yjW-ZOscCsI93oV1r(nN!qi|mkCZy zkBD@1Kd@;t6>6H8dTkdQo}1(H;iUePmv>^^!Kb<@iLA99WDddA6eBzGL=i0j>CY4p z@G!aKO_{7v6ZiI_nUs=3t4zRozrdICQPD5w2L@Lt5zn0%E8e0`q(3e4D6aA}tF?6} zCktzPG?jg4Ax34V`*X?8X&FhKgB!r|3d{r!H&E8Su2ylS-6VUei=RsG91MI7V z??YaP>7I(re!$A|lM^eq4++qDwZj-?MAj@~^81tPoo>(T?H@<&ryE_%4W3);g4q;O zevWn^`p0R$v-gW9hpC1KdD+b5BmTR1Clq{tZMc8&LGdhqK@qo~UAbQE`?-xU65pb> z@=};WaX-bl*6<>N1FZArMB=*;PPD&^nJvOgQ`C1ELY&x6|p&WdTkxVv~q*OoEudwAnP+Jm@!OW+XMbSJNsd|nz z#UgRM)e*$b%DM~iHz{JT%BVMjBGra%V8P*7AB%nmNHjSg0WtA|Svt0( z{ZUkhpR@Gx^)%NNs%QVSCoeZ&JIFIq+IJV{s;`pWj`{j#XW8opzTWV9_W44K^?hE; zx|HXmnan*=5PWJ@>UoNh*cGW*hj>pog{C>WIi5L*Ikh>nIk)*Ea|!dFIBJpcmG-p- zI=|>qncHkqd;v+cs9(~^#lzJ9DNtEfng-I*BXFJ%umS!TohE-m?1$!$&Ah)W^uWZC zDi6K#U!`Eqd`Car@PXbTb9^pXSCX#W&keL_ce`lssZ17O&U6=yMgS<20=p8o`wf4@ z6t3$V`v6tx9S)!>ohVC4XY;)ZZe!=EV%sV({or}*!%;^tbL(}(fv~BeLlLintCwS2 z+~~K4iL*XoUx&&#RLwGwYDB)+tlJ)$N&V%-f!xYuHoM! zx$b{BXITl@U@-bD1fPVW^j=t6w-``_1q^<)&{5o+R+HVYuYvO)f-I-vEUEV*J7;%( zj-j+@-os!3jGFsW_VqgGD8{CCGudXcblWkL^g`NlNv)Q~;!G|cC%O}m(E)N4#|2Ud z7Q!%yBTGVU3)SNGj>3EQG@y=FGFQg3JiSe4U{}O>7Pr6O9QIhIZ8F9JJq(2Hb9)oc45D7HCWRXRHJud6rxJ zv$gW(RIXpSCC2TU)IXo7Nh~V!8|yHzeELMmemX_pSPP(_s&fFvxtty-nGvV{S8yQe zvO$r7q(kfKX!qMNKB6|_pQsK*Q6cxo=sA@Buc%;9AXv_spmCK3bRMPUqe`k36y(>E zooHk4YtR~EYx7Gp8xZ$*bf!DKcZ%R|RUs`6dV;K*`YF5_Og6w06Ia7$#Iq8^-pf5j z9K)GBP2BGH$5i=?T7KBn-r`5cdJZF*o5PAqwchXrhy2kr`K_KzHWqQNr>6y7u0(T+ zMT^!6CHE%aS{`#{JUx$RD5U}_t`{Als@yplHU*0(yr-yg(JQZtaA|0|=B@Nha);!j zqz>N~RgR8s`EEg|d&}2wntMx0iM3_YtaqFz>T{lcdh+wnHb39P{WGlqye1q=loxEd+WR#lSRZ{0 zQ;Q&*R#Yl)|69Qr==>wURzguVAAdo$)w~=OwMO~neB$vHivCbdg-l#phU>K^A_>Hgh)-x|H>>+1a`qiX>1fV<8Z zdm5xFIVHjIkZVPD$uNi)v!^k(81ucv{a8`9_&86X!_SG<1X9KJ0IL|Q$6 zIX86<+9hoKS=p+{NaGj?{FxRfX{@Asz)MEP<5g(fW6Q*wzN&?-$*VlqzJ*|)OUc%xC_Shqm-0n=rp%z3*bXuDTN z`e2KNB~OtK+f5f&EtPpN$&%|t;#owjs%IN1Z_SvaS<=l*t>NVEaHnh8Kiefh!*Xf- zB_0qH`F?+X$Hk_S$Kj9_jL$+vRmyK@`sw#bsq7Qur3>-V(6VDh*|W2*vKQ%7J*hdi z!y)5vRZ7@f#di}31F_idw5Lk(-Qw!y6je)>K$(f&I z!ny(xzzv0<0d6QP9P6cHGX{`mk^laf(+g@WCg*JDm+#?ckP;K&DV1^RDVBa4&d*(w zke=OmKI9>lnnCGd93D779&JNLXNqw|Cl@BiKqwm$8ZrF&KIv(Xa z2Ue1j{cb}yWB3B9#?W*~M$FZ*IFw{4AGN7qp}?Ivr;=ar|MEQO1+upCW9nRLPf~3Z zI@kQEjPx19BOfl0NX?*gKm@GK2@D3T-_OWzE@9&4b}NYB{O*bwEN;JGk^B*QXv`Om z*Y_$o_D>h_jEIgR!uqc--6D^d8DEwDXkP*6f!`zW`-^0$G~0{~{IC6U^uK+t=bi}H zRvM1^p9u*7lmGg?9)Yg7;m`JH{KIl^UlI|qtZ4%`c3g*f<^9@XMPyuF4e0JJHy@$0keVjlv5AAShFaCb|00D zP0U3-lAN*rBFwdA*mvD|O;WiSpkXp&+IBVS*I;)dXHPkJC=w1g5^*oP3EbOza(cWk zLR~q#5^GfxC4Dtzm1HuT^`OE$v5Joq2BNW`hOiTN0HJWuI*>ihYdW z?cTCSLeJN{hKKn}Cd*g64#LS_Y%YAKTYN|xI$_z=tHHT_wj-0RR~OAuU7Q&&9T5F$ zKcL&T^%>Ap{|XeVt9T_{R+?hMv1ozAQ1ZhDbzmF73Z#BN;CEs=OOKRsR+Wc23H-&6 zn$Q-E$Cqs}@}Xiq4P-!87s(G}Tu4&IORxI)gx`XMV1C!@*XOOFj7;tk;>qJ}_aoxA zH`h<+D-y`>P-QGMU8NWIC2Cc7pvY36o)?tlz0o?r8}&Iv^(^g*^yR~BH(!a)Y;w=O zK&_=72nspoNqU3;>`kg${2hwT2W`rbgxvgZZGz|G<(_4q%8DGq>v2?0E{3L37-#Z? z0;+B*MP4o!>`RoO~C?eK~($5p-b>w`ldFINHiab znNZk{MKE&yZJwNOay*e_X%lteiMaXT1u!^WUK7=d1RnF8AG$sfFVegdALTGYllRl| z)$tFL%j_3W#$uqp%ge=8od`YR=?Sb^|9p}z$&`HB`9O$O^4ap6n6#-vd*==B)|+E* zQGp16cdD)tfTyefdod;4^xUF_Wz8h;FxR1XmG<@SNPrB}Izq9DH zx8ykDzQ@^6tshiht`7E1HYWiv>q?Xpf>1* zoTs%iTO9EME+7dzi-!k8&a)0THs`{q-@#6F?eFt6R^90G@2v|uNV9Ugq*&A1u9NXc0M{eFlsg2e4|C*WtYO6T-{W%G_gQ&M zk`PhL%cze47kbRn__dLa&-ERhL|1U~mV^<|h%;H?FCfZ2#aJyDz(TdsmRyc5tLLls zA3G9Nl5dgL^HY;@VKPR29an+uS&R57S308nU79zA?Hm4b}@dbiydDSV%XjcU^-uV_F!Rf{H&c^EmrwMw+Ui8K-chsA1S zNCs3bDPOm{syQ^^L<)#~coz&)xgfxz?%}WHc_?MYx4Yu}mK3vwuS3B=(coQQ1|x>M zXm{pn$!+D=bog6WqWkZ-s_-I=+WpTWysn<^Hj}ToR8A`pk}+s>9}OJFM?XnnB67j& z!U=ib5g4o)O9b)`RUU?#noK3o42jjzD72lTy^DBd9w|rB4OwUKJ?P(W^)UOio`9Tv zxuoon+sU!3zGM`69O6Ta-Q9y{bTEF1x_Ed$^Gk@+0ADel(cxtKVdv`@G%y^tbSM!R z@1#6dQhOqzzC|S;+LSOw?lx#oh{r(6W867r@$)_~?q>KX4RtfyIrV|MddOCm#^)TF z(1r^lqzF8L(eKR1%$C_~yHH8Gevm}1Lvp~o-=!C-Kq(?Cp*Xllp>Z^8^cHg zM+_8s#4nhxa2EO5YdZt)_jb1zOR{OzIV>_Ou0x@4{NsN2R~;}6eMG~fN4^X*g- zsJGiX|DVu0lbB9tr)bUKth+#7g_5dcLC|1Q=b+Kfro5k*)YdhC1IqW|^W~^$|LdZ3 zlDs3muN@Q5#)l`cRcy_#tHje83kyD^78L~BUtx~aJ>7i~vuQlMBUK5mg3r@mQwF0)!ve1Cw~^DM(|G}OVu9+2cxUL{dmOIx zu1XG#QT@3{ZFOCuJeAlCo*X0m9cr;x(dL*Fq}|bh)c3O`e%%voy{P(2ZSG)M-DVfW z%PPhMwj+u;&798&e}QZ>=&&0Jof;0gV0X_70%bDq+>?{@D*_ALsoH`fYDWqPxUIiU^2>6}xQ8Fe@ zJELtzpD`M27opwA@k?r0e$hNYpCC6CW5R@&5YsW>`kw*Yb}b)`wxec3#|E*{_gg#n zg03*WyxMZTG$El&bCufQQxO^nLS0)?iQ6{bR1wpST6S!rECn4SmIeyru$D%iN9~>^ zXv@3~I{z2or-=jdnJ=iDmZv+DjZzWKcNeqt(y2HynQnP3Tn@`GLYw8+54OBhIzn#g zZxR9*+wTiWM@tDnUg?auOSZKfS$OkBYK+ee=wRD2qwzlyqB;dAhp899Zww1I#sihYj+`wms4;Kez))tfzqzM2f@;&J#u=S>{y>O5!|MrJA$!Y1j+ z6pE>shJzo*~Ns*i5dS4;5e~tt0&FAR2`_yZEGNS2~%b8A0 z?ty*f{YCDzxeL+-GA@D@8iqad+oL6nsdxC#?-7>oGq(hG4%ZXbXM#i=T3s% z1*5iMD`7pays=)8iam6$SUHAg?|5M{=07%YVJ1XvFTC<&HpF}6#YpfWhz!C4BkXx;-^y|SBLDU}#uEOaY0vlNF)eui z4P@4YumHYF$a|qkz-n-MaaTNyeZh4^BrYtajaA9yA10}zVk6^><0P$Xx9nS44zN0LC(^YV0$=A?euf1tFWf_jQ`2DrFpj6EJ0rsG&VKNbX1^AS~ z7qHpuK6o6+sMc#tiS@e`K0QFGp6xD;Ntcx?Rid!l^e<`0)U6qRpXWsV>W2}U&vAV? z^oS7`rwVUer4i#zkt+q92?9EQBRGQTJeID}03Z?XJ&^Y#e(zrtPOuAQ@eoS>C^nJu z8g=Fvv9&8EpNwG9--ztpO_;WIG3*yCGW#}Oy3;q7dv~xQfy=y%zxx_fDf{37()0@S zHmIHbDsq?Xd3~YclJV#I@{`ugV!Bn!%1$`NHl4UX7sltp#@jU>QG$&KL!4F`sCS_kC^}!< z31^2pdV3d=;)he7JofouNFc622f$39^gUkdVRSh>5@>{E@$!bo;E}ZlTe}sXp-K@B z;N|l9{-o}Mr9y7Iza^gc+|P<~ZjS;eFm@njYAO54&Z#^1=Zn@ifgXtXo z4IC;>Xt$3&`U5>%A~N9#aCOB+VJ&<=TSVmcnkH)cS=6Ir$_j7$#B@yjbhq@>Ea8tF zsT%-=0@4pc46(8Uj&s^BvLZLuK^|tn$>h5uSkWbRZww-Ee@HY(i)EGN!tMKCFup|d zVOX=xCSUen2^Yd3R~?TdO@{EaCuQ_IMp*~q(_{IrynDZ4DbJ#RnBM>C6>y@WkJ~R_ zka*^+gg<<0cc=n@1N;48O9;=8k z?2-W&%#M7PJ+AiTDrI6$nB}l8#$Ff5<2^0k1X9S*H7z*oVP$R{1(fyy%NQ}o3@Ws_ zuyo?w+}h5Cs({*_C2j%w3S2TPF7Po~Os(TpXPbSlByV;M-$HC|9&L z^`gg>H>33Z*@W*9ADIN81eV(Xy?)R zBcopd3Y?UMvJfcgRirUEcTx;*|8&0lbOnliMEdQXY z*#W};Ky6lnpDDqH@1BCA>qtq`SY!@JY6 zlc4i~=Q;BmUnDyX!Lj~LmrGQEcYg-o;MjmaMG*^iilW$FV%{l|9=EGm2r^2`4qpZoyc`M-j3&VX{n@Gml$wk)~v zi_<^yFKoC2=rI0QY;S@QXp8+t5{&|glbseYndk1|yic!u$6hb_NG;^>7VCx@0iCme z|M>@O?N09$@;#S)m4@oc3Th~8%OK0ngF9T|`i+jEj}JYXj`Kr6;i9bZ1$pqG1?&G> zf#*d4;K%w_LT+2y6}H-X5iQ=UaogKt5c$L?;U}x^im&HmxsS5+Ip0^S^)&xMo1I_4 z=t0_(^wWslkNmqFBfiwK=@#Wv(>D&?os%mnk@1OiNh%bb;Tsg_7-s|Un6kNkdY_N^ zh=DBN%3hG!U{D;b<2rghPzx#l$m4f_t6S9?fKrd&RYwk41S)B+RMUAKr2oz9qOH`zG%Y31@xubPIG@+$5nJ)G-}mniXR3pT z0xFWi@>-2^t&8ilI?qKsV<8y^$4Tzfqh}=Jo9b57HUZ4ZO z1z5M$CldjkSZ*LanA_uC&Ew*tq0C~bqlN_SK=ZIo1ONgg+DfUaaN9=r2ARaL~hkfSA)@{rbbis0ua%W1-(Ih>SM3VKBp| z2Hd$`0L}Xh>$XV%fQ`Wh2Zglmx5siEVPJQsq0;~gxQk4(E3JB`5fL|PLbQXK zC9lx8;y~~DOXUHZ=WX55b~G?ACHn4-@E71p*CDUhwC}il!8)stI^nbIzEEWr+E-H= zlU>BfwK*{I+Y=4YHP#2oySbYwWP2fK0}W0X;27UKhQy$OH7TZ-N4 zRyWp+Ym+%)=!6i>Hb{7P2u0SjAK$lVj`6!elaE}8-0qBawK+A=xqBVhqaWx|PVF+kD*RuWpNl zCKd(>xj?+~^yZuHBahK}MzEvSQ*K>+uKHquH%yCpUPVT(El=jmT0=ro@7tvNs1P2a z@mog|G2;9ISX8tF+MyXou@Ulev#z%cEU~=0Tlkr zUIwsbfUr~OJA$D_pR0!RZZ7MUPutE-yAtJi^a^i6b z+8b+zG(U_^lio2l6lpa1NO3yMdlB({2&sue)&)G~gipC1IB7iQ>s(Ur_m#x%X2U1A z?Z#fjx{N}WLtOW|{(ROB_=QNLd5}S;m_n||`QY!F;@P}p>k(prkRtVbQi%(X0f=f0 z`F1@a5zj9E2JahfYWLFV=g?n6?31f!Y;8rj3%N;4-pHUPZ~6(}$1`#Oii>O^xodaM zVFq*i(}96eN5MI7+~N=0E=%qo&$%p;_S|rqdIUC_4u0Jg)nxs7)<(cCTfQVD6m4!k zzVTySc>^F2$rteYL6c5VE_LL;Ebd%1r=S_(Dya^?N@>y2l2j|Jg%u;_@pcC8gl%cv) zx231B7_gg+&vZ~|ll9f;9r=Tdq~x-YIFhZmZ%}CGsRG6d%44o^63 zv5rQv=_PiGOZvRh^SEjLwY1iPK4?Uug^!76#h2^|v^5yMpUr1FuTE<7{er#Ye_9=? z`S#(Mw~1t^>i6b>r&Y)J*BaEmj??PIt^OnVWlYr0uC(xpWV5TT(<$Qa)@B{;-a3;1 zL<#I!!w{4@&j}~l5GRfyuE2ofx z@9TcyQOH6MAw;Lq%=iQF;E;x0!V=1$$IuZ)OFyoQe;A6_YxJ+eLA_xP6O0^%lO}xF zyug<=+;^}{^!z#<53s58yar5luM||GMdK%BJRBDWK1br+wHq> zL8km-%TCx3>9Rqc7a>-Lu4wD2%E@m3dJh5X*Mf(vBTUZ0%H@rY2PwKzk$&yU$hL2y zT{2y{=M}{w(}3(z5LU9Kq2*@qlVds$O;;u$uNBl2fo#vYRs9f*9+d)DA*oAtK~W}@ zU!ObfP|_Z3B-+2-?ro{Gv* zO0{cK^u60E9Slk#4F-}eOHCjev&5-FM+c@>E*3@IAJ&k#lPRP3%4gB`z@xDkuiT)p z4LBwrSNWVNYS%x77m_UmtPb)w#n6G(E=krG4|_kiI1-|OI+Qdq$Rb|8H`B*nf89ZH zHEZ#^9dpnn{Vwpo77=eq<8vuWsxIF&>vu0bx{NwnbEX-yw0a=-`}3@Z8c_hmYeKkj z+>>fB@#*NB)B`<>YUP3okVi+m;*%YFPt*&X-lgLM@sp-VFq2YxF=B1$X@eUC{N_XBGQ=!}iGqL-DeL&rj9N-EkpRl^DAYNHaL1zBn za&1d|Af28k!uwZ$p04r#N8(PN95@6=#n(#A^@NXR=4||I*@P`W^FVzKv&%cF03G_o`&Yyaqr0_ZI|64aq_&rLD{HZu5 z#-6#ff6ELj;im$NKh?&LC9oF%R3+SbzGGZ}m;%n+z_-Z;*eJliAsYR@P59>-_%nDg z$<7fC)9xf(VhMrYFd`^{R@WQ+`{z~anveh8*!|07Kr7o-`TO)S0soQ-{8@S{Vf9$f zzrTb7{L(-E06>W)4_oe$^v_HDmlpl`F_fnY|FRfJpO@+%T{ln}P570Qnf-ki2H=nX zi(3+6l!l;o!SH99M8xZ|MGGqecwOA%0JiJD6w<(RbLW*y{dqZLG7A2nASqR8%b*(Y z?EmAZ;h-<#(J{x&Wy2a&KD;aNXr(9wy#1?*bMli%eDh3y++q*f-kZ%0UN|50+BUnM z;W8a9N;RQl-~Ux)|Bv7Es*^?xLodA57#kcAOWuPgKA-}Z!66Ei+urAwj8HUR41P*7 z7|(voiNZLaP^24+?DJQa|KCdiC)mH^w}Kny?6+<2_1k8{qeD^{38ej7r(_iv02vyS z4bjlTpeO9SH*D>EzN4C?qqea) zGoHL>xmd7K=lGMZ+2M{=ugNEJlUYlWQCq_Kc%X2V_shiD7Mn`$W0%0N(QH|`vm&$9 zP5jzOe?Q9Sii+k~90~hxFK0fC0qvZ(6|d$@JbQiruNR;bb`Ili!O9DkxKXeakFwE~ zTM_+g@ca@Xlnr9v%SGpTt#MF5wk%+%skU?ZY`)wae%J8_(oR@$BqS6QI>pj}aWd2T z(zj~5RMAAQlgDc!2U5~xh#U5gXVE)hy92e)Qu-;0foYJ*ckU~za+ALOmd}k?2|3Ln zFxI?%OtT2}4uE@<)s&F)B{*3gc5bZRDRB0c4xA3L8I*>rZpE=sCUTw)S{@%e9IkQv z>;r_E|2i%LgY332L7`y;yLecVznfjoGUG<=tFvYH0U-@=Rt$d}K#i>|pMC^5Q8mYY z8@CrxY8U%TGj@v(zJL{GXYdf&9@y;==JW5WpAWw?;wZ1O<8_$6lM8x`ukm8i(f@9A zk$Qo(QjJc?$MIoY-i^=6_kV1@z|dRwA?lw$VOzJxGG{lJC=6^rL009&;OcPvN z%9f=dDH9<&eDHn&>B?555e%+vm_)>cQJ_z2P#ySP>j#u< zLC+jkU5|8DgC^EcE6WWGGIku%?`R=1@;QPt4+7)+=d-VaP;9kAdadogDXh`8bcX;l zgvO`#8lG!WZu@P5lLVLMs~&FhzpSvoC)aW`FZggM?jGq0ITmlhVcSQCN&;B5*gY~L zOqSpv0x5)aET;#$`4rI=4vp$q=_VycL57%tI?j794*B*1WYCxj>j^X;*}tB+pSA2* z>uCLBZJlkOe)=Bt(o5@IB4p5l+ku-eA_f^SyKdw00}dI+Z>V_af)KJqfu2@{3dl#} ze#Gt=`q->Ig5i@<<7W=?GCrB4%G(Vj*$RSb<^-k?)wfg9J&yz-JA-ArW9{$*$i#lI zL9_l~ajEld0cq{w>t0~nA-k?X!vqvofwZ|^_9tkpzOLVY z?}&F*xL&R@_`r!e@k(W?5ITI{J30|PI){DiI)Xdg%}zI9Nxb_-D3a0LETV^babOWI z-2~XMkYTp}6*G*=i`zXiTe%cW)RZX4;`Zg_NvayYw*%%psy1q6-G#S}j5ZA}0!BuNYK#M$}~;kMvsz~Xv<6_fH+i`J%HqrnPv6UlRx z7Uj_{=oC@D&Ozb4oHmPhLvc(R02`B$ zw`}Kro7Dxq|Bl+_te|#bNkP>m%Rww^*_b(c%y2U7qHH6I4iHiw5H2XQsNJ-9Nwj)6 z(l;s3pph)F>ycw)62)l1mEN+LJ;kZeHP?LbuLJl$UYOnGvj&m3-5#@9>e<$3$tMbiD|5 zP*yt6G&7l*g98T>PtnN!{YDkaFKU~H&8`v6(!xh=XFWULl`Z--c7WPIT1mFRBoXQ$ zc6Y2Cxrqcana)*yfug`+{(EB3n?n!#nUS6rglOU5TVtjk&&RhE&B&p{4L5Gu|Ncxm z9t}zLZRIce%g_9DUCw3{WZhd=SZD{vv0KCVVWN&WmuQ1vrg9H%Lku+I2CkP`_%w8r zGuD;-XfxkMcc9$6==O<^`^>1=i(F2()NjQ0JR9O!`k!>tJW@WeR9h8#1rc@ zx$k{t6OLVvfRb^X_tQKdty)Xa6TD$s)Xx~E4s3GZK4<^&@NA|5mw0SAvL{nLjG7)N z2OE!W8J3>#Lbp}Y2P-p8EItM9MJ(rlxA9WB38%a!UA}YGkMIB_$_J+{6z=iQ+Q}k> zGDYQ5u<+@>(4*Hz*<%-H5C(M>Rk*~iNC}IRG7=Q#!o!m+zak;xQEnPlO7gyL&qU19 z@R}{bLATNJ2oe31F_OqHfL3VcPf8AaRnbZsKi)Hvz93ZX5IlQ%ZtP*JH|qy`jxuzj5z z>RX+47(sg`Ve$?_jyUI5n1Bvy*)-1LddNxEW#;{k536b zxKmKCi*>ROjT<=QeXB2ULjtKRB>ft(apkrpq>esGwbGI3@JjWQ`lW;Jds33b!jV5F ztvD+u*hf`VcN)cnX} z&A#B-n`SBUsYmf?dj~ImC9b3AI_W1s*)Ee=zN9YOecK4qb?q2Msh6Vw5_ceth5Dnq zYCeXdgc75aFYu=eRhv~c6H}zt;FZ`+>NF1(obR!7qbX7?n3CkN2B#ks#8bxjo2;aj zI~l!0=sYlM^m!j&rD-17UO$VdV>3vzdFtMAU^zmsur~k%b1`T6ODz*1D?|!@$0dbDU~fTL!DZ+CjN! zlQ66jK&u!MEaqiTnkjbm(3yH1$GB+W2$2Bh+lD3vF4_T-ZCp%NTmMA|TnvKcZy`ZJ z{bh)%YDro`lB|gVa44Y1iQy4^8~DtQVa{Dj`Pul~FL%Ak{ZllRW=X_gSc2Umw8WEC z205zWu5^iE97a^_H6_E1aH;07d{NN;6(-#2dl z?tV2Bi4HZ)7^1XJPtPb5+aQ+@efa`&572q%e)XxNV-RYw!&0FcPs%#Qh%u+Djnh@uVqz+~1L{L+rT+Z*NtV3{v=CHYc zcLHQsZ41W+DDeImkx5g$0NJy~6OtRvOTQ0Y)ClruDWQ6KY>AZT;K#fKQK7I4{H}$? zIj|#LqBiCySEto)9`XGYUmXhSx1x-=h#IY`b5xX9RhY>jhJyq8{&qbHYP4{GNYGy4 z6&O6f{@!cK0x>qM`W9_dv~QmlkRLLJ>H)bIH;C_BK^gg+lePF-gtJ_Ol9!{QdO*^I-V;iVvW0{mFEbf!Z#fo;K33LI zy+h~O!QtFVLRt(bu(2H+EEaTuaS>8}6o% zQl(Pt6@rmXAFA2SXC`nxYZ5y~9Sar(3Ei_l>{|#qVN>o0Tj#EXmDW@^m%n7m^T+K` zOU{&;3s+26=6pBX(@1(5>|N8EA;OjO#Zm|oR3w^67Rxwo325G3Xp+#@M5 zXn|-PXm0TUbfR2xDc-@yqsMpNbjwq!Y-;%WN=QhmHrm^4aA4fDt1z;_U?ST}r9nbO zwIHK6u0X9z8UnCLu);dUjBk`vYng~_I5W9LTRDnEzgCzah4edunZDF6o+NgFw=f$7m<81R6_M^lCvLA<^EI350`WT&*oflGT=&om} zY1gQX;1!>CKqox~WH`_cXz?`jKiIFod_P2bnG$|-j^-d#Rhp_SY8+y(e}H56HE}M3 z;wt)2OhLv0qH5@B7e}Xss&UT#97^iM3n@8&B{s0Iys!WwhX}m6L>O)ir-w;bmuT@? zP&4KNAB@hFh0$(>1F7B-*4$cEz|v8{{>GG%G3xq<|* z^PJ7+^nd0Nj^L9lNHqtKE0IIm*P4YW+Qhut&jPoQMzHz0F$99P5PAG<&w*CVjCVj5 zI)OeW9<41lZfL#EUfXvYy6PoqmC^{4Wi8IFKp=;s^JiE_K}{CU2?;x9pCe2ou`8}H zEuFcj%R=7?KXH6Ws8D++;6i``0#J}N^seVrT6~2v-!#v%Xd@Co{3WGwAsG_dxp-LW z3nIAw^Urpc#PKU-A!bBK))JNu`fm$tnEQL{d3lDRw+i^BN|4JX0l_222SZ{)SzVCF z4Fv^3-|#I=fhvv%vRD_xdZ;Q!&jM<=`(r6pCOgAt+7ucG_JbW`yP5!Fmq zX(<0b2}c$;h9zrO*#Y<$A>a~MuZ<=b_HvIpF-$Z)-Z~6yc9d8tZ-&ZOqJh<@F2&_O zur)E*t_;$O1)WKzOo|HeIK^~BN88#`+ih>umXO{^3Rbm{^<8U(hvLK2OC5vIhrF}nIyd;Ufnv6AWlFD zf~_>r`TpIsj_y>FqFly-Repj3s{_A(1d0-RMA=0VA^PLzyqm&XcRkSZ**RsaDYw>9 z0(hR?ga!o^fQJmiD=oVx=tbkWH8Q%RkH5DsDcIGLOvY+@`%BI8&vlP8G#m~%#y z9P=s#AqlA0DMJdTBnvaWGG7|^t;F#d$Ct>=x{ErL*oYR*oWN;Bnf zMFme8xXDQt>xL{A5+Eih+=lWACa)eKCz;j`T2h_Y>lgOuhJQ zk-$%~mf{M0E+Zo)Kj0AOfB-V-DKudl>TP+!031lbly2LyTB~H;Tb60nBhtkDbP_Xep70ZIHcv^+x%h&dyUWtNg|$ z3={1@s)r|5;F19a#L}((%Yb_}f^jf`LL!7fs@d|}MoWB`nRwu^nDlAj^*NTT>~N8D zXdnsCoAfmbW19ZIY0)HwP{^xVQ9AD^oEdgW?wVhe9}z^5#4<-Q#JX6)^ZTzc$LPkS zBlBnbrTH{S)2}C1*EXsmwT#}75N~0GHSq&qSyFTAUlqNL%(yzuE2<_uCm z;L9D83VGvSf=6sX*jIr&gmH0GhL80`Tim9ux z;)r3OvtHDaEs*VB(K+=W(YXvnm`dt%-!D`n5w*v74hK#!aZEW)p(t-AZ4Eu?nyL3I zIE>%Rb=@i=?>UoAiv}fmN|?^3Fo0$wp;~l;z)V$k7GXy`E0M}r4L&IvjJFun7}IvJ zFf4R5jBmKo%c997`9T?3M-*wy6-*rBT)NnBlcB{kD6}OIjh7@2vhK*cCY%Tg3c^rM zkxB_Fl(}yPTUkQu=xT7(-~M6sZ4+4;VS|bHQxQu zIb25k3WJa?(c{I!szC5n^5yV&$U5Lv)EjoCUSKI^&PRGGC~_CS*R>hA0%~jLPJ>Tp z#PZVk4EybK=rfe-)Q4XDu!lF=44=p-^ipA7)kU%6-wvd35yyTfw@9t^=IRN2jGE>+ z^*!1HADrS?7)u4utHpT`DERY4pe*_|#op+0GdZeaTiLrHM<1%o6c=D|hD!o0y3dH_ zjA3lsEc)kWLFx2y!YqRs(j3F`b0{lg6#W=z_G1LXm);dyY;-zU+Mic_>a|Q)S-GL& zAS}Zv(wp7P?lxIsc_V2UNY^-IoS$@8J`OW8^7mUkiFcu~*`b~94|G>_A~2b1m0RYC zWgxPbo5v~W<-COSeTOC==w!dTso4d!v?-OWR>F z#oxZ*L7?yd{GBk!JyLO1zR@bS5v%`q&fJa!N~T_Kv@>n%i^9I-B`)S$Wn^JY#+uj_ zBTqavgLrGfVNFT&n+gdM&v)*K1RCjk2W0pp7pP!b00t+xG7Q8(q5am1c-=vG80so6 zA}S&T!JmTlvpf$@oHw~s{+(Q7mAkljQA>QB&DXajT_PtM#64-ur$F_X6}d~2jsP^r zucJ7s0b`W0Mo}$B4+uCBoeBr-ikv2?LL=l&Je>5_vR{#zv%0Fcc3-H1N6nM*` zwqF90a0ZnW3V%&H%SO2MGiFlGt8ZG2|5)+1JZbcw{KOr*YFw}$hZlX?N%D@znk3uX z5nIpa)}fh}XzEMWoD^Fw2HIYij^#uRp_-;DYc9QQ=4jjpwVX^vu8@n8U=u{;X#0e< zAFEk$(FVM=yiylUZW8ytZL|8&A)pnJr^j79JVuF7@`vj_&Q5W$Pcz4?ot`g_Uh*YT z@o2bebO>TFtjBS6C~?4smuZss+Uu(HIeO1}u?l>hqF?BCdYhKW`sWMHcqmoq2(RsV zMBKiXadln(UB+K(_-}hD7#WD)8i7&GjSbSWnSYRiC3|346~^sHNc^?|Gv#kG+7^bF z{fec?fu3VAJ&8NvQ(RV;+mCAMS#sg%B=l-L{a`o~0h4tCFK`kFE+J7al~j%z@K+Ea71SG&;isvw-( zU0I1~Se7=EHm0D!=ncwMQOn8Gjj<;@Qkhd6298Ud{Vg>$72quAg>0%=XdJ0>h%F;k$ zywP2EY^(F-#iZ19(b%xmuzIvjMI{%lk8avzXxl21O?>XAa=oai#hgb$S#2r~hkB&B zfas2#OxD9%~4J@1_icv&>t$85IrcFo^|I^|ev0xw+`$ zMIWdF$-x!VaG|r*Hyl#Yp8DQ{DmHF_llJ^!MUUKFGb|}ew-UPIgtAq@ogu;dIut%aK5Q$OraF+nsBKhNM7ef|>{iVR(DfNl8 zW~SHHTTz8u=oPB`)yqAF3zm1|R@@GTN>@B-8XxAmJL)V>XrA3vofAsYD~mG{z_N}J z9-3MB35?~#t$Qm^XFZoMP?fjx4n?}H>mY6HMI$qJL#fA53wWk96aD(QNKz5Pv4^@&BB74!}D7zj$MfAUS{J22$ zdkDqyVfCZ)!6aF;x2sU=WheIe?Ty&^;2f;;!@2(aOQK(acdn^-PV0?Q~Ovi}c zOazZfa_@D_i0Fu<{60B))RJf}sj;|>w~p`DOpCe#jo+MSdD_qu`G(K2)Vga?6NUszt(6lVJ==Pi0@NtC zl@<=@EQCT~JU<9z0-ICA+zOBK8v*iLE*YP;;8=(x)N_)O(L#m-B%kaDe@dn8=YuhJ z7ni0Yif4f!(bGLZW@kHCzJVP&n%1VS7N0BPz9aL24)mq4w4P0s2c|upo@YFOk-Cig z_3u`+PLeT{YO|P6DjZH)c4NoG0EmPXj?eZQwIyuii+YZ4YT^5&AEnC-71(SKvYaRj z-MtwDru8biqAC0S?LTmV>@g6k6(em&bO|@B zILk=Kqd3bxjC)xDeqxRKfa)P{8k7|=!T_cScqzuKIK`LFUGMhlGluH|w^I_asfF)K zJHH2f6U=Ut`}@~={LRtBB(uUJhuT2c(U-7rV<|Nu-WB76Svl9Yv8SRL zugob9boc^ekXo2?z)`n=1CFaljl5{gRdPLAiC!$$0&SlTBg>eKd2Mi~8EII$w3gp7 zd=8@l#XBryL1@8G)6hTlzSM%HfW|`9?_<=@UXQS}&&`w%UF;su4I^QEve7fYR5|l^ z=zOFyIMhT)+u=h%>6Z<$k}um+OhlaQ$LQG+^K6={vE&qZ>P9f5CjRDp?=WBc9`7fa z_ST~L^s(S+ajZV#xnLe5{u)2xq?)p;D|$M~P7N@+_)!ln=&*0=s-Q7RG~#P%T+b#& z>69dLjCh37N07HXW5NuIljYC~u2JQp8gGTYxi7Q+IuX)|WUuAA&9;7=L}HMF1=@j_ z_uwfbZVbAI?=oCuh+jP#5j<#$-V?~6th6A<m4Tr0^_zMyV)AmH z)YoVsQ(U#twm_w^p9^1P0fHqsnoLN&i52_TKbW^AE>b5s=7*yXNNL85FFRzu!Z(eJ z{QhcRfT}&o+u#ZR+snMPCLZk&Na66s*Ot>DV|xu^{nRP`g@93h{3|Z2DIEDBY9g2d zm@avu^0TA&(w=5X1KP|Ox7+M3SZL;jlyQ}INVBH>g*a$AFj+AhGrQ!E*iFK!^{e6k@)$AAT z9PDAVtujG31Yx*i_=FH@ZQgdEFvx4#>+mUedcgxD3hCb!RBO^x70pX@hoel2&&~cY4(P;t~1l9sH}%^sYYm( z6iA8G%e$5~tlX{$$HHX`VVyyp7RDpWhp4E~xP$ z1VRf#h@TC=4E{n*&$B-)M90HLZulUyt)Ve2uoXtrRn&GIY6JDWX4r zDw!YG<)ba{t*8#%o*hn>#l*{cQx~2xLLw&MvOpO-Tu0eznOTN?#gfik_np#%dryf{pq5Y&IdB{U_t?D!QNHDjxvzV8_+;Bumw0()O(`{r`| zBGYXf5d7C!A7LMIhT--pg5|#a^3EP^vyTV#8GEcc&5oo$^%}EMDzv0DE0+qM84G~T z%YcoN%NN)cldRX=_c_TQ z6hG+5>)MlglK;7?8q1}=+cGM zYWm2Q+k7)CHd7Jxg6WZL+2mjwl#frJDMdY$!FAukAthuzD2z`{X6jP8vU?{!vactW z8vCL6lai3)$bo@WXgzCj@PwqQx)oWlv(wKAXpH)d+!X1;JGJp5k=C+`GGT5!)&8V3 z>eB0=>$2zhH-EMb1{wc9+a{IzWhG&b2zOMx*INn605L_CPYp&-r=m>5((&l_0l#J8 zwXG&=Yr-PVI2n5gl^i(69Piz8Aicm?3JX(%`IjU#^{JqD9s0;TC}yQJ%Hj5qSL`~X z-RVa(S-3O^I)>e?4Q{we(Nnn|1~;AVlq&vB3EjN4&A{H*1_^@ zf6Uo%PK^;md?v?D#rd4T~OGECY;gYuEw4pgl)BbX7Kb_-@$h$IC8v=@)h%rw`k zwZP|Zz-0^l@|i@&z5MID^9I6Cow`mrcbI3w)3e(~A>|8MPh~*3P{YhvC>#M#-KUU$ zy>7Gn#vbmOA;MQwoT%eG*kS4{Y2L&|qWS4r0@>Jx zp$(=Gwbb#NlRz`OYy^)Zc2W&sh6T}lZ9+Y3Iwe>0(Na|$9r`Y{7+v3GWx>USWIz6p z>L-iw>aVq05arRNNZ7cmbJ4sSvK~f#ftV zHrl?5C~+Lb`hzwqj>GhE9T(kE1IGwPKP6m7 zY)MX8!qQ(><|B9Q6$yN`UG3(IB*dRqAQyRqCm#nR4$#o5@es8qw@xW`twGStk245=e8*l^)J(KgJvfd*>5$>r-Ff zSEaJqKNuml>TxfWO(7Wbsq<^R06XwZ0=fuWQ5XV6W8OLp6#=Z7uF zW}j6D58^K7-Hy1(*Q{hIT}B_W=4nH7vVU>s#(c>YBQSP_Ori4KqqR0)U47MVbi+5DA__z~u@_kH_=3>H z4VNK_B|qa;(92D@SpKxRBv+u>oX!PjCDu^Qm?F4Ttqff_6v!qg&`7c~3P=X!?UiL* z5u*2(5>rOVl(0ju3U>>B-Np^b6HV7fnMZGn?O8-61puI7G%&Yny|_fh{9V1AmwnM& z05Xg~mpRd38c`@M50ICw=^HbNZKNXL-Y-~DS5KhNp89%5H(JdSxuZSCJ6i)`QXqdL z9Wx;BI==%TfX;Sj%YmSNBPiOrk80{kQda3rrgAT-bQIkHIvXf$^g*~i8+Kxq+Fs9@k{yH268a`F zj~Q)cOALUxlG9@`@M~62k|z`45U+Rszg!SZwg)GkV%zn%-sLt;(oj{W9XQS~QDkrYy>!N2*j|V8nv4L>C8Z zi+nf>ODM@O4T#v7yv)MLf>(pcKE{D$7G?seVCEHnulU@@0dB2X^rMcfNjS#EnpT|a zD*VcHwkp#7yatpK-;g+HDXp)7w(ACD9*YzmR$LWk84(_lf6ZHa`cRBd#{P1;>agIE zXuhxTaG}i*EBjYlQYGoq;pVAo=1zJxP;@rKJKI0Nc$oJ&HrpGLlKyV=s~;v-lIulF z;EE^F#bYm#;zMI)D=4o(eYUjoLxSc&UUo7V%jvqKA281+TP5YLD@c=6Pi>mH zs?TmX9X3wQ!y|*DA_kO)5`dhOGE_kAyex5uUOru7OCM4_c5C>|c0+;-QLz-37H&gI z5`&Ba5;>WPt#Q>p#laCk@A%fV(c_`s(-XC?ol~4g7-|ks%9AWsdtD#^25jfE`2Vot zaLAOygHSB+1cVqgjb8N(viAaQ+st!u2Z0I)WAXxj3Z}w38hYGKb7k}QSUr&&)hgS_ zJOjtl@=C95E!p^@N&aq33S@?EL~%iy-ZzXq{E{Kf$r~j@9A60T-l--jlx$1$iHibX zK5|oul+kl=rB2`19RIhMD@YIAoU903lh%0hCHm?GIjCqrr<2_W0F{$BqxPi)WKjk} z?B%3FaLDar%AJl9fDQ^K{P3!e=};wIEmxwk@y{BE=q*{HBxF$)*>BP1$DK#|vJ(hX z<2A^E8%}vA-Sd3TGP9Dj{7|!?)v=KD!e0xGRHVH_gjhN61Oi>zG8l&F(RU?!Zklkg z@!5{(H*OlJpOf(uO7OKRd1ubX+zzL%L18_6s-r5Fo`B?)3OUnA)62qI{49#eSbJgW zVDDoa%5mrdF|R3M*+U`i@WKj^b^<5Z2B{D4!Y1Q4Yc>pLrAhtI1RCO!@q)LYe>0l$wEoG$$Xhjkwp7xSZ+ z?@n-N!nqpZ81Ns@U6v}0T|#q_=c5q6=4svMji%ie_A|@Y^6)lAvLb)gR3t zRY!*&E3aaay%>5=bO0*~Ac+MOal|kMlDW`X=chh@`eu5NFf25vC@YCH#u^3c0oAU^ z7MJ$O7ig$K$H9@Q+FGXEa}sNnc4izbx!g&c(T7q~!P{eoeT5)efKJ?!XxJ;uH+D(br4W1m;f_GiY$*eDc&^2A(m zZ?X0dZ80SLqo(Zj<9mEN{m2}NSf1yk2v3TMGH!XXuZ}3weO{RsV2h*!ZOdeu$CR{o z?o9Gln_;#(o1(NjJjP|t=<`Z9jO>?Mm%2`D6fSJvcw2AJ*+y>9-tswHZaAmM?SD>U|CeFIDYGTMN*!F8fw{(1kjNaLjyl^Tm#7xZdQZqluMDfeMLLh{S^EnATXQ&i5EZ(F|`iiu|~ zw=9x*AgJMtb#lOh7p)+DMiCPc`>4AH|A)7?j>>xb{(V6t1Svtfk?s!Zhfqoo>6Vu6 zMjE8MM7pF)`T?Xvx?38QR9fP!NB7>p{r&y!z2l5K#yS5w)MtI>T5GN~=bH2VQk5;) zme1S9w9U32G#e{wBHHc3s9;D2KET+6@PYyAYyC5j)0KXVwko66^*=x0^ti(+#qVjYE#<3q+TZkIkb)rw&>hvJ-L z9Z*kQx|#rlnZZE4cw#rViP(!Y;nL{$ku^QzRYPdIn}xj10&nevN#|Np>R3|6o7KJ) ztS=;u=hN|xk13#81Za?V^2V^ib%L%abEKx=x?&N@R^MmZ_W*dMPfH`WD@pU&@q_-C zwMSxmy(r%#$}*%l>tibE!@_u#-@Nq4C674G{*m6yDeIZKI5TBkQTnL*@%by2$@o$! zB;qaAIANY}65i$zbTH{2GSjTLy^ZOb@{d14U^D)9f9e}}>?@JF0I~|N5yxmF_mp2e zH)TZMSN?Xa81Vl9!7?d)W?@qxq-bx7I;Dy`+66DX;q(Cuv?U*5=F(^NzW4oFQTeq5 z<`2w+LKbrv(}2JniI(5}=x1L;buiNmu&kfwZI9^3H4^`jYf^C$44<9z5X=FkuN z5&AX>8}nfe3540c4nVO_Oe7R&3dB#iQZ+vLAsq36ACg4bCh2VbHgz3d8H>QB%Kp3J zdEH+@p03;Ixfn%yLpELcsn|37oNfut2M-b`$hI!h4{$T}X`FBBjqV_0}^< zA^XPkssMoBa1hSYg28mSw;Ww_9H_#1j+~?r`y9VeLntgNGWUo+er>Ut7r+5y z3@WLZAhf&1EPeJ|CI&3lAD(7pEH(8Ft@6~EU*@fHSF7_VkS}MRRlI)zdk&NVF(3#z zl{4481g6i9-PZxx5##r|ND$t!xZEfuRQw1rW3pF6$KoAHz=%d7GPVmGYm(cb6-2Zk_ss3IBJlb#N)+B$s2@-suLN6gXz5t1y zcq9{K(NA_*JCOd6LC}D_V255{k(p*pT(LRvOBIL1Q%8C3xpjGmVhi9tYmI?O2gN-% zYH=Z)zQTJ)b2C4-lK#3;SA88-={4~|l;ou#d{WTH-CNi=^Sqxi4zvs*ZD_YwB9}ev zd{TK+_OxOQC|BE)_;JGMZ6C#+bb@1NVBKgs{4!j9pnCZxWGr=?t?B180}W)l zv=-67bF*0z)WoQ~5}pt#YBcov$|8c)ET-`_EH*0Rr!GM^Zw$bu-RD+QcW-RB+u#H5=7}_hPVkF!eVWO;r9AWiES!Jyb>bZ#= ziGCFEkdj&%_ev9PsR%(=e?cZ~-kU*Ou z2elSBOE7C-VKY!u~q?}7GOlg!hX z{d)5uFOd}UCqHx1ThEfn60)l@f0yIv*Cca!$fwy|7o3e({PXpsTUGKIN$udzd_gwp zNKDV&1()S^4-I`={0$smrNB^p@8+?kgRZ)@lqHFdjZ&_qa0l~)A|Gz+XKaikgI}}F zMA~`Ik>OVufH@ECjNTeL<@WO0?o4K#<}=Qi6(;5 zt>zS*lHGLiH1!g}0zFSmmCWkEQn7l&3TRMFRd`Nx+Rxd-*bcXQ^cLgyb{mar=7p`o1t0YugH|b2n^={3 zN)nxDnEMy>q$HwLd>^Ja<26k^u|6ma)bWsg}QYr0SFZ)Te*1bi>{`;MNC^tGl{KDz!i zt=ZeGO0F3N^PywgUpaL#duc@fhxPL<^E-a+Zi8JSMkdiQG;L`eM(c}gk9|)oeL(3Z zanZa|ZzLO?f*buah5WrmPFW`6uY$?Nu?ep@bTAl3jf7Up6&(XZawd&aEr{;j|AA~C z0m|WsO(SyRiMJaCD!qtU2!xgR8@joD#MtI*JXn{!Zz({gJHj-IfFhT!0HZV!x)16% zqS-uG((@4hMe$Z9<8b=k`Tn~HNsr{=I4amkyagsVcg9`LqwI$OpIT4 z2q=em5^-9$O%_6{YYx|XOkeCVnX5>LdKSmzFpE- zWjrL0Dt9v>mDdba75DLI0wvT!r|k_WoNzvuFB)zX2JKd)s6_LzrgJ-ySc*|J(;F6S zV-!i6=ehD7Hh44zwf7uep%+Yku33C?{$BFf#MxMu?WEE=Z;IiJhUjdM;L}5>(G!ws z5Yih4@Q2mqhi;eqmTIbkZb3#-h}Ec=yIX|nEaB>n+lb$@#)l^MyEGko2!Ttqp0n64 zLEiQe?2>uD^v9Z8$OeXebb5RF9#JP>-8&sawx2MHyekb7Ha0`aC`s^}xV(JBygY4ra8_CIE!`ic=#|wDD~@&oS))fSN?3Xk9NNza0`W0=K1tK%4caGycF>+j zRDsf7;yiPYCh~CdC~HW?8H;F66#P~9~J)o_U>`O5y4>eZc!`InlLZFOB9mok^ODm*W~im1B$xiJ%4zbCWRC@2%rkWuyW)`PiY7?CF7G`hHBqiJ zw&=a61}-m9w~C~};?PNkb9Q4+&QeE0Bn}Q7}PR9BLSKW>whmT@%xjXR=>9Vf%|xbUHI% zN*eB1B3$OFiAPJ>%;LVG{*(YB@!!q%k3a6XGnCo%$;Tn>>!KcC&3PBA!mq%OCf3);-mH?>MX4&Ex@P{u2 zwh&eQ0A~oMX@Tz%!jY!-GBBX%e;Dvj2S@d$6P?QIDEWpU25cx47mGCnKNMPuDbS2* zA7Dt3)FLauk}9pEMb=GM@ba}+3rT&UUp8La%V7XSQa;Q2?ujaiK-pmx|6J_!Y}80$ z_(|aePsU3G;cYCk(yA)X`!92|k#kl>+PT$D8h5$t^m)+tHKjpm#(^_1VdAj~+nmvc ze0+B2)gRklnJuOmzi=Lgr72-N41|uB&fFnf3zt4JE&jZu2wBcTTxBc&hVnHnz968r zz1Qu{@bTOY+^UAqO%>ZqQ2`Bv64?2*UkS2s?&^H_2qz~cRh`JI1;n~o$dibU01etf zsvHKYY3aVpta_u|o3-2as%~Cz9Qm<%x>F7?E_008{~)wqQ1)_>BBwe2Ii=^M}i?% z43{j9QRdk;eQQ>|xjeqyF+5v*51YTunh7~;E*bkEVz8ch*JeWh-pV`g-p1!Ul<6P# z9&z^08PB#M6)gH8^mIT5N1s-6n)#Z;QFy@Tz%zQQD@HL_C(pRgLZWl?l9-?GlDUZU z3!M3BJ{n)&x2e7Pc8I_&2D*(t#EB6;$EZ%zRjJC6cLwpQ{+WLtelSOMo#bDu8CX1H zX5u#s6Lg^}0W8bT2PsVcj=YcZaL&42IBT&!g=>{{E6*9s7k<}(GBQiFVY&iI_BP3^f3q=mxJ)- zEqH=J6?)71^qW=a$hb7EPwPDD2PnG`=3(V5{mkS$w~^YDo6Q}OK>1z7*LTZQd~cRo|2nS2|}e zt8=`dG3{KKXMdGE;Wc%Vtd4?W1AETFJrJ@nGdWSiNCE}DN-$8qou8M+W*$*B) zkT`XD7se6W`6mC%{laACi6&|B8>rthYO1$R$Tx6PT;4aKc6{hzI0eqt;cKste;k2= zTWCA;g9iefd&KSt6hbM09W)R}f8eQJ;i}R%>RrWJSCyCCEPir7ZrdKx9Q3UBnUG9& z&gYVb1F+E{B6}t^vwg<)^qF+jA1*Inf~IZ% zmu`Kf4(Jsz4-Vt<%zeqk`Rf(@oGV%D-qjU0iWdoR{&ECXkVMPk*&bbR7YLd&WBhOxcyoI4^KlR0tVDjUNPc&Ot3COTG2!3SrPISMxc02I0E)Sl?L?O^v^myD&p*Lng7zoS1AWp;Z43-Jn1n z&({m-rz!zG9H`tUQOv=76ffWsO!+^(w8k6U;0`l=pWY)IBv6w=G8G`S7dPq2J?AjU zz^lkjOGUNVa9)B#_LaU{kh3piB7j87nGD>XnAV5%IB1zbxzWIO|1&e6R?vx&mGy`W zYai=oTTOSp44uVE}Yg>2tc%670zxOfF~^)g@6Ry*UMu;;){ zUjNOvv8e1>+u4V>vFjZWY%k(YTOBW|V#YgW7Dnsr^e79b zyndwH3)&?vcStpjPm?H%u-6bt{q!jB*x!ZWPDJhQ`!|m6=R-|$ibDB4jlSd-K+xNIR*sZUOxda6CqFs8 z_~z2#c`@nto-}=k@)?LuwL)buJ>2qYaY(YwwZm4r@{^UkEJQJzvp`cVkH#7QtgHvm zy@{gNTGdAcT!70)QS~}S{u|0M<#a0Lo=Lnvwx~Yq@3mlS4p|J?k13=S>S2_+e^NIP zY@eHukx-bJ2t ztI(ix{ADAow|4tuycQaCnyipi9_^N&UB3p?R&+6bO}1O%?`!}`baLh2pcBweWAc-aIx;%V0JLxrLpbl~Bdz8xCr* z7=4CQR2N!L#>!x%K)x@PybH`8K>wnm1ox4#E#%`$A6dvE5oU8&@=0#jJV%0{8*P4M z$_z^C!{R(OjHy3;I5~M?s|gysl8P3DIEO??pGT6>RE3G?cZlc9@4K$zhApc~Vpvf5 ziRJ_#O(!n6%6BNj;dlcls`Gry)w+u8*rK*ZDhXsX9OK6gRTY0|r#|Gtnl~2@l zKbBF$xK(T8gB!n?I;@gE5E2p4hTVV~9ZY%Kce`x+1sVdiIGrZ3aF1$Um`~`x*@Vmd zv?*N~nI!hI4T}9AUk{WVE+1hlmN77_p!e_^X}(H_MA_S*g0}gpNFQ>IU~f>d%PACy zY)?AY9DtOx>^If!Fo*Jt^`z1dRZdz!fDuV~!1rSUuayn;OXML6ZEP4ETvR_2CS>7H zGNU6ZbPq!Lggolb4fu@~Ys zOP-|g+usba=Byic5lB)BpjWv?2T{2f+34FeWI)*{?r+f1$cl@<-x{YUG5_;nKt*cR z?}5QzelX8Ja#V^dodVx2wU?h0P(YvY7n>;f!+i1BA;Pb&R*)Vg1fZjF;N3XX&p3Ci zv+fzjC6%Hwh&(wVm_sp}VhYo-SkudhV5w}INY|MV;Ii+5oEj?j+Ewu63ql<>p{#vFS=N{d#C2gBZ0pAirQxng zC8Vp>s-3M)cEXbxF z$a}Q3ppc|7l2!5GgK&Id)9ld&F~sTEHHfspoP!7Vy(>I7FUG>qZ?9MldP;4x6iN{>w=Fe$)#s^J25j*cUQx?NF zS{q9S*t{hxiW<5Iz{`fCKr$#oY&Y{x6}@PN{)bc1>40>eydxU2=Rd`$exnbJ5wZ0E zlct)|7s+n`$%BZ8=;7Djz+0A(%!;1hGGi%8_v}A^2yfSg4TAR~WBk=ra18b%Yz~sK zQR$t9d!*o~{f~GRCSL}N*#G~kipk6T)64+Es()#T849BQ9Txvf^$GSf6Uu+L=>Ojl zNaL1qbGvhWo8#OZ%`m7HuD;?Pon$3a#EfuxQ-F2*jg~cWCHjN+JH6H$)7;bf_s3|w zV=`~AN~%k94LsdL_VZcIJTKXVgdDF(BEjQ_=5*paKyd;Ze##z-AFEryU;6lu2=NqW za8$Y&tiDOxRWBFl^D@jlc)}dzJ4j=4#xxoJCXi24U=r*eEGM~?0{v-5Qa@qc_4QM-aTTM#t z8Z5+DCwxZ)%~0&}!oL%=4`BSUUV5xQBWnjrbHzZn^)DG=pf}6ZfMV?VIN>Zt(W{o` zxh7dC7#8~}EIqg!7~+4cvioCbX7{~qTkc!$Gu!#vLyN0TTc7P!g2?omD4*l+n7hl+ z!`;KX>xeVbw;3-zBb<}XfcRzSNGttdYqM*#&#$q}k6t^>u8pX9`0yMxcIVG;kITdY}Y8mIBakhnr`-ve16*)jWIZWi&HQLqMV8w3OEL}Q# z!s;DN(w2zFOc;8;urj#fUwKH##~P>#xEd89bj5E z{~QP3Ivexuh{OBWlCb;!RfPWD@|KT*XB8A+W{ucXh2Pkl0@+?qliBS-b=%QEhMFCq z%}a(}U;S+vrs4)t->1 zAb{WJD&RAN6B4bW?EXUV=e1NLMjb=R0d>@AsnA)XWxe^xEgi#j+TQXoidEqEP)j5| zuiavu@@nCv5&f39;nuH$%K({HbQcrs>Lyp={M@8W$ZRor7F1Fh2@k0Ld+p$tFJ{9e zJBhfR5vQVbpW&A;=L4DbLl>>DzU`N@uGb_m)ls8u+l0us{1Wpbiux^-$)8jGsA~*v zL|jw(PNI~xhBU5z>fb5CRK%mOv0MSpxF_zZtF6!JFDj7_gFEW5_ys5bG(MKrm` zH1w_QSH5A*8f`%vVdHW(htq164~c&K!`M5Dm}Pdt>PXeC%9 zRu$7#$;D(#4JOE-(ov7MmR$`WT^Srx=zQGwY?gfzVY=)eb0~E*Rb<#gkyweQ=S6_7 zE>-gB-ct=;MWDyN&iWIHNZVkp`1F;A8a46EEpP3Z@1pAw!vIrxL2ddYLA#w$D=W(d zH-tzj?nyfm?bij@`!7hJ?y|~2h$DrrdH3*pC3AHwTRsxa^Cy!wWA+7$5ILLg`2k@* zC0SF-Q*xm&J;0bdzg%InVynYn2;c8Ma~LB!(*oMzP92m_zG^XJVcdOsU(wJ_bzKfb z`I7ym0VdFR@?MhBT-Qg(zN8q2w})R>*B5`CAo=i>6YdqUsLYWKBBPVbxzkL&)FI?D zY^n{Sy{g^NqBFtmv*d7C#0`5fT+oUj(`Tvra&FL@l@VMMQecf2*ol8AP=0}s+&>g3 z$v28<9{MZ)P@v`l-v6OMtv=iJWVsPPBvANGfr55w33zZH7dk|It^H356q(Y0P@o(m z{!pN7fBqK*$^jIa{l8G4Y#D%6lG`ewUPh%5g)>~3!n`qprnYI+3mo*cnI$lhoG;P^ z*IALBb3QwKPgG~Ky16@6{=t#?!|`%~cAiF{6&d-Sdjk4}yb^P7kY0$u z+V=i;h@@{r;2}%nbOT<`I)$uJ_qRy0!H9ph9iS&EBHxaFFV>GzvKq1wPvQ3vIo(w4 z+#c8mQp!{~v#TTOJN4L5qrf}x64KvA#i>W={fC*yV#ER@?sAZKZpMgg0L3VO z>U*7ALT**Ses$NGIm&8Hh0<$kb1Q{3kr|`ZHgxNgYx7MpV!jgFFCW`|jQh?i-YT`{GyjRxwlRRE1}2rb@#!7AJm`K8w%NY6FugJRlCpYrEf07o4s)EC{D^$Xi#@Z94*vJq#K!0;A&#hh-PU z;5uA9n)%MP4i_Dj!Z-;Iva_WWcIr7g0Ow*7R&HDr7~&JJ6Q#WSm5^*u^x`ISNf9j_ zCD$l0#_V5QrQt-jlc=%ZT%~OF-(00}j`@Fcl^lkZFp%HCxJn2CCMfoNg3|LGJYE9Q z^M`P0MtPaaS)WKW|N5L(j_GWHpu}o%ze>3qhm$jNuu9d4cosQz(D?#asBm#JBhmTv zv#Rn*A&{w2=?c80U1A+`c8ksS6(E0aZyx$4wF}$D(#qU+<BSp!;t|A1Q5~+E z>ghM;HNdgmcAUKtv8rG-ukgt3Gp_(7g2JH%m;RCBm3(YVxoi%cLOFXl0emc}Y^@gv zE?o1{CY~GVZU>8q0ulFCunqn8)2f>*ETN!Vpw{G?#Ug>}N0bh2TKmqDK zE$!gZZ5SPCY4#isH7d^rr8}7GxD)d(+hUNoqaQc`B??@iu89Jf8Ibv+#YFlLtjeF= z92~bg+AHK(ld?T3_{_k^hLS!jRHn@8D}bC;F-voPie@^9G&LHoF)+ zR&dkxN%t?!EWg1m{)VP%gogf%+m2mLT|2m{xs^!gmb;c?^SzI#0RYm9PmP*_v+_D< zf68lCPj^HQ3*(4z4DHI9LQg&us^p_~!%E$N$8Qt89FVX{)UYhQP-OM?$6O7!^Oo27 zc|s{wrpvi=**1$7Wv=!K#O(UB`F5S}-_pK-3fEw_Uv9OSOBro!HVbtfSagjrqVqYdOykUy8;jahV;a{H_nN zKi>d!TjUCqi#54F$!eRxXic5`JPQ}_!VtiW3w`9zv`F0^#$ecu1{7t*G19^ z%Y>TGB?T`#RIg5cvTX?Ne3qiGS1a$>Q92>34_&_Kw#`HEJKk9jj1LO5XY56x=qE`R zjCd+@$Zm>pM7MBPUYHTzwn~0?6;Zz8txfw8jaDWJoT;xpKYcjzmB!%=Fe)wPB_-_O zI7O%AmXDz!MHe(4l9skR!L!)h;n4!L+}Ya#9b{qo)($=>Pwg1Hq%G#~_DL$fIq00K zKK2F<&sVPxR(NHUn(4D80MvtLjP`8UxohWO69+rNH*u(4 zE5Fjky3g(e-`mYw87Zow(qRKzk(lu7ea9+4$owObq6ydv?^_QX-0E05oI@&J2S<)1rYKKP&+Eo6DGtQ%n$*h@b zKhC`>nzlt}Z&h~|Qc_#eZbV=A|69aeeTG7#LLfM&Xn2laPFnk)U~r!W77gC#{6C>& z{l61)K6tWf*uO=$6W?|xHw>ZA|647|mBgc1=1N zOP*A^Ew_wI&F9{^)+tdClL`QgnOHcyO=`V4AiDubs)^ljKKlAYGR&nNKnfOS2$w&@oo_G+v1&I& ztpIg;N)bGojlvVHMSDS;Rdu-YE#7=khx1731$NSq0X@4=7`LE4$mrL2BJqz)&IOgk z1+M+@F}>sdIc~3$CmvfT0+&{R7)xutR5jB{Xml^&f6~6owCYofEq^i1n6(7_dJjC@ z*S|Ws2>x)7T>L#XE2_eGIz_$YLG+az6av?2&W0j+=zWB&RsW0Nl&~#OdRR~H?ZpL- zp!2O(u662JuX#m|-$Z^EpW~+DH;y+V=;_t|zaz??l0)wKx{~Z-nT7X2n)>AG{b8SU zTAkHRLGLcuLq$a`bcwIda<~Ab0Wl=D5}}+9a{16RQTxEZf0|D51MCb_QS%W< zR68wzVSj**woNU|#4W+TiQJb2e?1_&%|KHU`a`yOcW0u|d}f)B$a>I;88m=o8_{Jr zzl{!)%fn}F?dpJ_{VjnWD~3fjiuP-+tt}x6`}X#1(TluZ*OQ*y4!&DW3~VHXW`|sp9H#V-UE` zXJn}#4xDONXQP8Cjj>xR-XuD+wQ4%|oMP^2NtlNi<|>ewW|0b084+fifvjVqyIGTR z&jZ?l1leJWISN(a<QQ%F>kF92Ig8_$P(wZ0;`FfYc z;+KHqCEm^L$lF8=JQ7-gFYCV!=VEzA6QJA}8T@P&6|gyI;V#H7AWu)^ga_BN~tMQ7633nQYJOqgfZGsT-jk}+?m75mSC;R$<&|u zp;;?PGmRfZk%#b_&q?E`#G@+N?gy^Zy=aCpQ4B*MG74FF5%<1{y5T~vuC!liPP|Bx zNlAYh>ftrxL+FhJPp|;-1wHCyH^YPlpJ4p~g71%f?|aNwpQPD4>@{sowsUmopU3`O z{0=Z;nrE$Rj*6MjPi`rB96o!a-!g~R zY2DWXc!z{V z#%ndV%8JY%mE>0ISpokNx0gI_L}bwIRD@x0trL?avmak9q!>H&6Rfe z9ZlnZz8|7;R?W|q2SJmW)+hjob6{;I(3#+X%Jk7@^qC+H$=LqWbN2+xN}xxm@DSF1 zM1p~U736CY`m$XRm?7fuX{an#ic;_)7Fk5i`@OllC!ifz$0t|;v+`8a)Z)Fym%v}-ati^+6S_Vw zk+n=!Zc#APa3VBWBTTF+>fmSYJ8R!jF0Z@?iGo8;1u-RfZ363e zfC=;PQs8I_5ad_ifnG@6Fm$a((-Brmp;zkaa#h(mIsO9!14U*d8Dvaw|7>}GO}C3n zPxA3qGyQ~2o?eu9-z$B(N9U?%NTaYx$V%72_q!U;hWw1Evx(3=AC**4d%r)oaJtnCfB@b0W8%6>!#x0o;CN4 zIW>fzvpRPM<6SkZDR|my_8Y6rk1|*?c0>z8EG%N@HKrua#!57A&itBGAKltZrpJZf z$h?TM)E%VW9MZX-N@vtcf(7ABBJD|uCMt2d+VC~)+ZYLcoqDffEq>3pTp8l$H1_+0 z#lQMA8KX$v_CV1WO1#^hyCNPn_=NKMm7UB$0E=wtlgAQX>RWh!{ns8Mx(z3sr=pp7bHWYa9NCp~-r>JXp<^i6)zbdb;|$lz%kd)lcZR?L_%;avWMsEynKt}m+IqP3XDG;a*Q*!hdTbH#(y a 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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/inittestscene.PNG b/src/assets/godot/dungeonCrawler/inittestscene.PNG new file mode 100644 index 0000000000000000000000000000000000000000..fbed70ccf0da586e6bf22b0540c71efb83e01d23 GIT binary patch literal 70124 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
    erv&MOYjRES=bB>pFONHbcK0Y4OEm6 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 literal 0 HcmV?d00001 diff --git a/src/assets/godot/dungeonCrawler/movementscriptsetpimage.PNG b/src/assets/godot/dungeonCrawler/movementscriptsetpimage.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e13c06fb39357e7a5e6d40562b5c52840bacafff GIT binary patch literal 21222 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 +1. First let's create a new folder, and call it something like 'Assets' + Then, let's extract the assets from the folder we downloaded, and at them into our Assets folder. Mine looks like this, but it's fine if yours looks slightly different. -Let's also create two new top level folders called **Scripts** and **Scenes** + ![Assets](/src/assets/godot/dungeonCrawler/assets.png) -![Folders](/src/assets/godot/dungeonCrawler/folders.png) +2. Let's also create two new top level folders called **Scripts** and **Scenes** + ![Folders](/src/assets/godot/dungeonCrawler/folders.png) -To ensure our pixel art assets look crisp and not blurred we'll want to make one quick change. +3. To ensure our pixel art assets look crisp and not blurred we'll want to make one quick change. + Using the buttons in the top left of the screen, select **Project -> Project settings** In this menu, select the **General** tab, and scroll until you see the **Rendering** header. Under this, select **Textures** + Change **Default Texture Filter** from **Linear** to **Nearest** -Using the buttons in the top left of the screen, select **Project -> Project settings** In this menu, select the **General** tab, and scroll until you see the **Rendering** header. Under this, select **Textures** - -Change **Default Texture Filter** from **Linear** to **Nearest** - -![Folders](/src/assets/godot/dungeonCrawler/TextureFilter.png) + ![Folders](/src/assets/godot/dungeonCrawler/TextureFilter.png) + ### Checklist diff --git a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx index 7d153ab..3afd5b7 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx @@ -7,6 +7,7 @@ description: Creating our player scene and scripts import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Creating the Player @@ -19,11 +20,16 @@ Godot Documentation for nodes discussed in this section: Great! Let's start by making a basic version of our player character that will let us move around. We'll worry about more complicated things like attacking later. -Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** -Give the **CharacterBody2D** a name like **Player** and give it two children: + -A **CollisionShape2D** and an **AnimatedSprite2D** +1. Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** + Give the **CharacterBody2D** a name like **Player** + +2. Give it two children: + A **CollisionShape2D** and an **AnimatedSprite2D** + + Here's how my scene looks with no other modifications: @@ -33,81 +39,96 @@ Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it som ### Animations -Let's give ourselves something to look at! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. -Click on **\** and create a new **Spriteframes** Click on the **Spriteframes** you created. This will open a new window at the bottom of the screen. +Let's give ourselves something to look at! + +1. Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. -This is where we'll create our player's animations. Rename the *General* animation to *Idle* and click the *Add frames from File* Button (The folder icon) +2. Click on **\** and create a new **Spriteframes** Click on the **Spriteframes** you created. This will open a new window at the bottom of the screen. + This is where we'll create our player's animations. Rename the *General* animation to *Idle* and click the *Add frames from File* Button (The folder icon) -Navigate to your *assets/frames* folder, and decide which character you want to be your player. I'll be using the Plague Doctor. Using Shift + Click select all the frames for your character labeled *Idle* (This should be four frames) then open them. +3. Navigate to your *assets/frames* folder, and decide which character you want to be your player. I'll be using the Plague Doctor. Using Shift + Click select all the frames for your character labeled *Idle* (This should be four frames) then open them. -![Idle Animation Frames](/src/assets/godot/dungeonCrawler/idleanim.png) + ![Idle Animation Frames](/src/assets/godot/dungeonCrawler/idleanim.png) -You'll see them added to the animation timeline. We'll want to select two things in the timeline. The **Loop** Button (To ensure the animation loops) and the **Play on start button** (To ensure the animation plays automatically) -Let's also increase the FPS to 8 so that the animation plays a little faster. + You'll see them added to the animation timeline. -Hit play to test! You'll see the player now has an idle animation that loops! +4. We'll want to select two things in the timeline. The **Loop** Button (To ensure the animation loops) and the **Play on start button** (To ensure the animation plays automatically) + Let's also increase the FPS to 8 so that the animation plays a little faster. -Let's add our characters walking animation. Add a new animation using the **Add animation** Button and call it something like "Walk" + ![Idle Animation Frames](/src/assets/godot/dungeonCrawler/autoloop.png) -![Idle Animation Frames](/src/assets/godot/dungeonCrawler/addanim.png) + Hit play to test! You'll see the player now has an idle animation that loops! -Do the same thing we did to grab the frames for the idle animation, but this time, grab all the frames labeled "Run" it should again be 4 frames. We want this animation to loop, but we **don't** want it to autoplay. Let's also give this a framerate of 8 FPS. +5. Let's add our character's walking animation. Add a new animation using the **Add animation** Button and call it something like "Walk" -![Walk Animation Frames](/src/assets/godot/dungeonCrawler/walkanim.png) + ![Idle Animation Frames](/src/assets/godot/dungeonCrawler/addanim.png) -Finally, just select your idle animation again, to make sure this is what our player will start on. + Do the same thing we did to grab the frames for the idle animation, but this time, grab all the frames labeled "Run" it should again be 4 frames. We want this animation to loop, but we **don't** want it to autoplay. Let's also give this a framerate of 8 FPS. -great! That's our animations all done! + ![Walk Animation Frames](/src/assets/godot/dungeonCrawler/walkanim.png) -### Collision and Movement + Finally, just select your idle animation again, to make sure this is what our player will start on. -Now that we have something to look at, let's give our player a hitbox. Open the inspector for the **CollisionShape2D** we added, and add a new shape in the **empty** shape field. -It's a good idea to use a **CapsuleShape** as it will make us less likely to get stuck on corners. Position and adjust the capsule so that it's *slightly* smalle than the sprite for our player. -Mine looks like this: + Great! That's our animations all done! + -![CollissionShape](/src/assets/godot/dungeonCrawler/collshapeimg.png) +### Collision -Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player.gd" and make sure we're saving it -in our Scripts folder. We also need to make sure we **untick** the **template** box as we will not be using the template! This is because the template is designed for gravity based platformers. +Now that we have something to look at, let's give our player a hitbox. + +1. Open the inspector for the **CollisionShape2D** we added, and add a new shape in the **empty** shape field. + It's a good idea to use a **CapsuleShape** as it will make us less likely to get stuck on corners. Position and adjust the capsule so that it's *slightly* smaller than the sprite for our player. + Mine looks like this: -With our script created and attached, let's get to programming our movement! + ![CollissionShape](/src/assets/godot/dungeonCrawler/collshapeimg.png) -First, let's set up a variable to control our speed. +2. Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player.gd" and make sure we're saving it in our Scripts folder. + We also need to make sure we **untick** the **template** box as we will not be using the template! This is because the template is designed for gravity based platformers. + -```gdscript -@export var speed = 200 -``` - -The **\@export** tag will allow us to easily edit our speed variable, without needing to open the script! +With our script created and attached, let's get to programming our movement! -Then, we'll want to use Godots built in **_physics_process(delta):** function for our movement logic. Inside that we'll want to get the combined vector of all the inputs the player is pressing. +### Movement -```gdscript -func _physics_process(delta): - var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") -``` + -We'll then multiply this vector by our speed, and then invoke Godots built in **move_and_slide()** function +1. First, let's set up a variable to control our speed. -```gdscript -velocity = direction * speed + ```gdscript + @export var speed = 200 + ``` -move_and_slide() -``` + The **\@export** tag will allow us to easily edit our speed variable, without needing to open the script! -giving us a final script that looks like this: +2. Then, we'll want to use Godots built-in **_physics_process(delta):** function for our movement logic. Inside that we'll want to get the combined vector of all the inputs the player is pressing. -```gdscript -extends CharacterBody2D + ```gdscript + func _physics_process(delta): + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + ``` -@export var speed = 200 +3. We'll then multiply this vector by our speed, and then invoke Godots built-in **move_and_slide()** function -func _physics_process(delta): - var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + ```gdscript velocity = direction * speed move_and_slide() -``` + ``` + +4. giving us a final script that looks like this: + + ```gdscript + extends CharacterBody2D + + @export var speed = 200 + + func _physics_process(delta): + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + velocity = direction * speed + + move_and_slide() + ``` + For now our movement is controlled using the arrow keys, but we'll go over how to map it to whatever we want later in the guide. Switch back to 2D view at the top of the screen. diff --git a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx index a2b5f90..13252bf 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx @@ -16,27 +16,37 @@ Godot Documentation for nodes discussed in this section: [TileMapLayer](https://docs.godotengine.org/en/stable/classes/class_tilemaplayer.html) ::: -Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "World" +import { Steps } from '@astrojs/starlight/components'; -Save the scene in our Scenes folder, calling it something like "world.tscn". +Let's move onto giving us something to walk around on! -Give our root node a child of type **Node2D** and call it something like "level" + +1. Create a new scene. Give it a node2D as its root node, and call it something like "World" -To this node, add two children of type **TilemapLayer** + Save the scene in our Scenes folder, calling it something like "world.tscn". -call the top one "floor" and the bottom one "walls" +2. Give our root node a child of type **Node2D** and call it something like "level" -Let's start with the "Floor" layer, as it'll be slightly more simple, and we'll redo all the steps for the "walls" layer. +3. To this node, add two children of type **TilemapLayer** -Click on the "floor" Node, and in the inspector, you'll see **Tile Set - Empty** click on **Empty** and create a **new Tileset** then click on the newly created **Tileset** + call the top one "floor" and the bottom one "walls" -You'll notice two new tabs have appeared at the bottom of the screen **TileSet** and **TileMap** we'll be working with both of these, but open the **TileSet** tab first. +4. Let's start with the "Floor" layer, as it'll be slightly more simple, and we'll redo all the steps for the "walls" layer. -using the **+** button in the lower left, navigate to your assets, and load in the "atlas_floor-16x16.png" hit **Yes** when prompted. + Click on the "floor" Node, and in the inspector, you'll see **Tile Set - Empty** click on **Empty** and create a **new Tileset** then click on the newly created **Tileset** -You can think of this as a palette we'll use to pain our level! Our dungeon will be made up from a series of tiles that we can arrange however we want! + You'll notice two new tabs have appeared at the bottom of the screen **TileSet** and **TileMap** we'll be working with both of these, but open the **TileSet** tab first. + + using the **+** button in the lower left, navigate to your assets, and load in the "atlas_floor-16x16.png" hit **Yes** when prompted. + + You can think of this as a palette we'll use to pain our level! Our dungeon will be made up from a series of tiles that we can arrange however we want! + + + +:::note[Decorations] + We won't be implementing the spikes/buttons/levers. So if you add these to your level they'll be purely decorative.** +::: -**Note: We won't be implementing the spikes/buttons/levers. So if you add these to your level they'll be purely decorative.** Now, click on the **floor** layer and follow the same steps, except this time loading in the "atlas_walls_low-16x16.png" file. @@ -44,25 +54,33 @@ With our **Tilesets** setup we can now go to the **TileMap** tab. From here, if you click on a tile and then in the scene, you'll notice you're able to paint them into the scene! This is how we'll create our levels! you can click between the floor and wall **Tilemaps** to get access to the different tiles and to paint the different layers. -**Note:** Why do we have a different layer for the two? We'll want our walls to have collision, but not our floors! So we have them on different **TilemapLayer** nodes. +:::note[Layers] +Why do we have a different layer for the two? We'll want our walls to have collision, but not our floors! So we have them on different **TilemapLayer** nodes. +::: Spend some time and get familiar with painting and removing tiles! Aim to create a single room that we can use to test our game. -**Tip:** If you find you can't paint, make sure you're on the **TileMap** tab and NOT the **TileSet** tab (confusing, I know) +:::tip +If you find you can't paint, make sure you're on the **TileMap** tab and NOT the **TileSet** tab (confusing, I know) +::: -**Tip: You can use the Rect tool to draw a rectangle of tiles all at once** +:::tip + You can use the Rect tool to draw a rectangle of tiles all at once ![Rect tool](/src/assets/godot/dungeonCrawler/recttoolimg.png) -**Tip: You can use the Erase tool to remove tiles, just remember to click it again when you want to start painting again** +You can use the Erase tool to remove tiles, just remember to click it again when you want to start painting again ![Rect tool](/src/assets/godot/dungeonCrawler/eraseTool.png) +::: Here's what my room looks like: ![Basic Level](/src/assets/godot/dungeonCrawler/basicroomimg.png) -**Note:** Don't go too crazy on your level design just now! This first area will just be to test! +:::note[Testing] +Don't go too crazy on your level design just now! This first area will just be to test! +::: ### Adding our player to the level @@ -76,27 +94,33 @@ Don't worry if the names of your nodes are different, leave them as they are for You should be able to move around! Though you'll quickly notice you're able to walk through walls, which isn't ideal, so let's fix that! ### Level collision + +1. Click on your **Walls TilemapLayer** Node, Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. + +2. Under the **Physics Layers** drop-down, click **Add Element.** -Click on your **Walls TilemapLayer** Node, Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. Under the **Physics Layers** drop-down, click **Add Element.** +3. Here you'll see the **Collision Layer** section, make sure **1** and **3** are selected. For the **Collision Mask** section, only **1** should be selected. -Here you'll see the **Collision Layer** section, make sure **1** and **3** are selected. For the **Collision Mask** section, only **1** should be selected. +4. Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop-down, select **Physics Layer 0.** Here's how things look for me! -Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop-down, select **Physics Layer 0.** Here's how things look for me! + ![Physics Layers](/src/assets/godot/dungeonCrawler/tilesetphysicslayer.png) -![Physics Layers](/src/assets/godot/dungeonCrawler/tilesetphysicslayer.png) + Think of the blue square that has appeared under the **Paint** tab as our brush that we'll use to paint collisions onto our **Tileset** with the blue square representing where exactly our player will collide. -Think of the blue square that has appeared under the **Paint** tab as our brush that we'll use to paint collisions onto our **Tileset** with the blue square representing where exactly our player will collide. + You can click and drag the white diamonds to move them, and click on the edges to add new points. pressing F (Full) will make the collider occupy the whole square, and pressing C (Clear) will make it occupy none of it. -You can click and drag the white diamonds to move them, and click on the edges to add new points. pressing F (Full) will make the collider occupy the whole square, and pressing C (Clear) will make it occupy none of it. +5. using this, try to create colliders for each tile that closely match their sprite. -So using this, try to create colliders for each tile that closely match their sprite. + :::tip + It'll be easiest to do them in batches of tiles that have the same collision! + ::: -Tip: It'll be easiest to do them in batches of tiles that have the same collision! + Here's how mine look: -Here's how mine look: + ![Wall colliders](/src/assets/godot/dungeonCrawler/wallcolliders.png) -![Wall colliders](/src/assets/godot/dungeonCrawler/wallcolliders.png) + Now try playing your game again! You'll notice you actually collide with the walls! Great! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx index 06f0eee..79e704e 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx @@ -7,6 +7,7 @@ description: Upgrading our player scene import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Improving our player @@ -23,43 +24,47 @@ make sure our animation changes to our walking animation when we move, and make We'll also be implementing attacking, but we'll do that in its own section! ### Input mapping + +1. To change our inputs, we'll first need to set up our **Input Map** to do this, we'll navigate to **Project -> Project Settings** in the top left of the workspace. -To change our inputs, we'll first need to set up our **Input Map** to do this, we'll navigate to **Project -> Project Settings** in the top left of the workspace. +2. Then, open the **Input Map** tab. -Then, open the **Input Map** tab. +3. We'll add our new Inputs by typing a name for each of them in the **Add New Action** box and hitting add. -We'll add our new Inputs by typing a name for each of them in the **Add New Action** box and hitting add. + I'll be calling mine "Up" "Down" "Left" "Right" and i'll also add one called "Attack" -I'll be calling mine "Up" "Down" "Left" "Right" and i'll also add one called "Attack" + ![Input Actions](/src/assets/godot/dungeonCrawler/inputmappreinputs.png) -![Input Actions](/src/assets/godot/dungeonCrawler/inputmappreinputs.png) +4. To add buttons to these, we'll hit the "+" to the right of each action, we'll then physically press the key we want to assign on our keyboard, and hit "Ok" -To add buttons to these, we'll hit the "+" to the right of each action, we'll then physically press the key we want to assign on our keyboard, and hit "Ok" + For my **Attack** action i'll be using **Left Click* for which you'll want to physically click *once* inside the **Listening for input** box. -For my **Attack** action i'll be using **Left Click* for which you'll want to physically click *once* inside the **Listening for input** box. + Here's what my inputs look like: -Here's what my inputs look like: + ![Input Actions with buttons](/src/assets/godot/dungeonCrawler/inputswithbuttons.png) -![Input Actions with buttons](/src/assets/godot/dungeonCrawler/inputswithbuttons.png) + If you're happy with your inputs, you can then hit **Close** at the bottom of the screen. Let's navigate back to our **player_movement.gd** script. This can be done by opening our **player** scene, clicking on the **CharacterBody2D** and clicking the **Script** tab at the top of the screen. -If you're happy with your inputs, you can then hit **Close** at the bottom of the screen. Let's navigate back to our **player_movement.gd** script. This can be done by opening our **player** scene, clicking on the **CharacterBody2D** and clicking the **Script** tab at the top of the screen. +5. To change our inputs, all we need to do is change the predefined inputs to what we called ours! -To change our inputs, all we need to do is change the predefined inputs to what we called ours! + :::Note[Case Sensitivity] + What you named your input actions *is* case sensitive + ::: -**Note:** What you named your input actions *is* case sensitive + So, "ui_left" becomes "Left" + "ui_right" becomes "Right" and so on! -So, "ui_left" becomes "Left" -"ui_right" becomes "Right" and so on! + leaving that line in our script looking like this: -leaving that line in our script looking like this: - -```gdscript - var direction = Input.get_vector("Left", "Right", "Up", "Down") -``` + ```gdscript + var direction = Input.get_vector("Left", "Right", "Up", "Down") + ``` + if you run your game, you'll notice your inputs are now changed! We won't assign our Attack option just yet, but it's good we've created it already. + ### Animation switching To change our animation depending on if we're moving or not, we'll only need to add a few lines to our script. But first, we'll need a reference to our **AnimatedSprite2D** in our script. @@ -77,48 +82,52 @@ if it doesn't look like this, delete the line and try again, making sure you're Great! Let's get to changing our animation! -Under where we set our velocity, we'll simply add a check to see if our velocity is anything other than 0 and change our animation based on that! + -We can check this simply with: +1. Under where we set our velocity, we'll simply add a check to see if our velocity is anything other than 0 and change our animation based on that! -**Note:** Why can't we just do velocity != 0? This is because velocity actually contains both our X (Horizontal) and Y (Vertical) velocity, so we need to make sure **Both** aren't zero. + We can check this simply with: -```gdscript -if velocity != Vector2.ZERO: -``` + ```gdscript + if velocity != Vector2.ZERO: + ``` + :::note[Vector2s] + Why can't we just do velocity != 0? This is because velocity actually contains both our X (Horizontal) and Y (Vertical) velocity, so we need to make sure **Both** aren't zero. + ::: -Then, we can play our run animation! +2. Then, we can play our run animation! -```gdscript -if velocity != Vector2.ZERO: + ```gdscript + if velocity != Vector2.ZERO: animated_sprite_2d.play("walk") -``` + ``` -and if we're not moving, let's play our idle +3. If we're not moving, let's play our idle -```gdscript -else: - animated_sprite_2d.play("idle") -``` + ```gdscript + else: + animated_sprite_2d.play("idle") + ``` -Giving us a movement script that looks like this: +4. Giving us a movement script that looks like this: -```gdscript -extends CharacterBody2D + ```gdscript + extends CharacterBody2D -@export var speed = 200 -@onready var animated_sprite_2d = $AnimatedSprite2D + @export var speed = 200 + @onready var animated_sprite_2d = $AnimatedSprite2D -func _physics_process(delta): - var direction = Input.get_vector("Left", "Right", "Up", "Down") - velocity = direction * speed - if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") - else: - animated_sprite_2d.play("idle") + func _physics_process(delta): + var direction = Input.get_vector("Left", "Right", "Up", "Down") + velocity = direction * speed + if velocity != Vector2.ZERO: + animated_sprite_2d.play("walk") + else: + animated_sprite_2d.play("idle") - move_and_slide() -``` + move_and_slide() + ``` + Play your game, and you'll notice your animation changes when you move! @@ -128,51 +137,56 @@ To flip our player based on the direction we're moving, all we really need to do I'll be adding this section **beneath** the animation section, but before the **move_and_slide()** function call. -let's start by checking the Horizontal portion of our movement: + -```gdscript -if(velocity.x < 0): -``` -if our x velocity is less than 0 (moving to the left) we want to flip our sprite. - -```gdscript -animated_sprite_2d.flip_h = true -``` +1. Let's start by checking the Horizontal portion of our movement: -And if it's greater than 0, we'll unflip it + ```gdscript + if(velocity.x < 0): + ``` +2. If our x velocity is less than 0 (moving to the left) we want to flip our sprite. -```gdscript -elif(velocity.x > 0): - animated_sprite_2d.flip_h = false -``` + ```gdscript + animated_sprite_2d.flip_h = true + ``` -giving us a movement script that looks like this: +3. And if it's greater than 0, we'll unflip it -```gdscript -extends CharacterBody2D + ```gdscript + elif(velocity.x > 0): + animated_sprite_2d.flip_h = false + ``` -@export var speed = 200 -@onready var animated_sprite_2d = $AnimatedSprite2D +4. Giving us a movement script that looks like this: -func _physics_process(delta): - var direction = Input.get_vector("Left", "Right", "Up", "Down") - velocity = direction * speed - - if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") - else: - animated_sprite_2d.play("idle") - - if(velocity.x < 0): - animated_sprite_2d.flip_h = true - elif(velocity.x > 0): - animated_sprite_2d.flip_h = false + ```gdscript + extends CharacterBody2D - move_and_slide() -``` -**Note:** Why didn't we juse use **else:**? - If we'd just used **Else:** our sprite would have jarringly flipped to face left whenever we stopped moving, or if we were just moving up and down. -This way the direction our sprite is facing doesn't change unless we move either left or right! + @export var speed = 200 + @onready var animated_sprite_2d = $AnimatedSprite2D + func _physics_process(delta): + var direction = Input.get_vector("Left", "Right", "Up", "Down") + velocity = direction * speed + + if velocity != Vector2.ZERO: + animated_sprite_2d.play("walk") + else: + animated_sprite_2d.play("idle") + + if(velocity.x < 0): + animated_sprite_2d.flip_h = true + elif(velocity.x > 0): + animated_sprite_2d.flip_h = false + + move_and_slide() + ``` + :::note[Flipping] + Why didn't we juse use **else:**? - If we'd just used **Else:** our sprite would have jarringly flipped to face left whenever we stopped moving, or if we were just moving up and down. + This way the direction our sprite is facing doesn't change unless we move either left or right! + ::: + + Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx index 460bce4..1e12cab 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx @@ -7,8 +7,9 @@ description: Implementing the weapon scene and script import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; -## The Weapon +## Creating our Weapon :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -20,116 +21,125 @@ Let's give our player something to attack with! ### Weapon Scene -Let's create a new scene for our weapon! -Give it a root node of just a **Node2D** with two children, a **Sprite2D** and a **Animationplayer** -Give the sprite a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** - -Name the root **Node2D** something like "Weapon" +Let's make our weapon! + +1. Create a new scene for our weapon! + Give it a Root node of a **Node2D** and name it something like "Weapon" + +2. Give it two children, a **Sprite2D** and a **Animationplayer** + Give the **Sprite2D** a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** -Here's how my scenetree looks: + Here's how my scenetree looks: -![Weapon scenetree](/src/assets/godot/dungeonCrawler/weaponscenetree.png) + ![Weapon scenetree](/src/assets/godot/dungeonCrawler/weaponscenetree.png) -Make sure you save the scene, calling it something like "Weapon.tscn" + Make sure you save the scene, calling it something like "Weapon.tscn" -Let's start by picking a sprite for our weapon, so we can see what we're working with! -Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! +3. Let's start by picking a sprite for our weapon, so we can see what we're working with! + Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! -Don't worry that it's pointing up, we'll rotate it in a minute. + Don't worry that it's pointing up, we'll rotate it in a minute. -Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. -Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. +4. Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. + Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. -let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** +5. let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** -Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** + Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** -Here's how my sword scene and inspector look: + Here's how my sword scene and inspector look: -![Sword Scene Inspector](/src/assets/godot/dungeonCrawler/swordsceneinspector.png) + ![Sword Scene Inspector](/src/assets/godot/dungeonCrawler/swordsceneinspector.png) -Before we move on, navigate to the inspector tab of the **Area2D** node and find the **Collision** tab, under **Layer** make sure nothing is selected. Under **Mask** Make sure *only* 2 is selected. +6. Before we move on, navigate to the inspector tab of the **Area2D** node and find the **Collision** tab, under **Layer** make sure nothing is selected. Under **Mask** Make sure *only* 2 is selected. + ### Weapon Script + +1. Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" -Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" - -We'll need this script to do two things: + We'll need this script to do two things: -1. Rotate around our player, facing the mouse. -2. Play the animation when we press our attack input. + 1. Rotate around our player, facing the mouse. + 2. Play the animation when we press our attack input. -The first step will be nice and easy! In the **process** function, add the line -```gdscript -look_at(get_global_mouse_position()) -``` -This will cause this node to always face toward the position of the mouse! - -Next, we'll need to get a reference to our **AnimatedSprite2D** node, we'll do this the same way we did for the **animated_sprite_2d** node for the player' by clicking, dragging, and then holding ctrl before we let go of the click. +2. The first step will be nice and easy! In the **process** function, add the line + ```gdscript + look_at(get_global_mouse_position()) + ``` + This will cause this node to always face toward the position of the mouse! -We'll also want a variable that keeps track of if we're *currently* attacking, as we don't want the sword to destroy enemies when we haven't attacked. +3. Next, we'll need to get a reference to our **AnimatedSprite2D** node, we'll do this the same way we did for the **animated_sprite_2d** node for the player' by clicking, dragging, and then holding ctrl before we let go of the click. -your script should look like this: + We'll also want a variable that keeps track of if we're *currently* attacking, as we don't want the sword to destroy enemies when we haven't attacked. -```gdscript -extends Node2D + your script should look like this: -@onready var animation_player = $AnimationPlayer -@export var attacking : bool = false + ```gdscript + extends Node2D -func _process(delta): - look_at(get_global_mouse_position()) -``` + @onready var animation_player = $AnimationPlayer + @export var attacking : bool = false -Great, now let's add a check to see if we've just used the **Attack** input action we created earlier, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! + func _process(delta): + look_at(get_global_mouse_position()) + ``` -Making sure that the Input action name, and animation name match, including case sensitivity. -```gdscript -extends Node2D +4. Now, let's add a check to see if we've just used the **Attack** input action we created earlier, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! -@onready var animation_player = $AnimationPlayer + Making sure that the Input action name, and animation name match, including case sensitivity. + + + ```gdscript + extends Node2D -@export var attacking : bool = false + @onready var animation_player = $AnimationPlayer -func _process(delta): - look_at(get_global_mouse_position()) - - if Input.is_action_just_pressed("Attack"): - animation_player.play("Attack") + @export var attacking : bool = false -``` + func _process(delta): + look_at(get_global_mouse_position()) + + if Input.is_action_just_pressed("Attack"): + animation_player.play("Attack") + ``` + ### Sword Animation -Now, let's start creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" -Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. +Now, let's start creating our attack animation! + +1. Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" + +2. Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. -We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. + We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. -Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! + Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! -Finally, scroll until you see the **Position** property. + Finally, scroll until you see the **Position** property. -Phew! That was quite a few steps, but our animation track is created! + Phew! That was quite a few steps, but our animation track is created! -Great, now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. +3. Now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. -To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! + To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! -The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) + The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) -Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. + Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. -Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. +4. Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. -Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. + Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. -Play it again, and you'll notice it's much faster! + Play it again, and you'll notice it's much faster! -We'll want to add another **Property Animation Track** this time to modify the **attacking** variable, to keep track of if our weapon is "Active" or not. +5. We'll want to add another **Property Animation Track** this time to modify the **attacking** variable, to keep track of if our weapon is "Active" or not. -Add a new animation track, select property, and you should see "attacking" right at the top! Add two keyframes, one right at the start, and one right at the end. The first we'll want to set the value to "on" (as we're now attacking) and the one at the end will set the property back to "off" (or unticked) + Add a new animation track, select property, and you should see "attacking" right at the top! Add two keyframes, one right at the start, and one right at the end. The first we'll want to set the value to "on" (as we're now attacking) and the one at the end will set the property back to "off" (or unticked) + And that's it! We'll come back later to add the code for destroying enemies. Great! Let's get our weapon added to our player! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx index 7309599..82a851c 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx @@ -7,6 +7,7 @@ description: Implementing the player health system import Box from '/src/components/tutorial/Box.astro'; import Checklist from '/src/components/tutorial/Checklist.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Health @@ -19,311 +20,340 @@ Godot Documentation for nodes discussed in this section: ### Player Health -Let's start setting up our health system on the player side, we'll start by adding a new Node to our player, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** -give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." +Let's start setting up our health system on the player side! + +1. We'll start by adding a new Node to our player Scene, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** + give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." -In the **Inspector** of the **Area2D** Navigate to the **Collision** section. Deselect all numbers under the **Layer** Section, and ensure *only* 2 is selected under the **Mask** Section. + In the **Inspector** of the **Area2D** Navigate to the **Collision** section. Deselect all numbers under the **Layer** Section, and ensure *only* 2 is selected under the **Mask** Section. -Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** + Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** -Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! -In the timer's inspector, set its **Wait Time** field to 0.5s +2. Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! + In the timer's inspector, set its **Wait Time** field to 0.5s -Great! this **Area2D** will be used to detect collision with enemies, potions, and coins! For now we'll just be setting it up to handle health, both healing and damage. + Great! this **Area2D** will be used to detect collision with enemies, potions, and coins! For now we'll just be setting it up to handle health, both healing and damage. -Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" +3. Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" -This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its functionality up into multiple scripts, but for our scope this is fine! -Let's break down what we need it to do: +4. This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its functionality up into multiple scripts, but for our scope this is fine! + Let's break down what we need it to do: -1. Track our health -2. Detect collisions with potions/enemies/coins -3. Change our health value -4. Update the UI + 1. Track our health + 2. Detect collisions with potions/enemies/coins + 3. Change our health value + 4. Update the UI -Let's start by creating the variables we'll need, those being: +5. Let's start by creating the variables we'll need, those being: -1. The signal we'll use to talk to the UI when our health has changed -2. While we're here, a signal for when we've collected a coin, as it'll also talk to the UI -3. A max health, and current health value -4. A reference to the timer we created. -5. A boolean determining if we can take damage + 1. The signal we'll use to talk to the UI when our health has changed + 2. While we're here, a signal for when we've collected a coin, as it'll also talk to the UI + 3. A max health, and current health value + 4. A reference to the timer we created. + 5. A boolean determining if we can take damage -These should look something like this, using the same click + drag + ctrl method to get the reference to the **Timer** + These should look something like this, using the same click + drag + ctrl method to get the reference to the **Timer** -```gdscript -signal on_health_changed(new_health : int) -signal on_point_gained -@export var max_health : int = 6 -@onready var damage_timer = $damageTimer -var health : int -var can_take_damage : bool = true -``` + ```gdscript + signal on_health_changed(new_health : int) + signal on_point_gained + @export var max_health : int = 6 + @onready var damage_timer = $damageTimer + var health : int + var can_take_damage : bool = true + ``` -**Remember:** We can use the **\@export** to modify the max health value, without editing the script! + :::note[\@export] + We can use the **\@export** to modify the max health value, without editing the script! + ::: -**Note:** Why are we starting at 6 health? We're doing this because each point of health will represent half a heart to the UI, for a total of 3 full hearts! Using ints like this is safer than using a float, -because what if we somehow end up with 0.001 health! + :::note[Health] + Why are we starting at 6 health? We're doing this because each point of health will represent half a heart to the UI, for a total of 3 full hearts! Using ints like this is safer than using a float, + because what if we somehow end up with 0.001 health! + ::: -in our **_ready** function we'll want to set some default values, and emit the health_changed signal to send our starting health to the UI. +6. In our **_ready** function we'll want to set some default values, and emit the health_changed signal to send our starting health to the UI. -```gdscript -func _ready(): - damage_timer.connect("timeout", allow_damage) - health = max_health - emit_signal("on_health_changed", health) -``` - -Right, let's get onto the most complicated function in the script, the function for taking damage! In this function, there'll be a few different possible outcomes. -1. We can't take damage as we're currently immune. In this case. Nothing happens -2. Otherwise we'll take damage. Emitting the signal to change the UI. -3. If we do take damage, we might be reduced to 0 hitpoints -4. If we are, we die! If we're not. We start our immunity timer. - -Great! Let's write that in gdscript: - -```gdscript -func take_damage(): - if can_take_damage: - health = health - 1 + ```gdscript + func _ready(): + damage_timer.connect("timeout", allow_damage) + health = max_health emit_signal("on_health_changed", health) - - if health <= 0: - get_tree().paused = true - else: - can_take_damage = false - damage_timer.start() -``` - -You'll notice we connected our timer to a function called **allow_damage()** which doesn't exist, let's create that now. All it's going to do is set the **can_take_damage** boolean to **True** as unfortunately Godot doesn't let you assign a value to a variable directly via the **connect()** function. - -```gdscript -func allow_damage(): - can_take_damage = true -``` - -Next we'll do healing! This one is *much* easier. We just need to check if we have room to be healed (Our health is less than our max health). If we do, increase our health by 1. Then emit the signal to update the UI! We'll also want to delete the potion, so it can no longer be used. - -```gdscript -func heal(body): - if health < max_health: - health = health + 1 + ``` + + + +1. Right, let's get onto the most complicated function in the script, the function for taking damage! In this function, there'll be a few different possible outcomes. + + 1. We can't take damage as we're currently immune. In this case. Nothing happens + 2. Otherwise we'll take damage. Emitting the signal to change the UI. + 3. If we do take damage, we might be reduced to 0 hitpoints + 4. If we are, we die! If we're not. We start our immunity timer. + +2. Great! Let's write that in gdscript: + + ```gdscript + func take_damage(): + if can_take_damage: + health = health - 1 + emit_signal("on_health_changed", health) + + if health <= 0: + get_tree().paused = true + else: + can_take_damage = false + damage_timer.start() + ``` + +2. You'll notice we connected our timer to a function called **allow_damage()** which doesn't exist, let's create that now. All it's going to do is set the **can_take_damage** boolean to **True** as unfortunately Godot doesn't let you assign a value to a variable directly via the **connect()** function. + + ```gdscript + func allow_damage(): + can_take_damage = true + ``` + +3. Next we'll do healing! This one is *much* easier. We just need to check if we have room to be healed (Our health is less than our max health). If we do, increase our health by 1. Then emit the signal to update the UI! We'll also want to delete the potion, so it can no longer be used. + + ```gdscript + func heal(body): + if health < max_health: + health = health + 1 + emit_signal("on_health_changed", health) + body.queue_free() + ``` + +4. Finally, we need a function that calls our **heal** and **damage** functions based on what we've collided with. To check what type of object we've collided with, we'll be using **Groups!** These are something we'll assign to our enemies/potions/coins later. + + To check if something has collided with us, we'll need to the **on_body_entered** signal! To connect this, swap to the **Node** tab of the **Inspector** and click on the **Area2D** node in the **SceneTree** again. You'll see a list of all the signals we have available to us! + Click the **on_body_entered** signal and press **Connect** select the **Area2D (hitbox)** node and click **Connect** + + You'll see a new function appear in our script! On that'll be called whenever something enters this **Area2D** + + In here, we can check the **Group** of what we've collided with! Let's also add a check to see if we've collected a coin here, to save us some time later! + + ```gdscript + func _on_body_entered(body): + if body.is_in_group("enemy"): + take_damage() + elif body.is_in_group("health"): + heal(body) + elif body.is_in_group("coin"): + emit_signal("on_point_gained") + body.queue_free() + + ``` +5. that's it! Giving us a full script that looks something like this: + + ```gdscript + extends Area2D + + signal on_health_changed(new_health : int) + signal on_point_gained + @export var max_health : int = 6 + @onready var damage_timer = $damageTimer + var health : int + var can_take_damage : bool = true + + # Called when the node enters the scene tree for the first time. + func _ready(): + damage_timer.connect("timeout", allow_damage) + health = max_health emit_signal("on_health_changed", health) - body.queue_free() -``` - -Finally, we need a function that calls our **heal** and **damage** functions based on what we've collided with. To check what type of object we've collided with, we'll be using **Groups!** These are something we'll assign to our enemies/potions/coins later. - -To check if something has collided with us, we'll need to the **on_body_entered** signal! To connect this, swap to the **Node** tab of the **Inspector** and click on the **Area2D** node in the **SceneTree** again. You'll see a list of all the signals we have available to us! -Click the **on_body_entered** signal and press **Connect** select the **Area2D (hitbox)** node and click **Connect** - -You'll see a new function appear in our script! On that'll be called whenever something enters this **Area2D** - -In here, we can check the **Group** of what we've collided with! Let's also add a check to see if we've collected a coin here, to save us some time later! - -```gdscript -func _on_body_entered(body): - if body.is_in_group("enemy"): - take_damage() - elif body.is_in_group("health"): - heal(body) - elif body.is_in_group("coin"): - emit_signal("on_point_gained") - body.queue_free() - -``` -and that's it! Giving us a full script that looks something like this: - -```gdscript -extends Area2D - -signal on_health_changed(new_health : int) -signal on_point_gained -@export var max_health : int = 6 -@onready var damage_timer = $damageTimer -var health : int -var can_take_damage : bool = true - -# Called when the node enters the scene tree for the first time. -func _ready(): - damage_timer.connect("timeout", allow_damage) - health = max_health - emit_signal("on_health_changed", health) - -func _on_body_entered(): - if body.is_in_group("enemy"): - take_damage() - elif body.is_in_group("health"): - heal(body) - elif body.is_in_group("coin"): - emit_signal("on_point_gained") - body.queue_free() - -func take_damage(): - if can_take_damage: - health = health - 1 - emit_signal("on_health_changed", health) + func _on_body_entered(): + if body.is_in_group("enemy"): + take_damage() + elif body.is_in_group("health"): + heal(body) + elif body.is_in_group("coin"): + emit_signal("on_point_gained") + body.queue_free() + + + func take_damage(): + if can_take_damage: + health = health - 1 + emit_signal("on_health_changed", health) + + if health <= 0: + get_tree().paused = true + else: + can_take_damage = false + damage_timer.start() - if health <= 0: - get_tree().paused = true - else: - can_take_damage = false - damage_timer.start() - -func heal(body): - if health < max_health: - health = health + 1 - emit_signal("on_health_changed", health) - body.queue_free() - -func allow_damage(): - can_take_damage = true -``` + func heal(body): + if health < max_health: + health = health + 1 + emit_signal("on_health_changed", health) + body.queue_free() + + func allow_damage(): + can_take_damage = true + ``` + + :::note[Signals] + If you copy and paste the above, you'll still need to manually connect the **on_body_entered** signal! + ::: -**Note:** If you copy and paste the above, you'll still need to manually connect the **on_body_entered** signal! + And that's the player side of health done! Let's move onto the UI side! ### Health UI -Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! +#### UI Setup -Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whatever the size of our screen is, the health will always be pinned to the top left! +Time to start making some UI! + +1. Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" -Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) +2. Add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! -Let's also, to the **Root** node, and a child of type **Label** call it something like "diedLabel" + Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whatever the size of our screen is, the health will always be pinned to the top left! -In the inspector for this label, in the **Text** box, write "You Died!" then look for the **Theme Overrides** section, open this, find **Font Size** and change this to about 35px. -Next, in the 2D view of the UI, move the Text so that it's where you want it, I placed mine in the middle of the screen. Then, as we want this to be hidden by default, click the little 'eye' icon next to the label in the **SceneTree** to hide it! + Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) - Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points) +3. Let's also, to the **Root** node, and a child of type **Label** call it something like "diedLabel" - Add a script to the root node, calling it something like "ui.gd" + In the inspector for this label, in the **Text** box, write "You Died!" then look for the **Theme Overrides** section, open this, find **Font Size** and change this to about 35px. - Let's think about what we need this script to do: - 1. Store our three different heart images - 2. Recieve signals from our player when we take damage - 3. Update our health UI. +4. Next, in the 2D view of the UI, move the Text so that it's where you want it, I placed mine in the middle of the screen. Then, as we want this to be hidden by default, click the little 'eye' icon next to the label in the **SceneTree** to hide it! + - We'll set this up so that it automatically adjusts depending on the players **max_health** when the game is run, so you can easily have more (or less) than three hearts! - (Or, you could implement an item that increases your max hp!) +Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points) - Thankfully, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image +#### UI Scripting -Find these in your filesystem, and drag in the references, it should look something like this: + +1. Add a script to the root node, calling it something like "ui.gd" -```gdscript -const UI_HEART_EMPTY = preload("res://Assets/frames/ui_heart_empty.png") -const UI_HEART_FULL = preload("res://Assets/frames/ui_heart_full.png") -const UI_HEART_HALF = preload("res://Assets/frames/ui_heart_half.png") -``` + Let's think about what we need this script to do: + 1. Store our three different heart images + 2. Recieve signals from our player when we take damage + 3. Update our health UI. -Let's also get a reference to our **healthContainer** node, our **diedLabel** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) -We won't set this variable here, as it'll be set by whatever the most health we've had so far has been. + We'll set this up so that it automatically adjusts depending on the players **max_health** when the game is run, so you can easily have more (or less) than three hearts! + (Or, you could implement an item that increases your max hp!) + +2. Thankfully, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image + Find these in your filesystem, and drag in the references, it should look something like this: -```gdscript -@onready var health_cont = $healthContainer -@onready var died_label = $diedLabel -var maxHealth : int = 0 -``` -Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! + ```gdscript + const UI_HEART_EMPTY = preload("res://Assets/frames/ui_heart_empty.png") + const UI_HEART_FULL = preload("res://Assets/frames/ui_heart_full.png") + const UI_HEART_HALF = preload("res://Assets/frames/ui_heart_half.png") + ``` -1. If our health is set to 0, show the "You died text" Otherwise, If the health received is bigger than our highest health so far, make that our new highest health. Easy enough! +3. Let's also get a reference to our **healthContainer** node, our **diedLabel** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) + We won't set this variable here, as it'll be set by whatever the most health we've had so far has been. -```gdscript -func changed_health(newHealth : int): - if(newHealth == 0): - died_label.visible = true + ```gdscript + @onready var health_cont = $healthContainer + @onready var died_label = $diedLabel + var maxHealth : int = 0 + ``` +4. Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! - if newHealth > maxHealth: - maxHealth = newHealth -``` + If our health is set to 0, show the "You died text" Otherwise, If the health received is bigger than our highest health so far, make that our new highest health. Easy enough! -2. we'll want to check if we have enough hearts currently to represent that, if we don't, we'll need to add some more. (We'll create the function for this last) + ```gdscript + func changed_health(newHealth : int): + if(newHealth == 0): + died_label.visible = true -```gdscript - if(maxHealth/2 > health_cont.get_child_count()): - for h in (maxHealth/2) - health_cont.get_child_count(): - add_heart() -``` + if newHealth > maxHealth: + maxHealth = newHealth + ``` -3. we'll iterate through all the children our **healthContainer** node has, and assign an image based on the current health. +5. We'll want to check if we have enough hearts currently to represent that, if we don't, we'll need to add some more. (We'll create the function for this last) -This section may look complicated, but once you get your head around it, it's fairly simple! Spend some time looking over it, and thinking about the conditions for each heart to be drawn. -When I was figuring out how to program this, I found it useful to draw out the hearts on paper, at different levels of health! + ```gdscript + if(maxHealth/2 > health_cont.get_child_count()): + for h in (maxHealth/2) - health_cont.get_child_count(): + add_heart() + ``` -```gdscript -for i in health_cont.get_child_count(): - if (i * 2) + 1 < newHealth: - health_cont.get_child(i).texture = UI_HEART_FULL - elif (i * 2) < newHealth: - health_cont.get_child(i).texture = UI_HEART_HALF - else: - health_cont.get_child(i).texture = UI_HEART_EMPTY -``` +6. We'll iterate through all the children our **healthContainer** node has, and assign an image based on the current health. -giving us a full **changed_health** function that looks like this: + This section may look complicated, but once you get your head around it, it's fairly simple! Spend some time looking over it, and thinking about the conditions for each heart to be drawn. + When I was figuring out how to program this, I found it useful to draw out the hearts on paper, at different levels of health! -```gdscript -func changed_health(newHealth : int): - if newHealth > maxHealth: - maxHealth = newHealth - - if(maxHealth/2 > health_cont.get_child_count()): - for h in (maxHealth/2) - health_cont.get_child_count(): - add_heart() - + ```gdscript for i in health_cont.get_child_count(): - if (i * 2) + 1 < newHealth: - health_cont.get_child(i).texture = UI_HEART_FULL - elif (i * 2) < newHealth: - health_cont.get_child(i).texture = UI_HEART_HALF - else: - health_cont.get_child(i).texture = UI_HEART_EMPTY -``` + if (i * 2) + 1 < newHealth: + health_cont.get_child(i).texture = UI_HEART_FULL + elif (i * 2) < newHealth: + health_cont.get_child(i).texture = UI_HEART_HALF + else: + health_cont.get_child(i).texture = UI_HEART_EMPTY + ``` + +7. Giving us a full **changed_health** function that looks like this: + + ```gdscript + func changed_health(newHealth : int): + if newHealth > maxHealth: + maxHealth = newHealth + + if(maxHealth/2 > health_cont.get_child_count()): + for h in (maxHealth/2) - health_cont.get_child_count(): + add_heart() + + for i in health_cont.get_child_count(): + if (i * 2) + 1 < newHealth: + health_cont.get_child(i).texture = UI_HEART_FULL + elif (i * 2) < newHealth: + health_cont.get_child(i).texture = UI_HEART_HALF + else: + health_cont.get_child(i).texture = UI_HEART_EMPTY + ``` + + Not too bad! + +8. Let's add that **add_heart** function, which just creates and configures another child if we need one. -Not too bad! + ```gdscript + func add_heart(): + var img : TextureRect = TextureRect.new() + img.expand_mode = TextureRect.EXPAND_FIT_WIDTH + health_cont.add_child(img) + ``` -Let's add that **add_heart** function, which just creates and configures another child if we need one. +9. Let's also while we're here, add an empty function for our point system, which we'll come back to later! -```gdscript -func add_heart(): - var img : TextureRect = TextureRect.new() - img.expand_mode = TextureRect.EXPAND_FIT_WIDTH - health_cont.add_child(img) -``` + ```gdscript + func add_point(): + pass + ``` -Let's also while we're here, add an empty function for our point system, which we'll come back to later! +10. Save the scene as something like "UI.tscn" -```gdscript -func add_point(): - pass -``` + -Save the scene as something like "UI.tscn" +#### Getting things connected -Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that the UI 'sticks' to the camera, rather than existing within the game) + +1. Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that the UI 'sticks' to the camera, rather than existing within the game) -*Finally,* to get everything hooked up, we just need to connect that signal! Open up **hitbox.gd** +2. *Finally,* to get everything hooked up, we just need to connect that signal! Open up **hitbox.gd** -First, we'll get a reference to our new **UI** scene. Put this with the other variable declarations. +3. First, we'll get a reference to our new **UI** scene. Put this with the other variable declarations. -```gdscript -@onready var ui : Control = $"../../CanvasLayer/UI" -``` + ```gdscript + @onready var ui : Control = $"../../CanvasLayer/UI" + ``` -Then, finally, before we call the signal the first time, connect the signal with: +4. Then, finally, before we call the signal the first time, connect the signal with: -```gdscript -on_health_changed.connect(ui.changed_health) -``` -we'll also connect our point signal with: + ```gdscript + on_health_changed.connect(ui.changed_health) + ``` + we'll also connect our point signal with: -```gdscript -on_point_gained.connect(ui.add_point) -``` + ```gdscript + on_point_gained.connect(ui.add_point) + ``` + Run your game! And you should have 3 hearts! Great! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx index fa90b9a..dd1ee46 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx @@ -7,6 +7,7 @@ description: Implementing pickups for the player to collect import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Pickups @@ -23,61 +24,69 @@ Thankfully the setup for the two will be extremely simple, and they won't even n ### Coins -For coins, we'll create a new scene with a root node of **Staticbody2D** calling it something like "Coin" + -It should have a child of type **CollisionShape2D** +1. For coins, we'll create a new scene with a root node of **Staticbody2D** calling it something like "Coin" -We'll also want to add an **AnimatedSprite2D** to the root node. + It should have a child of type **CollisionShape2D** -Here's how my scene looks: +2. We'll also want to add an **AnimatedSprite2D** to the root node. -![Coin Scene](/src/assets/godot/dungeonCrawler/coinScene.png) + Here's how my scene looks: -We'll add the animation the same way we did with our player! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** create a new **Spriteframes** + ![Coin Scene](/src/assets/godot/dungeonCrawler/coinScene.png) -Click on the new **Spriteframes** and add sprites from file. (The coin has four frames) Make sure to click **autoplay** (The 'A' in the pointy box) -and then assign a shape to the **CollisionShape2D** that loosely matches the coin. (I just used a circle) +3. We'll add the animation the same way we did with our player! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** create a new **Spriteframes** -The coin as is is very small, so open the inspector for the root **Staticbody2D** and change the **Scale** values to 2. +4. Click on the new **Spriteframes** and add sprites from file. (The coin has four frames) Make sure to click **autoplay** (The 'A' in the pointy box) + and then assign a shape to the **CollisionShape2D** that loosely matches the coin. (I just used a circle) -Now, all that's left to do is create a **Group.** With the root **Staticbody2D** still selected, navigate to the **Node** tab of the inspector, then to the **Groups** tab. +5. The coin as it is very small, so open the inspector for the root **Staticbody2D** and change the **Scale** values to 2. -![Groups](/src/assets/godot/dungeonCrawler/groups.png) +6. Now, all that's left to do is create a **Group.** With the root **Staticbody2D** still selected, navigate to the **Node** tab of the inspector, then to the **Groups** tab. -In the box, type "coin" and click **Add** + ![Groups](/src/assets/godot/dungeonCrawler/groups.png) -Then, click **Manage Groups** and select each Node, followed by **Add** to ensure that each node in the scene is in the group. + In the box, type "coin" and click **Add** -Finally, we'll want to open the **Collision** tab on the inspector of the **Staticbody2D** setting the **Layer** to *only* 2, and deselecting all numbers under the **Mask** as we don't want our coin to be looking for collisions, or to be physically collided with! +7. Then, click **Manage Groups** and select each Node, followed by **Add** to ensure that each node in the scene is in the group. + +8. Finally, we'll want to open the **Collision** tab on the inspector of the **Staticbody2D** setting the **Layer** to *only* 2, and deselecting all numbers under the **Mask** as we don't want our coin to be looking for collisions, or to be physically collided with! + + And that's our coin! The only script work we need to do is in our **UI** script! But first we'll need to add a UI element to track our points! Don't worry, we've done all the hard work of connecting signals earlier! This'll be nice and easy! -Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it something like "pointContainer" + + +1. Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it something like "pointContainer" + +2. Give it two children, a **TextureRect** and a **Label,** name the label something like **pointsLabel** -Give it two children, a **TextureRect** and a **Label,** name the label something like **pointsLabel** +3. In the inspector of the **TextureRect** set the **Expand Mode** to "Fit Width" and assign the first coin image to the **Texture** field using the **Load** Option -In the inspector of the **TextureRect** set the **Expand Mode** to "Fit Width" and assign the first coin image to the **Texture** field using the **Load** Option +4. Finally for UI setup, in the inspector of the **Label** write "0" in the **Text** field. You'll notice this is pretty small! Scroll down in the **Inspector** until you see **Theme Overrides.** in this section you'll find **Font Sizes.** Set this to something you think looks good! I went with 40px. -Finally for UI setup, in the inspector of the **Label** write "0" in the **Text** field. You'll notice this is pretty small! Scroll down in the **Inspector** until you see **Theme Overrides.** in this section you'll find **Font Sizes.** Set this to something you think looks good! I went with 40px. +5. Great! Now we just need to add two lines of code to our UI. and then our points are done! -Great! Now we just need to add two lines of code to our UI. and then our points are done! + First, a reference to our label, same way we've been doing, this should be second nature by now! -First, a reference to our label, same way we've been doing, this should be second nature by now! + ```gdscript + @onready var points_label = $pointContainer/pointsLabel + ``` -```gdscript -@onready var points_label = $pointContainer/pointsLabel -``` + then, we'll finish the function we created earlier. -then, we'll finish the function we created earlier. + ```gdscript + func add_point(): + points_label.text = str(int(points_label.text) + 1) + ``` + This looks a little silly, but what we're doing is taking the current text in the label, converting it to a number, adding 1 to it, and then converting to *back* to a string. -```gdscript -func add_point(): - points_label.text = str(int(points_label.text) + 1) -``` -This looks a little silly, but what we're doing is taking the current text in the label, converting it to a number, adding 1 to it, and then converting to *back* to a string. + If you've set it all up right, you should notice this number going up each time you pick up a coin! Add a few instances of the coin scene to your level to test! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx index 720fae8..e3fa00e 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx @@ -6,6 +6,7 @@ description: Adding an enemy for the player to fight --- import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Enemies @@ -25,117 +26,122 @@ We'll be keeping our enemy fairly simple, it'll operate off a circular detection Let's get to making the scene! -It'll need: a root **CharacterBody2D** (Called "Enemy") with three children: a **CollisionShape2D,** an **Area2D** (named "range") and an **AnimatedSprite2D** + -Additionally we'll want to give the **Area2D** a **CollisionShape2D** as a child. +1. It'll need: a root **CharacterBody2D** (Called "Enemy") with three children: a **CollisionShape2D,** an **Area2D** (named "range") and an **AnimatedSprite2D** -![Enemy Scene](/src/assets/godot/dungeonCrawler/enemyScene.png) + Additionally we'll want to give the **Area2D** a **CollisionShape2D** as a child. -First, on the **CharacterBody2D** under the **Collision** section, we'll want **Layer** **2** and **3** selected. With only **3** selected under **Mask** + ![Enemy Scene](/src/assets/godot/dungeonCrawler/enemyScene.png) -Let's skip down to setting up the **AnimatedSprite2D.** Create two animations, call the first "idle" and the second "move". Then, pick something to be your enemy! Selecting both the idle and move animation as we did for the player, using the **Add from file** button. +2. First, on the **CharacterBody2D** under the **Collision** section, we'll want **Layer** **2** and **3** selected. With only **3** selected under **Mask** -You may want to speed the animations up as they're fairly slow by default, I found 10 fps to be good for both! You'll also want to make sure you set the **idle** animation to be autoplay! +3. Let's skip down to setting up the **AnimatedSprite2D.** Create two animations, call the first "idle" and the second "move". Then, pick something to be your enemy! Selecting both the idle and move animation as we did for the player, using the **Add from file** button. -Set the **CollisionShape2D** that's a child of the root node to have a shape that generally matches the sprite. + You may want to speed the animations up as they're fairly slow by default, I found 10 fps to be good for both! You'll also want to make sure you set the **idle** animation to be autoplay! -Set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! +4. Set the **CollisionShape2D** that's a child of the Root node to have a shape that generally matches the sprite. -Finally, let's create a new **Group** and call it "enemy", and assign it to the root node of the scene. +5. Set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! -### Enemy Scripting - -Now let's get the enemy moving! - -Let's create some variables: -1. a boolean to keep track of if the player is in range -2. a reference to the player -3. a variable to control our speed - -It should look something like this, again getting the reference to the **AnimatedSprite2D** the usual way: -```gdscript -var in_range : bool = false -var target - -@export var speed : float = 50.0 -@onready var animated_sprite_2d = $AnimatedSprite2D -``` - -Then, we'll want to connect two signals from the "range" **Area2D** node, we'll want to connect both the "on_body_entered" and "on_body_exited" signals to the script we created! - -Let's write those functions. When the player enters the range, we'll want to set our **in_range** boolean, and play our move animation - -``` gdscript -func _on_range_body_entered(body): - if(body.is_in_group("player")): - in_range = true - target = body - animated_sprite_2d.play("move") -``` - -and in the exited function, we'll want to do the inverse! - -```gdscript -func _on_range_body_exited(body): - if(body.is_in_group("player")): - in_range = false - animated_sprite_2d.play("idle") -``` - -Now, in the **_process()** function, we'll want to check if our player is in range, if they are, move toward them. We'll also want to flip our sprite based on where the player is in relation to the enemy. - -```gdscript -func _process(delta): - if(in_range): +6. Finally, let's create a new **Group** and call it "enemy", and assign it to the root node of the scene. - velocity = (target.global_position - global_position).normalized() * speed + - if(target.global_position.x < global_position.x): - animated_sprite_2d.flip_h = true - else: - animated_sprite_2d.flip_h = false - - move_and_slide() -``` - -for a final script that looks like this: - -```gdscript - -extends CharacterBody2D - -var in_range : bool = false -var target - -@export var speed : float = 50.0 -@onready var animated_sprite_2d = $AnimatedSprite2D +### Enemy Scripting -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta): - if(in_range): - - velocity = (target.global_position - global_position).normalized() * speed - - if(target.global_position.x < global_position.x): - animated_sprite_2d.flip_h = true - else: - animated_sprite_2d.flip_h = false - move_and_slide() +Now let's get the enemy moving! + +1. Let's create some variables: + 1. a boolean to keep track of if the player is in range + 2. a reference to the player + 3. a variable to control our speed + + It should look something like this, again getting the reference to the **AnimatedSprite2D** the usual way: + ```gdscript + var in_range : bool = false + var target + + @export var speed : float = 50.0 + @onready var animated_sprite_2d = $AnimatedSprite2D + ``` + +2. Then, we'll want to connect two signals from the "range" **Area2D** node, we'll want to connect both the "on_body_entered" and "on_body_exited" signals to the script we created! + + Let's write those functions. When the player enters the range, we'll want to set our **in_range** boolean, and play our move animation + + ``` gdscript + func _on_range_body_entered(body): + if(body.is_in_group("player")): + in_range = true + target = body + animated_sprite_2d.play("move") + ``` + +3. In the exited function, we'll want to do the inverse! + + ```gdscript + func _on_range_body_exited(body): + if(body.is_in_group("player")): + in_range = false + animated_sprite_2d.play("idle") + ``` + +4. Now, in the **_process()** function, we'll want to check if our player is in range, if they are, move toward them. We'll also want to flip our sprite based on where the player is in relation to the enemy. + + ```gdscript + func _process(delta): + if(in_range): + + velocity = (target.global_position - global_position).normalized() * speed + + if(target.global_position.x < global_position.x): + animated_sprite_2d.flip_h = true + else: + animated_sprite_2d.flip_h = false + + move_and_slide() + ``` + +5. For a final script that looks like this: + + ```gdscript + + extends CharacterBody2D + + var in_range : bool = false + var target + + @export var speed : float = 50.0 + @onready var animated_sprite_2d = $AnimatedSprite2D + + # Called every frame. 'delta' is the elapsed time since the previous frame. + func _process(delta): + if(in_range): + + velocity = (target.global_position - global_position).normalized() * speed + + if(target.global_position.x < global_position.x): + animated_sprite_2d.flip_h = true + else: + animated_sprite_2d.flip_h = false + move_and_slide() + - -func _on_range_body_entered(body): - if(body.is_in_group("player")): - in_range = true - target = body - animated_sprite_2d.play("move") + func _on_range_body_entered(body): + if(body.is_in_group("player")): + in_range = true + target = body + animated_sprite_2d.play("move") -func _on_range_body_exited(body): - if(body.is_in_group("player")): - in_range = false - animated_sprite_2d.play("idle") + func _on_range_body_exited(body): + if(body.is_in_group("player")): + in_range = false + animated_sprite_2d.play("idle") -``` + ``` + and that's it! The last thing we need to do is head over to our **Player** scene, create a group called "player" and add the root node of the scene to it. @@ -145,36 +151,38 @@ Although there's one problem... We can't destroy it! ### Destroying the enemy! -Head to your weapon scene and open the **weapon.gd** script. We'll just need to make some slight modifications to check if the sword is colliding with enemies when we attack. +Head to your Weapon Scene and open the **weapon.gd** script. We'll just need to make some slight modifications to check if the sword is colliding with enemies when we attack. -First, let's get a reference to the **Area2D** node. + +1. First, let's get a reference to the **Area2D** node. -```gdscript -@onready var area_2d = $Sprite2D/Area2D -``` -Then, in our **_process()** function, if we're attacking, we'll want to get all the bodies we're colliding with and check if they're enemies. + ```gdscript + @onready var area_2d = $Sprite2D/Area2D + ``` +2. Then, in our **_process()** function, if we're attacking, we'll want to get all the bodies we're colliding with and check if they're enemies. -```gdscript -if attacking: - for body in area_2d.get_overlapping_bodies(): - if body.is_in_group("enemy"): - body.queue_free() -``` + ```gdscript + if attacking: + for body in area_2d.get_overlapping_bodies(): + if body.is_in_group("enemy"): + body.queue_free() + ``` -leaving the **_process():** function looking like this: +3. Leaving the **_process():** function looking like this: -```gdscript -func _process(delta): - look_at(get_global_mouse_position()) - - if Input.is_action_just_pressed("Attack"): - animation_player.play("Attack") + ```gdscript + func _process(delta): + look_at(get_global_mouse_position()) - if attacking: - for body in area_2d.get_overlapping_bodies(): - if body.is_in_group("enemy"): - body.queue_free() -``` + if Input.is_action_just_pressed("Attack"): + animation_player.play("Attack") + + if attacking: + for body in area_2d.get_overlapping_bodies(): + if body.is_in_group("enemy"): + body.queue_free() + ``` + Test it out, and hopefully you'll find you can now destroy the enemies! diff --git a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx index 8c0462b..778f278 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx @@ -1,12 +1,13 @@ --- type: tutorial unitTitle: More Levels -title: Another Floors +title: Adding more levels description: Adding a level-switching system to our game --- import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Another floor @@ -30,37 +31,43 @@ To create multiple levels, we'll want to save each level and *everything* in the An easy way to remember what we want to store in a level, is by thinking of what we want to *belong* or exist as part of the level! Now, for our levels, we'll obviously need our **TileMapLayers!** But we don't want to be redoing **all** of the tileset settings each time... So what we'll want to do, is save a blank version of our current **TileMapLayers** so that we can reuse them! + +1. Let's go to what is currently our testing scene, go to your **TileMapLayers** and erase all the tiles you've painted, so it's just two blank **TileMapLayers** with all of our settings and our assets loaded. Now, let's right-click the parent node of **both** **TileMapLayers** and click **Save Branch as Scene** calling it something like "Level_Template" -So go to what is currently our testing scene, go to your **TileMapLayers** and erase all the tiles you've painted, so it's just two blank **TileMapLayers** with all of our settings and our assets loaded. Now, let's right-click the parent node of **both** **TileMapLayers** and click **Save Branch as Scene** calling it something like "Level_Template" +2. Great! Now we can get to actually setting up our first level! A level will only *Need* a couple of things to function: -Great! Now we can get to actually setting up our first level! A level will only *Need* a couple of things to function: + 1. The **TileMapLayers** + 2. A node that represents the players spawn -1. The **TileMapLayers** -2. A node that represents the players spawn + Anything else, like enemies or coins, are optional -Anything else, like enemies or coins, are optional +3. Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling "player_spawn" -Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling "player_spawn" +4. To edit the two **TileMapLayers** we'll need to right click on the **Level_Template** we imported, and tick **editable children** which makes this a unique instance of the scene, which we want anyway! -To edit the two **TileMapLayers** we'll need to right click on the **Level_Template** we imported, and tick **editable children** which makes this a unique instance of the scene, which we want anyway! + And that's the most basic form of a level setup! From here, paint the level using the **TileMap** (Remembering to use the right layers for walls and floors) and adding enemies, potions, and coins, all as children of the **Root** node. -And that's the most basic form of a level setup! From here, paint the level using the **TileMap** (Remembering to use the right layers for walls and floors) and adding enemies, potions, and coins, all as children of the **Root** node. +5. Once you've made a level, save the scene. Creating a new folder called "Levels" to store it in! Try creating two levels "level_1" and "level_2" making sure they're somewhat different, so you can tell when you've changed levels. -Once you've made a level, save the scene. Creating a new folder called "Levels" to store it in! Try creating two levels "level_1" and "level_2" making sure they're somewhat different, so you can tell when you've changed levels. +6. You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. -You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. + -Here's an example of a level I made: +Here's an example of a level I made, take note of the order of the nodes in the SceneTree: ![Initial Scene](/src/assets/godot/dungeonCrawler/createdLevel.png) ### Level Loader -The very last step for our game, is creating something to actually transition us between levels! But first, let's quickly clean up our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) +The very last step for our game, is creating something to actually transition us between levels! + +1. But first, let's quickly clean up our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) -We'll add one additional node as a child of the **root** node called "levelHolder" +2. We'll add one additional node as a child of the **root** node called "levelHolder" -From your filesystem, drag your newly created "level_1.tscn" onto the **levelHolder** so that it becomes its child, as we want level 1 to be loaded from the start! +3. From your filesystem, drag your newly created "level_1.tscn" onto the **levelHolder** so that it becomes its child, as we want level 1 to be loaded from the start! + + Here's how my **World** scene looks: @@ -68,45 +75,47 @@ Here's how my **World** scene looks: We'll make that **level_transition** node now! -For the final scene of our project, let's create a new scene, with a root **Node2D** called something like "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** + -Set the shape of the **CollisionShape2D** to be a square. +1. For the final scene of our project, let's create a new scene, with a root **Node2D** called something like "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** -let's create a script attached to the root node, called something like "level_transition.gd" +2. Set the shape of the **CollisionShape2D** to be a square. -Let's think about the variables for this script: +3. let's create a script attached to the root node, called something like "level_transition.gd" -1. The level we want to load (We'll use an \@export for this) -2. A reference to our "levelHolder" node -3. A reference to our player, to set their position +4. Let's think about the variables for this script: -```gdscript -@export var to_load : PackedScene + 1. The level we want to load (We'll use an \@export for this) + 2. A reference to our "levelHolder" node + 3. A reference to our player, to set their position -@onready var levelHolder : Node2D = $"../../../levelHolder" -@onready var player : CharacterBody2D = $"../../../player" -``` + ```gdscript + @export var to_load : PackedScene -Great! The \@export will allow us to assign what level want to load from each level, within the editor! + @onready var levelHolder : Node2D = $"../../../levelHolder" + @onready var player : CharacterBody2D = $"../../../player" + ``` -Now, if the player enters this region, we'll + Great! The \@export will allow us to assign what level want to load from each level, within the editor! -1. Remove the last Level -2. Load the new level -3. Set the players position +5. Now, if the player enters this region, we'll -```gdscript -func _on_area_2d_body_entered(body): - if(body.is_in_group("player")): - levelHolder.get_child(0).queue_free() - var loaded = to_load.instantiate() - levelHolder.call_deferred("add_child",loaded) - player.global_position = loaded.get_node("player_spawn").position -``` + 1. Remove the last Level + 2. Load the new level + 3. Set the players position -Great! Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so the player expects the change) -And in the inspector of the **level_transition,** *after* you've added an instance to a scene, find the level you want it to open in your filesystem, and drag it into the "to_load" slot. + ```gdscript + func _on_area_2d_body_entered(body): + if(body.is_in_group("player")): + levelHolder.get_child(0).queue_free() + var loaded = to_load.instantiate() + levelHolder.call_deferred("add_child",loaded) + player.global_position = loaded.get_node("player_spawn").position + ``` +6. Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so the player expects the change) + And in the inspector of the **level_transition,** *after* you've added an instance to a scene, find the level you want it to open in your filesystem, and drag it into the "to_load" slot. + ### Checklist diff --git a/src/content/docs/game-design/godot/dungeoncrawler/9-finish/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/9-finish/index.mdx index ca6fa16..75e2fc6 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/9-finish/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/9-finish/index.mdx @@ -1,12 +1,13 @@ --- type: tutorial unitTitle: The End -title: Finishing up +title: The End description: Some final comments on our dungeon crawler game --- import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; +import { Steps } from '@astrojs/starlight/components'; ## Finishing up! From c0c374334f57fb557ec87fcc3ea7368ecec16ee9 Mon Sep 17 00:00:00 2001 From: Darkflame72 Date: Mon, 7 Oct 2024 21:48:14 +1300 Subject: [PATCH 26/29] fix: use correct file extension --- src/assets/godot/dotNet/{DevKit.PNG => DevKit.png} | Bin .../godot/dotNet/{GDDownload.PNG => GDDownload.png} | Bin src/assets/godot/dotNet/{editor.PNG => editor.png} | Bin .../godot/dotNet/{godotbuild.PNG => godotbuild.png} | Bin .../godot/dotNet/{typeSelect.PNG => typeSelect.png} | Bin .../{TextureFilter.PNG => TextureFilter.png} | Bin .../dungeonCrawler/{addanim.PNG => addanim.png} | Bin .../{animlength.PNG => animlength.png} | Bin .../{animtimeline.PNG => animtimeline.png} | Bin .../godot/dungeonCrawler/{assets.PNG => assets.png} | Bin .../dungeonCrawler/{autoloop.PNG => autoloop.png} | Bin .../{basicroomimg.PNG => basicroomimg.png} | Bin .../dungeonCrawler/{coinScene.PNG => coinScene.png} | Bin .../{collshapeimg.PNG => collshapeimg.png} | Bin .../{createdLevel.PNG => createdLevel.png} | Bin .../dungeonCrawler/{eraseTool.PNG => eraseTool.png} | Bin .../dungeonCrawler/{folders.PNG => folders.png} | Bin .../godot/dungeonCrawler/{groups.PNG => groups.png} | Bin .../dungeonCrawler/{idleanim.PNG => idleanim.png} | Bin .../{inittestscene.PNG => inittestscene.png} | Bin ...{inputmappreinputs.PNG => inputmappreinputs.png} | Bin ...{inputswithbuttons.PNG => inputswithbuttons.png} | Bin .../dungeonCrawler/{layersimg.PNG => layersimg.png} | Bin ...iptsetpimage.PNG => movementscriptsetpimage.png} | Bin .../{playerscenebasic.PNG => playerscenebasic.png} | Bin .../{recttoolimg.PNG => recttoolimg.png} | Bin ...rdsceneinspector.PNG => swordsceneinspector.png} | Bin ...esetphysicslayer.PNG => tilesetphysicslayer.png} | Bin .../dungeonCrawler/{walkanim.PNG => walkanim.png} | Bin .../{wallcolliders.PNG => wallcolliders.png} | Bin .../{weaponscenetree.PNG => weaponscenetree.png} | Bin .../{worldScene.PNG => worldScene.png} | Bin 32 files changed, 0 insertions(+), 0 deletions(-) rename src/assets/godot/dotNet/{DevKit.PNG => DevKit.png} (100%) rename src/assets/godot/dotNet/{GDDownload.PNG => GDDownload.png} (100%) rename src/assets/godot/dotNet/{editor.PNG => editor.png} (100%) rename src/assets/godot/dotNet/{godotbuild.PNG => godotbuild.png} (100%) rename src/assets/godot/dotNet/{typeSelect.PNG => typeSelect.png} (100%) rename src/assets/godot/dungeonCrawler/{TextureFilter.PNG => TextureFilter.png} (100%) rename src/assets/godot/dungeonCrawler/{addanim.PNG => addanim.png} (100%) rename src/assets/godot/dungeonCrawler/{animlength.PNG => animlength.png} (100%) rename src/assets/godot/dungeonCrawler/{animtimeline.PNG => animtimeline.png} (100%) rename src/assets/godot/dungeonCrawler/{assets.PNG => assets.png} (100%) rename src/assets/godot/dungeonCrawler/{autoloop.PNG => autoloop.png} (100%) rename src/assets/godot/dungeonCrawler/{basicroomimg.PNG => basicroomimg.png} (100%) rename src/assets/godot/dungeonCrawler/{coinScene.PNG => coinScene.png} (100%) rename src/assets/godot/dungeonCrawler/{collshapeimg.PNG => collshapeimg.png} (100%) rename src/assets/godot/dungeonCrawler/{createdLevel.PNG => createdLevel.png} (100%) rename src/assets/godot/dungeonCrawler/{eraseTool.PNG => eraseTool.png} (100%) rename src/assets/godot/dungeonCrawler/{folders.PNG => folders.png} (100%) rename src/assets/godot/dungeonCrawler/{groups.PNG => groups.png} (100%) rename src/assets/godot/dungeonCrawler/{idleanim.PNG => idleanim.png} (100%) rename src/assets/godot/dungeonCrawler/{inittestscene.PNG => inittestscene.png} (100%) rename src/assets/godot/dungeonCrawler/{inputmappreinputs.PNG => inputmappreinputs.png} (100%) rename src/assets/godot/dungeonCrawler/{inputswithbuttons.PNG => inputswithbuttons.png} (100%) rename src/assets/godot/dungeonCrawler/{layersimg.PNG => layersimg.png} (100%) rename src/assets/godot/dungeonCrawler/{movementscriptsetpimage.PNG => movementscriptsetpimage.png} (100%) rename src/assets/godot/dungeonCrawler/{playerscenebasic.PNG => playerscenebasic.png} (100%) rename src/assets/godot/dungeonCrawler/{recttoolimg.PNG => recttoolimg.png} (100%) rename src/assets/godot/dungeonCrawler/{swordsceneinspector.PNG => swordsceneinspector.png} (100%) rename src/assets/godot/dungeonCrawler/{tilesetphysicslayer.PNG => tilesetphysicslayer.png} (100%) rename src/assets/godot/dungeonCrawler/{walkanim.PNG => walkanim.png} (100%) rename src/assets/godot/dungeonCrawler/{wallcolliders.PNG => wallcolliders.png} (100%) rename src/assets/godot/dungeonCrawler/{weaponscenetree.PNG => weaponscenetree.png} (100%) rename src/assets/godot/dungeonCrawler/{worldScene.PNG => worldScene.png} (100%) diff --git a/src/assets/godot/dotNet/DevKit.PNG b/src/assets/godot/dotNet/DevKit.png similarity index 100% rename from src/assets/godot/dotNet/DevKit.PNG rename to src/assets/godot/dotNet/DevKit.png diff --git a/src/assets/godot/dotNet/GDDownload.PNG b/src/assets/godot/dotNet/GDDownload.png similarity index 100% rename from src/assets/godot/dotNet/GDDownload.PNG rename to src/assets/godot/dotNet/GDDownload.png diff --git a/src/assets/godot/dotNet/editor.PNG b/src/assets/godot/dotNet/editor.png similarity index 100% rename from src/assets/godot/dotNet/editor.PNG rename to src/assets/godot/dotNet/editor.png diff --git a/src/assets/godot/dotNet/godotbuild.PNG b/src/assets/godot/dotNet/godotbuild.png similarity index 100% rename from src/assets/godot/dotNet/godotbuild.PNG rename to src/assets/godot/dotNet/godotbuild.png diff --git a/src/assets/godot/dotNet/typeSelect.PNG b/src/assets/godot/dotNet/typeSelect.png similarity index 100% rename from src/assets/godot/dotNet/typeSelect.PNG rename to src/assets/godot/dotNet/typeSelect.png diff --git a/src/assets/godot/dungeonCrawler/TextureFilter.PNG b/src/assets/godot/dungeonCrawler/TextureFilter.png similarity index 100% rename from src/assets/godot/dungeonCrawler/TextureFilter.PNG rename to src/assets/godot/dungeonCrawler/TextureFilter.png diff --git a/src/assets/godot/dungeonCrawler/addanim.PNG b/src/assets/godot/dungeonCrawler/addanim.png similarity index 100% rename from src/assets/godot/dungeonCrawler/addanim.PNG rename to src/assets/godot/dungeonCrawler/addanim.png diff --git a/src/assets/godot/dungeonCrawler/animlength.PNG b/src/assets/godot/dungeonCrawler/animlength.png similarity index 100% rename from src/assets/godot/dungeonCrawler/animlength.PNG rename to src/assets/godot/dungeonCrawler/animlength.png diff --git a/src/assets/godot/dungeonCrawler/animtimeline.PNG b/src/assets/godot/dungeonCrawler/animtimeline.png similarity index 100% rename from src/assets/godot/dungeonCrawler/animtimeline.PNG rename to src/assets/godot/dungeonCrawler/animtimeline.png diff --git a/src/assets/godot/dungeonCrawler/assets.PNG b/src/assets/godot/dungeonCrawler/assets.png similarity index 100% rename from src/assets/godot/dungeonCrawler/assets.PNG rename to src/assets/godot/dungeonCrawler/assets.png diff --git a/src/assets/godot/dungeonCrawler/autoloop.PNG b/src/assets/godot/dungeonCrawler/autoloop.png similarity index 100% rename from src/assets/godot/dungeonCrawler/autoloop.PNG rename to src/assets/godot/dungeonCrawler/autoloop.png diff --git a/src/assets/godot/dungeonCrawler/basicroomimg.PNG b/src/assets/godot/dungeonCrawler/basicroomimg.png similarity index 100% rename from src/assets/godot/dungeonCrawler/basicroomimg.PNG rename to src/assets/godot/dungeonCrawler/basicroomimg.png diff --git a/src/assets/godot/dungeonCrawler/coinScene.PNG b/src/assets/godot/dungeonCrawler/coinScene.png similarity index 100% rename from src/assets/godot/dungeonCrawler/coinScene.PNG rename to src/assets/godot/dungeonCrawler/coinScene.png diff --git a/src/assets/godot/dungeonCrawler/collshapeimg.PNG b/src/assets/godot/dungeonCrawler/collshapeimg.png similarity index 100% rename from src/assets/godot/dungeonCrawler/collshapeimg.PNG rename to src/assets/godot/dungeonCrawler/collshapeimg.png diff --git a/src/assets/godot/dungeonCrawler/createdLevel.PNG b/src/assets/godot/dungeonCrawler/createdLevel.png similarity index 100% rename from src/assets/godot/dungeonCrawler/createdLevel.PNG rename to src/assets/godot/dungeonCrawler/createdLevel.png diff --git a/src/assets/godot/dungeonCrawler/eraseTool.PNG b/src/assets/godot/dungeonCrawler/eraseTool.png similarity index 100% rename from src/assets/godot/dungeonCrawler/eraseTool.PNG rename to src/assets/godot/dungeonCrawler/eraseTool.png diff --git a/src/assets/godot/dungeonCrawler/folders.PNG b/src/assets/godot/dungeonCrawler/folders.png similarity index 100% rename from src/assets/godot/dungeonCrawler/folders.PNG rename to src/assets/godot/dungeonCrawler/folders.png diff --git a/src/assets/godot/dungeonCrawler/groups.PNG b/src/assets/godot/dungeonCrawler/groups.png similarity index 100% rename from src/assets/godot/dungeonCrawler/groups.PNG rename to src/assets/godot/dungeonCrawler/groups.png diff --git a/src/assets/godot/dungeonCrawler/idleanim.PNG b/src/assets/godot/dungeonCrawler/idleanim.png similarity index 100% rename from src/assets/godot/dungeonCrawler/idleanim.PNG rename to src/assets/godot/dungeonCrawler/idleanim.png diff --git a/src/assets/godot/dungeonCrawler/inittestscene.PNG b/src/assets/godot/dungeonCrawler/inittestscene.png similarity index 100% rename from src/assets/godot/dungeonCrawler/inittestscene.PNG rename to src/assets/godot/dungeonCrawler/inittestscene.png diff --git a/src/assets/godot/dungeonCrawler/inputmappreinputs.PNG b/src/assets/godot/dungeonCrawler/inputmappreinputs.png similarity index 100% rename from src/assets/godot/dungeonCrawler/inputmappreinputs.PNG rename to src/assets/godot/dungeonCrawler/inputmappreinputs.png diff --git a/src/assets/godot/dungeonCrawler/inputswithbuttons.PNG b/src/assets/godot/dungeonCrawler/inputswithbuttons.png similarity index 100% rename from src/assets/godot/dungeonCrawler/inputswithbuttons.PNG rename to src/assets/godot/dungeonCrawler/inputswithbuttons.png diff --git a/src/assets/godot/dungeonCrawler/layersimg.PNG b/src/assets/godot/dungeonCrawler/layersimg.png similarity index 100% rename from src/assets/godot/dungeonCrawler/layersimg.PNG rename to src/assets/godot/dungeonCrawler/layersimg.png diff --git a/src/assets/godot/dungeonCrawler/movementscriptsetpimage.PNG b/src/assets/godot/dungeonCrawler/movementscriptsetpimage.png similarity index 100% rename from src/assets/godot/dungeonCrawler/movementscriptsetpimage.PNG rename to src/assets/godot/dungeonCrawler/movementscriptsetpimage.png diff --git a/src/assets/godot/dungeonCrawler/playerscenebasic.PNG b/src/assets/godot/dungeonCrawler/playerscenebasic.png similarity index 100% rename from src/assets/godot/dungeonCrawler/playerscenebasic.PNG rename to src/assets/godot/dungeonCrawler/playerscenebasic.png diff --git a/src/assets/godot/dungeonCrawler/recttoolimg.PNG b/src/assets/godot/dungeonCrawler/recttoolimg.png similarity index 100% rename from src/assets/godot/dungeonCrawler/recttoolimg.PNG rename to src/assets/godot/dungeonCrawler/recttoolimg.png diff --git a/src/assets/godot/dungeonCrawler/swordsceneinspector.PNG b/src/assets/godot/dungeonCrawler/swordsceneinspector.png similarity index 100% rename from src/assets/godot/dungeonCrawler/swordsceneinspector.PNG rename to src/assets/godot/dungeonCrawler/swordsceneinspector.png diff --git a/src/assets/godot/dungeonCrawler/tilesetphysicslayer.PNG b/src/assets/godot/dungeonCrawler/tilesetphysicslayer.png similarity index 100% rename from src/assets/godot/dungeonCrawler/tilesetphysicslayer.PNG rename to src/assets/godot/dungeonCrawler/tilesetphysicslayer.png diff --git a/src/assets/godot/dungeonCrawler/walkanim.PNG b/src/assets/godot/dungeonCrawler/walkanim.png similarity index 100% rename from src/assets/godot/dungeonCrawler/walkanim.PNG rename to src/assets/godot/dungeonCrawler/walkanim.png diff --git a/src/assets/godot/dungeonCrawler/wallcolliders.PNG b/src/assets/godot/dungeonCrawler/wallcolliders.png similarity index 100% rename from src/assets/godot/dungeonCrawler/wallcolliders.PNG rename to src/assets/godot/dungeonCrawler/wallcolliders.png diff --git a/src/assets/godot/dungeonCrawler/weaponscenetree.PNG b/src/assets/godot/dungeonCrawler/weaponscenetree.png similarity index 100% rename from src/assets/godot/dungeonCrawler/weaponscenetree.PNG rename to src/assets/godot/dungeonCrawler/weaponscenetree.png diff --git a/src/assets/godot/dungeonCrawler/worldScene.PNG b/src/assets/godot/dungeonCrawler/worldScene.png similarity index 100% rename from src/assets/godot/dungeonCrawler/worldScene.PNG rename to src/assets/godot/dungeonCrawler/worldScene.png From ae2894246b8ebf94f4aa7f03110ebca87efb0ee1 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Tue, 8 Oct 2024 18:48:16 +1300 Subject: [PATCH 27/29] Resolves all changes except intro/screenshots --- .../dungeoncrawler/0-scenesetup/index.mdx | 6 +++--- .../godot/dungeoncrawler/1-player/index.mdx | 18 +++++++++++------- .../godot/dungeoncrawler/2-level/index.mdx | 6 +++--- .../3-playerimprovement/index.mdx | 6 +++--- .../godot/dungeoncrawler/4-weapon/index.mdx | 10 +++++----- .../godot/dungeoncrawler/5-health/index.mdx | 16 ++++++++-------- .../godot/dungeoncrawler/6-pickups/index.mdx | 7 ++++--- .../godot/dungeoncrawler/8-levels/index.mdx | 14 +++++++++----- 8 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx index a1d4975..6efe7e5 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx @@ -14,7 +14,7 @@ import { Steps } from '@astrojs/starlight/components'; This is a guide to making a 2-dimensional dungeon crawling game in [Godot](https://godotengine.org/). If you are unfamiliar with Godot, check out the [Godot basics](/game-design/godot/basics) doc as this tutorial assumes basic knowledge of navigating and using the Godot Engine. :::note[Version] -This guide is up-to-date with Godot 4.3 stable official release but will most likely work with any 4.x release. +This guide is up-to-date with Godot 4.3 stable official release, and will likely work with any version of Godot newer than 4.3. Due to the use of **TileMapLayers** which were introduced in 4.3, this tutorial isn't compatible with any version pre 4.3 ::: We'll be making a game in which the player explores a multi-floor dungeon in a top-down perspective. This project will include: @@ -44,12 +44,12 @@ Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing -1. First let's create a new folder, and call it something like 'Assets' +1. First let's create a new folder, and call it 'Assets' Then, let's extract the assets from the folder we downloaded, and at them into our Assets folder. Mine looks like this, but it's fine if yours looks slightly different. ![Assets](/src/assets/godot/dungeonCrawler/assets.png) -2. Let's also create two new top level folders called **Scripts** and **Scenes** +2. Let's also create two new top level folders called 'Scripts' and 'Scenes' ![Folders](/src/assets/godot/dungeonCrawler/folders.png) diff --git a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx index 3afd5b7..e55b911 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx @@ -23,8 +23,7 @@ Great! Let's start by making a basic version of our player character that will l -1. Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** - Give the **CharacterBody2D** a name like **Player** +1. Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. Call it 'Player' 2. Give it two children: A **CollisionShape2D** and an **AnimatedSprite2D** @@ -35,7 +34,7 @@ Here's how my scene looks with no other modifications: ![Basic player scene](/src/assets/godot/dungeonCrawler/playerscenebasic.png) -Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it something like **Player.tscn** +Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it **Player.tscn** ### Animations @@ -59,7 +58,7 @@ Let's give ourselves something to look at! Hit play to test! You'll see the player now has an idle animation that loops! -5. Let's add our character's walking animation. Add a new animation using the **Add animation** Button and call it something like "Walk" +5. Let's add our character's walking animation. Add a new animation using the **Add animation** Button and call it "Walk" ![Idle Animation Frames](/src/assets/godot/dungeonCrawler/addanim.png) @@ -95,6 +94,8 @@ With our script created and attached, let's get to programming our movement! 1. First, let's set up a variable to control our speed. ```gdscript + extends CharacterBody2D + @export var speed = 200 ``` @@ -107,12 +108,15 @@ With our script created and attached, let's get to programming our movement! var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") ``` -3. We'll then multiply this vector by our speed, and then invoke Godots built-in **move_and_slide()** function +3. We'll then add some lines to multiply this vector by our speed, and then invoke Godots built-in **move_and_slide()** function, which actually does the moving! ```gdscript - velocity = direction * speed + func _physics_process(delta): + var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") - move_and_slide() + velocity = direction * speed + + move_and_slide() ``` 4. giving us a final script that looks like this: diff --git a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx index 13252bf..ddd9fb0 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx @@ -21,11 +21,11 @@ import { Steps } from '@astrojs/starlight/components'; Let's move onto giving us something to walk around on! -1. Create a new scene. Give it a node2D as its root node, and call it something like "World" +1. Create a new scene. Give it a node2D as its root node, and call it "World" - Save the scene in our Scenes folder, calling it something like "world.tscn". + Save the scene in our Scenes folder, calling it "world.tscn". -2. Give our root node a child of type **Node2D** and call it something like "level" +2. Give our root node a child of type **Node2D** and call it "level" 3. To this node, add two children of type **TilemapLayer** diff --git a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx index 79e704e..299741e 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx @@ -99,7 +99,7 @@ Great! Let's get to changing our animation! ```gdscript if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") + animated_sprite_2d.play("walk") ``` 3. If we're not moving, let's play our idle @@ -147,14 +147,14 @@ I'll be adding this section **beneath** the animation section, but before the ** 2. If our x velocity is less than 0 (moving to the left) we want to flip our sprite. ```gdscript - animated_sprite_2d.flip_h = true + animated_sprite_2d.flip_h = true ``` 3. And if it's greater than 0, we'll unflip it ```gdscript elif(velocity.x > 0): - animated_sprite_2d.flip_h = false + animated_sprite_2d.flip_h = false ``` 4. Giving us a movement script that looks like this: diff --git a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx index 1e12cab..b250221 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx @@ -24,7 +24,7 @@ Let's give our player something to attack with! Let's make our weapon! 1. Create a new scene for our weapon! - Give it a Root node of a **Node2D** and name it something like "Weapon" + Give it a Root node of a **Node2D** and name it "Weapon" 2. Give it two children, a **Sprite2D** and a **Animationplayer** Give the **Sprite2D** a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** @@ -33,7 +33,7 @@ Let's make our weapon! ![Weapon scenetree](/src/assets/godot/dungeonCrawler/weaponscenetree.png) - Make sure you save the scene, calling it something like "Weapon.tscn" + Make sure you save the scene, calling it "Weapon.tscn" 3. Let's start by picking a sprite for our weapon, so we can see what we're working with! Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! @@ -45,7 +45,7 @@ Let's make our weapon! 5. let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** - Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** + Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to **20px** Here's how my sword scene and inspector look: @@ -56,7 +56,7 @@ Let's make our weapon! ### Weapon Script -1. Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" +1. Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it "weapon.gd" We'll need this script to do two things: @@ -146,7 +146,7 @@ Great! Let's get our weapon added to our player! ### Adding our weapon to our player -Navigate to your player scene. From the filesystem, drag in your weapon scene (Likely called something like **weapon.tscn**) and attach it as a child of the main +Navigate to your player scene. From the filesystem, drag in your weapon scene (called **weapon.tscn**) and attach it as a child of the main **CharacterBody2D** node. Play your game, and you should hopefully have a weapon that rotates around the player and stabs when you click it! If it doesn't seem to be rotating around the middle of the player sprite, feel free to adjust its position within the Player scene. diff --git a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx index 82a851c..46fc555 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx @@ -23,18 +23,18 @@ Godot Documentation for nodes discussed in this section: Let's start setting up our health system on the player side! 1. We'll start by adding a new Node to our player Scene, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** - give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." + give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to "Hitbox." In the **Inspector** of the **Area2D** Navigate to the **Collision** section. Deselect all numbers under the **Layer** Section, and ensure *only* 2 is selected under the **Mask** Section. Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** -2. Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! +2. Let's give the **Area2D** one more child of type **Timer** and name it "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! In the timer's inspector, set its **Wait Time** field to 0.5s Great! this **Area2D** will be used to detect collision with enemies, potions, and coins! For now we'll just be setting it up to handle health, both healing and damage. -3. Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" +3. Let's attach a script to the **Area2D** (that we named "Hitbox") and call it "hitbox.gd" 4. This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its functionality up into multiple scripts, but for our scope this is fine! Let's break down what we need it to do: @@ -205,15 +205,15 @@ And that's the player side of health done! Let's move onto the UI side! Time to start making some UI! -1. Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" +1. Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node "UI" 2. Add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whatever the size of our screen is, the health will always be pinned to the top left! - Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) + Rename the node to "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) -3. Let's also, to the **Root** node, and a child of type **Label** call it something like "diedLabel" +3. Let's also, to the **Root** node, and a child of type **Label** call it "diedLabel" In the inspector for this label, in the **Text** box, write "You Died!" then look for the **Theme Overrides** section, open this, find **Font Size** and change this to about 35px. @@ -225,7 +225,7 @@ Great! That's all the UI setup we'll need to do for now (Though we'll come back #### UI Scripting -1. Add a script to the root node, calling it something like "ui.gd" +1. Add a script to the root node, calling it "ui.gd" Let's think about what we need this script to do: 1. Store our three different heart images @@ -326,7 +326,7 @@ Great! That's all the UI setup we'll need to do for now (Though we'll come back pass ``` -10. Save the scene as something like "UI.tscn" +10. Save the scene as "UI.tscn" diff --git a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx index dd1ee46..f84f75a 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx @@ -26,7 +26,7 @@ Thankfully the setup for the two will be extremely simple, and they won't even n -1. For coins, we'll create a new scene with a root node of **Staticbody2D** calling it something like "Coin" +1. For coins, we'll create a new scene with a root node of **Staticbody2D** calling it "Coin" It should have a child of type **CollisionShape2D** @@ -53,6 +53,7 @@ Thankfully the setup for the two will be extremely simple, and they won't even n 8. Finally, we'll want to open the **Collision** tab on the inspector of the **Staticbody2D** setting the **Layer** to *only* 2, and deselecting all numbers under the **Mask** as we don't want our coin to be looking for collisions, or to be physically collided with! +9. Save the scene as "Coin.tscn" And that's our coin! The only script work we need to do is in our **UI** script! But first we'll need to add a UI element to track our points! @@ -61,9 +62,9 @@ Don't worry, we've done all the hard work of connecting signals earlier! This'll -1. Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it something like "pointContainer" +1. Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it "pointContainer" -2. Give it two children, a **TextureRect** and a **Label,** name the label something like **pointsLabel** +2. Give it two children, a **TextureRect** and a **Label,** name the label "pointsLabel" 3. In the inspector of the **TextureRect** set the **Expand Mode** to "Fit Width" and assign the first coin image to the **Texture** field using the **Load** Option diff --git a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx index 778f278..4926bc4 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx @@ -32,7 +32,7 @@ An easy way to remember what we want to store in a level, is by thinking of what Now, for our levels, we'll obviously need our **TileMapLayers!** But we don't want to be redoing **all** of the tileset settings each time... So what we'll want to do, is save a blank version of our current **TileMapLayers** so that we can reuse them! -1. Let's go to what is currently our testing scene, go to your **TileMapLayers** and erase all the tiles you've painted, so it's just two blank **TileMapLayers** with all of our settings and our assets loaded. Now, let's right-click the parent node of **both** **TileMapLayers** and click **Save Branch as Scene** calling it something like "Level_Template" +1. Let's go to what is currently our testing scene, go to your **TileMapLayers** and erase all the tiles you've painted, so it's just two blank **TileMapLayers** with all of our settings and our assets loaded. Now, let's right-click the parent node of **both** **TileMapLayers** and click **Save Branch as Scene** calling it "Level_Template.tscn" 2. Great! Now we can get to actually setting up our first level! A level will only *Need* a couple of things to function: @@ -41,7 +41,7 @@ Now, for our levels, we'll obviously need our **TileMapLayers!** But we don't wa Anything else, like enemies or coins, are optional -3. Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling "player_spawn" +3. Let's create a new scene with a root **Node2D** and call it "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling "player_spawn" 4. To edit the two **TileMapLayers** we'll need to right click on the **Level_Template** we imported, and tick **editable children** which makes this a unique instance of the scene, which we want anyway! @@ -51,6 +51,8 @@ Now, for our levels, we'll obviously need our **TileMapLayers!** But we don't wa 6. You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. +7. Save the scene as "level_1.tscn" + Here's an example of a level I made, take note of the order of the nodes in the SceneTree: @@ -77,11 +79,11 @@ We'll make that **level_transition** node now! -1. For the final scene of our project, let's create a new scene, with a root **Node2D** called something like "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** +1. For the final scene of our project, let's create a new scene, with a root **Node2D** called "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** 2. Set the shape of the **CollisionShape2D** to be a square. -3. let's create a script attached to the root node, called something like "level_transition.gd" +3. let's create a script attached to the root node, called "level_transition.gd" 4. Let's think about the variables for this script: @@ -113,7 +115,9 @@ We'll make that **level_transition** node now! player.global_position = loaded.get_node("player_spawn").position ``` -6. Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so the player expects the change) +6. Save the scene as "level_transition.tscn" + +7. Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so the player expects the change) And in the inspector of the **level_transition,** *after* you've added an instance to a scene, find the level you want it to open in your filesystem, and drag it into the "to_load" slot. From 0b7e82f82f46d37e9b111c74406bed7db6aeed9f Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Wed, 9 Oct 2024 01:21:08 +1300 Subject: [PATCH 28/29] Added preview + Refactored headings for clarity in tutorial tracker --- .../godot/dungeonCrawler/screenshot.PNG | Bin 0 -> 57964 bytes .../dungeoncrawler/0-scenesetup/index.mdx | 25 +++++++++++------- .../godot/dungeoncrawler/1-player/index.mdx | 8 +++--- .../godot/dungeoncrawler/2-level/index.mdx | 8 +++--- .../3-playerimprovement/index.mdx | 10 +++---- .../godot/dungeoncrawler/4-weapon/index.mdx | 11 ++++---- .../godot/dungeoncrawler/5-health/index.mdx | 13 +++++---- .../godot/dungeoncrawler/6-pickups/index.mdx | 9 +++---- .../godot/dungeoncrawler/7-enemy/index.mdx | 9 +++---- .../godot/dungeoncrawler/8-levels/index.mdx | 5 ++-- 10 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 src/assets/godot/dungeonCrawler/screenshot.PNG diff --git a/src/assets/godot/dungeonCrawler/screenshot.PNG b/src/assets/godot/dungeonCrawler/screenshot.PNG new file mode 100644 index 0000000000000000000000000000000000000000..65a65f98ab58b6de681221e421107e0c77ee38fe GIT binary patch literal 57964 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%0D=RU&8VqY=hE@U%MS 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 Cq1m_q literal 0 HcmV?d00001 diff --git a/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx index 6efe7e5..bb212d0 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/0-scenesetup/index.mdx @@ -17,17 +17,20 @@ This is a guide to making a 2-dimensional dungeon crawling game in [Godot](https This guide is up-to-date with Godot 4.3 stable official release, and will likely work with any version of Godot newer than 4.3. Due to the use of **TileMapLayers** which were introduced in 4.3, this tutorial isn't compatible with any version pre 4.3 ::: -We'll be making a game in which the player explores a multi-floor dungeon in a top-down perspective. This project will include: -- Movement -- Attacking -- Health loss & Gain -- Pickups (Coins & Potions) -- Enemies +## What you'll be making -We will not be creating our own assets as part of this project, although you are of course welcome to! +![Screenshot preview of the game](/src/assets/godot/dungeonCrawler/screenshot.png) -We'll instead be using a free asset pack by Ox72 on Itch.IO which [can be found here](https://0x72.itch.io/dungeontileset-ii) Just click *Download now* followed by *No thanks, just take me to the download* and download the file called *0x72_DungeonTilesetII_v1.7.zip* +In this tutorial, you'll work step by step through creating your very own Dungeon Crawler! In this game, the player will navigate through a multi-level dungeon of your design, full of enemies to fight, and treasure to collect! +You'll learn to: +- Create an animated player character +- Create enemies that chase and attack the player +- Create a User Interface that tracks health and points +- Switch levels +- Design 2D Combat + +Let's jump right in! ## Making the project @@ -38,9 +41,11 @@ Godot Documentation for nodes discussed in this section: ::: -Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing our assets. +We won't be creating our own assets as part of this project, we'll instead be using a free asset pack by Ox72 on Itch.IO which [can be found here](https://0x72.itch.io/dungeontileset-ii) Just click *Download now* followed by *No thanks, just take me to the download* and download the file called *0x72_DungeonTilesetII_v1.7.zip* +Create a new 2D project, using the Forward+ Renderer. +Let's start by importing our assets! @@ -61,7 +66,7 @@ Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing -### Checklist +## Checklist - [ ] I have imported the assets - [ ] I have setup my folders and changed the settings diff --git a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx index e55b911..a15dc3d 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx @@ -36,7 +36,7 @@ Here's how my scene looks with no other modifications: Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it **Player.tscn** -### Animations +## Animations Let's give ourselves something to look at! @@ -71,7 +71,7 @@ Let's give ourselves something to look at! Great! That's our animations all done! -### Collision +## Collision Now that we have something to look at, let's give our player a hitbox. @@ -87,7 +87,7 @@ Now that we have something to look at, let's give our player a hitbox. With our script created and attached, let's get to programming our movement! -### Movement +## Movement @@ -140,7 +140,7 @@ Switch back to 2D view at the top of the screen. And that's our player ready to go for now! -### Checklist +## Checklist - [ ] I've created the player scene - [ ] I've setup the animations diff --git a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx index ddd9fb0..1ae5792 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx @@ -8,7 +8,7 @@ description: Setting up a basic test level import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; -## Building a level +## Level Scene :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -82,7 +82,7 @@ Here's what my room looks like: Don't go too crazy on your level design just now! This first area will just be to test! ::: -### Adding our player to the level +## Adding our player to the level Now that we have a basic level set up, let's add our player to it so we can start to properly test our game! To do this, we'll just drag our player scene from the **Scenes** folder in the file browser, into our **scene tree** as a child of the root node! Finally, we'll give the player a child of type **Camera2D.** here's what my scene looks like: @@ -93,7 +93,7 @@ Don't worry if the names of your nodes are different, leave them as they are for You should be able to move around! Though you'll quickly notice you're able to walk through walls, which isn't ideal, so let's fix that! -### Level collision +## Level collision 1. Click on your **Walls TilemapLayer** Node, Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. @@ -125,7 +125,7 @@ You should be able to move around! Though you'll quickly notice you're able to w Now try playing your game again! You'll notice you actually collide with the walls! Great! -### Checklist +## Checklist - [ ] I've set up the Tilemaps - [ ] I've added collision diff --git a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx index 299741e..e85740d 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx @@ -9,7 +9,6 @@ import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; import { Steps } from '@astrojs/starlight/components'; -## Improving our player :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -23,7 +22,8 @@ make sure our animation changes to our walking animation when we move, and make We'll also be implementing attacking, but we'll do that in its own section! -### Input mapping +## Input mapping + 1. To change our inputs, we'll first need to set up our **Input Map** to do this, we'll navigate to **Project -> Project Settings** in the top left of the workspace. @@ -65,7 +65,7 @@ if you run your game, you'll notice your inputs are now changed! We won't assign our Attack option just yet, but it's good we've created it already. -### Animation switching +## Animation switching To change our animation depending on if we're moving or not, we'll only need to add a few lines to our script. But first, we'll need a reference to our **AnimatedSprite2D** in our script. @@ -131,7 +131,7 @@ Great! Let's get to changing our animation! Play your game, and you'll notice your animation changes when you move! -### Sprite facing +## Sprite facing To flip our player based on the direction we're moving, all we really need to do is add another If to check only the **Horizontal** part of our velocity, as thankfully the **AnimatedSprite2D** node has a built-in way to flip our sprite! @@ -190,7 +190,7 @@ I'll be adding this section **beneath** the animation section, but before the ** Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! -### Checklist +## Checklist - [ ] I've setup the Inputs - [ ] My sprite flips from left to right diff --git a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx index b250221..181bcd8 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx @@ -9,7 +9,6 @@ import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; import { Steps } from '@astrojs/starlight/components'; -## Creating our Weapon :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -19,7 +18,7 @@ Godot Documentation for nodes discussed in this section: Let's give our player something to attack with! -### Weapon Scene +## Weapon Scene Let's make our weapon! @@ -54,7 +53,7 @@ Let's make our weapon! 6. Before we move on, navigate to the inspector tab of the **Area2D** node and find the **Collision** tab, under **Layer** make sure nothing is selected. Under **Mask** Make sure *only* 2 is selected. -### Weapon Script +## Weapon Script 1. Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it "weapon.gd" @@ -105,7 +104,7 @@ Let's make our weapon! ``` -### Sword Animation +## Sword Animation Now, let's start creating our attack animation! @@ -144,7 +143,7 @@ And that's it! We'll come back later to add the code for destroying enemies. Great! Let's get our weapon added to our player! -### Adding our weapon to our player +## Adding our weapon to our player Navigate to your player scene. From the filesystem, drag in your weapon scene (called **weapon.tscn**) and attach it as a child of the main **CharacterBody2D** node. @@ -155,7 +154,7 @@ You're also welcome to adjust the size of the weapon (Although, you're best to d -### Checklist +## Checklist - [ ] I've created the weapon scene - [ ] I've created the weapon script diff --git a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx index 46fc555..3e8f1eb 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx @@ -9,7 +9,6 @@ import Box from '/src/components/tutorial/Box.astro'; import Checklist from '/src/components/tutorial/Checklist.astro'; import { Steps } from '@astrojs/starlight/components'; -## Health :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -18,7 +17,7 @@ Godot Documentation for nodes discussed in this section: ::: -### Player Health +## Giving our player Health Let's start setting up our health system on the player side! @@ -199,9 +198,9 @@ Let's start setting up our health system on the player side! And that's the player side of health done! Let's move onto the UI side! -### Health UI +## Health UI -#### UI Setup +### UI Setup Time to start making some UI! @@ -222,7 +221,7 @@ Time to start making some UI! Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points) -#### UI Scripting +### UI Scripting 1. Add a script to the root node, calling it "ui.gd" @@ -330,7 +329,7 @@ Great! That's all the UI setup we'll need to do for now (Though we'll come back -#### Getting things connected +### Getting things connected 1. Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that the UI 'sticks' to the camera, rather than existing within the game) @@ -359,7 +358,7 @@ Run your game! And you should have 3 hearts! Great! -### Checklist +## Checklist - [ ] I've given the player a hitbox - [ ] I've created the health UI diff --git a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx index f84f75a..b8e03fa 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx @@ -1,7 +1,7 @@ --- type: tutorial unitTitle: Pickups -title: Health & Coins +title: Potions & Coins description: Implementing pickups for the player to collect --- @@ -9,7 +9,6 @@ import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; import { Steps } from '@astrojs/starlight/components'; -## Pickups :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -22,7 +21,7 @@ Let's get onto pickups! Our game will have two types of pickups: Coins, and Poti Thankfully the setup for the two will be extremely simple, and they won't even need a script! As all logic is handled by our hitbox script! -### Coins +## Coins @@ -91,14 +90,14 @@ Don't worry, we've done all the hard work of connecting signals earlier! This'll If you've set it all up right, you should notice this number going up each time you pick up a coin! Add a few instances of the coin scene to your level to test! -### Potions +## Potions For potions the process is exactly the same! You should be able to do it on your own! Just follow the steps for creating the coin scene. Except in this case we'll just want a regular **Sprite2D** As the potion sprite isn't animated, and we'll want the group to be called "health" (make sure it matches the line we wrote in **hitbox.gd**) Don't worry if you don't seem to be able to pick up the potions! It's probably because you have full health! -### Checklist +## Checklist - [ ] I've created a coin pickup - [ ] I've created a potion pickup diff --git a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx index e3fa00e..fadd790 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx @@ -8,7 +8,6 @@ import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; import { Steps } from '@astrojs/starlight/components'; -## Enemies :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -22,7 +21,7 @@ Something to fight! We'll be keeping our enemy fairly simple, it'll operate off a circular detection range, and walk toward the player if it enters that range, without taking into account walls (Though it will of course still collide with walls) -### Enemy Scene +## Enemy Scene Let's get to making the scene! @@ -48,7 +47,7 @@ Let's get to making the scene! -### Enemy Scripting +## Enemy Scripting Now let's get the enemy moving! @@ -149,7 +148,7 @@ Add an enemy to the scene, and you should notice that if you get close to it, it Although there's one problem... We can't destroy it! -### Destroying the enemy! +## Destroying the enemy! Head to your Weapon Scene and open the **weapon.gd** script. We'll just need to make some slight modifications to check if the sword is colliding with enemies when we attack. @@ -187,7 +186,7 @@ Head to your Weapon Scene and open the **weapon.gd** script. We'll just need to Test it out, and hopefully you'll find you can now destroy the enemies! -### Checklist +## Checklist - [ ] I've created the enemy scene - [ ] I've created the enemy script diff --git a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx index 4926bc4..853222e 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx @@ -9,7 +9,6 @@ import Checklist from '/src/components/tutorial/Checklist.astro'; import Box from '/src/components/tutorial/Box.astro'; import { Steps } from '@astrojs/starlight/components'; -## Another floor :::note[Godot Documentation] Godot Documentation for nodes discussed in this section: @@ -24,7 +23,7 @@ Until now, our game has only had one level. Let's change that! Thankfully, Godot Let's get straight into it! -### Creating Multiple Levels +## Creating Multiple Levels To create multiple levels, we'll want to save each level and *everything* in the level, as a **Scene.** A level should contain **Everything** that we want to be part of the level, such as enemies, coins, and potions. However we *don't* want the player or the UI to be saved in the level. @@ -59,7 +58,7 @@ Here's an example of a level I made, take note of the order of the nodes in the ![Initial Scene](/src/assets/godot/dungeonCrawler/createdLevel.png) -### Level Loader +## Level Loader The very last step for our game, is creating something to actually transition us between levels! From 484773039de759d3ec120c02928913b3a7ebfbe1 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Thu, 10 Oct 2024 21:40:18 +1300 Subject: [PATCH 29/29] fixed file extension --- .../{screenshot.PNG => screenshot.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/assets/godot/dungeonCrawler/{screenshot.PNG => screenshot.png} (100%) diff --git a/src/assets/godot/dungeonCrawler/screenshot.PNG b/src/assets/godot/dungeonCrawler/screenshot.png similarity index 100% rename from src/assets/godot/dungeonCrawler/screenshot.PNG rename to src/assets/godot/dungeonCrawler/screenshot.png

    a>c}dF8?%7Px0mo_({DzqNgdbEjdRZ-vZ@t$gdBp_Z@zh`e@qM*7PScSy5YJ?WJn2u`J@tq%DzCd^ z3jo(!N}qH;{5n*Kzt%&^AX|!;7k2$N9Pc&gWz(z)vG1{IaWy9|*YBSI6V~t}Euo&q z{y({9ZW=36xome1MIFGh+_9sEFG43xy?aVsvc8nD`zeP)Twd>4M8&eZy55|Zo4|6q zM<@$a_WH-F@Y$`?DEz8+KfvX%r}fa5Huhve6+{-h+j{NO#yh&AsP)5yyVgTLJCx?S zUt~Wjrbc{D?|zG$ zXi9mf{BnL&Pw<}I621qEyjgSq4{h%q)nwXr4>O~KI*3?CQG%eNSP)Suks47ciV7-4 zDT#=JfDn3zs36WD0TB^Jnj+GPh!{#jMi>c22qkm~A|>>i5E3Byt~oHiX#sr##2zo zK~JH%}7kHOPD!1&P}_8$z2siw(+0%pwk_6X-4ow z0e@Hl0nhvG{-Iy?jy~B$U7gi{bwNiW87B>};q|fS}#_cs+G@ z{iKh(9q(k=uQ(Fh(W^Vzq?9d++7O2D_B%G*vCWb#oKYGsa;zgx-qZw@yU(07^4h6# zo6Y^wFtweZVtgHDr-o5Mk>^#bvR2*pQ7E4%Q_~tE>#N8$70=eoO!^kM^y5hj4zn|& zq}7P|!54M%6h~nM3WJ$9wJVeGJu^!SSY;HK5@B^-P1cXegy%GmsY~8}aH#0O{K#ji zqz5)Nzxrx$cZd0_UzEBN=D9B1f->R*5t4P3P7!NgZ3+=o9DJQUr8J`IJ}jU7;dD}B ze?lg0>*;Ds5l3M(x1AKa`%Q#d!uE+jbB#35UZ_uMvfr(Vohs9j0vfZEbo|KJ2G4tl z`BFrvMtiROJV&1-%(E`dGUAS)Fq_ES&m!C%9GmD*4{o7GZ7?X)b3R@$eUP^YYxU-P zk{XWT-Ii#*Fg%@+*&g6NPY_#U4dJhQu)zv=b%cEa=WU=^V?{IOL+~%#NBOPJSV#=$ zl-V9Pc*MObWV7=~SYw6^xz|@+AE$=Nnl5?vxXF9m=BLE9D>hSqi;&lGyaLw1`2B?$ z-1bUwpWeytJLkfK)D!$9G}@+Z^XW9~5kQhQvL9Q`Li@d%T9^?<35z0qj9O-Et-2#A z#cRh2EKP!XOqef?=cJ!M@b=2sRspJ2plHFb{ZI1n_w_Xv4nD&5UC!e8tlP>qV}Y7Z za-uaakX&X(kM-0fyiI;)7U8{{TDL>{gxDIJTUbU@jJ^h2L3Q=p;b#^QDecR3d8*J^ z6)iZG=p=1q-(wLUeg;15E1MeeQ2XvPQp=RvEZRO=3!^c`tm5^Y2_{G1V7eK@raO-m4rf2eJDLJi zZy##V`Xg(xd(fHNV@BmD`~AbPcg38^LMG#`eW5FlA!Rks`9e$jn%6%Q!;F(oKqQ6p>%=d;MiJmQIlT>sz1y@VTau$u7HQ8FZ8RH| z?Q)jJ^4fJNL$5ohQwD+y!O`ZTL}RimMsX^jD>RLB78mQ?(@cV~akEtuq7-!tV1Ais zov?~VMPsqDSGO>Od%`Kc9bhmC9C4pvc_0*$pl>Q?Le`y_lH_)dm!d!gY4<%V%$5M} z;i*|75O#~Uk0$3}c+I2-V0u@JgLdM`|O!v0xM6zAUJ!Co#{ta%r?zx&HIv@iaGt!j<;W4AIX&~UND^G9_hg|CLJR1_>leofsfm8e6;Mg+4rN%^I0zt+CUHQIra^jjPF}+uImOy)r4Bq}s!7NO+&; z%)bqcVK&Gl=r^1-utJfo-9HX5={svJ?8(eAsVP5#d;k4lt+uN));4gR*g!5zygvUb zZ7lyGCEUA@iDxNu%gj_ufq?FpW~4!6@X;?HbmCW68PhJZk&byvGx^Tl)Jb~qW_b3R zA_P}0RJCU$U0LAa$x@*Opb0@r6~83r;l;$hqVF$Jjiv{RAksgv2Q}yTT|kZ$3>kzI z@xy`XuGDMI@#-Q_^A;+4(RIcp0QOf)Vi~aYynr5rprZYg zkK^ct23}v$pVp%xUcXfHF6Sh=WYRV(0y>&0rAx^AAR4*Ozq8M#8wh1Z^VlL7*n-cO zrvnHcx$8cKH4^&alU(zm2T(hP>BhnPKuK$CY(Yw0-^X##gu%L@@CubByw8_lq1}MO zIL4cPzy`@94KB$%%^@^9DX6eHOIpfVBZ!$lSCnkeK>x8jb<*x4acVxVM#$!(DV+#7 zmq*uAskJw266Oc~^fG!NcqramC>vmgc+X%NYf3oESF^gY*)X9&P_b#na|vP3PFIqu zpa2u3bh~`<8b$0UX7)|+NAWtqn{rAJQ??$ybxszXHjCM}V>XrS$(Bztbi<+SLZ9)j zF6|{BU`P0^yFNQl!)t}z|cfJ;Jqbph7c+bLMb-7u8Lw!U0?K9zd4L3Pe zu9NXesiM?ZtL=PP^e)gS6m;rnMgh{8pBNxk?UMwDpR(&1EZ`VnreC#t6+-#1?Kscj z+=jhp!@BT*yhHgj2d}r{wm7JfU`?^FWEgjCIk}D<8m;hZatH?cwSvahHo&>5$qY?6 z=IEzpJzVcfonDZXG%xs7H+#O7_j#O4OJ5!Z-HVsWC#vD?YV7=NDHY!`*fV^;>c(PiU}hXevino<1V0hO7nxA8P^P~ z$V^~gp~W*yM{V)vdaO9m`PeR{Zbl#TB+XRwoUF3uIZk2TnY}1LV}n5DtP#2HvvR*E z7BHNB7LTobaBSWA)vlMs{P`(xFymCFo?a?hCFw67-}zSktU9mWsiVTCOhDVwTl#t2 zwW{}`Ru5emYf|n3uSQ*sz)qWeChrsWQnR`~Dx>681^vEMn96<{_ZF>WxKtG74+~Fr z71*IuclA{(hYI>y{5I3hd!t)CV@Ggp-1UKiC(UZb?zODm6HN)bg9ZIE_$MpAi@Qr4 zG3D8&dY?bGG8?G}k#FCgDO|r|;jEG-@%AgTB|8GA!G2NP-)XK7XFuObfAdo)V47=U zsp14@J;GaU(1+kl|Ls-r!o1!m-RU4D!_ET2SZKlq{{=#`lK%pcTR3@9CY61QRZ|J@ z_Y>eq!*$+115a*C+q^(baL5RZVJO-spD*T<_`pJIMFB6yByxx`O-T-KSln-9{(j@T zn)^Za&F+aOZEgp0zto57q;SNhlVaNtpKFs!gXbjIf}`r-2)lRMYjc>nQPT8t5Gfpp z*GKRUfHPkdvdKZ)L@kg;A_4^=K#HNs?74)G!c;)kS1egz7dJq6~nLUg?Z*j^#es=kAGWZ7X((BRbR=h z`&!%BL~UD1BZbt-u;$2OW19USk&6Uf1nUyDS8UC5?PisZqmY{`nmq`{2GdE3tg-;D z0B+W9qVHg7>~I>()mSOt_P0;381u++>%1v8Txv#AV(1p{{32IwMQ0amdZ1^%FwGEqi|Jw$BG$d>#LY0Vy~5Ch9A<>0?oXYbDa^ zKHs2fR^u=x?9dosjI`^Uk9*^;q(^CenCo%~N2(RxDtt@fw(TjpH~n!y);wD@ z8JD1@fp$&b&R|ZKh1An~)SIpEim4|wXBe5X=O27&T5NOLl}~Ewo1%^Xe0-bWE3^+$^_uEWL{BJ zs?(GoGwkV|+)oYJn{?9(!ZoFq^((N!6fiAKx^G zO=gW9p(mc_P&ag-&BRt@+&Ox`|3Wg!pZ3J@uimMe7q3vN7_P*qT=>WK!~@TZ&(khv zl)F}SSIe5I#$#lcDvY6_UvdSB0tSK*%~yPB;ZAICUC+Gx&@lzphCCKouY$g$*607! zKVs6l+#a{{j^9(@v%b1uFijH4`s3YsU4tZ)y+D$?F(_ScNBNZZG>}cpruDt)I2LDM z(m29Zk7P>0U811iuPeE4=-TuY42&Zp;{F~JHx1!yDVP+FnJN9A{Qj(I+8kI35X9!x zvbZMyM84f{kg(%b`(W^U;EC5`$9=>c{(_64wTU}UtcX@Pt84rDrTa_Cz!;AV=DZ4f z{)Sb01MCI^4Z3zLHh=ZB2X4mV#d-g}_?nS>JBY{O??A{D<>=RZ$zH0sY0~&%Gb%6| zG*>szyBl*f0h4Z=pgAsw2s{ceH_XDmeF?i+{gS6Exi{6;9+R?|J@ib+$o}{?T6beU z>KPlK7QL1j&2$0vlPBB3NesmEo|wY=^1|>xYgT*OF<RF63GnA0&r8nDJ8L0pz=5QyyW-M=Vi`Ej+@`tTGoLE&>U%!K1FTi~Aeia3b6$m`z8 zoBjPg0~g5OC#sF0DXG6WfA+`y4}ZH#12uIFF2ye2XQd)rkciN%767%mX@7uU^FBiY zIgPRH8@`vkGs=`uSU3!7`^S2+$DZ4ro(?2@i+^-s6QxO3YYX^V$;ezW}{IG;5 zvp@M=&D);ASn-1C|HmKl`j zzwT|gu(5u1XYEYM zGeaVF+^|Nwpw>ByW#>{sNs0pDLs)q5H#ei90;JzgQq!&GA5)Z*18Vvra%Jl4^$RXEdHvCS*D zhavZZH}Ozax~(3eOaiP8aCC9}i{{MQ5YeoFZ#Jb=>W9Q#scEvFN#-PqIy&1J>k*b8Tn+9 zxJ5HcIWaF_H)xktYca2&iEUc9NO~mZc-_0_TUkO7*HueO_+0?yX*b#j1i z>#!TtW*kDuLB$XtVE{YY2~i1_O?sf_34=&cYU)ccDrYfri5rj(QpDMLv$SXq{wO48 z+lS37-N8b=vHWlxfmz%jw9Cuyw__mvK;YzOtnRJ9Hv5jQJZ-EA` z6LYi<8lT#$i#{`hGJtbmGz&nE>Ko@JP_vc-Xmr93z)tG1R#h&nAJu4l&gg#AE<5n%H^BiDdVVjYlg0M}!BqbEm)8vBT}wHIi*u+5###X! zP}(Vx;4i=ElH`oZYWHb=TL@B6|GKfH@Wo}HOAB87pb0OwFo*zcF4ufFfnP5J%J)w% zxq&(h#vkVY)K^AhgeU>lfYAa7h{gP$x+P84z2ud%@84HxC)F%Wd&uy+**zTKR*`hP*;havIgUjHG)#ew0(EM80ZJ=jSMcit;o8TBpepcvhwzv&`mrc5aQL_2cspY8clqLfd<0ElPQ?yLKpHXvH{kj1 zJw<#y$pSjilWgxqag_!HpE^1Xva|++qw9OXKV!5zCmv$_PML9<7f-x6sHu#`x)BX+47zYs{m}E zC)@Suz2*PqhZ9_-7Od=?e|CqrsZHyo+xf8XKZM1&vdmfesc^aE|J$Yi>*q*Sq%5L0 zpjE-QCxrfLyZPJN$<@j>y<*>rck7;C8V8~BUE z+|rYAqliVdGoo1CAfOKg?1R0f<=Z<>p|v;P|ZYG){d$fbVyXx zgAds`v9z5N!DlWJeAZstRn99S?Kw0zDZc5d)qLYm*VAbhX5QVq#dcCE9_N$RiGnWmapBboed;7bfv1MptX&-^F9^XB)q;dY|+I3I#p za-~cc+)KML+|n*>4lyfZk7od0gXb~Gym>xsa=^2vs2x7!UaA@R z#PrUCzUsLm61(VdUwxkC&?ooqc{7hwCY@}%r}@_`nl*TDnR+~sKgcq(`FORz*a03y z_jCy99e%-VDBUhM0&7}NeJllHJifWb;6avq(WwF*dcSh202V&5YNett-?Id8W6@3j zj7I29Z9nf~_z?T(p#8rVl~ zwCyi}0Xl<0fzV~(`rln3{&8zTKhSS5m_*6-)RDyiyAC@JA`{~blH;*gcOKOCU|+fJ zPF3dowZFS1GDUGS)!en~WOuPBD#L~KKDwjrr3*(ikGFZc6jXo-;}NVAmw6>J-LJ_B z!YQ%^ty!{3m<>sz37e=lw@!ajWtENNiM*>ux>E0p@khdlvvo;PRx1_zcKri{E^V>< z-*2&DL3POSU0ey{=esy({vI7KsliyViykOxh=mnepZ*vzo$YG>pmGpJeb?w&Mphjw zgq1!mXukIVjgnmPT&n*dE#-YES1a^A1}sR>;5Iys?l~%KhioGjxB#h3^F=sxRRQME zvj6M<%~a_a1R`||tl1t>60?0*l+}FMTA*=n^=wc`}Fj&AT5~^;c)d$WRvhv z{X$CzwL?UTnZHgxBTU$GM!mF~-i}=7sm{BWf4!5l_3c6b**}iijLK8)%SU%@q?Z?r zw{l$wF4Chr>FSu#P9yST^PdzfKMwha(bafIvF|bG4XnIDYLvx}as(_4@6~)iS;U2B z&N&8LG(fzV`+k2D!xH<8fEIk%s5^+=JXKO{sVKPkLAl41;?9g`N1iG#jCe;C_-KKQ z*QH)I93ASC>Rc>_9ml#?6pz_IKQd)sqHk04z%nd!u;-Z1 zhx%hW{liE0+^GqUm`*tM?yXB^`Lx{03=X(?6G?+qSvYD!res811wy0JP=eaEeL8n0 zO%62w%oE9V%xn4E9PsXpjbptT&Ro0ZCs2$a`Tcfi-auVzY#@a|cRIBYy8bE`vKnHO zD9RdyLPoI@?FRnd5%Sr!_tmDnkMW*}9x$PPDjvq({4!-zB66q|-l02aLoJVzA8PB? z>3J%sNbhhnOGcLbmKKq56LiN?>F3;+z=b|AOK25)g5aF;8{0@N-z-0vzY^i9bSvEt zGm%O3FGITe&m*&oBif%2<_D>{d<+XnD4frpo7pzppMco_a;e|)YLtJR0ZRJb1gqSQ z83!o#V6Y1mw^a{!g(PZ^5c-3?jIdkr?C7Y6(u%epUAw8n5^E68lyO5xUhPiZ)|Rh~ z%zMe0Mk=J%8E98zRg_s^F3p?vS8kSf*&O;v#(ek92>Kxq$ear|s*b*TqpYn6P(h3o z>glt9#xmYFv{g9;nU_0MA#2GQQk7wz`T13Qg6{`ny|x=@a``(*108v1>Ekt-R2{KW z5sBR=lX`*UI|fYV-nr%0%jgc&u#5NjkKX44VCT{^VdI6}hhq}^pHEYS=}0%%WA62_ zPW6SNR+p3RRD%O^TYyU|!KsZIUiQX%gfK*Te7diLbGGC;BVX9Azl-N|%&*2^bHN$y z_@b4HKKH^NB}xk;LHDuV1F@&!9b#dzo)(0=^fwuzMrD7s!f9e-EpMg7)iI|VCk^2X z^UtG#69TS)$nhMCW@&tH-*8f?>_e%~3M~CC7K2gK zHbkdWv+(`8m5L{7a(J3nrQ1AAg?+SaOT6iH;^u}~D}`mt*@!bagTifxJg zZ&k;H@oELhcIFkXXrnQM2N&lf78KEsnA_P|r%5bodcKMp!mSom+<#XLLs*v1{R-{+{KyCdrfeeO?ByA^t@57e)GzAAdSfl?Pd<9Qa`(k(KtNq{=84Aqb+tpT<9^(GPPFv) zFKobc8*@-CQDix!6SznNsok}$Z+aS?CNk{-L2)RKk#iueF^0ijqaLrSVVX6DlF3Zl zOr-)f9vnvIM2xnib>~gLcMvvYU^CaOyyy{orjwRk5#l%Y%_cA=58t(&`!QiYKV7>R zmG>l3u=9SRwOr?6fWSY-=Zx4gwY@J4vY&%xQA(QgpM}F5JNKrtId}JW_uzOMBioKR zw>_H3T@jWV%i@{8KNRashfSu(w0aUZAQG&hbMh&`VEz1VATZwY&$H>}jZuq%%1F$j`z4mXlTBGoJl89<~g%DRsTiA>e7OJ-I5cG{N|7VY5w~5_=N$R`(>1@oSt2PX@CA9_JUmgR)s=m z=v~l(t(WXi7SgocWo#wcY;MCnxQS9Tpp}U7MhG|OS?AY@WL}o!GA-amc#Q@X_3(Ja zs1#8ZoLYmt+$!9fRTR^$hlo}u^G6FtCw+0*@pTOJy`ytg6r+H$DU@mxI0flbO0_XY z_DR_Tg2>#$m&+nbMT#InyGS)i{>IS2sGnkT-%K$fDtAo#*jjj2vFzER&u=T8qdb%;7rN3mToe2jqE&hB!u~^M3x6%(ncGmN~BU`Df7eZsulw+Bo zVJh<>jb^oR)Q6i#9me!enUz?fi7+L?gv-}Yyjux^U-wcKqiYX~E6&`+5kEgOc?4UN1+`Wj>>U|R!D5U~Vg7m~Jevsan zX*1RHA94^_xRY48*O#FDLJ4ln=PP9=a+2}!ykB3F%@fCCy8EOw+KKYPN2c;t%1^Nsu6+#IT$ivgjQ&DzG91z=-r^&H zyU&=Bh`hRLuaKd?A)>_(N2L*6kK@erRCF*HyBwHZtkH%ef9kQ@T_5M?$`u~rt?)NKv|I%@CiGQ3N z;inbE9IndvKG=)X9>{OGK}?r#Z4UlsgK8ZB z!iDtsHrEc=TzfvKfp?CxBWruB`xI+yR`XPP(sfUW?!jy5ofO+ilCiBu6kSL5#$8%Z zWne%n$+jPyO|6hCv*jN$3xLO?H$WSssephTHcY~zRpWhW<~{*zcGIsHg931{^%#Z@ z=C{DD?9PXv&2W^$RGxU`kt{t*UtMCE@2!^>lrGpNhNM3)Hn9x0$-^9jtBdY-LLKyjPD+rG zdcGbrPsW(LGtY|EzoMt!PkhY-NDsB?-#Fg4HUfZHa#E?Sdhm1`$IB>_vEcWPLG8lM zQNHokwkS6H^_|fAt7Q_+*x#XIinYxsj6bNekiawZZW=TU(t&IchYnVo(kBM1LIS;+ z6VBKUO*w_=HE3WN;~CSwbYhyRlc z@(#4w5lC$2lhlY|Z(b9?vany(PBI2bZjtJ#nzWtg;Oab&VHTGOCGr1Lf*I9C@mfsh zEc>WOTOi&Wh{Ip=0>vT#jMzN^`P50q{#YmpVON=tWp{LwH_DC2YaTpGKY&l~L0V^*aL)w%95CG;5u%J%PL40xJ5U8Ip zXsD);wsZI(7g{}uB!WEmYyeUJcNCA|`~&L#{koe#l5}{r9S5{b5f&6Sw5uyLB`B9P zxwlWV>?*0_;6a9dIFsQ^&SdRMu;M_J%q20OIUe@fsdr}BZnA&1nax~Ecv{>5>O4;y zIAmR`0Dvi2fWT`c@xet9-7NuE-(LqfG7Mk60MVhz{#SNPJh}ZIw~rCs^$WVRs=iBT z@hU$amOjmDHp@R$iNn=j_lv;ePiCN`r&i>8PovOb!FzwhlntQaY8wi^6>zg@$`@&| zkF&;~(8odSjF_Pa+Xiuw0F^#mzLXgK8u0Pu13u@%rsTIu?OJ4Zb*qAyrh2UAc$+35orj#~)cd;suTY$3CQ`De|9mT=c zRz7by(>XIwj5*451qbN=nzWYS`@#)9gz8hEB96bu7XAjFK>~KpJ4s{J!Wg77VUKq>%JXx53?`w#U3RG;x^2ll?vc#aFG8w^V@PV0xWg+ZeLu} zue&lsG)O9ZJH2Uj5e*P$I6rAt(}YKt_@)p544l6#klKvI{V=n=2;vSp)2w$1>_`Yw z5DI>xZBi3I4qXmPu&;FiClH?(0{Z#AD{kbcf#o&=CRNK+S)1jEK65}8x~^*8}TLXRVF5lYgN$l8w4K83EO4wNc|wNE7jJ*pkbi2qiX(*C&(~G z*CF7kwhYU9Y?%&Z`1!PI75XCfex8Z{I(OoxmbxuqU~-}nPRe{c*F))P`DpS<#Ds#n zm?pcCD(*b;tUK6jY&DuV7ce_gg)Z@x99a{tF=@UP9uQ-eFg(Q8D;;VdcP6WRXg|AB zpf?g&X$Q(*TOIv_e>!Dw(xBl0W1Iq3s`n4PfyJzp#RjSxXExXJOYZ}jvIN%%Gqc^P zR|q3dCMHu*!3E8SMCfOW)XaSvOWyR)FfB(WH+2B<97&(M;GhzG2$j~=f{ah4h+RzQ z4!ICe51zyWrJ?^D2^1RJ`b6utceYVI4#IY0UGG}A7xmCfySu9?hQ)Zz>UR&U?>Wd7 zZ_!woAD-Ztjo(uiiZ&_(r63AwjDd!z@k?^WQ`Y(35WIUm+q^=4Cg=~#GEgJ#jbM*t zOneyAFX_=oNQP+)W^S#2Wx_4rta6l9-m^ETeXLN;q^k`Q1K^$z~XG(t%-#w`Qawkve9L2uhI`q#Y)&d7YbG55(WHVubj zwv&_3pLi%QZDH^X_oUN_Uk;oRb{f=exI9-#Q|^9O0j5Xqi;=P^t5?2#rr>4&nDFzG z_uFy7xv$MPo|p7C*AJ!Y#)Y0Xka|&5g(Geb+*4pWP~aeU&q6XlTnSOIC!R+T$_@#4 z?@M<#qE~nSz4vC76-`PhV4790X&NwtFRxrN1j=7 zCCaK^ujJV#{e+8a?6R-CdwEo2E@sbUOWLN_CSjcg0ah)H^2n%hS8r&t{5IAf+-fRj zq3m01_V>G1lsvs+YR0mX!*V2%;8rc37y>~$#9O1jpP{j-HD$gbtEwFFUr-Z&6PL}Z)XK}N@BJs0nlozYsakDe3}jZzT$8b8P{hg zUhwf*n1zP#g;^&`%H)^dBVr z0y^sogWBwpzAVqKa8#95KE3#U`cU7QXCJE^*MOQ~OM=leb9X7SgMsT9gQ$sJd1NN1 z+(=!Fsw@SGw#mXiT$AIESsZ14f|%#K>phIrki|w)bHF z8(Q!;-+8g~T;T^J`_hbv?|CnO4@nrG?Fx~(|1)Cn-~LxpliH$7O9LCM7QkWV!qY>r z@iMchK`$v)WI)oC@?mnU+J0o?QSY+NlXg#qw7K_x&l27Et~{%Dw|T^Pf)|JV#-lU1 zauyt9+i|@GKHNu@IlqA+Vys#;ycLP76d^|ivf~3;FU1;%`Jpdp4+tCsP)Ay4_6hI| zO{CliO|rHzTD*v9VNk8WTg{L2SazpU=76ToQqj=TQ&w+_JoI}4LMq{;)XwrCSGh3! z{syy9S<>YD!}c`hk>4ZQBRk*qXHT?7cl|Za^aIvqm)d-bd^b^K#_(rJ_V}YH`yO@} z%=7$OBOtNqG^XV|PiJXtT_IU;g5E1%^MKsz>I?}dWJiEPQ|} zcLw&ZR17$t^sc78{Crf-1tg#s11b$*=Ks(p#sTzB9R`r+8}Xf-YlNfPj`lP2LbxE; z*VUm`pd(&ZHLyt;TSIQO&RopzmBfWyh(_ie4&GO<6Mottmt7${c>uQNCJ&ok3;XWUBpghaP|@_c%REJp>UcI-+Rbk$Y(e=fOVJN4jYzms0maTa5jaTAcA%LXO(M8PAO zb=V=uXN$^xA?qg9;rM$-$27n`80Z_kU66?6TT_^IVfT%2{I8&VV;xlGQW6FcvQtQa zLzBm8dKqrBRQ%%)&RxqLfnuN%+A(6LrbeXX%MEyyHVUpA^|u31w3LXPWkNFxo4&Q5l;c=djjiaahIP0mAWe zM2&_qwdz2xPf=mpQ#c1|o~a3--2RIT0p9#h;%hSBYAv}K8$bs;&mJ>)B_J_CJFyX? z0MjEsBIuZ+Tjo$&T z@yk5eh=9Ps8>dfc8ZPpVC40I56c?BCCv-y>ui}Nk?L++wqmFPWxVpN2?HPmIZ%EkH zGiWV?275{APP?y&XWugoAU^p+C+kE|#d~tSK&?N4)IE9~IAb9ExPIda0HO;m5MRA0 zl9r18g~PJu8C#rdkcGLgSmGvr8{*FKYXY#j+g1w|L;~my4UJ0Gjn52eoKE)z4XJ#ZLmAlGmeRsV>0j#1fY>4Oia43vB zd=vD$NBco(U2DXMI>e}a1>O%NOr@cO=>Woo3zg8|Tm$%)e%ufPQsaM@mjnjM%Ugf? zT}6y4?*HXVcT_X&*LI{=>voFs$HtSEO@!f+r#)pwJrZd7rI{`fLWNA!4CX**w;(u@ zda%rwus#oPBYoa3FeK?@9gr4WV!wY?5m5|^iE0%AzhF)x6lOg>=GV2Ia>V9C{hN{C zJP-kzEZ&1?QxRg+U6ar?9`@6K2(8P>GBElj!4)V+ffz@ViUw!UBK>uw3=eX71W?ro z4kFh%yvnN$c}kTbj){sOaQ6qGOx8l2#v%Zc#?8CAR0*LECT0MzMeas*&G*CW7!PcU z6qV0wxY}LzDUE>&;t!(b-*h@!c0iNFMjE$h@qTDG1T;at_9 zWlZCGCfmm@ql~($33RxaC`w~*X1=XMV~*=oz^vjt>xC<$OM~<6Oy?WM*mlR%lB~mU`gw0rb4U|hbnh&z_dYc+w!jNae8%Xy+LDYPYR9ii1 z-SVo7!!ewf?06}#<6)~5eX4T9XZ$vXsW`thyA%{8zp=iT_H%XnT0=Pk!*uOd$0FC0 zv$MH!rOYaH7?~2Qpa@*IYtY!2WS|M#4;5T8|b1714EwF#qkeR<@>} z_@MdRe6M0u;vjGr*Cm89BAdsju1sh2pFL*d<2AE*|C@VvK5qQhL7yn!6MF<7TKnl6hFdgeLtv`41rqMT*;yxMMEjuUGy0K7!*Er=)= zUQFs`S9;eMr^Gs+U+d7+;o;fB=ITu5MNlrE!H8zZ<{p-ar0>MtS?SdkLz7Ox%;4R?y&l0H5I}gMQma#%42)qpd1ve4n2|S>|9AD>f}4fBv1E;B#o6k(guT zZr9n#DmzRkOv?%FjrTEL`%`az5Ud^Lr!Jl z9VoWu-tONbX;VJ2Zk$% z>^yu)&R%RdNocAgIXbjrI&!*dykd=1xMkbDXfj>eYD!G^up4`XJ;@q;S!GRbK900f zhu`-1#+2R@E&i=Lt|2np{jQAN;Z#B8)Soza1QiDm{DR?C0wYz6Jh5esJ|tEpxYa6byUDglnd7_n#RSxC2BJwL z(}zM#n6JWbbi2!x=-~((NKX>AOYSFyA+nAJ)KDLMiBjY&G*BFHD^*XFBtTHi3h^}o z8oa4?r^;t^!?H`X=}5XY0;ioFQuj~`+2x>$OcNu0ew0x{P6*f#Fcq$81Zc!Ri+G<~ zr}3po=H~9}kH{*M9owROeD_4gUdm?Fjb8%Qb54^}ULQl%DDRBRH*3xe?cam@KpF46 z>^|~Lw!QS_u!%7^tE=Z=hi*+=e7tO5%Q<^Mcm!o~lb?4Smy>!mhz610!=>64QD`W& z3|z-oh!piC)ujXDf@M4n`qkyROo7FdM;T|7G#Hn~qcdcBr?2-8t!?#c&ahRRQkLHs z^orc8Wb3jg*i-0G!Jelb2hNxErNcm{mJ;3DiFg&g3U=QaEF-6~@qmls{ZKtXU^zqA zoqZ&@(MJf+5Jv?pJUBeww#V6ALq`WGQb25*%}p_htMUz?*&o0^j_jGr3-WOJ#Xu#X zHz%cxyxZh;ISUAx6`YIhxG1|_baIP}&3vH-Hl1u?qcXio8n|z zu%^@h)I;JKN;mg=XDdC9ctg?HE6@o1yb?h1Qw2;b-in@^= z5E1otWz&8wYkyoBQS{-)pc*H-nOCM04d@c8oaV*y*0>>bU%U=r=aoQKKu{5gKZ9Oj zHS~&JyS^++|DpWip{E_^^&B0fK~+n#3A)@!%;nw#bE8Q>asA88KACRdV)izp-`vdo zY<9`R!_w;36%OxqAB>>9iO9IJ`*>};UGnZv5gFPeR*eQacg5Bq>y-gimtnK}aSr|A z!xQv!7CgI97Rh`>d-=&X;K(c8?Ai@3o3R9AKp(N3Td7C}G-`(Xt>37+$9sQKbZN(5 zaTWcDYw!VjEf=O@D(LOHSK&QhWO|NxcQUrPJz@E30kOdT1t5zzdogHv%?xmMW>$1g zIC@xh)K9N-n9^b_106bk=0ZGscrEdAik+6gA0{YgMHaZtOD26?ba! zH0jV?y(3|jE7(sNcCrO++9y`55rNzmFFjnE=%r<}HrD9sNL{wn+JB;C8_JyDxBI+f@99Vht7 z{uB~Q;`SFsQJzQCp2Quyk~b6PwK+K6q&(`V%P;4}em;H7xknaH7DYa72M-8thh$$6)8w|N*n-7Ct~-Sd=3QwtVHyu>G*_)Qa}th^LqvZ*G0eb0NOE!k|>b1*vc| z$3SU>P+D|Cfw|>wrpum(K{|Wml=ef?oYj-uU?CXcx4yUrD=4O23-ZNZRQx44A|3#N z;etZiOR&W<#HH=JG#@XG@W*9bs^t3|1P`E3TEr?@p7EM`mNj{jwa4(`j#Cn-|@A!BaxTyD@V{c4CbVniGGgVLj-zfX1dwtiO zey4pR&}=+^FXUm*6SfxY(!xnA_m*#hWSc@0^rTFZ%NvjT=w$=-By*p>j)^Za=)bu2 zCmr>r@fwi=CmgRxe~9uLYISf9$fEBBE*8Zm;_3;B41#tpUD&9xTsc0#(M&vgS~ox0 zq~Z4*a>ACm%31$X5wew%SH#4rvR=AW_&KEf8Z$S-1p}$>$a(QSjQYusdgu@nwF>3F zBbB40NbiNw*<-!#kIlZEMrB0G5b=K$KV?>Up-5|WT zXoHa<*i#rb2rBHL1V18wA**BhW*mzP6rn&QhVA%y^xxs$TSxELz+Zcu(qwc-p!Rnb z2pGEcHvE0FN9R5xA>M^Azoeo`v3@{}vvZnuIlYw(UT+xiW-*|C@kZ(C;+cW_YQ9!! z+VnI)7GR;KKb;$Mt_$Nb`Bl**xOC;%(z+sneGU{GRX(<_Jq2ny1Qe=({UuB!uO5$; z_$E&saNHm=rOumkWS?#wX<_5}GP}0wPX9v6F}+Muw#Z>L*!zMX+Pf z@9Y!N6uxZ@oFgcdH@~pLaQGuY_6Y8QgeM(^+WZx73`8-~o}*5H>seLboKXWhJKrhC z5Oa35`AYy<4;Ei+C${>yz;PDXLHJ0%NU1;5^m1fTcbr+XE`JUN(I;cvN-HGf(p#r% zNy5++y!?6!;=vSvPL8((e-$)@Ofao$$CMN(rC6{Ai#!67JP@!HV?) z1_X~bEG`^S-gd{={9O`8ogd+jV>j20K{FfhA+4eU6h5vEU-+_r4=xl zm(cS;{j&3xIGV;|-cY?ckUZXz`W=ArlihG$qTqn&6dLrSI_%Zoq28>%PT*!d3kgY# zO=x0S;sQ%}$IK)U zfb^9ze;^g4pOZVqo8H+45{27Fcs3U)3jAPMPI-!(k`n*_6xz` z3Mn0Iu~9RTffP(2W{@wR0WRwkFuowWSRHqJtq1X|BG|x0v(gx2hd1~$%dgvvIvHbp z%TUo*g5#+VmU92nY~&5FiLCcu!I+?9*tNnVnYJE*#7yrSaVCoCRqEkUs<;alW8Rq^ z-q;}*idA2YyFfG>D z7f-H?Yfe4HQZpVSXuB8Cb6n{E)5Sb#H!0&p9N2h(PR8aleiChIZS{`)gDNEAT%V(m zeTZXd#@qfVcVy##zHkuN_YC~eh+yRZ@SRLI36MDW`i1|GkDde;PVp9jN&_E*9*6v& z1PmTqpxUY-Z{@girx;a$sLhof6x^8j&pM9>--bl02G)4^+wvh)f$G86Z_3&QRuyjF zDQveh^{3lS(=^JG9+&!uY`IY&crKT!JTQ?|3Yg6z4Ttg%#`@FP-4i)`4Y3&jDiyqd z4+4d<{*~@BL+M8FHg>^NieH=@&m)_3^~}z~x?XJG)c}!dNr^W4Wk9qC|Jg6!1*^Ky zG~Y387so<^M*{dXJy}{qEl5e}Saro%pZ?ZK5)dL@ zH!Uig7PA+y-L{^3+u9)v%#)x`R$*NY<)dG}(1K@=gLGqL(M}_wY2TX~n$;To`yp8Q z5M%PnA_||l_wQR6**6(sGoG7t{eO*JcQ~AB*PpBn@g~@nwR%Zp*+h`6HhQF!2r0tq zVr8@teblkhHc=*GMGz%<6NG4sAO=}&L@-+PvP>9884PAd{mwJ7<$AC0{jSe-`RAFZ z+~wToKKCiVUk#}k>5GXP^kvUNuvuX4%@Icm<(3Y8bu5};M~t05pP=?Qj8(0KAXRUO zxnOX7^knEupuKuaN=BeHXjbBX44Y_=rMCN3p|>FpX!oYZ@z?LW$v8o)a;;W^v)f0l zc!h>{Qqno^>w~7$M7w?&=6PlQWK5IJ?YssZQOaOd5&^4Xw0`%UFV!*B2s=92C<5<` z6B`{`)$8AE=pKLVg{dfu?O$yaQL{70Zj3PMsx-&=AcCDIvN1vnp%}P`6wgB4P{Vdq z4B?d|?h0Xk;AnP+00N(xi4G4Za+Pr^y7iyD-Da=Uo+&r6CLW5+bcdIi(m1=8GSqg%oIZa*8{UjCrH zeDxf~;v8k@|9atnJpI>WWm6ClrxF;2$j%C>PJ{qEGr~$!3j>Vkla|<-*SRUa7J(Zh zb}ccN$bB1u=^krWOH0&55nLZIB;kV|Vv%lv5w|1YSWUq>JVMQ-i{@4CD2SGrKJyw79_WwOdA5+}%YPs~$ zDi8|rcOSPZJ{BqdikKdx8kYuEEP8{mU#<)a&)k{M7V9&_tywiD;8|P>mgqJtAO4p3 zVy9R(O}JJD7Wv>OgA{}BOXiwRtTDUmu1Y^XUi->(bNH2DrI$?LY`x!=OUIzkCO zxctqJzSSjqZOfu=+?aHg?>3pC_4SN3%@f;<6>iGg466iS;L>3DtGqqL>n*+I_e}KM zDd}BjjWQ_^*g_npvBqBH+@ZRD@|ApG3P6{u@;JXZfBF#s`6ZVWyb8D+6{BvKp#izs zIfib2S%+f9yNhmjpGjp1=Mf7OUs2vb5?W2Q(&k!uZS0}gpsmgQidAK8zaet{Dfa^o zC>siL<7uY(kOAxoyY|O@PR2-DL1{XpMu43RbRjHdHfiirTwATLzL`ILu!RA^0>5SE zV#9S(f4`ALae-wLI2G|6#KHBY^!QU56O31dkrml!uNoDv3 z8!P3+-?eH2zwoGz{VJ%T?)RDJXYP=;nOwReb&5vC8q?<< z&yRz*>KHhQHR1$#oR0`qI?Sgf(i+=bdLtsDlZb`j<5d4aEx-6kPBDJw-lc*E_N(_& zhG>?Ox2;tQJth2I@w%(72kwR}cGpkzX$Yd$N2X-c;_}T67~^S%?QI1_&MfxRiNbC a*JnCjwy78?0=nR) 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 F{{YU>Fq!}W literal 0 HcmV?d00001 diff --git a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx index 67b5f50..4df5379 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx @@ -48,6 +48,8 @@ From here, if you click on a tile and then in the scene, you'll notice your able Spend some time and get familiar with painting and removing tiles! Aim to create a single room that we can use to test our game. +**Tip:** If you find you can't paint, make sure you're on the **TileMap** tab and NOT the **TileSet** tab (confusing, I know) + **Tip: You can use the Rect tool to draw a rectangle of tiles all at once** ![Rect tool](/src/assets/godot/dungeonCrawler/recttoolimg.png) diff --git a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx index 03d03de..9189c75 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx @@ -29,16 +29,20 @@ To create multiple levels, we'll want to save each level and *everything* in the An easy way to remember what we want to store in a level, is by thinking of what we want to *belong* or exist as part of the level! -Now, for our levels, we'll obviously need our tilemap! But we don't want to be redoing **all** of the tileset settings each time... So what we'll want to do, is save a blank version of our current tilemap so that we can reuse it! +Now, for our levels, we'll obviously need our **TileMapLayers!** But we don't want to be redoing **all** of the tileset settings each time... So what we'll want to do, is save a blank version of our current **TileMapLayers** so that we can reuse them! -So go to what is currently our testing scene, go to your **TileMap** and erase all the tiles you've painted, so it's just a blank **TileMap** with all of our settings. Now, let's right-click that and click **Save Branch as Scene** calling it something like "Level_Template" +So go to what is currently our testing scene, go to your **TileMapLayers** and erase all the tiles you've painted, so it's just two blank **TileMapLayers** with all of our settings and our assets loaded. Now, let's right-click the parent node of **both** **TileMapLayers** and click **Save Branch as Scene** calling it something like "Level_Template" Great! Now we can get to actually setting up our first level! A level will only *Need* a couple of things to function: -1. The TileMap +1. The **TileMapLayers** 2. A node that represents the players spawn -Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling it something like "player_spawn" +Anything else, like enemies or coins, are optional + +Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling "player_spawn" + +To edit the two **TileMapLayers** we'll need to right click on the **Level_Template** we imported, and tick **editable children** which makes this a unique instance of the scene, which we want anyway! And that's the most basic form of a level setup! From here, paint the level using the **TileMap** (Remembering to use the right layers for walls and floors) and adding enemies, potions, and coins, all as children of the **Root** node. @@ -46,6 +50,10 @@ Once you've made a level, save the scene. Creating a new folder called "Levels" You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. +Here's an example of a level I made: + +![Initial Scene](/src/assets/godot/dungeonCrawler/createdLevel.png) + ### Level Loader The very last step for our game, is creating something to actually transition us between levels! But first, let's quickly cleanup our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) @@ -58,6 +66,8 @@ Here's how my **World** scene looks: ![World Scene](/src/assets/godot/dungeonCrawler/worldScene.png) +We'll make that **level_transition** node now! + For the final scene of our project, let's create a new scene, with a root **Node2D** called something like "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** Set the shape of the **CollisionShape2D** to be a square. @@ -73,8 +83,8 @@ Let's think about the variables for this script: ```gdscript @export var to_load : PackedScene -@onready var levelHolder : Node2D = $"../levelHolder" -@onready var player : CharacterBody2D = $"../player" +@onready var levelHolder : Node2D = $"../../../levelHolder" +@onready var player : CharacterBody2D = $"../../../player" ``` Great! The \@export will allow us to assign what level want to load from each level, within the editor! @@ -90,7 +100,7 @@ func _on_area_2d_body_entered(body): if(body.is_in_group("player")): levelHolder.get_child(0).queue_free() var loaded = to_load.instantiate() - levelHolder.add_child(loaded) + levelHolder.call_deferred("add_child",loaded) player.global_position = loaded.get_node("player_spawn").position ``` From d94e7820e261555a0bda9387d51e3601bcb2c999 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 17:53:54 +1300 Subject: [PATCH 22/29] Changed order of Godot pages --- astro.config.mjs | 26 +++++++++---------- .../godot/dungeoncrawler/1-player/index.mdx | 2 +- .../godot/dungeoncrawler/6-pickups/index.mdx | 1 + 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index fb993f3..20738f2 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -72,27 +72,27 @@ export default defineConfig({ link: 'game-design/index' }, { label: "Godot", items: [{ - label: "3D Intro", - link: "game-design/godot/3d" - },{ - label: "3D Game", - link: "game-design/godot/3dgame" - },{ - label: "Basics", + label: "Godot Basics", link: "game-design/godot/basics" },{ - label: "Setting up C# For Godot", - link: "game-design/godot/projectsetup" + label: "Universal Features", + link: "game-design/godot/universal" },{ label: "Survivors-Like", link: "game-design/godot/survivors" - },{ - label: "Universal Features", - link: "game-design/godot/universal" },{ label: "Top-down Dungeon Crawler", link: "game-design/godot/dungeoncrawler/0-scenesetup/" - }], + },{ + label: "3D Intro", + link: "game-design/godot/3d" + },{ + label: "3D Game", + link: "game-design/godot/3dgame" + },{ + label: "Setting up C# For Godot", + link: "game-design/godot/projectsetup" + }], collapsed: true }], }, diff --git a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx index 4111849..7d153ab 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/1-player/index.mdx @@ -1,5 +1,5 @@ --- - +type: tutorial unitTitle: Creating our player title: Setting up our player. description: Creating our player scene and scripts diff --git a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx index 48751df..fa90b9a 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/6-pickups/index.mdx @@ -85,6 +85,7 @@ If you've set it all up right, you should notice this number going up each time For potions the process is exactly the same! You should be able to do it on your own! Just follow the steps for creating the coin scene. Except in this case we'll just want a regular **Sprite2D** As the potion sprite isn't animated, and we'll want the group to be called "health" (make sure it matches the line we wrote in **hitbox.gd**) +Don't worry if you don't seem to be able to pick up the potions! It's probably because you have full health! ### Checklist From 1bf05ebf80229bb593c9680255b79b9f2c0b5ea0 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Fri, 4 Oct 2024 22:52:59 +1300 Subject: [PATCH 23/29] Spelling pass --- .../game-design/godot/2d Dungeon Crawler.mdx | 1204 ----------------- .../godot/dungeoncrawler/2-level/index.mdx | 8 +- .../3-playerimprovement/index.mdx | 14 +- .../godot/dungeoncrawler/4-weapon/index.mdx | 6 +- .../godot/dungeoncrawler/5-health/index.mdx | 16 +- .../godot/dungeoncrawler/7-enemy/index.mdx | 2 +- .../godot/dungeoncrawler/8-levels/index.mdx | 8 +- 7 files changed, 25 insertions(+), 1233 deletions(-) delete mode 100644 src/content/docs/game-design/godot/2d Dungeon Crawler.mdx diff --git a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx b/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx deleted file mode 100644 index 0790a53..0000000 --- a/src/content/docs/game-design/godot/2d Dungeon Crawler.mdx +++ /dev/null @@ -1,1204 +0,0 @@ ---- -unitTitle: Making a 2D top down dungeon crawler -title: Setting up our scene. -description: This page works through 2D top down dungeon crawler step-by-step -sidebar: - order: 5 ---- - - -This is a guide to making a 2-dimensional dungeon crawling game in [Godot](https://godotengine.org/). If you are unfamiliar with Godot, check out the [Godot basics](/game-design/godot/basics) doc as this tutorial assumes basic knowledge of navigating and using the Godot Engine. - -:::note[Version] -This guide is up-to-date with Godot 4.2 stable official release but will most likely work with any 4.x release. -::: - -We'll be making a game in which the player explores a multi-floor dungeon in a top-down perspective. This project will include: -- Movement -- Attacking -- Health loss & Gain -- Pickups (Coins & Potions) -- Enemies - -We will not be creating our own assets as part of this project, although you are of course welcome to! - -We'll instead be using a free asset pack by Ox72 on Itch.IO which [can be found here](https://0x72.itch.io/dungeontileset-ii) Just click *Download now* followed by *No thanks, just take me to the download* and download the file called *0x72_DungeonTilesetII_v1.7.zip* - - -## Making the project - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - - -Set up a Basic 2D project, using the Forward+ Renderer. Let's start by importing our assets. -First let's create a new folder, and call it something like 'Assets' - -Then, let's extract the assets from the folder we downloaded, and at them into our Assets folder. Mine looks like this, but it's fine if yours looks slightly different. - -TODO: Image here - -![Godot new project window](/src/assets/godot/3DGameGuide/3dgameprojectsetup.png) - -Let's also create two new top level folders called **Scripts** and **Scenes** - -TODO: Image here - - -To ensure our pixel art assets look crisp and not blurred we'll want to make one quick change. - -Using the buttons in the top left of the screen, select **Project -> Project settings** In this menu, select the **General** tab, and scroll until you see the **Rendering** header. Under this, select **Textures** - -Change **Default Texture Filter** from **Linear** to **Nearest** - -TODO: Settings image - - -## Creating the Player - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - - -Great! Let's start by making a basic version of our player character that will let us move around. We'll worry about more complicated things like attacking later. - -Start by creating a new 2D Scene, with a **CharacterBody2D** as the root node. call it something like **Player** - -Give the **CharacterBody2D** a name like **Player** and give it two children: - -A **CollisionShape2D** and an **AnimatedSprite2D** - -Here's how my scene looks with no other modifications: - -TODO: Player scene basic img - -Let's hit **Ctrl + S** and save this scene in our **Scenes** folder, call it something like **Player.tscn** - -### Animations - -Let's give ourselves something to look at! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** you'll see **\** in the **Spriteframes** field. -Click on **\** and create a new **Spriteframes** Click on the **Spriteframes** you created. This will open a new window at the bottom of the screen. - -This is where we'll create our player's animations. Rename the *General* animation to *Idle* and click the *Add frames from File* Button (The folder icon) - -Navigate to your *assets/frames* folder, and decide which character you want to be your player. I'll be using the Plague Doctor. Using Shift + Click select all the frames for your character labeled *Idle* (This should be four frames) then open them. - -TODO: Image - -You'll see them added to the animation timeline. We'll want to select two things in the timeline. The **Loop** Button (To ensure the animation loops) and the **Play on start button** (To ensure the animation plays automatically) -Let's also increase the FPS to 8 so that the animation plays a little faster. - -Hit play to test! You'll see the player now has an idle animation that loops! - -Let's add our characters walking animation. Add a new animation using the **Add animation** Button and call it something like "Walk" - -TODO: add animation button image - -Do the same thing we did to grab the frames for the idle animation, but this time, grab all the frames labeled "Run" it should again be 4 frames. We want this animation to loop, but we **don't** want it to autoplay. Let's also give this a framerate of 8 FPS. - -TODO: Walk anim image - -Finally, just select your idle animation again, to make sure this is what our player will start on. - -great! That's our animations all done! - -### Collision and Movement - -Now that we have something to look at, let's give our player a hitbox. Open the inspector for the **CollisionShape2D** we added, and add a new shape in the **empty** shape field. -It's a good idea to use a **CapsuleShape** as it will make us less likely to get stuck on corners. Position and adjust the capsule so that it's *slightly* smalle than the sprite for our player. -Mine looks like this: - -TODO: image CollisionShape2D - -Great! Our player now has collision. We'll do one more thing while we're here, which is give our player a script to handle movement. Right click on the **CharacterBody2D** and Attach a script. Call it something like "player.gd" and make sure we're saving it -in our Scripts folder. We also need to make sure we **untick** the **template** box as we will not be using the template! This is because the template is designed for gravity based platformers. - -With our script created and attached, let's get to programming our movement! - -First, let's set up a variable to control our speed. - -```gdscript -@export var speed = 200 -``` - -The **\@export** tag will allow us to easily edit our speed variable, without needing to open the script! - -Then, we'll want to use Godots built in **_physics_process(delta):** function for our movement logic. Inside that we'll want to get the combined vector of all the inputs the player is pressing. - -```gdscript -func _physics_process(delta): - var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") -``` - -We'll then multiply this vector by our speed, and then invoke Godots built in **move_and_slide()** function - -```gdscript -velocity = direction * speed - -move_and_slide() -``` - -giving us a final script that looks like this: - -```gdscript -extends CharacterBody2D - -@export var speed = 200 - -func _physics_process(delta): - var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") - velocity = direction * speed - - move_and_slide() -``` -For now our movement is controlled using the arrow keys, but we'll go over how to map it to whatever we want later in the guide. - -Switch back to 2D view at the top of the screen. - -## Building a level - - -Let's move onto giving us something to walk around. Create a new scene. Give it a node2D as its root node, and call it something like "World" - -Save the scene in our Scenes folder. - -Give our root node a child node with the type **TileMap** this will handle the visuals and collision of our level. Call it something like "Level 1" -In the inspector, create a new **Tile Set** for the **empty** **Tile Set** field. - -You'll notice two new tabs have appeared at the **TileSet** and **TileMap** we'll be working with both of these, but open the **TileSet** tab first. - -using the **+** button in the lower left, navigate to your assets, and load in the "atlas_floor-16x16.png" hit **Yes** when prompted. - -Do the same for the "atlas_walls_low-16x16.png" file, again hitting **Yes** when prompted. - -You can think of these two as palettes we'll use to paint our levels! Our dungeon will be made up from a series of tiles that we can arrange however we want! - -**Note: We won't be implementing the spikes/buttons/levers. So if you add these to your level they'll be purely decorative.** - -Next, we'll want to make sure our walls appear **ontop** of our floors! To do this we'll use layers! On the right, in the inspector for the **TileMap** you'll see a section called layers, with one already there! - -Call this one "Floors" and modify its **Z Index** field to be -1. - -Click **Add Element** to add another layer. Call this one "Walls" and set its **Z Index** field to be 1. - -Todo: layers image - -With our **Tilesets** setup we can now go to the **TileMap** tab. - -From here, if you click on a tile and then in the scene, you'll notice your able to paint them into the scene! This is how we'll create our levels! you can click between the floor and wall tilesets to get access to the different tiles. - -You'll also notice you can switch layers in the top righ of the **TileMap** section. Make sure you're in the right layer for what you're painting! Otherwise they won't appear right! It might be a good idea to do the floors first, followed by the walls. - -Spend some time and get familiar with painting and removing tiles! Aim to create a single room that we can use to test our game. - -**Tip: You can use the Rect tool to draw a rectangle of tiles all at once** - -TODO: rect tool image - -Here's what my room looks like: - -TODO: Basic Room Image - -**Note:** Don't go too crazy on your level design just now! This first area will just be to test! - -### Adding our player to the level - -Now that we have a basic level set up, let's add our player to it so we can start to properly test our game! To do this, we'll just drag our player scene from the **Scenes** folder -in the file browser, into our **scene tree** as a child of the root node! Finally, we'll give the player a child of type **Camera2D.** here's what my scene looks like: - -[TODO: image] - -You should be able to move around! Though you'll quickly notice you're able to walk through walls, which isn't ideal, so let's fix that! - -### Level collision - -Click on your **TileMap** Node again, select **TileSet** at the bottom of the screen, and click on your Wall **TileSet** Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. -Under the **Physics Layers** drop down, click **Add Element.** - -Here you'll see the **Collision Layer** section, make sure **1** and **3** are selected. For the **Collision Mask** section, only **1** should be selected. - -Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop down, select **Physics Layer 0.** Here's how things look for me! - -[TODO: Image] -Think of the blue square that has appeared under the **Paint** tab as our brush that we'll use to paint collisions onto our **Tileset** with the blue square representing where exactly our player will collide. - - -You can click and drag the white diamonds to move them, and click on the edges to add new points. pressing F (Full) will make the collider occupy the whole square, and pressing C (Clear) will make it occupy none of it. - -So using this, try to create colliders for each tile that closely match their sprite. - -Tip: It'll be easiest to do them in batches of tiles that have the same collision! - -Here's how mine look: - -[TODO: Image] - -Now try playing your game again! You'll notice you actually collide with the walls! Great! - -## Improving our player - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - - -Let's spend some time further improving our player. Let's implement some different controls (Well be doing WASD, but you can using any controls you like) -make sure our animation changes to our walking animation when we move, and make sure our sprite faces in the direction we're moving. - -We'll also be implementing attacking, but we'll do that in it's own section! - -### Input mapping - -To change our inputs, we'll first need to set up our **Input Map** to do this, we'll navigate to **Project -> Project Settings** in the top left of the workspace. - -Then, open the **Input Map** tab. - -We'll add our new Inputs by typing a name for each of them in the **Add New Action** box and hitting add. - -I'll be calling mine "Up" "Down" "Left" "Right" and i'll also add one called "Attack" - -[TODO: Images] - -To add buttons to these, we'll hit the "+" to the right of each action, we'll then physically press the key we want to assign on our keyboard, and hit "Ok" - -For my **Attack** action i'll be using **Left Click* for which you'll want to physically click *once* inside the **Listening for input** box. - -Here's what my inputs look like: -[TODO: Image] - -If you're happy with your inputs, you can then hit **Close** at the bottom of the screen. Let's navigate back to our **player_movement.gd** script. This can be done by opening our **player** scene, clicking on the **CharacterBody2D** and clicking the **Script** tab at the top of the screen. - -To change our inputs, all we need to do is change the predifined inputs to what we called ours! - -**Note:** What you named your input actions *is* case sensitive - -So, "ui_left" becomes "Left" -"ui_right" becomes "Right" and so on! - -leaving that line line in our script looking like this: - -```gdscript - var direction = Input.get_vector("Left", "Right", "Up", "Down") -``` -if you run your game, you'll notice your inputs are now changed! - -We won't assign our Attack option just yet, but it's good we've created it already. - -### Animation switching - -To change our animation depending on if we're moving or not, we'll only need to add a few lines to our script. But first, we'll need a reference to our **AnimatedSprite2D** in our script. - -We can do this easily, by **Clicking** and **Dragging** our **AnimatedSprite2D** into our script, making sure we hold **Ctrl** on the keyboard after grabbing it, but before dropping it. - -We'll want to drop it below - -```gdscript -@export var speed = 200 -``` -It should get added to our script looking like: - -```gdscript -@onready var animated_sprite_2d = $AnimatedSprite2D -``` - -if it doesn't look like this, delete the line and try again, making sure you're holding **Ctrl** on your keyboard after picking it up. - -Great! Let's get to changing our animation! - -Under where we set our velocity, we'll simply add a check to see if our velocity is anything other than 0 and change our animation based on that! - -We can check this simply with: - -**Note:** Why can't we just do velocity != 0? This is because velocity actually contains both our X (Horizontal) and Y (Vertical) velocity, so we need to make sure **Both** aren't zero. - -```gdscript -if velocity != Vector2.ZERO: -``` - -Then, we can play our run animation! - -```gdscript -if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") -``` - -and if we're not moving, let's play our idle - -```gdscript -else: - animated_sprite_2d.play("idle") -``` - -Giving us a movement script that looks like this: - -```gdscript -extends CharacterBody2D - -@export var speed = 200 -@onready var animated_sprite_2d = $AnimatedSprite2D - -func _physics_process(delta): - var direction = Input.get_vector("Left", "Right", "Up", "Down") - velocity = direction * speed - if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") - else: - animated_sprite_2d.play("idle") - - move_and_slide() -``` - -Play your game, and you'll notice your animation changes when you move! - -### Sprite facing - -To flip our player based on the direction we're moving, all we really need to do is add another If to check only the **Horizontal** part of our velocity, as thankfully the **AnimatedSprite2D** node has a built in way to flip our sprite! - -I'll be adding this section **beneath** the animation section, but before the **move_and_slide()** function call. - -let's start by checking the Horizontal portion of our movement: - -```gdscript -if(velocity.x < 0): -``` -if our x velocity is less than 0 (moving to the left) we want to flip our sprite. - -```gdscript -animated_sprite_2d.flip_h = true -``` - -And if it's greater than 0, we'll unflip it - -```gdscript -elif(velocity.x > 0): - animated_sprite_2d.flip_h = false -``` - -giving us a movement script that looks like this: - -```gdscript -extends CharacterBody2D - -@export var speed = 200 -@onready var animated_sprite_2d = $AnimatedSprite2D - -func _physics_process(delta): - var direction = Input.get_vector("Left", "Right", "Up", "Down") - velocity = direction * speed - - if velocity != Vector2.ZERO: - animated_sprite_2d.play("walk") - else: - animated_sprite_2d.play("idle") - - if(velocity.x < 0): - animated_sprite_2d.flip_h = true - elif(velocity.x > 0): - animated_sprite_2d.flip_h = false - - move_and_slide() -``` -**Note:** Why didn't we juse use **else:**? - If we'd just used **Else:** our sprite would have jarringly flipped to face left whenever we stopped moving, or if we were just moving up and down. -This way the direction our sprite is facing doesn't change unless we move either left or right! - -Test your game, and you'll notice your sprite now faces left or right depending on the direction we're facing! - -## The Weapon - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - -Let's give our player something to attack with! - -### Weapon Scene - -Let's create a new scene for our weapon! -Give it a root node of just a **Node2D** with two children, a **Sprite2D** and a **Animationplayer** -Give the sprite a child of type **Area2D** and give the **Area2D** a child of **CollisionShape2D** - -Name the root **Node2D** something like "Weapon" - -Here's how my scenetree looks: - -[TODO: Weapon scenetree] - -Make sure you save the scene, calling it something like "Weapon.tscn" - -Let's start by picking a sprite for our weapon, so we can see what we're working with! -Select the sprite node, and in the **Empty** texture field, select Load. Navigate to your assets folder, and select a weapon that you like! - -Don't worry that it's pointing up, we'll rotate it in a minute. - -Let's open the **CollisionShape2D** node and assign a shape, you'll probably just want to use a rectangle shape. This will be the hitbox of the sword, and determine whether an enemy has been hit! Adjust its bounds so that it vaguely matches the sprite. -Although you'll likely want to make it a little bigger than the sprite, as we don't want our game to feel like the player has to be too precise. - -let's rotate the **Sprite2D** node. Do this by selecting the node in the scenetree, navigating to the inspector, opening the **Transform** tab and changing the rotation to **90** - -Let's also offset it's position a little, to help it rotate around our player smoothly. Set its x-position to something like **20px** - -Here's how my sword scene and inspector look: - -[TODO: swordSceneInspector] - -Before we move on, navigate to the inspector tab of the **Area2D** node and find the **Collision** tab, under **Layer** make sure nothing is selected. Under **Mask** Make sure *only* 2 is selected. - -### Weapon Script - -Let's create a script to control our weapon, create it using the default template and attach it to the **root node2d,** call it something like "weapon" - -We'll need this script to do two things: - -1. Rotate around our player, facing the mouse. -2. Play the animation when we press our attack input. - -The first step will be nice and easy! In the **process** function, add the line -```gdscript -look_at(get_global_mouse_position()) -``` -This will cause this node to always face toward the position of the mouse! - -Next, we'll need to get a reference to our **AnimatedSprite2D** node, we'll do this the same way we did for the **animated_sprite_2d** node for the player' by clicking, dragging, and then holding ctrl before we let go of the click. - -We'll also want a variable that keeps track of if we're *currently* attacking, as we don't want the sword to destroy enemies when we haven't attacked. - -your script should look like this: - -```gdscript -extends Node2D - -@onready var animation_player = $AnimationPlayer -@export var attacking : bool = false - -func _process(delta): - look_at(get_global_mouse_position()) -``` - -Great, now let's add a check to see if we've just used the **Attack** input action we created earler, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! - -Making sure that the Input action name, and animation name match, including case sensitivity. -```gdscript -extends Node2D - -@onready var animation_player = $AnimationPlayer - -@export var attacking : bool = false - -func _process(delta): - look_at(get_global_mouse_position()) - - if Input.is_action_just_pressed("Attack"): - animation_player.play("Attack") - -``` - -### Sword Animation - -Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" -Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. - -We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. - -Then, when prompted, we'll select the **Sprite2D** as this is what we want to change the position of! - -Finally, scroll until you see the **Position** property. - -Phew! That was quite a few steps, but our animation track is created! - -Great, now we need to determine the keyframes our sword will animate between. We'll need three: The first being the start position, the second being the extent of the attack, and the third being returning to the start position. - -To add a keyframe, right click on the animation track. (In the **Position** Row) and press **Insert Key** do this until you have three keyframes. If we select each keyframe, we can modify their values! - -The first and last keyframe, we want to be at **Time** 0 and 1.0 respectively, with their values being unchanged (Remember, we want both of these to represent the sword at rest) - -Our second keyframe, we'll for now put at a **Time** of 0.5. Let's however, set its **x-value** to 30. - -Great! Let's hit the play button on the animation, and you'll notice we have a simple stabbing animation. But it's a little slow... We can fix this by adjusting the total length of the animation, this can be done over on the right. - -Change the length from 1.0 to 0.5. We'll then need to adjust our keyframes, adjusting the middle one to be at a **Time** of 0.25, and the last to be at 0.5. - -Play it again, and you'll notice it's much faster! - -We'll want to add another **Property Animation Track** this time to modify the **attacking** variable, to keep track of if our weapon is "Active" or not. - -Add a new animation track, select property, and you should see "attacking" right at the top! Add two keyframes, one right at the start, and one right at the end. The first we'll want to set the value to "on" (as we're now attacking) and the one at the end will set the property back to "off" (or unticked) - -And that's it! We'll come back later to add the code for destroying enemies. - -Great! Let's get our weapon added to our player! - -### Adding our weapon to our player - -Navigate to your player secene. From the filesystem, drag in your weapon scene (Likely called something like **weapon.tscn**) and attach it as a child of the main -**CharacterBody2D** node. - -Play your game, and you should hopefully have a weapon that rotates around the player and stabs when you click it! If it doesn't seem to be rotating around the middle of the player sprite, feel free to adjust its position within the Player scene. - -You're also welcome to adjust the size of the weapon (Although, you're best to do this within the weapon scene itself) it's your game after all! - -## Health - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - - -### Player Health - -Let's start setting up our health system on the player side, we'll start by adding a new Node to our player, as a child of the root **CharacterBody2D** node. The node should be of type **Area2D** -give the **Area2D** a child of type **CollisionShape2D** rename the Area2D to something like "Hitbox." - -In the **Inspector** of the **Area2D** Navigate to the **Collision** section. Deselect all numbers under the **Layer** Section, and ensure *only* 2 is selected under the **Mask** Section. - -Give the **CollisionShape2D** a shape, ideally a rectangle or circle, and make it *slightly* bigger than the shape for the **CharacterBody2D's** **CollisionShape2D** - -Let's give the **Area2D** one more child of type **Timer** and name it something like "damageTimer" this timer will be used to determine how quickly we can take damage again after being hurt, think of it as invulnerability time! -In the timer's inspector, set its **Wait Time** field to 0.5s - -Great! this **Area2D** will be used to detect collision with enemies, potions, and coins! For now we'll just be setting it up to handle health, both healing and damage. - -Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" - -This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its funcitonality up into multiple scripts, but for our scope this is fine! -Let's break down what we need it to do: - -1. Track our health -2. Detect collisions with potions/enemies/coins -3. Change our health value -4. Update the UI - -Let's start by creating the variables we'll need, those being: - -1. The signal we'll use to talk to the UI when our health has changed -2. While we're here, a signal for when we've collected a coin, as it'll also talk to the UI -3. A max health, and current health value -4. A reference to the timer we created. -5. A boolean determining if we can take damage - -These should look something like this, using the same click + drag + ctrl method to get the reference to the **Timer** - -```gdscript -signal on_health_changed(new_health : int) -signal on_point_gained -@export var max_health : int = 6 -@onready var damage_timer = $damageTimer -var health : int -var can_take_damage : bool = true -``` - -**Remember:** We can use the **\@export** to modify the max health value, without editing the script! - -**Note:** Why are we starting at 6 health? We're doing this because each point of health will represent half a heart to the UI, for a total of 3 full hearts! Using ints like this is safer than using a float, -because what if we somehow end up with 0.001 health! - -in our **_ready** function we'll want to set some default values, and emit the health_changed signal to send our starting health to the UI. - -```gdscript -func _ready(): - damage_timer.connect("timeout", allow_damage) - health = max_health - emit_signal("on_health_changed", health) -``` - -Right, let's get onto the most complicated function in the script, the function for taking damage! In this function, there'll be a few different possible outcomes. -1. We can't take damage as we're currently immune. In this case. Nothing happens -2. Otherwise we'll take damage. Emitting the signal to change the UI. -3. If we do take damage, we might be reduced to 0 hitpoints -4. If we are, we die! If we're not. We start our immunity timer. - -Great! Let's write that in gdscript: - -```gdscript -func take_damage(): - if can_take_damage: - health = health - 1 - emit_signal("on_health_changed", health) - - if health <= 0: - print("you died!") - else: - can_take_damage = false - damage_timer.start() -``` - -**Note:** For now we'll just having dying print to the console and do nothing else, as we'll want some proper UI. - -You'll notice we connected our timer to a function called **allow_damage()** which doesn't exist, let's create that now. All it's going to do is set the **can_take_damage** boolean to **True** as unfortunately Godot doesn't let you assign a value to a variable directly via the **connect()** function. - -```gdscript -func allow_damage(): - can_take_damage = true -``` - -Next we'll do healing! This one is *much* easier. We just need to check if we have room to be healed (Our health is less than our max health). If we do, increase our health by 1. Then emit the signal to update the UI! We'll also want to delete the potion, so it can no longer be used. - -```gdscript -func heal(body): - if health < max_health: - health = health + 1 - emit_signal("on_health_changed", health) - body.queue_free() -``` - -Finally, we need a function that calls our **heal** and **damage** functions based on what we've collided with. To check what type of object we've collided with, we'll be using **Groups!** These are something we'll assign to our enemies/potions/coins later. - -To check if something has collided with us, we'll need to the **on_body_entered** signal! To connect this, swap to the **Node** tab of the **Inspector** and click on the **Area2D** node in the **SceneTree** again. You'll see a list of all the signals we have available to us! -Click the **on_body_entered** signal and press **Connect** select the **Area2D (hitbox)** node and click **Connect** - -You'll see a new function appear in our script! On that'll be called whenever something enteres this **Area2D** - -In here, we can check the **Group** of what we've collided with! Let's also add a check to see if we've collected a coin here, to save us some time later! - -```gdscript -func _on_body_entered(body): - if body.is_in_group("enemy"): - take_damage() - elif body.is_in_group("health"): - heal(body) - elif body.is_in_group("coin"): - emit_signal("on_point_gained") - body.queue_free() - -``` -and that's it! Giving us a full script that looks something that this: - -```gdscript -extends Area2D - -signal on_health_changed(new_health : int) -signal on_point_gained -@export var max_health : int = 6 -@onready var damage_timer = $damageTimer -var health : int -var can_take_damage : bool = true - -# Called when the node enters the scene tree for the first time. -func _ready(): - damage_timer.connect("timeout", allow_damage) - health = max_health - emit_signal("on_health_changed", health) - -func _on_body_entered(): - if body.is_in_group("enemy"): - take_damage() - elif body.is_in_group("health"): - heal(body) - elif body.is_in_group("coin"): - emit_signal("on_point_gained") - body.queue_free() - - -func take_damage(): - if can_take_damage: - health = health - 1 - emit_signal("on_health_changed", health) - - if health <= 0: - print("you died!") - else: - can_take_damage = false - damage_timer.start() - -func heal(body): - if health < max_health: - health = health + 1 - emit_signal("on_health_changed", health) - body.queue_free() - -func allow_damage(): - can_take_damage = true -``` - -**Note:** If you copy and paste the above, you'll still need to manually connect the **on_body_entered** signal! - -And that's the player side of health done! Let's move onto the UI side! - -### Health UI - -Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! - -Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whetever the size of our screen is, the health will always be pinned to the top left! - -Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) - - Great! That's all the UI setup we'll need to do for now (Though we'll come back to it later for points, and a "You died" message) - - Add a script to the root node, calling it something like "ui.gd" - - Let's think about what we need this script to do: - 1. Store our three different heart images - 2. Recieve signals from our player when we take damage - 3. Update our health UI. - - We'll set this up so that it automatically adjusts depending on the players **max_health** when the game is run, so you can easily have more (or less) than three hearts! - (Or, you could implement an item that increases your max hp!) - - Thankfull, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image - -Find these in yor filesystem, and drag in the references, it should look something like this: - -```gdscript -const UI_HEART_EMPTY = preload("res://Assets/frames/ui_heart_empty.png") -const UI_HEART_FULL = preload("res://Assets/frames/ui_heart_full.png") -const UI_HEART_HALF = preload("res://Assets/frames/ui_heart_half.png") -``` - -Let's also get a reference to our **healthContainer** node, and create a variable to keep track of the most health we've had so far (This lets us know how many empty hearts to have!) -We won't set this variable here, as it'll be set by whatever the most health we've had so far has been. - -```gdscript -@onready var health_cont = $healthContainer -var maxHealth : int = 0 -``` -Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! - -1. If the health recieved is bigger than our highest health so far, make that our new highest health. Easy enough! - -```gdscript -func changed_health(newHealth : int): - if newHealth > maxHealth: - maxHealth = newHealth -``` - -2. we'll want to check if we have enough hearts currently to represent that, if we don't, we'll need to add some more. (We'll create the function for this last) - -```gdscript - if(maxHealth/2 > health_cont.get_child_count()): - for h in (maxHealth/2) - health_cont.get_child_count(): - add_heart() -``` - -3. we'll iterate through all the children our **healthContainer** node has, and assign an image based on the current health. - -This section may look complicated, but once you get your head around it, it's fairly simple! Spend some time looking over it, and thinking about the conditions for each heart to be drawn. -When I was figuring out how to program this, I found it useful to draw out the hearts on paper, at different levels of health! - -```gdscript -for i in health_cont.get_child_count(): - if (i * 2) + 1 < newHealth: - health_cont.get_child(i).texture = UI_HEART_FULL - elif (i * 2) < newHealth: - health_cont.get_child(i).texture = UI_HEART_HALF - else: - health_cont.get_child(i).texture = UI_HEART_EMPTY -``` - -giving us a full **changed_health** function that looks like this: - -```gdscript -func changed_health(newHealth : int): - if newHealth > maxHealth: - maxHealth = newHealth - - if(maxHealth/2 > health_cont.get_child_count()): - for h in (maxHealth/2) - health_cont.get_child_count(): - add_heart() - - for i in health_cont.get_child_count(): - if (i * 2) + 1 < newHealth: - health_cont.get_child(i).texture = UI_HEART_FULL - elif (i * 2) < newHealth: - health_cont.get_child(i).texture = UI_HEART_HALF - else: - health_cont.get_child(i).texture = UI_HEART_EMPTY -``` - -Not too bad! - -Let's add that **add_heart** function, which just creates and configures another child if we need one. - -```gdscript -func add_heart(): - var img : TextureRect = TextureRect.new() - img.expand_mode = TextureRect.EXPAND_FIT_WIDTH - health_cont.add_child(img) -``` - -Let's also while we're here, add an empty function for our point system, which we'll come back to later! - -```gdscript -func add_point(): - pass -``` - -Save the scene as something like "UI.tscn" - -Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that that the UI 'sticks' to the camera, rather than existing within the game) - -*Finally,* to get everything hooked up, we just need to connect that signal! Open up **hitbox.gd** - -First, we'll get a reference to our new **UI** scene. Put this with the other variable declarations. - -```gdscript -@onready var ui : Control = $"../../CanvasLayer/UI" -``` - -Then, finally, before we call the signal the first time, connect the signal with: - -```gdscript -on_health_changed.connect(ui.changed_health) -``` -we'll also connect our point signal with: - -```gdscript -on_point_gained.connect(ui.add_point) -``` - -Run your game! And you should have 3 hearts! Great! - -## Pickups - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - - -Let's get onto pickups! Our game will have two types of pickups: Coins, and Potions. Coins will give us a point, and Potions will heal us for half a heart! - -Thankfully the setup for the two will be extremely simple, and they won't even need a script! As all logic is handled by our hitbox script! - -### Coins - -For coins, we'll create a new scene with a root node of **Staticbody2D** calling it something like "Coin" - -It should have a child of type **CollisionShape2D** - -We'll also want to add an **AnimatedSprite2D** to the root node. - -Here's how my scene looks: - -[TODO: coin scene] - -We'll add the animation the same way we did with our player! Click on the **AnimatedSprite2D** and in the inspector, under **Animation** create a new **Spriteframes** - -Click on the new **Spriteframes** and add sprites from file. (The coin has four frames) Make sure to click **autoplay** (The 'A' in the pointy box) -and then assign a shape to the **CollisionShape2D** that loosely matches the coin. (I just used a circle) - -The coin as is is very small, so open the inspector for the root **Staticbody2D** and change the **Scale** values to 2. - -Now, all that's left to do is create a **Group.** With the root **Staticbody2D** still selected, navigate to the **Node** tab of the inspector, then to the **Groups** tab. - -[TODO: Groups img] - -In the box, type "coin" and click **Add** - -Then, click **Manage Groups** and select each Node, followed by **Add** to ensure that each node in the scene is in the group. - -Finally, we'll want to open the **Collision** tab on the inspector of the **Staticbody2D** setting the **Layer** to *only* 2, and deselecting all numbers under the **Mask** as we don't want our coin to be looking for collisions, or to be physically collided with! - -And that's our coin! The only script work we need to do is in our **UI** script! But first we'll need to add a UI element to track our points! - -Don't worry, we've done all the hard work of connecting signals earlier! This'll be nice and easy! - -Let's head to our UI Scene. To the root node, add a new child, of type **HBoxContainer** call it something like "pointContainer" - -Give it two children, a **TextureRect** and a **Label,** name the label something like **pointsLabel** - -In the inspector of the **TextureRect** set the **Expand Mode** to "Fit Width" and assign the first coin image to the **Texture** field using the **Load** Option - -Finally for UI setup, in the inspector of the **Label** write "0" in the **Text** field. You'll notice this is pretty small! Scroll down in the **Inspector** until you see **Theme Overrides.** in this section you'll find **Font Sizes.** Set this to something you think looks good! I went with 40px. - -Great! Now we just need to add two lines of code to our UI. and then our points are done! - -First, a reference to our label, same way we've been doing, this should be second nature by now! - -```gdscript -@onready var points_label = $pointContainer/pointsLabel -``` - -then, we'll finish the function we created earlier. - - -```gdscript -func add_point(): - points_label.text = str(int(points_label.text) + 1) -``` -This looks a little silly, but what we're doing is taking the current text in the label, converting it to a number, adding 1 to it, and then converting to *back* to a string. - -If you've set it all up right, you should notice this number going up each time you pick up a coin! Add a few instances of the coin scene to your level to test! - -### Potions - -For potions the process is exactly the same! You should be able to do it on your own! Just follow the steps for creating the coin scene. Except in this case we'll just want a regular **Sprite2D** As the potion sprite isn't animated, and we'll want the group to be called "health" (make sure it matches the line we wrote in **hitbox.gd**) - -## Enemies - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - -We've got a weapon, we've got health, we've got treasure to collect. What's missing? - -Something to fight! - -We'll be keeping our enemy fairly simple, it'll operate off a circular detection range, and walk toward the player if it enters that range, without taking into account walls (Though it will of course still collide with walls) - -### Enemy Scene - -Let's get to making the scene! - -It'll need: a root **CharacterBody2D** (Called "Enemy") with three children: a **CollisionShape2D,** an **Area2D** (named "range") and an **AnimatedSprite2D** - -Additionally we'll want to give the **Area2D** a **CollisionShape2D** as a child. - -[TODO: Enemy scene image] - -First, on the **CharacterBody2D** under the **Collision** section, we'll want **Layer** **2** and **3** selected. With only **1** selected under **Mask** - -Let's skip down to setting up the **AnimatedSprite2D.** Create two animations, call the first "idle" and the second "move". Then, pick something to be your enemy! Selecting both the idle and move animation as we did for the player, using the **Add from file** button. - -You may want to speed the animations up as they're fairly slow by default, I found 10 fps to be good for both! You'll also want to make sure you set the **idle** animation to be autoplay! - -Set the **CollisionShape2D** that's a child of the root node to have a shape that generally matches the sprite. - -Set the shape of the **CollisionShape2D** child of the **Area2D** to be a circle, making it however large you want the 'detection' range of the enemy to be! - -Finally, let's create a new **Group** and call it "enemy", and assign it to the root node of the scene. - -### Enemy Scripting - -Now let's get the enemy moving! - -Let's create some variables: -1. a boolean to keep track of if the player is in range -2. a reference to the player -3. a variable to control our speed - -It should look something like this, again getting the reference to the **AnimatedSprite2D** the usual way: -```gdscript -var in_range : bool = false -var target - -@export var speed : float = 50.0 -@onready var animated_sprite_2d = $AnimatedSprite2D -``` - -Then, we'll want to connect two signals from the "range" **Area2D** node, we'll want to connect both the "on_body_entered" and "on_body_exited" signals to the script we created! - -Let's write those functions. When the player enters the the range, we'll want to set our **in_range** boolean, and play our move animation - -``` gdscript -func _on_range_body_entered(body): - if(body.is_in_group("player")): - in_range = true - target = body - animated_sprite_2d.play("move") -``` - -and in the exited function, we'll want to do the inverse! - -```gdscript -func _on_range_body_exited(body): - if(body.is_in_group("player")): - in_range = false - animated_sprite_2d.play("idle") -``` - -Now, in the **_process()** function, we'll want to check if our player is in range, if they are, move toward them. We'll also want to flip our sprite based on where the player is in relation to the enemy. - -```gdscript -func _process(delta): - if(in_range): - - velocity = (target.global_position - global_position).normalized() * speed - - if(target.global_position.x < global_position.x): - animated_sprite_2d.flip_h = true - else: - animated_sprite_2d.flip_h = false - - move_and_slide() -``` - -for a final script that looks like this: - -```gdscript - -extends CharacterBody2D - -var in_range : bool = false -var target - -@export var speed : float = 50.0 -@onready var animated_sprite_2d = $AnimatedSprite2D - -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta): - if(in_range): - - velocity = (target.global_position - global_position).normalized() * speed - - if(target.global_position.x < global_position.x): - animated_sprite_2d.flip_h = true - else: - animated_sprite_2d.flip_h = false - move_and_slide() - - -func _on_range_body_entered(body): - if(body.is_in_group("player")): - in_range = true - target = body - animated_sprite_2d.play("move") - -func _on_range_body_exited(body): - if(body.is_in_group("player")): - in_range = false - animated_sprite_2d.play("idle") - - -``` - -and that's it! The last thing we need to do is head over to our **Player** scene, create a group called "player" and add the root node of the scene to it. - -Add an enemy to the scene, and you should notice that if you get close to it, it'll walk toward you, and take health away whenever it touches you! - -Although there's one problem... We can't destroy it! - -### Destroying the enemy! - -Head to your weapon scene and open the **weapon.gd** script. We'll just need to make some slight modifications to check if the sword is colliding with enemies when we attack. - -First, let's get a reference to the **Area2D** node. - -```gdscript -@onready var area_2d = $Sprite2D/Area2D -``` -Then, in our **_process()** function, if we're attacking, we'll want to get all the bodies we're colliding with and check if they're enemies. - -```gdscript -if attacking: - for body in area_2d.get_overlapping_bodies(): - if body.is_in_group("enemy"): - body.queue_free() -``` - -leaving the **_process():** function looking like this: - -```gdscript -func _process(delta): - look_at(get_global_mouse_position()) - - if Input.is_action_just_pressed("Attack"): - animation_player.play("Attack") - - if attacking: - for body in area_2d.get_overlapping_bodies(): - if body.is_in_group("enemy"): - body.queue_free() -``` - -Test it out, and hopefully you'll find you can now destroy the enemies! - -## Another floor - -:::note[Godot Documentation] -Godot Documentation for nodes discussed in this section: - -[Controls](https://docs.godotengine.org/en/stable/classes/class_control.html) [Labels](https://docs.godotengine.org/en/stable/classes/class_label.html#class-label) [User Interface](https://docs.godotengine.org/en/stable/tutorials/ui/index.html) -::: - -Until now, our game has only had one level. Let's change that! Thankfully, Godot makes this fairly easy! There's only a couple of things we'll need to do. - -1. Actually create and store multiple levels. -2. Load the level when we enter a specific spot. - -Let's get straight into it! - -### Creating Multiple Levels - -To create multiple levels, we'll want to save each level and *everything* in the level, as a **Scene.** A level should contain **Everything** that we want to be part of the level, such as enemies, coins, and potions. However we *don't* want the player or the UI to be saved in the level. - -An easy way to remember what we want to store in a level, is by thinking of what we want to *belong* or exist as part of the level! - -Now, for our levels, we'll obviously need our tilemap! But we don't want to be redoing **all** of the tileset settings each time... So what we'll want to do, is save a blank version of our current tilemap so that we can reuse it! - -So go to what is currently our testing scene, go to your **TileMap** and erase all the tiles you've painted, so it's just a blank **TileMap** with all of our settings. Now, let's right-click that and click **Save Branch as Scene** calling it something like "Level_Template" - -Great! Now we can get to actually setting up our first level! A level will only *Need* a couple of things to function: - -1. The TileMap -2. A node that represents the players spawn - -Let's create a new scene with a root **Node2D** and call it something like "Level 1" drag in your **Level_Template.tscn** as a child of this. Also giving the root node another child of type **Node2D** calling it something like "player_spawn" - -And that's the most basic form of a level setup! From here, paint the level using the **TileMap** (Remembering to use the right layers for walls and floors) and adding enemies, potions, and coins, all as children of the **Root** node. - -Once you've made a level, save the scene. Creating a new folder called "Levels" to store it in! Try creating two levels "level_1" and "level_2" making sure they're somehwat different, so you can tell when you've changed levels. - -You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. - -### Level Loader - -The very last step for our game, is creating something to actually transition us between levels! But first, let's quickly cleanup our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) - -We'll add one additional node as a child of the **root** node called "levelHolder" - -From your filesystem, drag your newly created "level_1.tscn" onto the **levelHolder** so that it becomes its child, as we want level 1 to be loaded from the start! - -Here's how my **World** scene looks: - -[TODO: world scene] - -For the final scene of our project, let's create a new scene, with a root **Node2D** called something like "levelTransition" with a child **Area2D** and give that a child **CollisionShape2D** - -Set the shape of the **CollisionShape2D** to be a square. - -let's create a script attached to the root node, called something like "level_transition.gd" - -Let's think about the variables for this script: - -1. The level we want to load (We'll use an \@export for this) -2. A reference to our "levelHolder" node -3. A reference to our player, to set their position - -```gdscript -@export var to_load : PackedScene - -@onready var levelHolder : Node2D = $"../levelHolder" -@onready var player : CharacterBody2D = $"../player" -``` - -Great! The \@export will allow us to assign what level want to load from each level, within the editor! - -Now, if the player enters this region, we'll - -1. Remove the last Level -2. Load the new level -3. Set the players position - -```gdscript -func _on_area_2d_body_entered(body): - if(body.is_in_group("player")): - levelHolder.get_child(0).queue_free() - var loaded = to_load.instantiate() - levelHolder.add_child(loaded) - player.global_position = loaded.get_node("player_spawn").position -``` - -Great! Now to each of our level scenes that we've created, add in this scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so they player expects the change) -And in the inspector of the **level_transition,** *after* you've added an instance to a scene, find the level you want it to open in your filesystem, and drag it into the "to_load" slot. - - - - -TODO: general cleanup pass -TODO: Update to 4.3 - - diff --git a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx index 4df5379..a2b5f90 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/2-level/index.mdx @@ -42,7 +42,7 @@ Now, click on the **floor** layer and follow the same steps, except this time lo With our **Tilesets** setup we can now go to the **TileMap** tab. -From here, if you click on a tile and then in the scene, you'll notice your able to paint them into the scene! This is how we'll create our levels! you can click between the floor and wall **Tilemaps** to get access to the different tiles and to paint the different layers. +From here, if you click on a tile and then in the scene, you'll notice you're able to paint them into the scene! This is how we'll create our levels! you can click between the floor and wall **Tilemaps** to get access to the different tiles and to paint the different layers. **Note:** Why do we have a different layer for the two? We'll want our walls to have collision, but not our floors! So we have them on different **TilemapLayer** nodes. @@ -71,17 +71,17 @@ in the file browser, into our **scene tree** as a child of the root node! Finall ![Initial Scene](/src/assets/godot/dungeonCrawler/inittestscene.png) -Don't worry if the names of your nodes are different, leave them as the are for now! +Don't worry if the names of your nodes are different, leave them as they are for now! You should be able to move around! Though you'll quickly notice you're able to walk through walls, which isn't ideal, so let's fix that! ### Level collision -Click on your **Walls TilemapLayer** Node, Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. Under the **Physics Layers** drop down, click **Add Element.** +Click on your **Walls TilemapLayer** Node, Then, navigate to the inspector. Click the **TileSet** Object at the top of the inspector. Under the **Physics Layers** drop-down, click **Add Element.** Here you'll see the **Collision Layer** section, make sure **1** and **3** are selected. For the **Collision Mask** section, only **1** should be selected. -Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop down, select **Physics Layer 0.** Here's how things look for me! +Now, back in the section at the bottom of the screen, navigate to the **Paint** tab, and using the drop-down, select **Physics Layer 0.** Here's how things look for me! ![Physics Layers](/src/assets/godot/dungeonCrawler/tilesetphysicslayer.png) diff --git a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx index fd1b15d..06f0eee 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/3-playerimprovement/index.mdx @@ -20,7 +20,7 @@ Godot Documentation for nodes discussed in this section: Let's spend some time further improving our player. Let's implement some different controls (Well be doing WASD, but you can using any controls you like) make sure our animation changes to our walking animation when we move, and make sure our sprite faces in the direction we're moving. -We'll also be implementing attacking, but we'll do that in it's own section! +We'll also be implementing attacking, but we'll do that in its own section! ### Input mapping @@ -44,14 +44,14 @@ Here's what my inputs look like: If you're happy with your inputs, you can then hit **Close** at the bottom of the screen. Let's navigate back to our **player_movement.gd** script. This can be done by opening our **player** scene, clicking on the **CharacterBody2D** and clicking the **Script** tab at the top of the screen. -To change our inputs, all we need to do is change the predifined inputs to what we called ours! +To change our inputs, all we need to do is change the predefined inputs to what we called ours! **Note:** What you named your input actions *is* case sensitive So, "ui_left" becomes "Left" "ui_right" becomes "Right" and so on! -leaving that line line in our script looking like this: +leaving that line in our script looking like this: ```gdscript var direction = Input.get_vector("Left", "Right", "Up", "Down") @@ -66,14 +66,10 @@ To change our animation depending on if we're moving or not, we'll only need to We can do this easily, by **Clicking** and **Dragging** our **AnimatedSprite2D** into our script, making sure we hold **Ctrl** on the keyboard after grabbing it, but before dropping it. -We'll want to drop it below +We'll want to drop it below the speed variable declaration ```gdscript @export var speed = 200 -``` -It should get added to our script looking like: - -```gdscript @onready var animated_sprite_2d = $AnimatedSprite2D ``` @@ -128,7 +124,7 @@ Play your game, and you'll notice your animation changes when you move! ### Sprite facing -To flip our player based on the direction we're moving, all we really need to do is add another If to check only the **Horizontal** part of our velocity, as thankfully the **AnimatedSprite2D** node has a built in way to flip our sprite! +To flip our player based on the direction we're moving, all we really need to do is add another If to check only the **Horizontal** part of our velocity, as thankfully the **AnimatedSprite2D** node has a built-in way to flip our sprite! I'll be adding this section **beneath** the animation section, but before the **move_and_slide()** function call. diff --git a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx index 65437b2..460bce4 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/4-weapon/index.mdx @@ -81,7 +81,7 @@ func _process(delta): look_at(get_global_mouse_position()) ``` -Great, now let's add a check to see if we've just used the **Attack** input action we created earler, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! +Great, now let's add a check to see if we've just used the **Attack** input action we created earlier, and play the animation we'll create next. This is all stuff we've done earlier, so this should be pretty easy. Here's what it'll look like! Making sure that the Input action name, and animation name match, including case sensitivity. ```gdscript @@ -101,7 +101,7 @@ func _process(delta): ### Sword Animation -Now, let's starting creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" +Now, let's start creating our attack animation! Navigate to the **Animationplayer** and click **Animation** and create a new animation. Call it "Attack" Now that we've created a new animation, we'll need to create an **Animation Track** which you can do by clicking **Add track.** This will ask us what type of Animation Track we want to create. We want to animation the **Position** of our weapon, this is a **Property** so we'll create a **Property** Track. @@ -136,7 +136,7 @@ Great! Let's get our weapon added to our player! ### Adding our weapon to our player -Navigate to your player secene. From the filesystem, drag in your weapon scene (Likely called something like **weapon.tscn**) and attach it as a child of the main +Navigate to your player scene. From the filesystem, drag in your weapon scene (Likely called something like **weapon.tscn**) and attach it as a child of the main **CharacterBody2D** node. Play your game, and you should hopefully have a weapon that rotates around the player and stabs when you click it! If it doesn't seem to be rotating around the middle of the player sprite, feel free to adjust its position within the Player scene. diff --git a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx index b1d9927..912e2df 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx @@ -31,7 +31,7 @@ Great! this **Area2D** will be used to detect collision with enemies, potions, a Let's attach a script to the **Area2D** (that we named "Hitbox") and call it something like "hitbox.gd" -This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its funcitonality up into multiple scripts, but for our scope this is fine! +This script is going to get a little complicated, as it's going to have to handle quite a few things. In a bigger project we would want to break its functionality up into multiple scripts, but for our scope this is fine! Let's break down what we need it to do: 1. Track our health @@ -115,7 +115,7 @@ Finally, we need a function that calls our **heal** and **damage** functions bas To check if something has collided with us, we'll need to the **on_body_entered** signal! To connect this, swap to the **Node** tab of the **Inspector** and click on the **Area2D** node in the **SceneTree** again. You'll see a list of all the signals we have available to us! Click the **on_body_entered** signal and press **Connect** select the **Area2D (hitbox)** node and click **Connect** -You'll see a new function appear in our script! On that'll be called whenever something enteres this **Area2D** +You'll see a new function appear in our script! On that'll be called whenever something enters this **Area2D** In here, we can check the **Group** of what we've collided with! Let's also add a check to see if we've collected a coin here, to save us some time later! @@ -130,7 +130,7 @@ func _on_body_entered(body): body.queue_free() ``` -and that's it! Giving us a full script that looks something that this: +and that's it! Giving us a full script that looks something like this: ```gdscript extends Area2D @@ -187,7 +187,7 @@ And that's the player side of health done! Let's move onto the UI side! Time to start making some UI! Let's make a new scene, of, as you may have guessed, type **User Interface.** call the Root node something like "UI" and add a child of type **HBoxContainer** This is a UI element that will neatly arrange our UI elements, in this case our hearts, horizontally! -Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whetever the size of our screen is, the health will always be pinned to the top left! +Let's open its inspector, navigate to the **Layout** tab and change it to "Anchors." Then change the **Anchor Preset** to "top left." This will make sure that whatever the size of our screen is, the health will always be pinned to the top left! Rename the node to something like "healthContainer." When we add hearts, this will be their parent Node, controlling their position on the screen and in relation to one another. (Like making sure they don't overlap) @@ -208,9 +208,9 @@ Next, in the 2D view of the UI, move the Text so that it's where you want it, I We'll set this up so that it automatically adjusts depending on the players **max_health** when the game is run, so you can easily have more (or less) than three hearts! (Or, you could implement an item that increases your max hp!) - Thankfull, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image + Thankfully, we can reference images in our filesystem the same way we can reference nodes, with the **Drag + Ctrl + Release** technique we've been using! We'll want: The full heart image, the half heart image, and the empty heart image -Find these in yor filesystem, and drag in the references, it should look something like this: +Find these in your filesystem, and drag in the references, it should look something like this: ```gdscript const UI_HEART_EMPTY = preload("res://Assets/frames/ui_heart_empty.png") @@ -228,7 +228,7 @@ var maxHealth : int = 0 ``` Next will be the function that our signal will call, where most of the logic will happen, so let's think about what we need it to do! -1. If our health is set to 0, show the "You died text" Otherwise, If the health recieved is bigger than our highest health so far, make that our new highest health. Easy enough! +1. If our health is set to 0, show the "You died text" Otherwise, If the health received is bigger than our highest health so far, make that our new highest health. Easy enough! ```gdscript func changed_health(newHealth : int): @@ -302,7 +302,7 @@ func add_point(): Save the scene as something like "UI.tscn" -Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that that the UI 'sticks' to the camera, rather than existing within the game) +Go back to your main level scene. Add a new child of type **CanvasLayer** and add your new UI scene as a child of this! (This ensures that the UI 'sticks' to the camera, rather than existing within the game) *Finally,* to get everything hooked up, we just need to connect that signal! Open up **hitbox.gd** diff --git a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx index bbfdf58..720fae8 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/7-enemy/index.mdx @@ -63,7 +63,7 @@ var target Then, we'll want to connect two signals from the "range" **Area2D** node, we'll want to connect both the "on_body_entered" and "on_body_exited" signals to the script we created! -Let's write those functions. When the player enters the the range, we'll want to set our **in_range** boolean, and play our move animation +Let's write those functions. When the player enters the range, we'll want to set our **in_range** boolean, and play our move animation ``` gdscript func _on_range_body_entered(body): diff --git a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx index 9189c75..8c0462b 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/8-levels/index.mdx @@ -2,7 +2,7 @@ type: tutorial unitTitle: More Levels title: Another Floors -description: Adding a level switching system to our game +description: Adding a level-switching system to our game --- import Checklist from '/src/components/tutorial/Checklist.astro'; @@ -46,7 +46,7 @@ To edit the two **TileMapLayers** we'll need to right click on the **Level_Templ And that's the most basic form of a level setup! From here, paint the level using the **TileMap** (Remembering to use the right layers for walls and floors) and adding enemies, potions, and coins, all as children of the **Root** node. -Once you've made a level, save the scene. Creating a new folder called "Levels" to store it in! Try creating two levels "level_1" and "level_2" making sure they're somehwat different, so you can tell when you've changed levels. +Once you've made a level, save the scene. Creating a new folder called "Levels" to store it in! Try creating two levels "level_1" and "level_2" making sure they're somewhat different, so you can tell when you've changed levels. You'll also want to make sure you place the "player_spawn" node in the position you want the player to spawn in the level. @@ -56,7 +56,7 @@ Here's an example of a level I made: ### Level Loader -The very last step for our game, is creating something to actually transition us between levels! But first, let's quickly cleanup our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) +The very last step for our game, is creating something to actually transition us between levels! But first, let's quickly clean up our main "World" scene. We'll want to delete everything from this scene *except* for the **Player & Camera2D** and the **CanvasLayer** that holds the **UI** (And obviously keeping the root node) We'll add one additional node as a child of the **root** node called "levelHolder" @@ -104,7 +104,7 @@ func _on_area_2d_body_entered(body): player.global_position = loaded.get_node("player_spawn").position ``` -Great! Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so they player expects the change) +Great! Now to each of our level scenes that we've created, add in the **level_transition** scene by dragging it from the filesystem. Place it somewhere you want the level to end (Ideally on some stairs, so the player expects the change) And in the inspector of the **level_transition,** *after* you've added an instance to a scene, find the level you want it to open in your filesystem, and drag it into the "to_load" slot. From c9c43d4f2adbd3d7f293786f083702d0f0a91557 Mon Sep 17 00:00:00 2001 From: Arianna Mulligan Date: Sat, 5 Oct 2024 13:55:57 +1300 Subject: [PATCH 24/29] fix: tutorial nav directories --- src/components/starlight/Pagination.astro | 6 ++++-- src/components/tutorial/ProgressStore.ts | 4 +--- src/components/tutorial/TutorialNav.astro | 9 ++++----- src/content/config.ts | 16 ++++++++++++++-- .../godot/dungeoncrawler/5-health/index.mdx | 2 ++ 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/components/starlight/Pagination.astro b/src/components/starlight/Pagination.astro index a73b17c..d7ac82c 100644 --- a/src/components/starlight/Pagination.astro +++ b/src/components/starlight/Pagination.astro @@ -1,13 +1,15 @@ --- import Default from '@astrojs/starlight/components/Pagination.astro'; import type { Props } from '@astrojs/starlight/props'; +import { isTutorialEntry } from '../../content/config'; import { getTutorialPages } from '../../util/getTutorialPages'; -import { pages } from '../tutorial/TutorialNav.astro'; +import { allPages } from '../tutorial/TutorialNav.astro'; -const { entry, pagination } = Astro.props; +const { entry, pagination, id } = Astro.props; const { type } = Astro.props.entry.data; let { prev, next } = pagination; +const pages = allPages.filter((page) => isTutorialEntry(page, id)); const tutorialPages = getTutorialPages(pages); if (type === 'tutorial') { diff --git a/src/components/tutorial/ProgressStore.ts b/src/components/tutorial/ProgressStore.ts index cba5c1c..7be16f2 100644 --- a/src/components/tutorial/ProgressStore.ts +++ b/src/components/tutorial/ProgressStore.ts @@ -207,8 +207,6 @@ export class ProgressStore { } private static slugFromPathname(pathname: string) { - // Remove the language segment from the path, - // and strip a trailing slash, if present. - return pathname.split('/').slice(2).join('/').replace(/\/$/, ''); + return pathname.replace(/\/$/, ''); } } \ No newline at end of file diff --git a/src/components/tutorial/TutorialNav.astro b/src/components/tutorial/TutorialNav.astro index b5191ec..7bdefc6 100644 --- a/src/components/tutorial/TutorialNav.astro +++ b/src/components/tutorial/TutorialNav.astro @@ -1,4 +1,5 @@ --- +import type { Props } from '@astrojs/starlight/props'; import { getCollection } from "astro:content"; import { isTutorialEntry } from '../../content/config'; import { getTutorialPages, getTutorialUnits } from '../../util/getTutorialPages'; @@ -8,13 +9,11 @@ import TabPanel from '../tabs/TabPanel.astro'; import Progress from './Progress.astro'; import UnitProgressIcon from './UnitProgressIcon.astro'; -export interface Props { - id: string; -} - const currentUrl = Astro.url.pathname.replace(/\/$/, ''); +const { id } = Astro.props; + export const allPages = await getCollection('docs'); -export const pages = allPages.filter(isTutorialEntry); +const pages = allPages.filter((page) => isTutorialEntry(page, id)); const tutorialPages = getTutorialPages(pages); const units = getTutorialUnits(tutorialPages); diff --git a/src/content/config.ts b/src/content/config.ts index 847f1f6..a727a0a 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,5 +1,6 @@ import { docsSchema, i18nSchema } from "@astrojs/starlight/schema"; import { type CollectionEntry, defineCollection, z } from "astro:content"; +import path from 'node:path'; // find all tutorial pages const baseSchema = z.object({ @@ -24,11 +25,22 @@ export type DocsEntry = CollectionEntry<'docs'> & { type DocsEntryType = DocsEntryData['type']; function createIsDocsEntry(type: T) { - return (entry: CollectionEntry<'docs'>): entry is DocsEntry => entry.data.type === type; + return (entry: CollectionEntry<'docs'>, id: string): entry is DocsEntry => { + if (entry.data.type !== type) { + return false; + } + const currentPath = path.parse(id); + const currentDir = path.dirname(currentPath.dir); + + const pagePath = path.parse(entry.id); + const pageDir = path.dirname(pagePath.dir); + + return pageDir === currentDir; + }; } export type TutorialEntry = DocsEntry<'tutorial'>; -export const isTutorialEntry = createIsDocsEntry('tutorial'); +export const isTutorialEntry = createIsDocsEntry<'tutorial'>('tutorial'); export const collections = { docs: defineCollection({ schema: docsSchema({ extend: docsCollectionSchema }) }), diff --git a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx index 912e2df..7309599 100644 --- a/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx +++ b/src/content/docs/game-design/godot/dungeoncrawler/5-health/index.mdx @@ -5,6 +5,8 @@ title: Player Health description: Implementing the player health system --- +import Box from '/src/components/tutorial/Box.astro'; +import Checklist from '/src/components/tutorial/Checklist.astro'; ## Health From 120aa5902a0ba50a1485ef65691f9d3668e1f6c5 Mon Sep 17 00:00:00 2001 From: Lillian Hide Date: Sat, 5 Oct 2024 16:08:37 +1300 Subject: [PATCH 25/29] Added steps to pages requiring them --- src/assets/godot/dungeonCrawler/autoloop.PNG | Bin 0 -> 19379 bytes .../dungeoncrawler/0-scenesetup/index.mdx | 27 +- .../godot/dungeoncrawler/1-player/index.mdx | 117 ++-- .../godot/dungeoncrawler/2-level/index.mdx | 76 ++- .../3-playerimprovement/index.mdx | 182 +++--- .../godot/dungeoncrawler/4-weapon/index.mdx | 144 ++--- .../godot/dungeoncrawler/5-health/index.mdx | 516 +++++++++--------- .../godot/dungeoncrawler/6-pickups/index.mdx | 67 ++- .../godot/dungeoncrawler/7-enemy/index.mdx | 246 +++++---- .../godot/dungeoncrawler/8-levels/index.mdx | 93 ++-- .../godot/dungeoncrawler/9-finish/index.mdx | 3 +- 11 files changed, 799 insertions(+), 672 deletions(-) create mode 100644 src/assets/godot/dungeonCrawler/autoloop.PNG diff --git a/src/assets/godot/dungeonCrawler/autoloop.PNG b/src/assets/godot/dungeonCrawler/autoloop.PNG new file mode 100644 index 0000000000000000000000000000000000000000..7d82530833bd438d519a4559c3ca80fb54d5b392 GIT binary patch literal 19379 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