From 6609a5783cc0fb311220c36fe6ed867389dabe6d Mon Sep 17 00:00:00 2001 From: OddlyTimbot Date: Mon, 12 May 2025 17:26:22 -0400 Subject: [PATCH] formatting update --- week5/README.md | 51 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/week5/README.md b/week5/README.md index 142240a..0acf0d5 100644 --- a/week5/README.md +++ b/week5/README.md @@ -5,6 +5,10 @@ This week we do: * Enemies * Player death +# Multiple Levels + +Having multiple levels means changing things so that the game controller remains persistent in memory across all other things in the display list getting reloaded, or even destroyed. + ### Moving the GameController The game controller needs to be persistent across the entire life of the game. Godot provides a way to move a class outside of the display tree to live on its own in a persistent manner. It is called an 'autoload' and it can be found in project settings > globals. @@ -19,7 +23,7 @@ Now that the game controller is persistent, it does not reload when the level ti We can use this example to show the relationship of the scene manager to the game controller - because the scene manager DOES reload each time the level is updated. As it loads, it will tell the game controller to reset the timer. -In game controller: +In `Gamecontroller`: ``` func reset(): @@ -41,7 +45,7 @@ Let's create a routine that allows the scene manager to connect signals from the Put all of your triggers in a blank Node2D, like we have done with our crates. -In Scenemanager>buildLevel: +In `Scenemanager`>buildLevel: ``` for obj in triggers.get_children(): @@ -52,7 +56,7 @@ for obj in triggers.get_children(): We can now update the game controller with a custom signal it will emit to indicate that the crate should be destroyed when it hits the "destroy" trigger. -In Gamecontroller: +In `Gamecontroller`: ``` func _on_trigger_fired(effect: Variant, body: Variant) -> void: @@ -72,14 +76,14 @@ Now if something hits the "destroy" trigger, the game controller checks to see i Lets move the option to load scenes to the scene manager as well, and trigger it using a custom signal from the game controller. -In Scenemanager: +In `Scenemanager`: ``` func loadLevel(): get_tree().reload_current_scene() ``` -In Gamecontroller, change any references to loading scenes to simple signal emits: +In `Gamecontroller`, change any references to loading scenes to simple signal emits: ``` func _on_trigger_fired(effect: Variant, body: Variant) -> void: @@ -103,7 +107,7 @@ func secondCounter(): We have now freed the game controller from the roll of loading scenes. And we have seen how to make additions to the functionality of our game. -### Multiple Levels +# Multiple Levels Copy your initial "game" level, and name the copies "level2" and "level3" @@ -248,5 +252,40 @@ func playerDamage(body, badguy): print("player got damaged") ``` +### Enemy Movement + +To get the enemy moving around, we will use Raycast2D to have them detect obstacles, or if they are reaching the edge of a ledge. + +We can use the `_process` function to update the position of the enemy every frame, and to update what direction they should be facing. + +``` +class_name Badguy extends Area2D +@onready var right_side_cast: RayCast2D = $RightSideCast +@onready var right_down_cast: RayCast2D = $RightDownCast +@onready var left_down_cast: RayCast2D = $LeftDownCast +@onready var left_side_cast: RayCast2D = $LeftSideCast +@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D + +var direction = 1 +var speed = 100 + +signal playerDamageSignal + +func _process(delta: float) -> void: + if not right_down_cast.is_colliding(): + #about to fall on the right.... + direction = -1 + sprite.flip_h = true + if not left_down_cast.is_colliding(): + direction = 1 + sprite.flip_h = false + + position.x += direction * speed * delta + +func _on_body_entered(body: Node2D) -> void: + playerDamageSignal.emit(body, self) + +``` +