{"id":585,"date":"2025-06-06T09:00:00","date_gmt":"2025-06-06T07:00:00","guid":{"rendered":"https:\/\/staratnight.de\/blog\/?p=585"},"modified":"2025-06-01T16:35:49","modified_gmt":"2025-06-01T14:35:49","slug":"area2d-und-signale","status":"publish","type":"post","link":"https:\/\/staratnight.de\/blog\/area2d-und-signale\/","title":{"rendered":"Area2D und Signale"},"content":{"rendered":"\n<p>Nachdem wir die Bewegung unseres Spielers oder unserer Spielerin und die solide Kollision mit einer Wand gemeistert haben, ist der n\u00e4chste Schritt, die Interaktion mit Objekten zu lernen, die man einsammeln oder ausl\u00f6sen kann, ohne dass sie einen physisch blockieren.<\/p>\n\n\n\n<p>Hierf\u00fcr kommt ein anderer wichtiger Node-Typ ins Spiel: der <strong>Area2D<\/strong>. Im Gegensatz zu den Physics Bodies (<code>CharacterBody2D<\/code>, <code>StaticBody2D<\/code>, <code>RigidBody2D<\/code>), die auf solide Kollisionen reagieren (Sto\u00dfen, Abprallen), ist eine <code>Area2D<\/code> daf\u00fcr da, <strong>\u00dcberlappungen zu erkennen<\/strong>. Sie blockiert nichts, sondern meldet nur, wenn ein anderer Physics Body oder eine andere <code>Area2D<\/code> in sie eintritt, sie verl\u00e4sst oder sich darin befindet.<\/p>\n\n\n\n<p>Um auf solche Ereignisse zu reagieren (&#8222;Ein Body ist in mich eingetreten!&#8220;), nutzen wir ein fundamentales Konzept von Godot: <strong>Signale<\/strong>. Nodes k\u00f6nnen Signale aussenden, wenn etwas Bestimmtes passiert. Andere Nodes k\u00f6nnen sich mit diesen Signalen verbinden, um eine eigene Funktion auszuf\u00fchren, wenn das Signal emittiert wird. Wenn du schonmal in anderen Programmiersprachen mit <strong>Events <\/strong>gearbeitet hast, kannst du dir sicher schon was darunter vorstellen.<\/p>\n\n\n\n<p>Wir erstellen eine einfache &#8222;M\u00fcnze&#8220;, die unser:e Spieler:in einsammeln kann.<\/p>\n\n\n\n<p>Du wirst:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Eine neue Scene f\u00fcr ein wiederverwendbares Objekt erstellen (eine M\u00fcnze).<\/li>\n\n\n\n<li>Den <code>Area2D<\/code> Node verwenden.<\/li>\n\n\n\n<li>Dem <code>Area2D<\/code> eine <code>CollisionShape2D<\/code> (f\u00fcr die Erkennung) und ein <code>Sprite2D<\/code> (f\u00fcr die Grafik) hinzuf\u00fcgen.<\/li>\n\n\n\n<li>Ein Script an die <code>Area2D<\/code> anh\u00e4ngen.<\/li>\n\n\n\n<li>Ein Signal (<code>body_entered<\/code>) des <code>Area2D<\/code> Nodes mit einer Funktion in unserem Script verbinden.<\/li>\n\n\n\n<li>In dieser Funktion pr\u00fcfen, ob der eintretende Body der Player ist und die M\u00fcnze dann &#8222;sammeln&#8220; (zun\u00e4chst indem wir sie aus der Scene entfernen).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 1: Eine neue Scene f\u00fcr die M\u00fcnze erstellen<\/h3>\n\n\n\n<p>Wir erstellen eine neue, eigenst\u00e4ndige Scene f\u00fcr unsere M\u00fcnze, die wir sp\u00e4ter beliebig oft in unserer <code>World<\/code>-Scene platzieren k\u00f6nnen:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Gehe im Men\u00fc auf <strong>Scene<\/strong> -&gt; <strong>New Scene<\/strong> (Strg + N).<\/li>\n\n\n\n<li>Klicke auf &#8222;Other Node&#8220; und w\u00e4hle <strong>Area2D<\/strong> als Root Node und klicke <strong>Create<\/strong>.<\/li>\n\n\n\n<li>Benenne den Root Node im Scene Dock um, z.B. zu <strong>Coin<\/strong>.<\/li>\n\n\n\n<li>Speichere diese neue Scene: <strong>Scene<\/strong> -&gt; <strong>Save Scene<\/strong> (Strg + S). Nenne sie <code>coin.tscn<\/code> und speichere sie im scene-Ordner.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 2: Visuelle Darstellung und Kollisionsform der M\u00fcnze hinzuf\u00fcgen<\/h3>\n\n\n\n<p>Wie schon beim Player, ben\u00f6tigt auch die M\u00fcnze eine visuelle Darstellung und eine Form f\u00fcr die Kollisionserkennung.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Stelle sicher, dass du im Scene Dock den <strong>Coin<\/strong> (<code>Area2D<\/code>) Node ausgew\u00e4hlt hast.<\/li>\n\n\n\n<li>Klicke auf den Button <strong>&#8222;+&#8220;<\/strong> (Child Node hinzuf\u00fcgen) oberhalb des Scene Trees.<\/li>\n\n\n\n<li>Suche in der Liste nach <strong>Sprite2D<\/strong>, w\u00e4hle ihn aus und klicke <strong>Create<\/strong>.<\/li>\n\n\n\n<li>W\u00e4hle den neuen <code>Sprite2D<\/code> Node im Scene Dock aus. Gehe im Inspector zum Abschnitt <strong>&#8222;Texture&#8220;<\/strong> und lade eine Bild-Datei, die einem Coin \u00e4hnelt. Du kannst dir hier z.B. bei <a href=\"https:\/\/free-game-assets.itch.io\/free-game-coins-sprite\">itch.io<\/a> welche herunterladen<\/li>\n\n\n\n<li>Klicke erneut auf den Button <strong>&#8222;+&#8220;<\/strong> (Child Node hinzuf\u00fcgen), w\u00e4hrend der <strong>Coin<\/strong> Node (<code>Area2D<\/code>) noch ausgew\u00e4hlt ist.<\/li>\n\n\n\n<li>Suche in der Liste nach <strong>CollisionShape2D<\/strong>, w\u00e4hle ihn aus und klicke <strong>Create<\/strong>.<\/li>\n\n\n\n<li>W\u00e4hle den neuen <code>CollisionShape2D<\/code> Node im Scene Dock aus. Im Inspector siehst du die Eigenschaft <strong>&#8222;Shape&#8220;<\/strong>, die momentan &#8222;Empty&#8220; ist.<\/li>\n\n\n\n<li>Klicke auf <strong>&#8222;&lt;empty&gt;&#8220;<\/strong> neben &#8222;Shape&#8220; und w\u00e4hle im Dropdown-Men\u00fc <strong>&#8222;New CircleShape2D&#8220;<\/strong>. Eine Kreisform ist oft passender f\u00fcr M\u00fcnzen.<\/li>\n\n\n\n<li>Godot erstellt eine neue Form. Klicke auf das neu erschienene <code>CircleShape2D<\/code> Symbol. Im Viewport siehst du nun die Kollisionsform als blauer Kreis.<\/li>\n\n\n\n<li>Ziehe die Ankerpunkte des Kreises im Viewport so, dass die Kollisionsform den <code>Sprite2D<\/code> (die M\u00fcnze) umschlie\u00dft. Du kannst auch den <code>Radius<\/code> im Inspector unter <strong>&#8222;Shape&#8220;<\/strong> anpassen (dazu nochmal auf den gerade ausgew\u00e4hlten <strong>CircleShape2D<\/strong> klicken).<\/li>\n\n\n\n<li>Speichere die Scene <code>coin.tscn<\/code> (Strg + S).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 3: Script an die M\u00fcnze anh\u00e4ngen und Signal verbinden<\/h3>\n\n\n\n<p>Nun kommt der Teil, der die Interaktion erm\u00f6glicht. Wir h\u00e4ngen ein Script an die <code>Coin<\/code> (<code>Area2D<\/code>) und verbinden ihr <code>body_entered<\/code> Signal, das ausgel\u00f6st wird, wenn ein <code>PhysicsBody<\/code> in die <code>Area2D<\/code> eintritt.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>W\u00e4hle im Scene Dock den <strong>Coin<\/strong> (<code>Area2D<\/code>) Node aus.<\/li>\n\n\n\n<li>Klicke auf den Button <strong>&#8222;Attach Script&#8220;<\/strong> (Pergamentrolle mit Plus) oberhalb des Scene Trees (oder \u00fcber das Kontextmen\u00fc).<\/li>\n\n\n\n<li>Stelle sicher, dass <strong>&#8222;Base Type&#8220;<\/strong> auf <code>Area2D<\/code> steht und der Pfad <code>coin.gd<\/code> vorschl\u00e4gt. Das <strong>&#8222;Template&#8220;<\/strong> kann auf &#8222;Node&#8220; bleiben.<\/li>\n\n\n\n<li>Klicke <strong>&#8222;Create&#8220;<\/strong>. Du siehst nun den Script Editor mit dem Basis-Template.&nbsp;<\/li>\n\n\n\n<li>Erg\u00e4nze&nbsp;<code>class_name Coin extends Area2D<\/code>&nbsp;am Anfang des Scripts.&nbsp;<\/li>\n\n\n\n<li>Stelle sicher, dass der <strong>Coin<\/strong> Node im Scene Dock ausgew\u00e4hlt ist.<\/li>\n\n\n\n<li>Gehe ins <strong>Node Dock<\/strong> (dieses befindet sich standardm\u00e4\u00dfig rechts neben dem Inspector, unter den Reitern &#8222;Inspector&#8220; und &#8222;Node&#8220;).<\/li>\n\n\n\n<li>Im Node Dock findest du eine Liste von Signalen, die der ausgew\u00e4hlte Node (<code>Area2D<\/code>) aussenden kann. Suche das Signal <strong><code>body_entered(body: PhysicsBody2D)<\/code><\/strong>.<\/li>\n\n\n\n<li>Klicke doppelt auf dieses Signal oder w\u00e4hle es aus und klicke unten im Node Dock auf <strong>&#8222;Connect&#8230;&#8220;<\/strong>.<\/li>\n\n\n\n<li>Ein Fenster <strong>&#8222;Connect a Signal&#8220;<\/strong> \u00f6ffnet sich. Im oberen Bereich siehst du das Signal (<code>body_entered<\/code>). Im unteren Bereich siehst du den Receiver. Stelle sicher, dass der <strong>Coin<\/strong> Node der Receiver ist (er ist bereits ausgew\u00e4hlt, da wir das Script an ihn geh\u00e4ngt haben). Die Methode, die generiert wird, sollte so aussehen: <code>_on_body_entered<\/code>.<\/li>\n\n\n\n<li>Klicke auf <strong>&#8222;Connect&#8220;<\/strong>. Godot erstellt automatisch die Funktion <code>_on_body_entered(body)<\/code> in deinem <code>coin.gd<\/code> Script und springt zum Script Editor.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 4: Kommunikation \u00fcber Signale: Player sammelt die M\u00fcnze ein<\/h3>\n\n\n\n<p>Um dem Player mitzuteilen, dass er eine M\u00fcnze ber\u00fchrt hat und diese dann &#8222;einsammeln&#8220; soll, nutzen wir <strong>eigene Signale<\/strong>. Das ist der Godot-Weg, um Nodes miteinander kommunizieren zu lassen, ohne dass sie direkt voneinander wissen m\u00fcssen. Die M\u00fcnze signalisiert lediglich, dass sie eingesammelt wurde. Unser Player kann dann auf dieses Signal h\u00f6ren und reagieren.<\/p>\n\n\n\n<p>Hierf\u00fcr werden wir:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ein benutzerdefiniertes Signal in unserem <strong><code>coin.gd<\/code><\/strong>-Script deklarieren und aussenden.<\/li>\n\n\n\n<li>Im <strong><code>player.gd<\/code><\/strong>-Script eine Funktion erstellen, die auf das Einsammeln reagiert.<\/li>\n<\/ul>\n\n\n\n<p>Die Verbindung zwischen dem M\u00fcnz-Signal und der Player-Funktion in unserer <strong><code>world.tscn<\/code><\/strong> herstellen, da die <code>World<\/code>-Scene sowohl den Player:in als auch die M\u00fcnzen kennt.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 5: Den Player identifizieren (Gruppen)<\/h3>\n\n\n\n<p>Wenn ein anderes Objekt jetzt das CollisionShape2D unserer M\u00fcnze ber\u00fchrt (in den K\u00f6rper eintritt), wird das Signal <code>body_entered<\/code> gesendet und jeder Abonnement informiert. In unserem Fall wird die Methode <code>_on_body_entered(body)<\/code> aufgerufen. Die Variable <code>body<\/code> in der Funktion <code><\/code>ist genau der Node, der gerade in unsere M\u00fcnz-Area eingetreten ist.<\/p>\n\n\n\n<p>Jetzt m\u00fcssen wir nur noch sicherstellen, dass der body auch wirklich ein Player ist. Nicht das die Gegner uns alle M\u00fcnzen klauen! Godot bietet ein sehr flexibles System, um Nodes zu identifizieren: <strong>Gruppen<\/strong>. Du kannst Nodes zu einer oder mehreren Gruppen hinzuf\u00fcgen. Dies ist der Weg, um Nodes nach ihrer &#8222;Rolle&#8220; oder ihrem &#8222;Typ&#8220; im Spiel zu kennzeichnen, anstatt sie direkt \u00fcber ihren Namen oder ihren spezifischen Node-Typ zu identifizieren.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Den Player einer Gruppe hinzuf\u00fcgen:<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u00d6ffne deine Scene <strong><code>player.tscn<\/code><\/strong>.<\/li>\n\n\n\n<li>W\u00e4hle im Scene Dock den Root Node <strong>Player<\/strong> (<code>CharacterBody2D<\/code>) aus.<\/li>\n\n\n\n<li>Gehe ins <strong>Node Dock<\/strong> (rechts neben dem Inspector). Dort findest du den Reiter <strong>&#8222;Groups&#8220; <\/strong>(gleich neben <strong>&#8222;Signals<\/strong>&#8222;).<\/li>\n\n\n\n<li>Klicke auf das &#8222;<strong>+<\/strong>&#8222;. Es \u00f6ffnet sich ein neues Fenster mit dem Namen &#8222;Create New Group&#8220;. Gib in das Feld <strong>&#8222;Name&#8220;<\/strong> den Namen <code>Player<\/code> ein und klicke auf <strong>&#8222;Ok&#8220;<\/strong>.\n<ul class=\"wp-block-list\">\n<li>Wichtig: Gruppennamen sind case-sensitive. Die Gro\u00df-Kleinschreibung ist sp\u00e4ter wichtig.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Du siehst nun <code>Player<\/code> in der Liste der Gruppen, zu der dein Player geh\u00f6rt (am Haken zu erkennen).<\/li>\n<\/ol>\n\n\n\n<p>Speichere die Scene <code>player.tscn<\/code> (Strg + S).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 6: Ein Signal in der M\u00fcnze deklarieren und aussenden<\/h3>\n\n\n\n<p>\u00d6ffne dein <code>coin.gd<\/code> Script. Ganz oben im Script, unter <code>extends Area2D<\/code>, deklarieren wir ein neues Signal namens <code>collected<\/code>. Danach wird dieses Signal in der <code>_on_Coin_body_entered<\/code>-Funktion ausgesendet, bevor die M\u00fcnze entfernt wird.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class_name Coin extends Area2D\n \n# Signal, das ausgesendet wird, wenn die M\u00fcnze eingesammelt wird.\nsignal collected\n \nfunc _on_body_entered(body):\n    if body.is_in_group(\"Player\"):\n        print(\"M\u00fcnze ber\u00fchrt!\")\n \n        # Sende das \"collected\"-Signal aus.\n        # Jeder Node, der mit diesem Signal verbunden ist, wird benachrichtigt.\n        emit_signal(\"collected\")\n \n        # M\u00fcnze am Ende des aktuellen Frames sicher aus der Szene entfernen\n        queue_free()<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>body.is_in_group(\"players\")<\/code> gibt <code>true<\/code> zur\u00fcck, wenn der Node in der Gruppe \u201eplayers\u201c ist, ansonsten <code>false<\/code>.&nbsp;<\/li>\n\n\n\n<li><code>signal collected<\/code>: So deklarieren wir ein benutzerdefiniertes Signal. Es ist sinnnvoll, Signale am Anfang des Scripts zu deklarieren.<\/li>\n\n\n\n<li><code>emit_signal(\"collected\")<\/code>: Ruft das Signal <code>collected<\/code> auf und informiert alle damit verbundenen Nodes.<\/li>\n\n\n\n<li><code>queue_free()<\/code> ist der Weg in Godot, um einen Node und alle seine Kinder sicher aus der Scene zu entfernen. Sie markiert den Node zur L\u00f6schung am Ende des aktuellen Frames. Das L\u00f6schen erst am Ende des Frames ist wichtig, um Fehler zu vermeiden, wenn der Node noch aktiv Operationen ausf\u00fchrt.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">&nbsp;Schritt 7: Eine Sammel-Funktion im Player erstellen<\/h3>\n\n\n\n<p>\u00d6ffne dein <code>player.gd<\/code> Script. Wir f\u00fcgen eine einfache Funktion <code>collect_coin()<\/code> hinzu, die sp\u00e4ter Punkte hinzuf\u00fcgen, Sound abspielen oder andere Logik ausf\u00fchren k\u00f6nnte, wenn der Player eine M\u00fcnze einsammelt.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class_name Player extends CharacterBody2D\n\nvar speed = 200 # Einheit: Pixel pro Sekunde\n\n# ... (Deine _ready, _process, _physics_process Funktionen bleiben unver\u00e4ndert)\n\n# Neue Funktion: Wird aufgerufen, wenn der Player:in eine M\u00fcnze einsammelt\nfunc collect_coin():\n    print(\"Player hat die M\u00fcnze erfolgreich gesammelt!\")\n    # Hier kommt sp\u00e4ter Logik wie Punkte erh\u00f6hen, Sound abspielen etc.<\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 8: Das Signal in der World-Scene verbinden<\/h3>\n\n\n\n<p>Damit unser Player auf das <code>collected<\/code>-Signal der M\u00fcnze reagieren kann, m\u00fcssen wir eine Verbindung herstellen. Die <code>World<\/code>-Scene ist der ideale Ort daf\u00fcr, da sie sowohl unseren Player:in als auch die instanziierten M\u00fcnzen kennt.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><p data-sourcepos=\"81:5-81:39\"><strong>Script an World-Scene anh\u00e4ngen:<\/strong><\/p>\n<ul class=\"wp-block-list\">\n<li>\u00d6ffne <code>world.tscn<\/code>.<\/li>\n\n\n\n<li>W\u00e4hle den Root Node <strong>World<\/strong> aus.<\/li>\n\n\n\n<li>Klicke auf <strong>&#8222;Attach Script&#8220;<\/strong> (Pergamentrolle mit Plus) oberhalb des Scene Trees.<\/li>\n\n\n\n<li>Als <strong>&#8222;Base Type&#8220;<\/strong> sollte <code>Node<\/code> stehen, und der Pfad <code>world.gd<\/code>. Klicke <strong>&#8222;Create&#8220;<\/strong>.<\/li>\n\n\n\n<li>Speichere das <code>world.gd<\/code> Script (Strg + S).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><p data-sourcepos=\"88:5-89:276\"><strong>Verbindung im <code>world.gd<\/code> Script herstellen:<\/strong> Wir nutzen die <code>_ready()<\/code>-Funktion der <code>World<\/code>-Scene, da diese aufgerufen wird, sobald die Scene und alle ihre Kinder (inklusive Player:in und M\u00fcnzen) bereit sind. Wir gehen alle Kinder der World durch, identifizieren Player:in und M\u00fcnzen und stellen die Verbindungen her.<\/p><\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class_name World extends Node\n\n# Called when the node enters the scene tree for the first time.\nfunc _ready():\n    # Referenz auf den Player holen\n    var player_node = null\n    for child in get_children():\n        # Pr\u00fcfen, ob das Kind eine Instanz von Player ist\n        if child is Player: \n            player_node = child\n            break # Player gefunden, Schleife beenden\n\n    if player_node == null:\n        print(\"Fehler: Player-Node in der Szene nicht gefunden!\")\n        return # Abbruch, wenn kein Player da ist\n\n    # Alle M\u00fcnz-Instanzen in der Szene finden und deren Signal mit dem Player verbinden\n    for child in get_children():\n        # Pr\u00fcfen, ob das Kind eine Instanz unserer Coin-Szene ist\n        # Hier nutzen wir auch den class_name f\u00fcr Coin,\n        if child is Coin:\n            # Verbinde das 'collected'-Signal der M\u00fcnze mit der 'collect_coin'-Funktion des Players\n            child.collected.connect(player_node.collect_coin)\n            print(\"M\u00fcnze ('\", child.name, \"') mit Player verbunden.\")<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>get_children()<\/code>: Gibt eine Liste aller direkten Kinder dieses Nodes (der <code>World<\/code>) zur\u00fcck. Dar\u00fcber iterieren wir.<\/li>\n\n\n\n<li><code>if child is Player<\/code>: Da wir unserem Player-Script <code>class_name Player<\/code> gegeben haben, k\u00f6nnen wir hier direkt den Typ des Nodes pr\u00fcfen. Das ist eine sehr robuste Methode.<\/li>\n\n\n\n<li><code>child.collected.connect(player_node.collect_coin)<\/code>: Dies ist der Kern der Signalverbindung im Code. Es sagt: &#8222;Wenn das <code>collected<\/code>-Signal von diesem <code>child<\/code> (unserer M\u00fcnze) ausgesendet wird, dann rufe die Funktion <code>collect_coin()<\/code> auf dem <code>Player<\/code> auf.&#8220;<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Das Sammeln der M\u00fcnze testen<\/h3>\n\n\n\n<p>Was haben wir gemacht, damit alles funktioniert? Eine ganze Menge:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Player zur Gruppe &#8222;Player&#8220; hinzugef\u00fcgt<\/strong><\/li>\n\n\n\n<li>Im <strong>M\u00fcnz-Script <\/strong><code>signal collected<\/code> definiert und&nbsp;<code>emit_signal(\"collected\")<\/code> in der Funktion <code>_on_body_entered(body)<\/code> aufgerufen und die M\u00fcnze entfernt.<\/li>\n\n\n\n<li><strong>Im Player<\/strong>&nbsp;die Funktion <code>func collect_coin()<\/code> implementiert.<\/li>\n\n\n\n<li><strong>Im World-Script <\/strong>alle M\u00fcnzen mit dem Player verbunden.<\/li>\n<\/ol>\n\n\n\n<p>Nun m\u00fcssen wir nur noch die M\u00fcnzen in der World platzieren.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u00d6ffne <code>world.tscn<\/code>. Platziere ein paar Instanzen unserer M\u00fcnz-Scene im Level (zieh die gespeicherte <code>coin.tscn<\/code> Datei aus dem Filesystem Dock in den Viewport oder auf den <strong>World<\/strong> Node im Scene Dock). Passe ggf. die Gr\u00f6\u00dfe an (im Inspector unter Node2D -&gt; Transform -&gt; Scale)<\/li>\n\n\n\n<li>F\u00fchre <code>world.tscn<\/code> aus (F5).<\/li>\n<\/ol>\n\n\n\n<p>Jetzt solltest du die M\u00fcnzen sehen, und wenn du mit deinem Player \u00fcber eine dr\u00fcberl\u00e4ufst, sollte sie verschwinden und sowohl <strong>&#8222;M\u00fcnze ber\u00fchrt!&#8220;<\/strong> (aus dem Coin-Script) als auch <strong>&#8222;Player hat die M\u00fcnze erfolgreich gesammelt!&#8220;<\/strong> (aus dem Player-Script) im Output Dock (unten im Editor) erscheinen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Dein n\u00e4chster Schritt<\/h3>\n\n\n\n<p>Sehr gut! Du hast jetzt erfolgreich interaktive Objekte erstellt, die auf \u00dcberlappungen reagieren, und dabei die <strong>Signal-Kommunikation<\/strong> in Godot genutzt. Wir haben gelernt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wie man <strong>Area2D<\/strong> Nodes nutzt, um \u00dcberlappungen zu erkennen.<\/li>\n\n\n\n<li>Das Konzept von <strong>Signalen<\/strong> in Godot, wie man sie deklariert, aussendet und im Code verbindet, um auf Ereignisse zu reagieren.<\/li>\n\n\n\n<li>Wie man <strong>Gruppen<\/strong> und <strong><code>class_name<\/code><\/strong> verwendet, um Nodes robust zu identifizieren.<\/li>\n\n\n\n<li>Wie man durch das Verbinden von Signalen in einer \u00fcbergeordneten Szene (der <code>World<\/code>) die Kommunikation zwischen verschiedenen instanziierten Szenen organisiert.<\/li>\n<\/ul>\n\n\n\n<p>Demn\u00e4chst werden wir weitere fortgeschrittene Anwendungen des <strong>Signalsystems<\/strong> beleuchten und beispielsweise ein simples UI-Element (HUD) erstellen, das die gesammelten M\u00fcnzen anzeigt.<\/p>\n\n\n\n<p>F\u00fcr unseren n\u00e4chsten Schritt bringen wir mit <strong>Animationen<\/strong> noch mehr Bewegung in die Szene.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nachdem wir die Bewegung unseres Spielers oder unserer Spielerin und die solide Kollision mit einer Wand gemeistert haben, ist der n\u00e4chste Schritt, die&hellip;<\/p>\n","protected":false},"author":2,"featured_media":630,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33],"tags":[35,41,34,40],"class_list":["post-585","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-godot","tag-2d-game","tag-collision","tag-godot","tag-kollision"],"_links":{"self":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/585","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/comments?post=585"}],"version-history":[{"count":6,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/585\/revisions"}],"predecessor-version":[{"id":618,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/585\/revisions\/618"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/media\/630"}],"wp:attachment":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/media?parent=585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/categories?post=585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/tags?post=585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}