Unser Spiel nimmt immer mehr Form an! Die Münzen sind animiert und unser Player bewegt sich geschmeidig. Aber noch fehlt etwas, um das Einsammeln der Münzen wirklich befriedigend zu machen: Sound und ein visueller Effekt.
In diesem Artikel werden wir:
- Einen Sound abspielen, wenn eine Münze eingesammelt wird.
- Eine neue Animation oberhalb der bestehenden Player-Animation abspielen, um das Einsammeln der Münze zusätzlich hervorzuheben.
Schritt 1: Einen Sound für die Münze hinzufügen
Soundeffekte sind entscheidend für das Spielerlebnis. Ein kurzer „Klingeln“-Sound, wenn eine Münze gesammelt wird, gibt sofortiges Feedback. In Godot nutzen wir dafür den Node AudioStreamPlayer2D
.
- Füge einen Sound-Node zur Münze hinzu:
- Öffne deine Szene
coin.tscn
. - Wähle im Scene Dock deinen Coin (
Area2D
) Node aus. - Klicke auf den „+“ Button (Kind-Node hinzufügen).
- Suche und wähle
AudioStreamPlayer2D
. Klicke „Create“. Benenne ihn zum Beispiel inCollectSound
um.
- Öffne deine Szene
- Lade eine Sounddatei:
- Gehe in den FileSystem-Dock und erstelle einen neuen Ordner „sounds„.
- Suche dir eine Sound-Datei aus (z.B. ein Sound-Effekt von itch.io), lade sie herunter und entpacke sie. Danach ziehe die ausgewählte Datei in den FileSystem-Dock in den gerade erstellen Ordner „sounds„.
- Wähle den neuen
CollectSound
Node im Scene Dock aus. - Gehe in den Inspector. Du siehst dort die Eigenschaft „Stream“, die momentan „<empty>“ ist.
- Klicke auf das Dropdown-Menü neben „Stream“ und wähle „Load“. Navigiere zu deiner Sounddatei und wähle sie aus.
- Spiele den Sound im Script ab:
- Öffne dein
coin.gd
Script. - Finde die Funktion
_on_Coin_body_entered(body)
. - Wir müssen den Sound-Node in unserem Script referenzieren, um ihn abzuspielen. Füge dazu die folgende Zeile oben im Script ein, ähnlich wie du es für
AnimatedSprite2D
gemacht hast:
- Öffne dein
1 2 3 4 5 6 |
class_name Coin extends Area2D # Deklariere ein neues Signal, das ausgesendet wird, wenn die Münze eingesammelt wird. signal collected @onready var collect_sound = $CollectSound # ... restlicher Code |
- Jetzt kannst du
collect_sound.play()
aufrufen, bevor die Münze entfernt wird.
Dein _on_Coin_body_entered
sollte nun so aussehen:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func _on_Coin_body_entered(body): if body.is_in_group("players"): print("Münze berührt!") collect_sound.play() # Aufsammeln-Sound abspielen emit_signal("collected") # Wichtig: Wir warten auf das Ende des Sounds. # Damit es so aussieht als sei die Münze schon gesammelt, blenden wir sie aus hide() await collect_sound.finished queue_free() |
Darauf achten: queue_free()
und Sound
Wenn du queue_free()
aufrufst, wird der Node am Ende des aktuellen Frames aus der Szene entfernt. AudioStreamPlayer2D
Nodes spielen ihren Sound nicht mehr weiter, wenn er entfernt wird. Da er ein Child-Node unseres Coins ist, würde der Sound also sofort wieder enden.
Wir warten mit await sound.finished
bis der Soundeffekt fertig abgespielt wurde. Erst dann rufen wir queue_free()
auf.
Das ist wichtig, da wir die Münze sofort verschwinden lassen wollen, der Sound aber komplett abgespielt werden soll.
Schritt 2: Eine Sammel-Animation für den Player hinzufügen
Neben dem Sound können wir auch eine kurze Animation am Player abspielen, die signalisiert, dass etwas eingesammelt wurde. Diese Animation soll kurz über der normalen Lauf- oder Idle-Animation erscheinen. Dafür nutzen wir einen zweiten AnimatedSprite2D
am Player.
- Füge einen zweiten AnimatedSprite2D zum Player hinzu:
- Öffne deine Szene
player.tscn
. - Wähle im Scene Dock deinen Player (
CharacterBody2D
) Node aus. - Klicke auf den „+“ Button (Kind-Node hinzufügen).
- Suche und wähle
AnimatedSprite2D
. Klicke „Create“. - Benenne diesen neuen Node in
AnimatioEffect
um, um ihn von deinem bestehenden Player-Animations-Node zu unterscheiden.
- Öffne deine Szene
- Erstelle eine neue SpriteFrames-Ressource für die Sammel-Animation:
- Suche dir eine weitere Animation aus (z.B. einen Effekt von OpenGameArt.org), lade sie herunter und entpacke sie. Danach ziehe die Datei 0 – 14 in den FileSystem-Dock in den Ordner „images„.
- Wähle den
AnimationEffect
Node im Scene Dock aus. - Gehe in den Inspector. Erstelle eine „New SpriteFrames“ Ressource für die Eigenschaft „Sprite Frames“.
- Klicke auf das SpriteFrames-Drop-Down um den Sprite-Frame-Editor zu öffnen.
- Benenne die Animation „default“ um in „collect“.
- Füge Frames hinzu, die den kurzen visuellen Effekt für das Einsammeln darstellen sollen. Achte darauf, dass diese Animation NICHT loopend ist (
Loop
deaktivieren) und stelle eine angemessene „Speed (FPS)“ ein (z.B. 15 FPS für die 15 Bilder des verlinkten Effekts). - Optional: du kannst die Größe der Animation im Viewport anpassen.
- Spiele die Animation im Player-Script ab:
- Öffne dein
player.gd
Script. - Referenziere den neuen
CollectAnimation
Node, ähnlich wie du es für die ersteAnimation
gemacht hast:
- Öffne dein
1 2 3 4 5 |
class_name Player extends CharacterBody2D @onready var animation = $Animation @onready var animation_effect = $AnimationEffect # ... restlicher Code |
- In der
collect_coin()
Funktion, die aufgerufen wird, wenn das Münz-Signal empfangen wird, können wir nun diese neue Animation starten.
Deine collect_coin()
-Funktion sollte nun so aussehen:
1 2 3 4 |
func collect_coin(): print("Player hat die Münze erfolgreich gesammelt!") animation_effect.show() # Effect-Animation sichtbar machen animation_effect.play("collect") # Sammel-Animation abspielen |
Darauf achten: Überlappende Animationen
Indem wir einen separaten AnimatedSprite2D
für die Sammel-Animation verwenden, kann dieser Effekt über dem Spieler abgespielt werden. Die Reihenfolge der Nodes im Scene-Node steuert dabei die Sichtbarkeit. Je weiter untenim Scene Tree steht, desto später wird er in die Szene gezeichnet.
Schritt 3: Sammel-Animation nach Beendigung ausblenden
Damit unsere Sammel-Animation nicht einfach stehen bleibt, nachdem sie abgespielt wurde, blenden wir sie wieder aus. AnimatedSprite2D
Nodes haben ein sehr nützliches Signal namens animation_finished()
, das ausgelöst wird, sobald eine nicht-loopende Animation beendet ist.
- Verbinde das
animation_finished()
-Signal derCollectAnimation
:- Öffne deine Szene
player.tscn
. - Wähle im Scene Dock den
Animation
Effect Node aus. - Gehe ins Node Dock (neben dem Inspector).
- Suche im Tab „Signals“ das Signal
animation_finished()
. - Klicke doppelt darauf oder wähle es aus und klicke „Connect…“.
- Im „Connect a Signal“-Fenster sollte der Player als „Receiver“ ausgewählt sein. Die Methode sollte
_on_animation_effect_animation_finished
lauten. - Klicke „Connect“. Godot erstellt die Funktion in deinem
player.gd
Script.
- Öffne deine Szene
- Implementiere die Ausblend-Logik im Player-Script:
- Öffne dein
player.gd
Script.In der neu erstellten Funktion
blenden wir den_on_animation_effect_animation_finished
()CollectAnimation
-Node einfach wieder aus.
player.gd
Script sollte nun diese neue Funktion enthalten: - Öffne dein
1 2 3 |
func _on_CollectAnimation_animation_finished(): # Blendet die Sammel-Animation aus, sobald sie beendet ist animation_effect.hide() |
Darauf achten: animation_finished()
vs. animation_looped()
AnimatedSprite2D
Nodes bieten zwei wichtige Signale, die sich auf den Status der Animation beziehen:
animation_finished()
: Dieses Signal wird einmalig ausgelöst, wenn eine Animation ihr Ende erreicht hat. Es wird nur für Animationen, die nur einmal abgespielt werden sollen (z.B. ein Sammel-Effekt, ein Treffer, ein Tod), und derenLoop
-Eigenschaft im SpriteFrames-Editor auf false gesetzt ist, ausgeführt.animation_looped()
: Dieses Signal wird jedes Mal ausgelöst, wenn eine Animation einen vollständigen Durchlauf abgeschlossen und erneut begonnen hat. Es wird nur für Animationen, die in einer Endlosschleife laufen (wie die Idle- oder Lauf-Animation unseres Players, derenLoop
-Eigenschaft auf true gesetzt ist) und du auf jeden Zyklus reagieren möchtest (z.B. einen Schritt-Sound nach jedem Schritt-Zyklus abspielen), ausgeführt.
Für unsere CollectAnimation
, bei der die Loop
-Eigenschaft im SpriteFrames-Editor auf false gesetzt ist, ist animation_finished()
die richtige Wahl.
Schritt 4: Speichern und Testen
- Speichere deine Szene
player.tscn
(Strg + S). - Speichere dein
player.gd
Skript (Strg + S) und deincoin.gd
Skript (Strg + S). - Führe dein Projekt aus (F5).
Jetzt sollte dein Player beim Einsammeln einer Münze nicht nur einen Sound abspielen, sondern auch eine zusätzliche, kurze Animation zeigen!
Dein nächster Schritt
Wir haben unseren Interaktionen Sound und zusätzliche visuelle Effekte hinzugefügt, was das Spielerlebnis deutlich verbessert. Du hast gelernt, wie man:
AudioStreamPlayer2D
Nodes für Soundeffekte einsetzt.- Mehrere
AnimatedSprite2D
Nodes an einem Charakter verwendet, um überlappende Animationen zu erzeugen. - Dafür sorgt, dass Animationen ausgeblendet werden, nachdem sie abgespielt wurden.
Als Nächstes werden wir unser Spiel noch dynamischer gestalten, indem wir einen Partikeleffekt erzeugen, wenn eine Münze eingesammelt wird. Das führt uns in die Welt der CPUParticles2D
Nodes und deren Konfiguration.