Create Your First Godot 4 Game

Lesson 6: Creating a collectible

Video Notes

Let’s give our raptor some treats! In this lesson, we’ll cover creating a collectible bug that our dino can grab to score some points.

The final code can be found here: https://github.com/quiver-dev/raptor-run.

Corrections

In Godot 4 Beta 16 or higher, the AnimatedSprite2D’s Playing checkbox has been removed from the Inspector. It has been replaced by the Autoplay button, which can be found in SpriteFrames panel next to the trashcan icon.

Make sure to turn off looping on the collected animation, otherwise the animation_finished signal will never be fired for the collectible and it will never be freed.

Improvements

With newer versions of Godot 4, you can simplify the platform selection with the following:

var random_platform = available_platforms.pick_random()

  • Anoniempje
    Nov. 7, 2022 at 7:55 p.m.

    As of godot 4 beta 4 there is a random pick from array function.
    At 15m55s, line 42 and 43 can now be:

    	var random_platform = available_platforms.pick_random()
    	var new_platform = random_platform.instantiate()
    
    • amit
      Nov. 8, 2022 at 12:14 a.m.

      Nice find! A small, but welcome addition to GDScript.


  • strawfervor
    Dec. 15, 2022 at 9:31 p.m.

    This could be very nice tutorial, but it’s way too fast. It is impossible to follow you in this course, because you are pasting things, so it’s very frustraiting to stop or rewind it all the times to catch you up. In this lesson you forgot to mention about line of code with collect_sound varible (9 minute).

    • amit
      Dec. 16, 2022 at 7:01 p.m.

      Thanks for the feedback. It’s difficult to find the pacing that suits everyone, but I agree we should avoid copy and pasting multiple lines and that’s something we’ll address in future tutorials. Speaking for myself, I find myself pausing the video even if I can keep up with the writing the code, since it often takes a moment for the idea to process.

      I believe the collect_sound variable is initialized at 8:30 in the video. Is that what you mean?


  • Malcx
    Feb. 12, 2023 at 12:31 p.m.

    Why do we set the label text on every frame rather than just when the score changes?

    And would it not be more performant to create the available_platforms array once rather than every spawn call?

    • amit
      Feb. 24, 2023 at 7:13 p.m.

      Both valid points. I think the best way to handle updating the score label would be using a setter function on the score variable, which we don’t cover in this tutorial. And available_platforms could certainly be initialized once.


  • ManoShu
    Oct. 20, 2023 at 2:02 a.m.

    A thing that could be done a little bit better is to put a clamp on the collectible_pitch variable, as, in the case of the game spawning multiple platforms with “row” collectibles, the sound becomes jarring.

    After the collectible_pitch += 0.1 line, add:

    collectible_pitch = clamp(collectible_pitch, 1.0, 2.0)

    • ManoShu
      Oct. 20, 2023 at 2:08 a.m.

      The increase on the collectible_pitch can also be reduced to have a similar effect while not using a high pitch value:

      collectible_pitch += 0.05 # or other lower values
      
    • amit
      Oct. 20, 2023 at 3:10 p.m.

      Great idea! This would be especially useful if you’re designing custom platforms with even more collectibles.


  • RedHoodJT
    March 15, 2024 at 12:07 a.m.

    For some reason when I run the game my animation for picking up the collectible runs in a loop over and over again and the last collectible becomes hidden behind the platform but I am still able to collect it. Here is my code for the collectible:

    extends Area2D
    
    @export var value = 10
    
    @onready var game = $"/root/World"
    @onready var sprite = $AnimatedSprite2D
    
    # Called when the node enters the scene tree for the first time.
    func _ready():
    	self.body_entered.connect(_on_body_entered)
    	
    func _on_body_entered(body):
    	if body.is_in_group("player"):
    		game.add_score(value)
    		sprite.play("collected")
    		sprite.animation_finished.connect(_on_animation_finished)
    		
    func _on_animation_finished():
    	queue_free()
    	
    func _process(delta):
    	pass
    

    I have gone back and looked at the code in the lecture to what I have but I didn’t notice anything different. I tried deleting the animation and recreating it but that didn’t seem to do anything. I feel like I missed a step in the code that removes it from the scene.


  • RedHoodJT
    March 15, 2024 at 12:44 a.m.

    Never mind. I forgot to disable looping.

Want to get into the mix? Sign in or register to comment.

Next lesson