Looks like you're not logged in

Login or Register to continue

Lesson Q&A

Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.

  • Another cool challenge/feature to addiguessfiveAfter just making it to the finish line and beating the AI, the game does not stop to play the confetti. The AI is not stopping and collides with player causing the game to reset before celebrating the player's win. A challenge could be making the AI stop when the player enters the finish line. If you would like to add this feature then wait to look at my approach below. ... ... ```gdscript # Add in main game script _finish_line.body_entered.connect(func(body: Node): if body is Runner: bouncer.set_physics_process(false) bouncer.set_animation_to_idle() ) # Add in `Bouncer` script func set_animation_to_idle(): _runner_visual.animation_name = RunnerVisual.Animations.IDLE _dust.emitting = false ``` 6 2 Oct. 29, 2024
  • My first and second challenge solutions!AJ Studios**1st Challenge:** - Top of the script - game.gd ```gdscript # Timer to delay the bouncer's start by 0.5 seconds @onready var _timer: Timer = %BouncerTimer ``` Inside the `_ready()` function: ```gdscript _count_down.start_counting() _runner.set_physics_process(false) _bouncer.set_physics_process(false) _count_down.counting_finished.connect( func() -> void: _runner.set_physics_process(true) get_node("BouncerTimer").start() ) func _on_timer_timeout() -> void: _bouncer.set_physics_process(true) ``` **2nd Challenge:** I was able to figure this one out thanks to *"the official documentation"* `move_toward()` the combination of other students solutions and my own experimentation. Top of the script ```gdscript ## The speed at which the bouncer starts running @export var current_max_speed := 400.0 ## The speed at which the bouncer will accelerate until it reaches the max_speed @export var increasing_speed := 50.0 ``` Inside the `_physics_process()` function: ```gdscript ## Using the new var 'current_max_speed' instead of 'max_speed' var speed := current_max_speed if distance > 100 else max_speed * distance / 100 ## Using the move_toward function so that the bouncer starts slow and then run at max_speed current_max_speed = move_toward(current_max_speed, max_speed, delta * increasing_speed) ``` Entire code: bouncer.gd ```gdscript extends CharacterBody2D ## The top speed that the runner can achieve @export var max_speed := 600.0 ## How much speed is added per second when the player presses a movement key @export var acceleration := 1200.0 ## How much speed is lost per second when the player releases all movement keys @export var deceleration := 1080.0 ## The speed at which the bouncer starts running @export var current_max_speed := 400.0 ## The speed at which the bouncer will accelerate until it reaches the max_speed @export var increasing_speed := 50.0 @onready var _dust: GPUParticles2D = %Dust @onready var _runner_visual: RunnerVisual = %RunnerVisualPurple @onready var _hit_box: Area2D = %HitBox func _ready() -> void: # Here's an idea to slowly move the boucer with a tween animation instead. # var tween = create_tween() # tween.tween_property(self, "max_speed", current_max_speed, 1.0) _hit_box.body_entered.connect(func(body: Node) -> void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_player_position()) var distance := global_position.distance_to(get_global_player_position()) var speed := current_max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity := direction * speed current_max_speed = move_toward(current_max_speed, max_speed, delta * increasing_speed) velocity = velocity.move_toward(desired_velocity, acceleration * delta) move_and_slide() if velocity.length() > 10.0: var angle := rotate_toward(_runner_visual.angle, direction.orthogonal().angle(), 8.0 * delta) _runner_visual.angle = angle var current_speed_percent := velocity.length() / max_speed _runner_visual.animation_name = ( RunnerVisual.Animations.WALK if current_speed_percent < 0.8 else RunnerVisual.Animations.RUN ) _dust.emitting = true else: _runner_visual.animation_name = RunnerVisual.Animations.IDLE _dust.emitting = false func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` 4 1 Dec. 30, 2024
  • The get_tree/root/get_node/"Game/Runner" didn't work.right-cheetahFor some reason using the third way of referencing a sibling node in the course text kept breaking the game, giving me a null instance: func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position However I was able to continue along using the get_node("../Runner").global_position approach. I'm wondering what I may have done wrong to make Godot throw up errors with the former approach. 2 1 Nov. 17, 2024
  • Try this on your own: confused.. RewardingChimpIn the game script, res//lessons/game.gd, try disabling the bouncer until the countdown ends. At the start of the game, it should not move, and when the countdown ends, it should start moving toward **the player.** It should be **the mouse** right .. I tryed to do it and reading ahead I apperently created dependencies. ```gdscript @onready var runner: Runner = %Runner func _physics_process(delta: float) -> void: if runner == null: return var direction := global_position.direction_to(runner.get_global_position()) # calculates a distance to runner var distance := global_position.distance_to(runner.get_global_position()) # sets the speed for arrive behaviour if its far speedy else slower and slower var speed := max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity := direction * speed velocity = velocity.move_toward(desired_velocity, acceleration * delta) move_and_slide() ``` I have a check but the bouncer would not work propper witout the player right ? 1 0 Apr. 01, 2025
  • Bouncer Scene Issue (Running it by itself)chubby-frogI encountered an issue that I was not sure if there was more information on, after fully completing the lesson successfully. 1.Everything runs fine if I run the game scene, or the runner scene by itself. 2.An error occurs if I run the Bouncer scene with the following function, stating invalid access to global position on base object of type null instance func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position 3.Once this error occurs, I can no longer successfully run the game scene since it returns to this error. This is slightly strange for me since it was running fine before attempting the Bouncer scene by itself, without any changes made to the script or inspector. 4.I discovered that if I reload the project, it works back to normal as long as I don't try to run the bouncer scene on its own again. Just a few questions about this. Is this error occurring because the this function in the script absolutely requires the game scene (with the runner in it), since there is no runner in the Bouncer scene alone--and since there is no node tree for it to look into the path to find the Runner? I just wanted to check if this is expected, or if there is anything that I am missing that should at least allow the scene to run even if no movement for the Bouncer occurs? I seemed to be able to resolve the issue by creating a condition (below) to return a dummy value if there is no node path to look for, but I am not even sure if there is any utility to including something like this. Just wanted to see your input on this and if it is something to worry about having downstream effects in a larger project? func get_global_player_position() -> Vector2: var player_node = get_tree().root.get_node("Game/Runner") if not player_node: return Vector2.ZERO else: return player_node.global_position 2 0 Mar. 27, 2025
  • A few questionsarjunI saw that the finish line reacts to the bouncer like it does to the actual player. When the bouncer touches the finish line, it walks to the middle, and the celebration turns on. If the player reaches the finish line first, the bouncer still walks toward it, even if it has to touch the finish line to do so, and it touches the player, restarting the game. Did I miss something, and is there any solution? I can think of a few, like using a tween to animate the bouncer's size property to make it shrink to nothingness when the player touches the finish line, but that doesn't stop the bouncer from being the one to touch it first and turning the celebration effect. What do you guys think I should do? 1 0 Mar. 20, 2025
  • Solution(s) for Challenge 2, what's the difference?required-cheetahSolution 1: ```gdscript Solution 1: extends CharacterBody2D @export var max_speed:= 600.0 @export var current_max_speed := 300.0 @export var acceleration:= 1200.0 @onready var timer: Timer = $Timer @onready var runner_visual_purple: RunnerVisual = %RunnerVisualPurple @onready var dust_particles: GPUParticles2D = %DustParticles @onready var hit_box: Area2D = %HitBox ## Emitted when the character has walked to the specified destination. signal walked_to func _ready() -> void: hit_box.body_entered.connect(func(body:Node) -> void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction = global_position.direction_to(get_player_global_position()) var distance = global_position.distance_to(get_player_global_position()) var speed = max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity = direction * speed current_max_speed += 120 * delta var initial_desired_velocity = direction * current_max_speed velocity = velocity.move_toward(initial_desired_velocity, acceleration * delta) if current_max_speed >= max_speed: velocity = velocity.move_toward(desired_velocity, acceleration*delta) move_and_slide() ``` Solution 2: ```gdscript extends CharacterBody2D @export var max_speed:= 600.0 @export var current_max_speed := 300.0 @export var acceleration:= 1200.0 @onready var timer: Timer = $Timer @onready var runner_visual_purple: RunnerVisual = %RunnerVisualPurple @onready var dust_particles: GPUParticles2D = %DustParticles @onready var hit_box: Area2D = %HitBox ## Emitted when the character has walked to the specified destination. signal walked_to func _ready() -> void: hit_box.body_entered.connect(func(body:Node) -> void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction = global_position.direction_to(get_player_global_position()) var distance = global_position.distance_to(get_player_global_position()) current_max_speed = move_toward(current_max_speed,max_speed,acceleration * delta) velocity = direction * current_max_speed var speed = max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity = direction * speed velocity = velocity.move_toward(desired_velocity, acceleration*delta) move_and_slide() ``` I experimented with both and didn't notice any visual differences, so I assume both solutions work. Could you maybe explain the difference? Which one is the better choice? :D 4 0 Mar. 14, 2025
  • Another way for get_global_player_position()PixAngelInstead of using this : ```gdscript func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` can we create a variable in the class scope : ```gdscript @onready var _runner = get_tree().get_first_node_in_group("runner") ``` Provided you have create a group "runner" for the runner Then modify our function : ```gdscript func get_global_player_position() -> Vector2: return _runner.global_position ``` Is it a bad synthax? 1 0 Mar. 13, 2025
  • Script inherits from native type 'CharacterBody2D', so it can't be assigned to an object of type: 'Node2D'lonely-pantherHaving an issue where my scene won't load due to the issue (Script inherits from native type 'CharacterBody2D', so it can't be assigned to an object of type: 'Node2D') ```gdscript extends CharacterBody2D ## The top speed that the runner can achieve @export var max_speed := 600.0 ## How much speed is added per second when the player presses a movement key @export var acceleration := 1200.0 @onready var _dust: GPUParticles2D = %Dust @onready var _runner_visual: RunnerVisual = %RunnerVisualPurple func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_mouse_position()) var distance := global_position.distance_to(get_global_mouse_position()) var speed := max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity := direction * speed velocity = velocity.move_toward(desired_velocity, acceleration * delta) move_and_slide() if velocity.length() > 10.0: _runner_visual.angle = rotate_toward(_runner_visual.angle, direction.orthogonal().angle(), 8.0 * delta) var current_speed_percent := velocity.length() / max_speed _runner_visual.animation_name = ( RunnerVisual.Animations.WALK if current_speed_percent < 0.8 else RunnerVisual.Animations.RUN ) _dust.emitting = true else: _runner_visual.animation_name = RunnerVisual.Animations.IDLE _dust.emitting = false ``` 1 0 Feb. 22, 2025
  • 2 other ways to give Bouncer a reference to Player -- are they okay?SingleMom420The two methods I first thought of in response to Bouncer needing a reference to player were: 1) Having the Main scene inject Bouncer with a reference to player at instantiation (if we were to instantiate Bouncer instead of having it already in the scene) or in `_ready()`. Since Player will always be a child of Main, this seems like it should be a stable/secure approach to me. 2) This one seems somewhat "cheaper" (less legit), but making a group "player" whose only member was Player, then having Bouncer invoke `get_first_node_in_group("player")`. Are there any downside to either method compared to the one used in the course? Also, is my feeling that the second option is somehow cheaper wrong? I'm not sure why but it just seems like cheating lol. Maybe it kind of seems like overkill because this would make Player globally available to anything calling the group? Doesn't that like go against general programming principles? 1 0 Feb. 04, 2025
  • I am confused about 2 thingsWalidI want to know why get_tree().call_deferred("reload_current_scene") works and simply get_tree().reload_current_scene doesn't. and can't we access the runner by using a unique reference in the bouncer script instead of accessing it through a path from the root. and as always a big thank you for puting this much work in the course it shows how much care you give to explain every litle bit of detail to us. 1 0 Feb. 03, 2025
  • Weird behaviour on a signalEndeiosHi GDQuest! Doing this lesson, I tried to fix the issue of the Bouncer catching the player after the finish line by doing this ```gdscript func _ready() -> void: _finish_line.body_entered.connect(func (body:Node)->void: _bouncer.disable_catch() # THIS! if body is not Runner: return var runner := body as Runner runner.set_physics_process(false) var destination_position := _finish_line.position-Vector2(0,-100) runner.walk_to(destination_position) runner.walked_to.connect( _finish_line.pop_confettis ) ) ``` Of course I needed to adjust the catch on the other side, by disconnecting the signal: at the beginning I thougth that this would work ```gdscript func _ready() -> void: if Engine.is_editor_hint(): return _hit_box.body_entered.connect(catch_player) func catch_player(body: Node)->void: if body is Runner: get_tree().call_deferred("reload_current_scene") func disable_catch()->void: _hit_box.body_entered.disconnect(catch_player) ``` BUT the signal didn't connect properly and i worked around whit this ```gdscript func _ready() -> void: if Engine.is_editor_hint(): return #_hit_box.body_entered.connect(func (body: Node)->void: catch_player(body)) _hit_box.body_entered.connect(catch_player) func catch_player(body: Node)->void: if body is Runner: get_tree().call_deferred("reload_current_scene") func disable_catch()->void: for connection in _hit_box.body_entered.get_connections(): _hit_box.body_entered.disconnect(connection.callable) ``` The question is : what is wrong in the first solution? or am I supposed to go trough the array for some othe reason? Thanks and great work! 8 0 Feb. 03, 2025
  • Using runner as unique scene instead of ...get_node()milk_manWe use `get_tree().root.get_node("Game/Runner").global_position`** to give us access to the Bouncer's sibling node Runner. But why not just mark Runner within the game scene as unique and then write the following code: ```gdscript #.... @onready var _runner: Runner = %Runner #.... func _physics_process(delta: float) -> void: # MOVEMENT var direction := global_position.direction_to(_runner.global_position) var distance := global_position.distance_to(_runner.global_position) #... ``` This works just fine and is more intuitive in my opinion then what we wrote. Was it supposed not to work because in **M7L5**, when Scene Unique Node were first introduced, the following limitation was explained: > ...you can use the `%` shortcut to access nodes with a scene-unique name only in the scene where you marked them as unique. For example, if we mark our **RichTextLabel** in dialogue.tscn as unique, we can't reference it from another scene using the `%` shortcut. We have to use the `get_node()` function with the path to the node. and yet I did exactly the opposite of what would supposedly not work, but it does. So what's going on here? 3 0 Jan. 22, 2025
  • My script (with challenges)euphoric-sheepNote: I kept my animation system for the bouncer as it worked out of the box For the first challenge I implemented an exported timer for the bouncer and checked for timeout in the _ready function as a nested Lambda function: ```gdscript extends Node2D @onready var _finish_line: FinishLine = %FinishLine @onready var _runner: Runner = %Runner @onready var _count_down: CountDown = %CountDown @onready var _bouncer: CharacterBody2D = %Bouncer @export var bouncer_delay := 1 func _ready() -> void: _runner.set_physics_process(false) _bouncer.set_physics_process(false) _count_down.start_counting() _count_down.counting_finished.connect(func() -> void: _runner.set_physics_process(true) get_tree().create_timer(bouncer_delay).timeout.connect(func() -> void: _bouncer.set_physics_process(true) )) ``` For the second challenge, I used a lerp to calculate the difference between the start speed and desired speed weighted by 0.2 (all editable by designers - will likely need to make my export prettier in the future). I also changed the animation script slightly to handle a bug I found: when the Bouncer is touching a wall or player, the animation continues to play as the velocity is not quite 0. As a result, I've added a minimum bound speed as well. ```gdscript extends CharacterBody2D #Speed handling variables - should be exported @export var max_speed := 600.0 @export var current_speed := 250.0 @export var speed_increase_perc := 0.2 @export var acceleration := 1200.0 @export var deceleration := 2000.0 @export var rotate_speed := 8.0 @export var animation_trigger_percert := 0.8 @export var distance_threshold := 100.0 #Changable skins - can make more complex later (character customisation?) @onready var _bouncer_visual: RunnerVisual = %RunnerVisualPurple #Effects & Particles @onready var _dust: GPUParticles2D = %Dust #Player interaction variables @onready var _player := get_tree().root.get_node("Game/Runner") @onready var _hit_box: Area2D = %HitBox #Checks for contact with player func _ready() -> void: _hit_box.body_entered.connect(func (body:Node) -> void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) #Hadles movement, ensure the bouncer accelerates over time func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_player_position()) var distance := global_position.distance_to(get_global_player_position()) var speed := current_speed if distance > distance_threshold else current_speed * distance/100 var desired_velocity := direction * speed current_speed = lerp(current_speed, max_speed, speed_increase_perc*delta) #Increases potential speed of the bouncer over time velocity = velocity.move_toward(desired_velocity, acceleration * delta) print (speed) move_and_slide() #Animations - ensure the bouncer flips and displays the correct animation when running or walking if direction.length() > 0.0: _bouncer_visual.angle = rotate_toward(_bouncer_visual.angle, direction.orthogonal().angle(), 8.0 * delta) var current_speed_percent := velocity.length() / max_speed if current_speed_percent < 0.8 and current_speed_percent > 0.02: _bouncer_visual.animation_name = RunnerVisual.Animations.WALK elif current_speed_percent >= 0.8: _bouncer_visual.animation_name = RunnerVisual.Animations.RUN _dust.emitting = true else: _bouncer_visual.animation_name = RunnerVisual.Animations.IDLE _dust.emitting = false func get_global_player_position() -> Vector2: return _player.global_position ``` 2 0 Jan. 19, 2025
  • Challenge 2GatrehI just set acceleration to a smaller value than the player since that seemed like the easiest solution.. We already had the variable after all. 2 0 Jan. 11, 2025
  • Type casting and unique names work for "get_node" as well!slim-lemurSo by playing around with the get_global_player_position function, I realized you can use "casting"( aka the "as" keyword) to get auto-completion for stuff like global_position. Also, Unique Names (e.g. %Runner) can be used as part of get_node's node path; and this lets you move Runner around in the Game scene without causing errors. Very cool. Before: ```gdscript func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` After: ```gdscript func get_global_player_position() -> Vector2: return (get_tree().root.get_node("Game/%Runner") as Runner).global_position ``` 2 0 Jan. 08, 2025
  • @export questionLucas PscheidtIs it possible and right to get the reference to the Runner with "@export var runner: Runner", on the bouncer's script? Is there any drawbacks or precautions that I need to keep aware? 2 0 Dec. 31, 2024
  • Getting an error "invalid access to property or key 'global_position'"AJ StudiosI checked the script and is exactly the same as the one in the lesson. What I'm I missing? here's to the folder from the lesson: [https://drive.google.com/drive/folders/1VGFxXfgbWZSu9Ht55M39_B99gyb1tzgl?usp=sharing](https://drive.google.com/drive/folders/1VGFxXfgbWZSu9Ht55M39_B99gyb1tzgl?usp=sharing) 5 0 Dec. 28, 2024
  • Bouncer never gets the runnerp_dev_Hey there. One thing I noticed is that the bouncer never touches the runner if its speed is limited according to the distance to the latter, as long as the player keeps moving. I know that the circuit is supposed to have obstacles and all, but it seemed like something to consider anyway. 1 0 Dec. 24, 2024
  • Final challengesPurpleSunriseHello, Super interesting lessons! Here's how I implemented the two challenges. It's all in the ready function of the game scene. I don't know if the second challenge should be done like this but I thought it was the simplest way to do it and the result is similar to the video: ```gdscript func _ready() -> void: _runner.set_physics_process(false) _bouncer.set_physics_process(false) _count_down.start_counting() _count_down.counting_finished.connect(func()->void: _runner.set_physics_process(true) await get_tree().create_timer(0.5).timeout _bouncer.set_physics_process(true) _bouncer.acceleration = 200.0 # I can switch it back to 1200.0 if I want the bouncer to have slow # acceleration only at the beginning of the run and not all the time. # For now, I thought it's nice to always have a bit of advantage on the bouncer. ) ``` Looking forward to the next lesson! 3 0 Dec. 12, 2024
  • Why does this not work for moving bouncer toward runner?◆ LPI removed the stuff we assigned to direction & distance variable in bouncer.gd & just kept their variable declaration with Vector2 & float type. Then, I added the direction & distance calculation in game.gd, using _bouncer.global_position & _runner.global_position, but I got this error when running: > Invalid assignment of property or key 'direction' with value of type 'Vector2' on a base object of type 'CharacterBody2D (bouncer.gd)'. Here is the code: ```gdscript # bouncer.gd var direction: Vector2 var distance: float # game.gd # Would moving it to _physics_process() work? func _ready() -> void: ... var bouncer_position = _bouncer.global_position var runner_position = _runner.global_position _bouncer.direction = bouncer_position.direction_to(runner_position) _bouncer.distance = bouncer_position.distance_to(runner_position) ``` 3 0 Dec. 12, 2024
  • This is my second challenge. Did I succeed? It works fine, but I wonder if my code on the speed setting is wrong? thank youhumble-pelican```gdscript extends CharacterBody2D @onready var dust: GPUParticles2D = %Dust @onready var _runner_visual_purple: RunnerVisual = %RunnerVisualPurple @onready var hit_box: Area2D = %HitBox @export var max_speed := 600.0 @export var current_max_speed := 300.0 @export var acceleration := 1200.0 @export var deceleration := 1080.0 func _ready() -> void: hit_box.body_entered.connect(func (body:Node) ->void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_player_position()) var distance := global_position.distance_to(get_global_player_position()) current_max_speed = move_toward(current_max_speed,max_speed,acceleration * delta) velocity = direction * current_max_speed var speed := max_speed if distance >100 else max_speed * distance /100 var desired_velocity := direction * speed velocity = velocity.move_toward(desired_velocity,acceleration * delta) dust.emitting = true move_and_slide() if velocity.length()>0.0: _runner_visual_purple.angle = rotate_toward(_runner_visual_purple.angle,direction.orthogonal().angle(),8.0*delta) var current_speed_percent := velocity.length() / current_max_speed _runner_visual_purple.animation_name = ( RunnerVisual.Animations.WALK if current_speed_percent < 0.8 else RunnerVisual.Animations.RUN ) else : _runner_visual_purple.animation_name = RunnerVisual.Animations.IDLE func get_global_player_position() ->Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` 1 0 Dec. 09, 2024
  • My second challengehumble-pelican```gdscript extends CharacterBody2D @onready var dust: GPUParticles2D = %Dust @onready var _runner_visual_purple: RunnerVisual = %RunnerVisualPurple @onready var hit_box: Area2D = %HitBox @export var max_speed := 600.0 @export var current_max_speed := 300.0 @export var acceleration := 1200.0 @export var deceleration := 1080.0 func _ready() -> void: hit_box.body_entered.connect(func (body:Node) ->void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_player_position()) var distance := global_position.distance_to(get_global_player_position()) current_max_speed = move_toward(current_max_speed,max_speed,acceleration * delta) velocity = direction * current_max_speed var speed := max_speed if distance >100 else max_speed * distance /100 var desired_velocity := direction * speed velocity = velocity.move_toward(desired_velocity,acceleration * delta) dust.emitting = true move_and_slide() if velocity.length()>0.0: _runner_visual_purple.angle = rotate_toward(_runner_visual_purple.angle,direction.orthogonal().angle(),8.0*delta) var current_speed_percent := velocity.length() / current_max_speed _runner_visual_purple.animation_name = ( RunnerVisual.Animations.WALK if current_speed_percent < 0.8 else RunnerVisual.Animations.RUN ) else : _runner_visual_purple.animation_name = RunnerVisual.Animations.IDLE func get_global_player_position() ->Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` 1 0 Dec. 09, 2024
  • Challenges Solutions (Did I get them right?)Abdul Hannan AhmedHi, Sir Nathan/Jad, Here is my code for the challenges. Could you give your feedback? Thanks in advance. Challenge 1: ```gdscript extends Node2D @onready var _finish_line: FinishLine = %FinishLine @onready var _count_down: CountDown = %CountDown @onready var _runner: Runner = $Runner @onready var _bouncer: CharacterBody2D = $Bouncer func _ready() -> void: _runner.set_physics_process(false) _bouncer.set_physics_process(false) _finish_line.body_entered.connect( func (body: Node2D) -> void: if body is not Runner: return var runner := body as Runner runner.set_physics_process(false) var destination_position := ( _finish_line.global_position + Vector2(0, 64) ) runner.walk_to(destination_position) runner.walked.connect(_finish_line.pop_confettis) ) _count_down.counting_finished.connect( func() -> void: _runner.set_physics_process(true) await get_tree().create_timer(0.5).timeout _bouncer.set_physics_process(true) ) ``` Challenge 2: ```gdscript extends CharacterBody2D @export var max_speed := 600.0 @export var acceleration := 1200.0 @export var increasing_factor := 15.0 @export var current_speed := 450.0 @onready var _dust: GPUParticles2D = %Dust @onready var _runner_visual: RunnerVisual = %RunnerVisualPurple @onready var _hit_box: Area2D = $HitBox func _ready() -> void: _hit_box.body_entered.connect(func(body: Node) -> void: if body is Runner: get_tree().call_deferred("reload_current_scene") ) func _physics_process(delta: float) -> void: var direction := global_position.direction_to(get_global_player_position()) var distance := global_position.distance_to(get_global_player_position()) var speed := current_speed if distance > 100 else max_speed * distance / 100 var desired_velocity := direction * speed current_speed = move_toward(current_speed, max_speed, delta * increasing_factor) velocity = velocity.move_toward(desired_velocity, acceleration * delta) move_and_slide() if velocity.length() > 100.0: _runner_visual.angle = rotate_toward(_runner_visual.angle, direction.orthogonal().angle(), 8.0 * delta) var current_speed_percent := velocity.length() / max_speed _runner_visual.animation_name = ( RunnerVisual.Animations.WALK if current_speed_percent < 0.8 else RunnerVisual.Animations.RUN ) _dust.emitting = true else: _runner_visual.animation_name = RunnerVisual.Animations.IDLE _dust.emitting = false func get_global_player_position() -> Vector2: return get_tree().root.get_node("Game/Runner").global_position ``` 1 0 Nov. 15, 2024
  • Challenge Solution CheckMoKTHey Nathan/Jad, I wanted to run my challenge solutions by you and see if you had any suggestions or efficiencies you would recommend? For the first one I had no issues: ```gdscript ## game.gd @onready var _timer: Timer = %Timer func _ready() -> void: _count_down.counting_finished.connect( func() -> void: _runner.set_physics_process(true) _timer.start() _timer.timeout.connect( func() -> void: _bouncer.set_physics_process(true) ) ) _count_down.start_counting() ``` For the second, I thought about using lerp() and range(), I was trying to find a step function where I could state a min & max value, and an increment, but after reading the help docs I realized that's not what those are used for, I don't think that exists in gdscript? I also thought about using a timer that limits the bouncers speed for a duration then ups it, but that would cause to quick a jump in speed. In the end I used an if loop to increment: ```gdscript ## bouncer.gd @export var max_speed_limit := 600.0 @export var max_speed := 0.0 @export var speed_increment := 600.0 func _physics_process(delta: float) -> void: #... +if max_speed < max_speed_limit: max_speed += speed_increment * delta +if max_speed > max_speed_limit: max_speed = max_speed_limit var speed := max_speed if distance > 100 else max_speed * distance / 100 #var speed := max_speed if distance > 100 else max_speed * distance / 100 var desired_velocity := direction * speed ``` 8 0 Nov. 09, 2024
  • Challengesram8761) In game.gd: ```gdscript _count_down.counting_finished.connect(func(): get_tree().create_timer(1).timeout.connect(_bouncer.set_physics_process.bind(true)) ) ``` 2) In bouncer.gd : ```gdscript func _ready() -> void: tween.tween_property(self, "max_speed", up_speed, 1.0) ``` 1 0 Nov. 06, 2024
  • Test question where the correct answer is "Game/Player"ram876In the test question where the correct answer is "Game/Player", we don't actually have a Player node. I was confused for a second when I didn't see this node. 1 0 Nov. 06, 2024
  • Store reference to playerBrain Siege GameworksDoing this lesson, I used a different method of getting the players position. Namely making the function to get the player position get the player node instead and then storing the value of the get_player() function in a global variable in the _ready() function. Then used this reference var for the target position for the Bouncer. I'm sure it's better to do it this way, considering you eliminate having to get a node twice every frame update. 5 0 Oct. 30, 2024
Site is in BETA!found a bug?