Einen kompletten Pixel-Platformer in Godot 4 erstellen! | Thomas Yanuziello | Skillshare
Suchen

Playback-Geschwindigkeit


1.0x


  • 0.5x
  • 0.75x
  • 1x (normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Einen kompletten Pixel-Platformer in Godot 4 erstellen!

teacher avatar Thomas Yanuziello, Indie Game Developer

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Einheiten dieses Kurses

    • 1.

      Einführung

      1:23

    • 2.

      0-1 Einführung in die Programmierung

      8:03

    • 3.

      0–2 Konstanten und Variablen

      9:11

    • 4.

      0-3 If-Aussagen und Bedingungen

      9:46

    • 5.

      0-4 While-Loops und Operatoren

      9:23

    • 6.

      0-5-Arrays und For-Loops

      10:32

    • 7.

      0–6 Stapel und Funktionen

      10:53

    • 8.

      0-7 Match und Return

      9:34

    • 9.

      0-8 Szenenbaum und Vererbung

      10:21

    • 10.

      0-9 Abstraktion und Verkapselung

      10:41

    • 11.

      0-10-Polymorphismus

      8:01

    • 12.

      0-11-Wörterbuch

      8:54

    • 13.

      0-12 Debugging

      9:08

    • 14.

      1-0-Setup

      10:21

    • 15.

      1-1 Figur

      6:44

    • 16.

      1-2 Eingaben

      8:58

    • 17.

      1-3 Fortbewegung

      8:32

    • 18.

      1-4 Sprünge

      6:45

    • 19.

      1-5 Animation

      5:53

    • 20.

      1-6 Zustandsmaschine

      6:05

    • 21.

      1–7 Effekte

      10:21

    • 22.

      2-1 Tilemap

      6:07

    • 23.

      2-2 Dekorationen

      6:17

    • 24.

      2-3 Kamera

      9:04

    • 25.

      2-4 Tooks

      7:07

    • 26.

      2-5 Hintergrund

      9:55

    • 27.

      2-6 Wasser

      11:16

    • 28.

      2-7 Grenzen

      9:09

    • 29.

      3-1-Daten

      8:07

    • 30.

      3-2 Münzen

      8:57

    • 31.

      3-3 Benutzeroberfläche

      9:01

    • 32.

      3-4 Leben

      10:24

    • 33.

      3-5 Brust

      10:20

    • 34.

      3-6 Schloss und Schlüssel

      10:02

    • 35.

      3-7-Karte

      10:10

    • 36.

      4-1 Schaden

      9:55

    • 37.

      4-2 Reaktion

      9:59

    • 38.

      4-3 Wiederherstellung

      9:51

    • 39.

      4-4 Checkpoint

      9:30

    • 40.

      4-5 Tod

      10:05

    • 41.

      4-6 Feinde

      10:27

    • 42.

      4-7 Game Over

      13:17

    • 43.

      5-1 Schwert

      11:24

    • 44.

      5-2-Angriff

      12:03

    • 45.

      5-3 Luftangriff

      9:43

    • 46.

      5-4 Patrouille

      9:28

    • 47.

      5-5 Aggression

      9:45

    • 48.

      5-6 Projektile

      14:01

    • 49.

      5-7-Chef

      13:52

    • 50.

      6-1 Pause

      8:59

    • 51.

      6-2 Titel

      9:49

    • 52.

      6-3 Stufenauswahl

      9:19

    • 53.

      6-4 Speichern

      8:40

    • 54.

      6-5 Entsperren

      10:35

    • 55.

      6-6 Musik

      9:43

    • 56.

      6-7 Export

      7:33

  • --
  • Anfänger-Niveau
  • Fortgeschrittenes Niveau
  • Fortgeschrittenes Niveau
  • Jedes Niveau

Von der Community generiert

Das Niveau wird anhand der mehrheitlichen Meinung der Teilnehmer:innen bestimmt, die diesen Kurs bewertet haben. Bis das Feedback von mindestens 5 Teilnehmer:innen eingegangen ist, wird die Empfehlung der Kursleiter:innen angezeigt.

352

Teilnehmer:innen

1

Projekte

Über diesen Kurs

Lerne in diesem Kurs, wie du einen kompletten Pixel-Platformer in Godot 4 aufbaust!  Egal, ob du neu in der Spielentwicklung bist, neu in der Godot-Engine bist oder deine Fähigkeiten mit einigen anspruchsvollen Designprinzipien verbessern möchtest, du wirst hier eine Menge lernen!  Der Anfang des Kurses konzentriert sich auf das Schreiben von Skripten und die GDScript-Sprache.  Wenn du bereits mit Godot und GDScript vertraut bist, kannst du diese Lektionen überspringen und direkt zur Setup-Lektion springen.

Klicke auf meinen Website-Link in meinem Profil, um unserem Discord-Server beizutreten!

Jeder Abschnitt des Kurses konzentriert sich in der Regel auf einen Aspekt des Spiels: Charakter, Levels, Schatz, Feinde usw.  Die Abschnitte sind in 7 Videolektionen unterteilt, die jeweils auf das Vermitteln einer Funktion der Godot-Engine, eines Skripts oder eines bestimmten Teils der Spielentwicklung ausgerichtet sind.  Am Ende jedes Abschnitts hast du eine Vorlage, um die verschiedenen Aspekte deines Spiels zu erstellen.

Es gibt eine Aufgabe, die du erledigen musst, bevor du mit dem Rest des Kurses fortfährst. Sie wiederholt viele der im gesamten Abschnitt gelehrten Lektionen, um mehr der Spielelemente zu implementieren, und bietet auch zusätzliche Herausforderungen für diejenigen, die sie ausprobieren möchten.  Die Challenges sind optional und nicht erforderlich, um mit den Lektionen fortzufahren.

Dieser Kurs beinhaltet das Scripting in der Godot-Skriptsprache.  Wenn du das erste Mal mit Scripting arbeitest, kannst du gerne mitmachen, und ich werde dir im Laufe der Zeit einzelne Elemente erklären.  Um neue Teilnehmer:innen nicht zu überwältigen, werde ich versuchen, nicht alles auf einmal zu erklären, sondern mich auf einzelne Elemente zu konzentrieren, die für jede Kurseinheit relevant sind.  Wenn du Erfahrung mit dem Scripting-Arbeiten in anderen Sprachen hast, ist das Godot-Skript extrem einfach zu erlernen und du wirst sehen, wie gut es für die Engine und die Spieleentwicklung im Allgemeinen optimiert ist.

Die in diesem Kurs verwendeten Assets sind kostenlos auf itch.io und FreeSound.org verfügbar.

Triff deine:n Kursleiter:in

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Kursleiter:in
Level: Intermediate

Kursbewertung

Erwartungen erfüllt?
    Voll und ganz!
  • 0%
  • Ja
  • 0%
  • Teils teils
  • 0%
  • Eher nicht
  • 0%

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

Jeder Kurs setzt sich aus kurzen Einheiten und praktischen Übungsprojekten zusammen

Mit deiner Mitgliedschaft unterstützt du die Kursleiter:innen auf Skillshare

Lerne von überall aus

Ob auf dem Weg zur Arbeit, zur Uni oder im Flieger - streame oder lade Kurse herunter mit der Skillshare-App und lerne, wo auch immer du möchtest.

Transkripte

1. Promo V2: Du hast angefangen, Gott zu lernen. Du hast Tutorials besucht und kleinere Projekte gemacht, aber du bist bereit, das nächste Level zu erreichen und ein vollständiges Spiel mit professionellem Niveau, Code, Struktur und Design zu erstellen . In diesem Kurs lernst du, wie du eine komplette Pixel-Plattform von Grund auf neu erstellst und wie ein skalierbares Spiel mit wiederverwendbarem Code erstellst, das auf Spiele anderer Genres angewendet werden kann . Du lernst, einen Charakter zu bauen , den der Spieler kontrollieren kann, und Levels entwerfen, den Fortschritt des Spielers im Spiel verfolgen und an Checkpoints reagieren, ein Kampfsystem mit Feinden und einem Bosskampf erstellen und skalierbare Designprinzipien für Gadot erlernen , die du auf jedes Gadot-Projekt anwenden kannst. Wenn du fertig bist, hast du eine Vorlage für ein komplettes Spiel, das du mit mehr Levels, mehr Mechaniken, mehr Gegenständen und mehr Feinden bevölkern kannst Mechaniken, mehr Gegenständen und mehr Feinden Falls du Hilfe benötigst, ist unser Discord-Server voll von anderen Studenten und Spieleentwicklern , die alle deine Fragen beantworten können Klicken Sie auf den Link zur Website und auf mein Profil, um Mitglied zu werden. Wir werden mit einem leeren Projekt in Godot Version 4.2 beginnen und kostenlose Assets aus dem Dot IO verwenden Sie können jedoch gerne Ihr eigenes Projekt mit verschiedenen Assets verfolgen Ihr eigenes Projekt mit verschiedenen Assets Zusätzliche Hinweise und Videos wurden ebenfalls hinzugefügt, um neue Funktionen in Godot Version 4.3 zu aktualisieren Lass uns anfangen, dein erstes vollständiges Spiel zu erstellen. 2. 0-1 Einführung in die Programmierung: Hallo Freunde. musst du die GDOGameEngine von gdongine.org herunterladen Falls du das noch nicht getan hast, musst du die GDOGameEngine von gdongine.org herunterladen. Die Engine ist kostenlos, aber du kannst spenden, um das Projekt zu unterstützen, Es gibt keinen Installationsvorgang. Sie können die komprimierte Datei einfach entpacken und öffnen. Stellen Sie sicher, dass Sie die ausführbare Datei an einen besseren Ort verschieben. Das erste Startfenster ist eine Liste Ihrer aktuellen Projekte Wenn Sie jedoch noch keine Projekte haben, werden Sie aufgefordert, sich Demo-Projekte anzusehen. Wir können das ignorieren und einfach unser eigenes neues Projekt erstellen , indem wir entweder auf diese Schaltfläche in der Projektliste oder auf die Schaltfläche Erstellen oben im Fenster klicken. Hier können wir unserem Projekt einen Namen geben , der normalerweise der Name Ihres Spiels wäre. Ich werde nur eine Einführung in die Programmierung geben. Das Projekt muss auf der Festplatte unseres Computers gespeichert werden , und wir erstellen einen neuen Ordner mit dem gleichen Namen wie das Projekt Standardmäßig möchte es alles im Dokumentenordner speichern, aber es wäre besser, einen neuen Unterordner für Godot-Projekte zu erstellen einen neuen Unterordner für Godot-Projekte Der Renderer ändert, wie bestimmte zwei D - und drei D-Objekte gerendert werden, aber wir werden nichts zeichnen, sodass wir diese Optionen ignorieren können Der Renderer kann auch später geändert werden. Und die Versionskontrollkompatibilität mit Github ist standardmäßig enthalten , wenn Sie damit Ihr Projekt sichern oder mit anderen teilen möchten Ihr Projekt sichern oder mit anderen teilen Wenn Sie bereit sind zu beginnen, klicken Sie auf Erstellen und Bearbeiten. Das GDOEditor-Fenster öffnet unser neu erstelltes leeres Projekt Der Editor ist in fünf Hauptdocks unterteilt. Eine Vorschau unseres Spiels befindet sich in der Mitte. Das untere linke Dock enthält einen Dateibrowser der den Inhalt des Projektordners anzeigt , den wir gerade erstellt haben. Es enthält derzeit nur das Gadot-Symbol. Das obere linke Dock enthält den Szenenbaum, eine Liste von allem, was sich in unserer aktuellen Szene ist derzeit leer, sodass wir einen Stamm für den Szenenbaum erstellen Wir werden nichts zeichnen, also müssen wir nicht angeben, ob es sich bei dieser Szene um zwei D oder drei D oder um eine Benutzeroberfläche handelt . Wir können also einfach einen anderen Knoten auswählen. Es gibt viele verschiedene Knoten, die wir erstellen können, aber wir sind nur daran interessiert zu lernen, wie man Skripte schreibt, also werden wir einfach einen Standardknoten verwenden. Wir können unseren neuen Knoten umbenennen indem wir auf ihn klicken, nachdem er ausgewählt wurde , oder indem wir mit der rechten Maustaste klicken, um sein Kontextmenü zu öffnen , und Umbenennen auswählen. Nennen wir diesen Knoten Lektion eins. Wenn Sie einen Knoten im Szenenbaum auswählen werden seine Eigenschaften im Inspektor angezeigt , der an der rechten Seite des Fensters angedockt ist Wir können den Namen des ausgewählten Knotens und seine Eigenschaften sehen, die in erweiterbare Kategorien unterteilt sind, aber keine dieser Eigenschaften aber keine dieser Eigenschaften trifft auf das zu, was wir gerade Bevor wir etwas anderes tun, sollten wir unsere neue Szene speichern, indem wir entweder im Szenenmenü die Option Szene speichern wählen oder die Tastenkombination Strg S oder Befehl S verwenden . Dadurch wird ein Dialogfeld geöffnet, in dem wir einen Namen für unsere Szene mit der TSCNEtension und einen Zielordner angeben können und Lassen Sie uns einen neuen Ordner für Lektion eins erstellen dann die Szene in diesem Ordner speichern Wir können jetzt auf der Registerkarte Dateisystem sehen, dass unser neuer Ordner für Lektion eins erstellt wurde und dass er die Szene aus Lektion 1 enthält, die mit dem Clapperboard-Symbol gekennzeichnet ist Als Nächstes hängen wir ein Skript den Stammknoten unserer Szene an, indem wir entweder den Stammknoten auswählen und auf die angehängte Skriptschaltfläche klicken oder indem wir mit der rechten Maustaste darauf klicken und das angehängte Skript auswählen Die Sprache ist GD Script, die Programmiersprache die wir lernen werden. Jedes Skript erbt standardmäßig von dem Knotentyp, an den es angehängt ist Da der Root-Node ein Standard-Knotentyp ist, erbt unser Skript vom Wir verwenden weder eine Vorlage noch ein integriertes Skript, und wir können angeben, wo dieses Skript innerhalb des Projekts gespeichert werden soll Lassen Sie uns das in denselben Ordner legen. Lektion eins. Bei der Benennung von Skripten ist es wichtig, nicht willkürlich zu sein, sondern stattdessen den Objekttyp oder das Verhalten zu beschreiben , das wir mit dem Skript erzeugen. Nennen wir das also Hallo. Skripte haben die Dateierweiterung dotGD. Klicken Sie anschließend auf Erstellen , um das Skript zu erstellen. Dadurch wechselt unsere Vorschau zur Skriptansicht unser neu erstelltes Hello-Skript wird angezeigt. Wir können unser Skript auch auf der Registerkarte Dateisystem sehen , das mit einem Zahnradsymbol gekennzeichnet ist, und der Stammknoten von Lektion 1 hat das Skriptsymbol, das uns zeigt , dass ein Skript angehängt ist Wenn wir den Mauszeiger darüber bewegen, wird uns der Name des Wenn Sie auf dieses Symbol klicken, wird das Skript auch geöffnet, sofern es nicht bereits geöffnet Unser Skript hat nur eine Zeile, die seine Vererbung vom Basis-Knotentyp mit dem Schlüsselwort extends beschreibt . Das bedeutet nur, dass unser Skript alles kann, was ein Knoten kann, plus alles, was wir hier schreiben. Es ermöglicht uns auch, das Verhalten des Knotens, das bereits existiert, mit neuen eigenen Verhaltensweisen zu überschreiben Knotens, das bereits existiert . Knoten haben zum Beispiel eine Funktion namens ready, aber sie tut nichts. Wenn wir also möchten, dass unser Skript dieses Verhalten , nichts zu tun, außer Kraft setzt, können wir unsere eigene Funktion mit dem gleichen Namen mit dem Schlüsselwort funk deklarieren . Funk folgt dann der Name der Funktion, der normalerweise in kleiner Schlangenschreibung geschrieben wird, was bedeutet, dass alle Kleinbuchstaben Wörter durch Unterstriche trennen Vielen der durch Knoten definierten Funktionen wird ein Unterstrich vorangestellt , und der Name muss exakt übereinstimmen, um das Verhalten zu überschreiben zu den Namen der Funktion müssen Klammern und ein Doppelpunkt folgen Wir werden später besprechen, warum. Wenn Sie nach dieser Zeile die Eingabetaste drücken, wird die nächste Zeile automatisch um eine Ebene eingerückt Auf diese Weise weiß GD Script, welche Zeilen in der Funktion enthalten sind und wo sie enden Die Zeile ist rot hervorgehoben , da Funktionen nicht leer sein dürfen. Es ist also eine gute Idee , das Wort Pass zu schreiben , um neuen Funktionen einen Körper zu geben, der nichts tut. Jetzt, da der Fehler behoben ist, können wir dieses blaue Pfeilsymbol vor der Funktionsdeklaration sehen . Dabei handelt es sich um das Override-Symbol, das darauf hinweist, dass dieses Skript jetzt das Bereitschaftsverhalten unseres Nodes überschreibt Anstatt nichts zu tun, möchten wir, dass unser Knoten Hallo sagt, was wir mit einer Print-Anweisung tun können, die die Zeile ersetzt, in der zuvor Pass stand Die Print-Anweisung sieht einer Funktionsdeklaration mit einem Namen gefolgt von Klammern ähnlich einem Namen gefolgt von Klammern da sie eine eingebaute Funktion aufruft Diese Funktion benötigt ein Argument, das in die Klammern gesetzt wird Und dieses Argument wird gedruckt. Mit Anführungszeichen können wir alles schreiben, was wir wollen, und es wird von unserem Skript ausgedruckt , wenn der Knoten bereit ist. Da das Skript Hello heißt, wollen wir ein Verhalten erzeugen dass der Knoten Hallo sagt. unser Skript fertig ist, können wir unser Spiel mit der Schaltfläche „Aktuelle Szene ausführen oben rechts oder mit der Tastenkombination F sechs ausführen. Dadurch wird ein leeres Fenster angezeigt, da unser Spiel nichts zeichnet, aber es öffnet auch das fünfte Dock, in dem das Ausgabefenster angezeigt wird. Und in unserer Ausgabe können wir sehen, dass unser Node die Worte Hello World gedruckt hat , als er fertig war. Wir können diese Simulation beenden, indem wir das Fenster schließen, auf die Stopp-Schaltfläche klicken oder die Tastenkombination F 8 verwenden. Wir können den gedruckten Text so ändern, dass er alles sagt, was wir wollen, und ihn erneut ausführen, um sicherzustellen, dass unser Node alles ausdrucken kann, was wir ihm sagen. Wir wissen jetzt, wie man Skripte an Knoten anhängt und sie ausführt. In der nächsten Lektion werden wir etwas über Konstanten und Variablen lernen über Konstanten und Variablen Wir sehen uns in der nächsten Lektion. 3. 0–2 Konstanten und Variablen: Hallo Freunde. Wir beginnen jede Lektion, indem wir zuerst einen neuen Ordner für die Lektion erstellen. Erstellen Sie dann eine neue Szene in diesem Ordner mit dem gleichen Namen. Doppelklicken Sie auf der Registerkarte Dateisystem auf eine Szene , um sie zu öffnen. mehrere Szenen geöffnet sind, können wir zwischen ihnen wechseln, indem wir im Vorschaudokument auf die entsprechenden Tabs klicken. Heute werden wir die Unterschiede zwischen Konstanten und Variablen anhand von Tagen als Bezugsrahmen erörtern Konstanten und Variablen anhand von Tagen als Bezugsrahmen Lassen Sie uns also ein neues Skript an den Stammknoten der Szene anhängen und es Tage nennen Beginnen wir mit Konstanten und deklarieren oben im Skript mit dem Schlüsselwort const, gefolgt vom Namen unserer neuen Konstante, die üblicherweise in Schlangengroßbuchstaben geschrieben wird Eine Konstante ist wie ein Container in dem wir Informationen speichern können, aber diese Informationen dürfen sich niemals ändern Etwas, das wir als Konstante betrachten würden , könnte die Anzahl der Tage in der Woche sein. Da sie nicht geändert werden kann, muss ihr sofort ein Wert zugewiesen werden, weshalb wir einen Fehler haben. Wir müssen dem Namen ein Gleichheitszeichen folgen lassen, dem Zuweisungsoperator, um der Konstante einen Wert zu geben. Die Anzahl der Tage in der Woche beträgt sieben. Es ist vernünftig anzunehmen , dass es immer sieben sein werden und es ist für alle gleich. Daher sollte es niemals nötig sein, seinen Wert zu ändern. Umgekehrt haben wir Variablen, bei denen es sich auch um Container zum Speichern von Informationen handelt, die jedoch so konzipiert sind, dass sie geändert werden können Wir können eine Variable auf die gleiche Weise mit dem Schlüsselwort VR deklarieren und ihr dann einen Namen geben, ihr dann einen Namen geben üblicherweise in Kleinbuchstaben geschrieben wird. Das macht es einfach, den Unterschied zwischen Konstanten und Variablen in unseren Skripten zu erkennen zwischen Konstanten und Variablen in unseren Etwas, das sich häufig ändert , könnte der Wert von heute Im Gegensatz zu Konstanten dürfen Variablen leer sein. Lassen Sie uns die Ready-Funktion unseres Basisknotens überschreiben und die Werte sowohl für die Anzahl der Wochentage als auch für den heutigen Tag ausgeben Wir können sehen, dass die Anzahl der Tage in der Woche sieben beträgt, aber der Wert von heute wird als Null ausgegeben, was bedeutet, dass der Wert leer ist oder kein Wert vorhanden ist. Lassen Sie uns das beheben, indem wir den heutigen Tag als Donnerstag initialisieren. Und wir können unsere Ausgabe lesbarer machen , indem wir etwas Kontext hinzufügen, indem wir mit etwas wie heute beginnen, dann ein Leerzeichen hinterlassen , danach ist ein Pluszeichen, dann unsere Variable In diesem Fall wird das Pluszeichen verwendet, um zwei Satzteile aneinander anzuhängen Wenn wir jedoch versuchen, dasselbe mit unserer Konstante zu tun , führt dies zu einem Fehler, da unsere Konstante eine Zahl und kein Wort ist Als wir unsere Konstante deklariert haben, haben wir ihr den Wert Sieben zugewiesen, was eine Zahl ohne Dezimalstellen ist, die in der Mathematik als Ganzzahl bezeichnet wird. Unsere Konstante hat also eine Art Ganzzahl. Heute wurde dagegen ein Wert zugewiesen, der aus einigen Zeichen besteht, die in Anführungszeichen gesetzt sind. In der Programmierung nennen wir das eine Zeichenfolge. Unsere Variable hat also eine Art von Zeichenfolge. Der Plus-Operator kann nur verwendet werden , wenn die Typen beider Operanden kompatibel sind Wir können dies umgehen, indem wir eine eingebaute Funktion verwenden, um den Typ, wie er hier verwendet wird, in eine Zeichenfolge zu ändern die Konstante als Argument an die Funktion zu übergeben Dadurch wird der Typ der ursprünglichen Konstante nicht geändert, sondern nur die Art und Weise, wie sie hier im Kontext der Anfügeoperation verwendet wird im Kontext der Anfügeoperation Und wir können auch danach mit einer weiteren angehängten Zeichenfolge weiteren Kontext hinzufügen , wobei wir daran denken müssen, ein zusätzliches Leerzeichen am Anfang hinzuzufügen Jetzt können wir unsere Konstanten und Variablen ausdrucken , indem wir sie in leicht verständlichen Sätzen Lassen Sie uns nach diesen Zeilen so tun, als ob ein Tag vergeht. Wir können unseren Skripten zusätzlichen Kontext hinzufügen , der von Spielern nie gesehen wird, sondern nur dazu da ist, uns als Entwickler zu helfen , unseren eigenen Code oder den von anderen geschriebenen Code zu verstehen oder den von anderen geschriebenen Code Diese werden als Kommentare bezeichnet und mit dem OctathorpPound-Zeichen oder dem Hashtag erstellt mit dem OctathorpPound-Zeichen oder dem Hashtag Jeder Text, der nach diesem Symbol geschrieben wird, wird grau eingefärbt und hat keinerlei Auswirkungen auf die Ausführung des Skripts Sie können sich in eigenen Zeilen oder am Ende einer Codezeile befinden. Lassen Sie uns also anhand eines Kommentars erklären , dass wir so tun, als ob zwischen dem Code über dieser Zeile und dem Code unten ein Tag vergangen über dieser Zeile und dem Code unten Wir ändern den Wert von heute auf Freitag und drucken einen weiteren Satz aus Heute ist plus Heute, was jetzt einen anderen Wert hat. Wir können sehen, dass der Wert von heute zuerst als Donnerstag gedruckt und dann geändert wurde und der nächsten Zeile als Freitag gedruckt wird. Der Kommentar hatte keine Auswirkung auf die Ausführung des Skripts. Wenn wir versuchen, den Wert unserer Konstanten zu ändern, führt dies natürlich zu einem Fehler, da Konstanten nicht geändert werden dürfen Wenn wir einige Codezeilen in unserem Skript nicht mehr verwenden möchten , können wir sie einfach in Kommentare umwandeln, indem sie markieren und Strg K oder Befehl K drücken und das Kommentarsymbol vor jeder hervorgehobenen Zeile hinzufügen vor jeder hervorgehobenen Zeile Durch erneutes Drücken werden die Kommentare entfernt. Wir können den Typ der Variablen oder Konstanten angeben , indem wir nach dem Namen einen Doppelpunkt hinzufügen. Gefolgt vom Typnamen wollen wir auch diese Konstante oder Variable einschränken. Beschränken wir unsere Konstante auf den Typ int und heute auf den Typ string. Neben Zeichenketten und Ganzzahlen gibt es zwei weitere primitive Typen, gibt es zwei weitere primitive Typen wir zum Speichern grundlegender Informationen verwenden können Wenn eine Zahl Dezimalstellen hat, handelt es sich nicht mehr um eine Ganzzahl, sondern um einen anderen Typ, der als Fließkommazahl bezeichnet wird und sondern um einen anderen Typ, der als Fließkommazahl bezeichnet wird den Typnamen float verwendet Fügen wir eine weitere Variable für das heutige Datum hinzu und geben ihr eine Art Fließkommazahl mit dem Wert 12,05, was dem heutigen Datum, dem 5. Dezember, entspricht Und der letzte Typ heißt Boolean und verwendet den verkürzten Namen Boole , der entweder wahr oder falsch sein kann Also fügen wir eine weitere Variable , ob heute ein Feiertag ist oder nicht Ich beschränke das auf einen booleschen Wert, gebe ihm aber keinen Anfangswert Fügen wir zwei weitere Print-Anweisungen hinzu, um die Werte dieser Variablen mit Kontext auszudrucken die Werte dieser Variablen mit Das heutige Datum ist ein Plus-Datum, und heute ist ein Feiertag. Colon Plus ist ein Feiertag. Wenn wir das jetzt ausführen, können wir unser Datum ausgedruckt sehen, aber ist ein Feiertag falsch, obwohl wir ihm keinen Wert geben. Das liegt daran, dass alle primitiven Typen einen Standardwert haben, aber der Standardwert kann nur zugewiesen werden , wenn wir den Variablentyp angeben. Da wir angegeben haben, dass ein Feiertag ein boolescher Wert ist, wurde er dem Standardwert für einen booleschen Wert zugewiesen , Der Standardwert für eine Ganzzahl und eine Fließkommazahl ist beide Null, und der Standardwert für eine Zeichenfolge ist nur eine leere Zeichenfolge, die nicht mit Null identisch ist, sondern eine Zeichenfolge ohne Zeichen Wenn wir den Typ einer Variablen nicht angeben, ihr Standardwert Null, aber ihr kann ein Wert eines beliebigen Typs zugewiesen werden, und ihr Typ kann sich jederzeit ändern. Lassen Sie uns den Typ aus dem Datum entfernen. Geben Sie ihm dann einen neuen Wert vom 13. Dezember und drucken Sie ihn ein zweites Mal aus. Der Variablen wird zunächst ein Wert in Form einer Fließkommazahl zugewiesen, wird von der Print-Anweisung verwendet, dann wird ihr ein Zeichenkettenwert zugewiesen bevor sie erneut ausgedruckt wird. Dies ist zulässig , da GD Script eine lose typisierte Sprache ist Dies bietet mehr Flexibilität beim Schreiben unserer Skripte, aber auch mehr Verantwortung, um Typkompatibilitätsfehler zu vermeiden , wie wir sie beim Plus-Operator gesehen haben Es wird empfohlen, dass Sie Ihren Variablen immer einen Typ geben, nicht nur um Fehler zu vermeiden, sondern auch, um die Effizienz der Ausführung Ihrer Skripte zu verbessern . Wenn die Engine den Typ Ihrer Variablen kennt, weiß sie auch genau wie viel Speicher sie belegen muss. Dies gilt auch für die Verwendung von Konstanten anstelle von Variablen Wenn die Engine weiß, dass sich der Wert nicht ändern kann, kann er effizienter verwendet werden In der nächsten Lektion lernen wir, wie wir den Ablauf unserer Skripte steuern können. Wir sehen uns in der nächsten Lektion. 4. 0-3 If-Aussagen und Bedingungen: Hallo Freunde. Ich habe bereits eine neue Szene in einem neuen Ordner für diese Lektion erstellt. Heute lernen wir , wie wir den Ablauf unserer Skripts steuern können, um verschiedene Codezeilen auszuführen und zu entscheiden, ob wir sehen können oder nicht. Lassen Sie uns also ein neues Skript an den Stammknoten unserer Szene anhängen und es Vision nennen. Wir werden unser Skript starten, indem wir die Basisknoten-Definition der Ready-Funktion überschreiben die Basisknoten-Definition der Ready-Funktion Die einfachste Methode zur Steuerung des Ablaufs unserer Skripten ist die I-Anweisung, die mit dem Schlüsselwort I beginnt. Auf sie folgt eine bedingte Anweisung , die entweder wahr oder falsch sein muss Lassen Sie uns zunächst „wahr“ sagen, worauf dann ein Doppelpunkt folgt. Ähnlich wie der Doppelpunkt am Ende unserer Funktionsdeklaration markiert dies das Ende der Anweisung, und wenn Sie mit der nächsten Zeile fortfahren, wird sie automatisch um eine weitere Ebene eingerückt Alle Codezeilen, die auf diese if-Anweisung folgen und eingerückt sind , werden nur ausgeführt wenn die Bedingung der if-Anweisung wahr ist Lassen Sie uns also so etwas wie die Bedingung als wahr ausdrucken und dann die aktuelle Szene ausführen , um zu sehen, ob unsere Print-Anweisung funktioniert Wenn wir wahr in falsch ändern, können wir sehen, dass die Druckanweisung dieses Mal übersprungen wird Wir können nach den if-Anweisungen, die den Hauptteil eingerückt haben, auf derselben Einzugsebene wie die I-Anweisung eine weitere Zeile hinzufügen if-Anweisungen, die den Hauptteil eingerückt haben, auf derselben Einzugsebene wie die , einfach mit dem Schlüsselwort se gefolgt von Dadurch wird ein weiterer Bedingungstext erstellt, der nur ausgeführt wird , wenn die Bedingung der ursprünglichen I-Anweisung nicht erfüllt wurde Lassen Sie uns die gedruckte Anweisung duplizieren und so ändern, dass sie etwas anderes aussagt. Da die Bedingung falsch war, wurde der se-Block anstelle des I-Blocks ausgeführt. Und wenn wir die Bedingung auf wahr ändern , passiert das Gegenteil. Dies ist nicht sehr nützlich, wenn wir immer wissen, dass das Ergebnis der bedingten Aussage wahr oder falsch ist, aber wir können es durch eine Variable ersetzen. Deklarieren wir eine boolesche Variable, die angibt , ob das Licht im Raum an ist oder nicht Boolesche Werte werden üblicherweise so benannt , dass sie ihre Verwendung als Bedingung implizieren In diesem Fall bedeutet Licht ist an, je nachdem, wie es benannt wurde, entweder wahr oder falsch Jetzt kann unsere if-Anweisung als Bedingung festlegen , ob der Wert unserer Variablen wahr ist oder nicht Wenn wir zwei Werte vergleichen, um festzustellen, ob sie gleich sind, verwenden wir ein doppeltes Gleichheitszeichen, den sogenannten Gleichheitsoperator, das sich von einem einfachen Gleichheitszeichen unterscheidet das wir zuvor als Zuweisungsoperator verwendet haben. Wir drucken dann entweder „Ich kann sehen“ oder „Ich kann nicht sehen“ aus, was darauf zurückzuführen ist, ob das Licht an ist oder nicht, gleich wahr ist. Da der Standardwert eines booleschen Werts falsch ist, können wir die Ausgabe so sehen, wie ich sie nicht sehen kann Aber wenn wir die Variable auf true setzen, ändert sie sich zu Ich kann sehen Da die Variable selbst ein boolescher Wert ist , entweder wahr oder falsch, können wir die Vergleichsoperation ganz entfernen und einfach den booleschen Wert als Bedingung verwenden und genau das gleiche Ergebnis erzielen Wir können den Wert eines beliebigen booleschen Werts umkehren, d. h. wenn er wahr ist, falsch oder wenn er falsch ist, wird er wahr, indem wir das Schlüsselwort not Wie bei der STR-Funktion, die wir in der vorherigen Lektion verwendet haben, ändert dies nur die Art und Weise, wie sie im lokalen Kontext verwendet wird , und ändert nicht wirklich den in der Variablen gespeicherten Wert Wenn nicht, ist Licht an, dann können wir nichts sehen, und sonst können wir sehen. Nichts kann auch durch ein Ausrufezeichen dargestellt werden. Lassen Sie uns den Wert der eingeschalteten Lichter ändern und es erneut ausführen. Ich setze diese Änderungen dann wieder auf den vorherigen Stand zurück Wir können unsere Bedingungen viel komplexer machen, indem mehrere Bedingungen mithilfe von logischen Operatoren miteinander kombinieren mithilfe von logischen Operatoren miteinander Lassen Sie uns eine weitere Variable mit dem Namen Has dark vision erstellen. Diese Variable impliziert , dass wir auch dann sehen können sollten , wenn das Licht nicht an ist. Wir können also zu unseren If-Aussagen die Bedingung hinzufügen, dass entweder das Licht an ist oder dass wir eine dunkle Sicht haben. Und wenn eine dieser Bedingungen zutrifft, dann können wir sehen. Nur wenn beide Bedingungen falsch sind, führt das dazu, dass wir nicht sehen können? Was ist, wenn wir statt Dunkelsicht eine Nachtsichtbrille tragen, da wir damit nur im Dunkeln sehen können, aber nicht im Licht den Variablennamen ändern, muss sich auch der Zustand unserer I-Anweisung ändern Denn wenn beide Bedingungen zutreffen, sollten wir nichts sehen können. Nur wenn die Werte dieser beiden Bedingungen unterschiedlich sind, sollten wir dann davon ausgehen, dass die zu prüfende Bedingung erfüllt ist? Wir können den Operator „ungleich“ verwenden , um zu überprüfen, ob die beiden Werte nicht gleich sind. Wenn Sie mit logischen Operationen vertraut sind, wird dies in anderen Sprachen als ausschließliches Oder bezeichnet Jetzt können wir nur noch sehen, wenn entweder das Licht an ist oder wir eine Nachtsichtbrille tragen und nicht beides Als Nächstes nehmen wir an, dass unsere hypothetische Person möglicherweise kein Mensch ist, und fügen eine Variable für die Anzahl der Is hinzu, die sie hat, die als Ganzzahl dargestellt werden sollte Vorerst geben wir ihr einen Wert von zwei Is. die anderen Variablen ignorieren Was wäre die Bedingung, die wir setzen, um anhand dieser Variablen sehen zu können, wenn wir die anderen Variablen Wenn die Anzahl unserer Augen größer als Null ist, sollten wir sehen können Wir können dies auch mit einem anderen Operator ausdrücken, größer oder gleich , und die rechte Seite durch eins ersetzen. Sie müssen also Augen haben, die größer oder gleich eins sind. Dies sind Vergleichsoperatoren, die ein boolesches Ergebnis zurückgeben , indem sie den Wert von Zahlen auf der linken und rechten Seite vergleichen den Wert von Zahlen auf der linken und rechten Wir können logischerweise den Schluss ziehen , dass es für jedes Lebewesen, ob Mensch oder anderes, unmöglich sein sollte jedes Lebewesen, ob Mensch oder , eine negative Anzahl von Augen zu haben Der Wert unserer Variablen sollte nur Null oder etwas größer als Null Und die Bedingung , sehen zu können, läuft wirklich auf diese beiden Optionen Haben wir keine Augen oder Augen, die nicht Null sind? So wie die boolesche Variable implizit als Bedingung verwendet werden kann, kann auch eine Ganzzahl auf diese Weise verwendet werden, wobei Null falsche Bedingung und alles andere als Null als wahr betrachtet wird Dieselbe Logik wird auch auf Fließkommazahlen angewendet. Wir können eine Float-Variable deklarieren, ihr den Namen Sichtweite geben und ihr einen beliebigen Wert von 7,8 Metern geben. Wir können unsere Vergleichsoperatoren verwenden, um festzustellen, ob diese Zahl größer als kleiner oder gleich einem bestimmten Wert ist , oder wir können sie implizit in ihrer eigenen Bedingung verwenden wobei Null als falsch und alles andere als wahr angesehen wird Was ist mit Saiten? Lassen Sie uns die Dinge etwas ändern und eine Zeichenkettenvariable für das, was wir gehört haben, deklarieren eine Zeichenkettenvariable für das, was wir gehört haben und ihr den Wert Bumps in the Night geben Dann könnten wir das logischerweise als Wenn-Aussage verwenden als ob das, was ich gehört habe, keine leere Zeichenfolge wäre, dann können wir sagen, ich habe etwas gehört Ansonsten habe ich nichts gehört. Und genau wie bei den anderen Variablentypen können wir den Vergleich fallen lassen und die Variable selbst als Bedingung verwenden . Bei allen Variablen werden ihre Standardwerte als falsch betrachtet, und alles andere wird immer als wahr angesehen, wenn es als Bedingung verwendet wird. Wenn wir eine Variable ohne Typ deklarieren, nennen wir sie so, wie ich es mir ansehe, geben ihr aber keinen Wert, dann wissen wir bereits, dass ihr Standardwert Null sein wird. Auch ohne einen Typ oder Wert kann jede Variable als Mobbing-Bedingung verwendet werden Jede Variable, die leer ist, was bedeutet, dass ihr Wert Null ist, wird als falsch betrachtet Wenn wir diese Variable mit einem Objekt auffüllen würden, würde ihr Wert als Bedingung als wahr angesehen Wir haben derzeit keine anderen Objekte, mit denen wir spielen können, aber wir können uns immer selbst benutzen Lassen Sie uns also den Wert dessen, was ich mir ansehe, auf das Schlüsselwort self setzen. Und das führt dazu , dass man sehen kann. In der nächsten Lektion werden wir Schleifen verwenden , um Codezeilen mehrmals zu wiederholen. Wir sehen uns in der nächsten Lektion. 5. 0-4 While-Loops und Operatoren: Hallo Freunde. Heute lernen wir, wie man Codezeilen mit Schleifen mehrfach wiederholt , indem wir uns eine Frau vorstellen , die sich zum ersten Mal verliebt hat, eine Blume in der Hand hält Also lasst uns ein neues Skript schreiben und es Blume nennen. Überschreiben Sie dann die Basisknoten-Definition der Ready-Funktion. Unsere imaginäre Dame hält eine Blume mit einer Anzahl von Blütenblättern in der Hand, die wir in einer Variablen speichern und ihren Typ auf eine Ganzzahl einschränken werden. Dann gib ihr einen Wert mit einer beliebigen Zahl, sagen wir fünf. Wir werden auch eine weitere Variable namens He Loves Me als booleschen Wert deklarieren , von der wir glauben, dass sie ihren Standardwert falsch hat Wir können unser Drehbuch beginnen, indem wir eine Geschichte über die verliebte Dame ausdrucken , die ihre Blume hält Sie entfernt jedes Blütenblatt nacheinander von der Blume und sagt, entweder er liebt mich oder er liebt mich Zuerst müssen wir die Anzahl der Blütenblätter auf der Blüte um eins reduzieren die Anzahl der Blütenblätter auf der Blüte um eins reduzieren Wir beginnen also mit der Variablen Anzahl der Blütenblätter und verwenden dann den Zuweisungsoperator, verwenden dann den Zuweisungsoperator um der Variablen einen neuen Wert zuzuweisen. Der Wert, den wir ihr zuweisen wollen, ist die Zahl, die sie bereits hat, minus eins. Wir wollen dann den Wert der Booling-Variablen ändern. Er liebt es, wenn ich sein Gegenteil bin. Er liebt mich also, ist dem Nichts zugeordnet. Er liebt mich kehrt den Wert von falsch wahr um oder umgekehrt Als Nächstes können wir die Ergebnisse ausdrucken. Er liebt mich. Vielleicht möchten wir diesen Teil in Anführungszeichen setzen, aber wenn wir versuchen, ein Anführungszeichen in unsere Zeichenfolge zu setzen, markiert es stattdessen das Ende der Einige Sonderzeichen wie Anführungszeichen können innerhalb einer Zeichenfolge mithilfe eines umgekehrten Schrägstrichs erstellt werden Wenn wir ein umgekehrtes Anführungszeichen schreiben, steht dies jetzt für ein Anführungszeichen, nicht für das Ende der Zeichenfolge Und wir können nach der Erklärung der Damen noch eine nach der Erklärung der Damen Lassen Sie uns diese Zeile duplizieren und die Erklärung dahingehend ändern , dass wir sagen: Er liebt mich nicht. Ein anderes Beispiel für ein Sonderzeichen, das wir mit dem Backslash schreiben können , ist der Backslash Wir können die beiden obigen Zeilen auch kombinieren und sie mit dem Backslash N trennen, was eine neue Zeile darstellt. Sie werden also von einer einzigen Druckanweisung aus auf zwei Ausgabezeilen gedruckt Wir haben jetzt zwei Möglichkeiten , die wir basierend auf dem Wert unserer booleschen Variablen ausdrucken möchten basierend auf dem Wert unserer booleschen Variablen ausdrucken Es scheint also, dass wir diese in eine if-Anweisung packen sollten diese in eine if-Anweisung packen Wenn er mich liebt, dann drucke das aus. Wenn er mich nicht liebt, dann drucke das aus. Aber in Fällen, in denen Anweisungen von einer einzigen booleschen Variablen abhängig sind , um eine geringfügige Änderung vorzunehmen, gibt es eine gibt es eine Kehren wir also zum ursprünglichen Format zurück . Unsere Erklärung wird sein, dass er mich liebt, wenn er mich liebt, sonst liebt er mich nicht. Dies ist trotz der Verwendung derselben Schlüsselwörter nicht dasselbe wie eine if-Anweisung, sondern wird als ternäre Operation bezeichnet Da sie keinen neuen Codeblock mit Einrückung erstellt , wird sie tatsächlich effizienter ausgeführt und es wird empfohlen, sie in einfachen Fällen wie diesem zu verwenden Wir können die Größe der Variante sogar noch weiter reduzieren , indem wir sie nur so ändern, dass sie entweder ein Ausrufezeichen oder ein Leerzeichen ist, gefolgt von dem Wort nicht, dann das Das funktioniert für den Fall, dass er mich liebt, aber wenn wir den Wert standardmäßig auf true ändern, dann sehen wir nur im anderen Fall nichts Genau wie in der Mathematik gibt es eine bestimmte Reihenfolge von Operationen , in der unsere Skripte mehrere Operationen in derselben Zeile ausführen . Da sowohl die Zeichenfolge append auch der ternäre I Operatoren sind, muss einer vor dem anderen ausgeführt werden, und in diesem Fall ist es die Zeichenfolge Und genau wie in der Mathematik werden Klammern immer zuerst ausgeführt Wir können also jede Operation in Klammern setzen, um sicherzustellen, dass sie in der Reihenfolge der Operationen zuerst ausgeführt wird . Wenn wir unsere ternäre Anweisung in Klammern setzen, wird sie nun vor dem Anhängen der Zeichenfolge ausgeführt und liefert uns das erwartete Ergebnis Jetzt haben wir also unseren Codeblock, der wiederholt werden muss, solange die Blume noch Blütenblätter hat Mit dem Schlüsselwort WW können wir, ähnlich wie bei einer if-Anweisung, ähnlich wie bei einer if-Anweisung, einen Codeblock mit Einrückung wiederholen , solange die Bedingung wahr bleibt Die Bedingung in diesem Fall ist, dass die Anzahl der Blütenblätter auf der Blüte nicht Null ist Unabhängig von der Anzahl der Blütenblätter auf der Blüte wird sie jedes Mal um eins reduziert. Nach der Print-Anweisung kehrt der logische Ablauf dieses Skripts zum Anfang von WWLoop zurück , um den Zustand erneut zu überprüfen Wenn die Anzahl der Blütenblätter Null erreicht, ist die Bedingung nicht mehr erfüllt und die Schleife wird unterbrochen, sodass mit dem Rest des Skripts fortgefahren wird, falls vorhanden Lassen Sie uns also auf der Grundlage der Ergebnisse ein kurzes Fazit zu unserer Geschichte schreiben . Sie steht mit Tränen in den Augen auf. Aber basierend auf dem endgültigen Wert von He Loves Me ist sie entweder glücklich oder traurig, und wir werden den anderen letzten Satz ausdrucken. Wenn wir diese Szene abspielen, können wir unsere Geschichte im Ausgabefeld ausgedruckt sehen , und mit fünf Blütenblättern ist die Dame glücklich. Wenn wir die Anzahl der Blütenblätter auf sechs ändern, erhalten wir ein anderes Ergebnis, da die Schleife sechsmal statt fünfmal wiederholt. Aber was passiert, wenn wir die Anzahl der Blütenblätter auf der Blüte auf Null ändern ? Die Schleife läuft überhaupt nicht und die Liebe war von Anfang an zum Scheitern verurteilt Ich empfehle nicht, diesem Beispiel zu folgen, sondern einfach zu beobachten, was passiert, wenn wir der Blume eine negative Anzahl von Blütenblättern geben der Blume eine negative Anzahl von Blütenblättern Das ist zwar realistischerweise unmöglich, in unserem Code ist es sehr problematisch Da die Bedingung unserer Wandschleife niemals erfüllt werden kann, wird sie niemals kaputt gehen, und das Skript ist darin gefangen und wird nie fertig Dies ist eine Endlosschleife und sollte um jeden Preis vermieden werden. In diesem Fall können wir die Endlosschleife verhindern, indem wir unsere Bedingung so ändern unsere Bedingung so die Anzahl der Blütenblätter größer als Null ist, da eine negative Zahl die Schleife immer noch unterbricht. Als Abkürzung können wir einen anderen Operator verwenden , um die Anzahl der Blütenblätter zu reduzieren. Da wir den Namen unserer Variablen nicht zweimal schreiben müssen , können wir mit einem speziellen Zuweisungsoperator einfache mathematische Operationen an unserer Anzahl von Variablen ausführen unserer Anzahl von Variablen . In diesem Fall kann der Operator minus gleich diese Codezeile in die Anzahl der Blütenblätter minus eins ändern Anzahl der Blütenblätter minus eins Diese Abkürzungen existieren für alle grundlegenden Rechenoperationen plus Gleichem multiplizieren gleich oder dividieren gleich und können mit jeder Zahl oder Variablen als dem anderen Operanden verwendet werden alle grundlegenden Rechenoperationen plus Gleichem multiplizieren gleich oder dividieren gleich und können mit jeder Zahl oder Variablen als dem anderen Operanden verwendet werden. gibt es noch einen weiteren Operator, Grundrechenarten gibt es noch einen weiteren Operator, den Modulo-Operator, der durch das Prozentzeichen dargestellt wird Modulus führt eine Divisionsoperation durch, gibt aber nicht den Quotienten als Ergebnis zurück, wie es der Divisionsoperator Stattdessen gibt er den Rest der Division zurück. Das gesamte Drehbuch bestimmt, abgesehen von der Geschichte, die erzählt wird, eigentlich nur, ob es sich bei der Anzahl der Blütenblätter auf der Blüte um eine gerade oder ungerade Zahl handelt, aber das geschieht auf die ineffizienteste Art und Weise, jedes einzelne Blütenblatt heruntergezählt Lassen Sie uns also die gesamte Wandschleife auskommentieren und stattdessen Modulus verwenden , um den Prozess zu beschleunigen wissen, dass alle geraden Zahlen durch zwei teilbar sind, können wir die Anzahl der Blütenblätter als Modul zwei verwenden Das einzig mögliche Ergebnis als Rest dieser Division ist entweder Null, wenn die Anzahl der Blütenblätter gerade ist oder eins, wenn die Anzahl der Blütenblätter ungerade ist Unser Skript könnte dahingehend vereinfacht werden, dass die Dame glücklich ist, wenn die Anzahl der Blütenblätter, Modul zwei, gleich eins ist Ansonsten ist sie traurig. Da wir wissen, wie ganze Zahlen als Bedingungen interpretiert werden, müssen wir die Vergleichsoperation hier nicht einmal durchführen , sondern können sie einfach auf I, Anzahl der Blütenblätter , Modul zwei, verkürzen I, Anzahl der Blütenblätter , Modul Das Ergebnis der Moduloperation könnte direkt der booleschen Variablen zugewiesen werden, um dasselbe Ergebnis zu erhalten , ohne dass eine if-Anweisung erforderlich wäre, und die Null oder Eins wird automatisch in falsch oder wahr umgewandelt Wir könnten noch weiter gehen, indem wir die Variable entfernen und einfach die Modulus-Operation direkt in der Turny-Anweisung verwenden Modulus-Operation direkt in der in In der nächsten Lektion lernen wir Sammlungen verwandter Variablen kennen Sammlungen verwandter Variablen Wir sehen uns in der nächsten Lektion. 6. 0-5-Arrays und For-Loops: Hallo Freunde. Heute werden wir darüber nachdenken, wie wir große Mengen von Variablen organisieren können, insbesondere wenn sie verwandte Informationen enthalten. Ich habe bereits ein Skript namens Census erstellt und die Basisknoten-Definition der Ready-Funktion außer Kraft gesetzt Basisknoten-Definition der Ready-Funktion Für unser hypothetisches Szenario in dieser Lektion stellen wir uns einen Volkszähler vor, der aufzeichnen muss, wie viele Menschen in jedem Haus an einer einzigen Straße in seiner Stadt leben jedem Wir können eine einzige Variable deklarieren , die all diese Informationen wir Und der Typ dieser Variablen wird ein Array sein. Ein Array kann eine Liste von Variablen aller anderen Typen enthalten . In diesem Fall handelt es sich den gesuchten Variablen um Ganzzahlen, die die Anzahl der Personen angeben, die in jedem Haus leben Wir können den Inhaltstyp eines Arrays angeben , indem wir eckige Klammern hinter dem Typnamen array verwenden und den Typ des Inhalts in die eckigen Klammern setzen den Typ des Inhalts in die eckigen Klammern Jetzt kann dieses Array nur ganze Zahlen als Inhalt enthalten. Bevor wir auf den Inhalt eines Arrays zugreifen können, muss es eine Größe haben, die Anzahl der Variablen, die darin enthalten sind Im Gegensatz zu anderen Variablen sind Arrays komplexer und haben ihre eigenen Funktionen Wir können auf diese Funktionen zugreifen, indem dem Namen der Variablen einen Punkt und dann den Namen der Funktion folgen dann den Namen der Funktion In diesem Fall die Resize-Funktion, die die Anzahl der Adressen innerhalb dieses Arrays festlegt und die Anzahl der Häuser an der Main Street darstellt, von der wir sagen, dass sie sechs ist Unsere vorgestellte Stadt ist insofern etwas ungewöhnlich die Hausnummern an der Main Street bei Null beginnen Unser Volkszähler beginnt also am Haus an der Main Street Null und klopft an die Tür, um den Bewohner des Hauses zu fragen wie viele Menschen in dem Haus leben Wir können einen Wert in einem Array speichern, beginnend mit seinem Namen, dann mit eckigen Klammern die Adresse der spezifischen Ganzzahl markieren , in diesem Fall Adresse Null, und dann den Zuweisungsoperator verwenden Wir können dieser Adresse eine Ganzzahl zuweisen. Nehmen wir an, in der Hausnummer Null an der Main Street leben fünf Personen. Auf dem Weg zum nächsten Haus an Main Street, Adresse Nummer eins, beantwortet jemand das Klopfen an der Tür und teilt dem Volkszähler mit, dass in diesem Haus zwei Personen leben Am nächsten Haus, Adresse Nummer zwei, befindet sich das Haus im Bau und hat ein Verkaufsschild, was bedeutet, dass dieses Haus eindeutig unbewohnt ist, und unser Volkszähler registriert die Anzahl der Einwohner mit Null An der Hauptstraße Nummer drei niemand die Tür, obwohl in der Einfahrt ein Auto steht und es Anzeichen von Besiedlung Was sollte unserer Meinung nach der Volkszähler als Zahl der Wir könnten denken, dass es Null sein könnte. Aber wie würden wir zwischen einer unbekannten Anzahl von Bewohnern und einem unbewohnten Haus unterscheiden einer unbekannten Anzahl von Bewohnern und einem unbewohnten Wenn wir bedenken, dass die Zahl der Bewohner eines Hauses niemals als negative Zahl betrachtet werden sollte, könnten wir die Zahl negativ eins verwenden, um zu bedeuten, dass die Anzahl der Bewohner des Hauses ein unbekannter Wert ist Und an der Main Street Nummer vier gibt es wieder keine Antwort an der Tür Aber das Haus scheint auch vernachlässigt zu sein, und wahrscheinlich hat dort seit geraumer Zeit niemand mehr gelebt. Wir könnten annehmen, dass die Anzahl der Bewohner Null ist vielleicht denselben negativen Eins-Wert für eine unbekannte Anzahl von Bewohnern verwenden Eins-Wert für eine unbekannte Anzahl oder negativere Wertcodes für verschiedene Situationen erstellen, wie z. B. negative Zwei zu verwenden , um wahrscheinlich unbewohnt, aber nicht bestätigt zu bedeuten Die Adresse Nummer fünf an der Main Street hat nicht einmal ein Haus, aber es ist nur ein Also auch hier könnte dies mit einer Null oder einem anderen negativen Wert dargestellt werden , um eine Art von Besprechung zu kodieren Lassen Sie uns die Ergebnisse der Volkszählung ausdrucken und sehen, wie sie aussehen Wir können uns unser Array als kommagetrennte Liste von Zahlen vorstellen , die in eckige Klammern gekapselt Dies stellt die Anzahl der Menschen , die in jedem Haus an der Main Street leben, anständig dar Anzahl der Menschen , die in jedem Haus an der Main Street leben Aber was wäre, wenn wir diese Daten verwenden wollten , um die Gesamtzahl der Bewohner aller Häuser an der Main Street oder im Durchschnitt Wenn wir die Summe all dieser Zahlen berechnen würden, die negative Darstellung der unbekannten Zahlen die Ergebnisse verfälschen würde die negative Darstellung der unbekannten Zahlen die Ergebnisse verfälschen Einer der größten Vorteile der Verwendung von Arrays zum Speichern verwandter Informationen auf diese Weise besteht darin, wie einfach es ist, sie in einer Schleife zu durchsuchen Mit dem Schlüsselwort vier schreiben wir als Nächstes den Namen einer neuen Variablen, eine, die jedes einzelne Element innerhalb des Arrays repräsentiert , gefolgt vom Schlüsselwort in dann dem Namen des Arrays Handelt es sich bei Anweisungen wie bei Funktionen um WA-Schleifen, folgt darauf ein Doppelpunkt und ein eingezogener Codeblock , der wiederholt wird Diese Codezeilen werden für jedes unserer sechs Häuser an der Main Street einmal wiederholt , und wir können dem variablen Haus einen Namen geben, da es für den Zugriff auf jedes einzelne Haus innerhalb der Schleife verwendet wird jedes einzelne Haus innerhalb der Schleife Nehmen wir an, wir wollen zunächst die durchschnittliche Anzahl der Bewohner ermitteln die durchschnittliche Anzahl der Bewohner , die in einem bewohnten Haus leben Das würde bedeuten, alle positiven Zahlen zu addieren und dann durch die Anzahl der bewohnten Häuser zu dividieren Wir benötigen also drei neue Variablen, eine für die Gesamtzahl der Bewohner, weitere für die Anzahl der bewohnten Häuser, beide als ganze Zahlen und eine Fließkommazahl für den Durchschnitt Für jedes Haus in der Main Street können wir überprüfen, ob das Haus bewohnt ist, ob die Zahl, die im Array an dieser Adresse gespeichert ist, jetzt in der Hausvariablen gespeichert ist, größer als Null ist Wenn dies zutrifft, kann die Gesamtzahl der Bewohner in bewohnten Häusern von Haus zu Haus erhöht werden, und die Anzahl der bewohnten Häuser kann um eins erhöht werden Nachdem alle sechs Häuser an der Main Street überprüft wurden, wird die Schleife unterbrochen und wir haben unsere beiden ganzen Zahlen. Wir können also den Durchschnitt berechnen, indem wir die Gesamtzahl der Bewohner durch die Anzahl der bewohnten Häuser teilen die Gesamtzahl der Bewohner durch die Anzahl der bewohnten Häuser Drucken Sie dann die Ergebnisse aus. Es gibt mehr bewohnte Häuser, plus bewohnte Häuser an der Main Street, mit einem Durchschnitt von mehr Durchschnittsbewohnern plus Bewohnern Aber wenn wir diesen Code ausführen, wird der Durchschnitt als Ganzzahl dargestellt, drei, was, wie wir wissen, nicht korrekt ist, da es in zwei bewohnten Häusern insgesamt sieben Einwohner gibt , sollte der Durchschnitt 3,5 Dies geschah, weil wir eine Divisionsoperation mit zwei ganzen Zahlen durchgeführt haben , weil wir eine Divisionsoperation mit zwei ganzen Zahlen und das Ergebnis der Operation ebenfalls eine Ganzzahl sein wird, obwohl wir sie einer Fließkommazahlvariablen zuweisen einer Fließkommazahlvariablen Godot warnt auch davor, Ganzzahlen in Divisionsoperationen zu verwenden Um dieses Problem zu lösen, können wir unsere Integer-Variablen in ihren Deklarationen in Fließkommazahlen ändern unsere Integer-Variablen , oder wir können ihren Typ lokal ändern , bevor wir die Division durchführen Ähnlich wie wir ganze Zahlen vor dem Anhängen in Zeichenketten umgewandelt haben, können wir eine Ganzzahl in eine Fließkommazahl umwandeln, bevor wir eine Division durchführen Das Ergebnis der Division wird ebenfalls in eine Fließkommazahl umgewandelt. Das Ändern des Typs einer Variablen auf diese Weise wird als Casting bezeichnet. Wir wandeln eine Ganzzahl in eine Gleitkommazahl um. Jetzt können wir die Ergebnisse sehen, die wir mit einem Durchschnitt von 3,5 Bewohnern pro bewohntem Haus erwartet hatten von 3,5 Bewohnern pro bewohntem Haus Ein Vorteil von GD Script, da es sich um eine lose typisierte Sprache handelt, besteht darin, dass wir unserer Variablen nicht spezifizieren müssen, einschließlich der Typen, die in einem Array enthalten sind Wenn wir zulassen, dass unser Array jede Art von Variablen enthält, können wir ändern, wie unser Volkszählungsmitarbeiter Nehmen wir an, dass die Adresse Null bei fünf Bewohnern gleich bleibt Adresse eins enthielt aber auch die Namen der beiden Einwohner, die dort leben Anstatt die Bewohner als Nummer zwei aufzuzeichnen, könnten wir ihre Namen in einer Zeichenfolge aufzeichnen Die Adresse Nummer eins an der Main Street wird also von Jordan und Ashley Smith besetzt Haus Nummer zwei war unbewohnt, was wir als Null darstellen konnten Wir könnten aber auch erwägen es stattdessen als booleschen Wert aufzuzeichnen und ihm den Wert False zu geben, was bedeutet, dass sich das Haus im Bau befindet und möglicherweise keine Bewohner haben kann In Nummer drei war niemand zu Hause, aber es leben definitiv Menschen dort Wir wissen einfach nicht, wie viele. Wir könnten diesen Wert auch als booleschen Wert speichern und ihm den Wert true geben Bei Nummer vier scheint es wirklich so, als ob dort niemand wohnt. Vielleicht möchten wir es als null Insassen kennzeichnen. Bei Adresse Nummer fünf könnten wir, da es dort nicht einmal ein Haus gibt, da es dort nicht einmal ein Haus gibt, in Betracht ziehen, Null als Wert zu verwenden , da Null das Fehlen eines Werts bedeutet Wir können das Schlüsselwort Null verwenden, um diesen Wert dem Array an Adresse fünf zuzuweisen. Jetzt sieht unser gedrucktes Array ganz anders enthält Variablen aller Typen statt nur Ganzzahlen Und wir können mehr Informationen daraus erkennen. Arrays können sogar andere Arrays als Inhalt enthalten. Lassen Sie uns also unsere Namensliste von einer einzelnen Zeichenfolge in ein Array von Zeichenketten ändern einer einzelnen Zeichenfolge in ein Array von Wir können dieses Array gleichzeitig mit eckigen Klammern erstellen und es dann mit einer durch Kommas getrennten Liste von Zeichenketten als Inhalt füllen einer durch Kommas getrennten Liste von Zeichenketten als Inhalt Wenn wir also wissen wollten, wie viele Menschen an der Adresse eins an der Main Street leben, könnten wir das als Mainstreet one dot SIE ausdrucken In der nächsten Lektion werden wir mehr darüber erfahren, wie Arrays verwendet werden können, um dynamischere Datensammlungen zu erstellen Wir sehen uns in der nächsten Lektion. 7. 0–6 Stapel und Funktionen: Hallo Freunde. Heute werden wir auf unterschiedliche Weise weiter mit Arrays arbeiten unterschiedliche Weise weiter mit Arrays indem wir ein Spiel von Old Made einrichten Ich habe bereits ein Skript namens Old Made erstellt und die Definition der Basisknoten der Ready-Funktion außer Definition der Basisknoten der Ready-Funktion Um Old Made spielen zu können, benötigen wir ein Kartenspiel, das eine Sammlung von Variablen ist , die wir in einem Array speichern können Da sich das Spiel Old Made nicht wirklich um die Farben der Karten kümmert, können wir diese Information ignorieren und jedes Element in der Reihe muss nur die Kartenrangfolge von Ass bis König als Ganzzahl enthalten . Um unser Deck zu generieren, können wir einen Vier-Loop-Modus verwenden. Aber anstatt die Vierer-Schleife zu verwenden , um durch ein Array zu iterieren, können wir sie einfach verwenden, um unsere Kartenränge abzuzählen Beginnend mit vier können wir eine Variable deklarieren, die den Rang einer Karte repräsentiert, gefolgt vom Schlüsselwort in, und dann eine Zahl angeben Wenn wir King als Zahl betrachten würden, wäre das der 13. Rang. Lassen Sie uns vorerst einfach den Rang ausdrucken , damit wir sehen können, was passiert. Die Vierer-Schleife beginnt mit einem Rangwert bei Null und zählt bis zu 12, wobei diese Schleife und die Druckanweisung 13 Mal wiederholt werden. Aus Gründen der Vernunft könnte es eine gute Idee sein, könnte es eine gute Idee sein, Karte Nummer zwei durch Rang zwei darzustellen, sodass Ass eins und König 13 wäre ist zwar sehr hilfreich, eine Vierer-Schleife bei Null zu starten durch Arrays zu iterieren, da ihre erste Indexnummer Null ist, in diesem Fall ist es nicht so hilfreich Wir können die Zählung einer Viererschleife ändern, indem die 13 durch den Funktionsaufruf range ersetzen Funktionsaufrufen folgen Klammern, die Argumente enthalten Die Argumente für diese Funktion sind die Unter- und Obergrenzen des Bereichs Die Untergrenze wird in den Bereich aufgenommen, die Obergrenze jedoch nicht. Bereich 114 wird alle Zahlen 1—13 enthalten, wir können sehen, dass das in der Ausgabe ausgedruckt ist Eine andere Möglichkeit, Informationen zu einem Array hinzuzufügen , anstatt die eckigen Klammern und die Indexnummer zu verwenden eckigen Klammern und die , besteht darin, eine Funktion namens append zu verwenden Diese Anfügefunktion akzeptiert ein Argument des Werts , der dem Array hinzugefügt wird Dadurch wird der hinzugefügte Wert an das Ende des Arrays gesetzt, wo auch immer das sein mag Und da es in einem Kartenspiel vier von jedem Rang gibt, eine für jede Farbe, sollten wir diese Codezeile für jeden Rang viermal wiederholen. Wir können das mit weiteren vier Schleifen machen Diesmal beginnen wir bei Null und zählen bis, aber ohne vier. das Deck ausdrucken, können wir sehen, dass unser Array vier von jeder Zahl 1—13 hat , also insgesamt 52 Karten Aber um altmodisch zu spielen, wollen wir drei der Damen entfernen, oder in diesem Fall 12. also in unserer Vierer-Schleife, die sich durch die Kartenfarben iteriert, Lassen Sie uns also in unserer Vierer-Schleife, die sich durch die Kartenfarben iteriert, überprüfen, ob der Rang 12 ist Und in diesem speziellen Fall wollen wir nur das Hinzufügen von 112 zulassen, wobei wir das Schlüsselwort break verwenden, das Schlüsselwort break verwenden um sofort aus dieser Schleife auszubrechen Break beendet nur die Schleife mit den meisten Einrückungen, in der es sich gerade befindet Wir beenden also den Suit für Loop, aber nicht den Rang für Loop Dadurch wird der Rang auf 13 erhöht und dem Deck werden vier Dreizehner hinzugefügt Und wenn wir es ausprobieren, können wir sehen, dass es nur 112 gibt. Das Erste, was in unserem Spiel passiert, ist das Mischen des Kartendecks, was im GD-Skript eine einfache eingebaute Funktion von Rayse ist einfache eingebaute Funktion von Rayse Wir müssen diese Funktion nur aufrufen und schon können wir sehen, dass die Karten in unserem Deck gemischt werden Außerdem benötigen wir eine weitere Variable, eine Reihe von Kartenhänden, die unsere Spieler repräsentieren Jede Hand innerhalb des Blatt-Arrays muss mehrere Karten enthalten, es handelt sich also auch um Arrays, die wir initialisieren müssen, bevor wir sie verwenden können also von Null bis vier zählen, können wir eine neue Hand an das Array anhängen Unsere Hand beginnt als leeres Array, das durch eckige Klammern dargestellt wird Wenn wir uns unser Kartendeck vorstellen, wobei die Vorderseite der Karten die Seite mit Rang und Farbe ist, die Rückseite der Karte leer ist, dann könnten wir uns auch vorstellen, dass das Deck verdeckt ist. Die Vorderseite der Reihe ist die Unterseite des Decks, und die Rückseite der Reihe ist die Oberseite des Decks. Das Austeilen der Karten kann durch iteratives Durchlaufen unseres Decks erfolgen, aber wir müssen nicht wirklich auf bestimmte Karten verweisen, da es eigentlich egal ist, um auf bestimmte Karten verweisen, da es eigentlich egal ist, welche es sich handelt, nur dass die Karte vom oberen Rand des Decks genommen und einem Spieler ausgehändigt Um also eine Karte von der Oberseite des Decks zu entfernen, können wir eine andere Funktion aufrufen Dieser heißt Pop Back. Es gibt nicht nur das letzte Element im Array zurück, sondern entfernt es auch aus dem Array. Wir wollen diese Karte dann der Hand des Spielers hinzufügen und beginnen mit Spieler eins, vorausgesetzt, Spieler Null ist der Dealer. So wie wir Popback verwenden können, um eine Karte zu entfernen, können wir auch eine Karte mit Pushback hinzufügen Die Karte, die wir auf den Handrücken des Spielers legen, ist dieselbe Karte, die wir von der Rückseite des Wir können diesen Funktionsaufruf einfach in die Klammern des Funktionsaufrufs setzen und seinen Rückgabewert als Argument für die Push-Funktion verwenden seinen Rückgabewert als Argument für die Push-Funktion Die Verwendung von Pushback entspricht exakt der Verwendung von append. Die Append-Funktion ist ein Erbe von Zeichenketten, da sie normalerweise als Zeichenarrays gespeichert werden, während Push und Pop aus der Verwendung von Stacks oder Cues stammen , wie wir es Um unsere nächste Karte austeilen zu können, müssen wir das Blatt, an das ausgeteilt wird, erhöhen Speichern wir das in einer Variablen als Ganzzahl und geben ihr den Anfangswert eins die Zahl in unserem Array-Index durch unsere Variable ersetzen, müssen wir sie um eins erhöhen , nachdem jede Karte ausgeteilt Aber das wird natürlich nur bis 51 zählen, und es gibt nicht so viele Hände Also müssen wir diese Zahl jedes Mal auf Null zurücksetzen , wenn sie vier erreicht. Dies kann mit unserem Trustee-Modulo-Operator erreicht werden , bei dem die Zuweisung von Hand auf Modulus gleich vier Wenn wir jedoch möchten, dass unser Code mit einer beliebigen Anzahl von Spielern funktioniert, wäre es besser, vier durch die Größe unseres Hands-Arrays zu ersetzen vier durch die Größe unseres Hands-Arrays Um zu sehen, wo wir uns bis jetzt befinden, drucken wir unsere Hände aus, indem wir durch das Hands-Array iterieren und jedes einzelne ausdrucken Drucken Sie dann das Deck aus. Wir können unsere vier Arrays sehen und das Deck ist leer. Wir können sogar die Anzahl der Spieler ändern und die Karten werden an die richtige Anzahl von Händen verteilt. Unsere Bereitschaftsfunktion wird immer umfangreicher. Wir können unseren Code besser organisieren , indem wir unsere eigenen Funktionen deklarieren Wir teilen unsere Logik in kleine Teile auf und haben einen Abschnitt, der unser erstes Kartendeck erstellt, einen, der die Hände des Spielers erstellt, und einen, der die Karten die Hände des Spielers erstellt, und einen, der die austeilt. Mit dem Schlüsselwort Funk können wir jedem dieser Codeblöcke einen Namen geben , gefolgt von Klammern und einem Deck initialisiert, Hände initialisiert und Deal. Dann kann die Ready-Funktion jede dieser Funktionen nacheinander aufrufen jede dieser Funktionen nacheinander Unsere Funktionen können auch Argumente akzeptieren, z. B. die Anzahl der Hände, die wir haben möchten. Übergeben wir vier als Argument. Um unsere Funktion so zu schreiben, dass sie das Argument akzeptiert, müssen wir einen passenden Parameter in die Klammern der Funktionsdeklaration einfügen in die Klammern der Funktionsdeklaration Ähnlich wie das Deklarieren einer Variablen hat sie einen Namen und optional auch Da wir dies verwenden, um die Größe eines Arrays zu ändern, ist es eine gute Idee, es auf eine Ganzzahl zu beschränken Wir können dann den Parameter innerhalb der Funktion genauso verwenden der Funktion genauso , wie wir jede andere Variable verwenden würden Das Letzte, was wir tun müssen, um mit dem Spielen zu beginnen, wäre , alle Paare aus der Hand jedes Spielers zu entfernen. wir also jede Hand in der Reihe der Hände durchgehen, können wir eine weitere Funktion aufrufen um die Paare aus dieser Hand zu entfernen, indem wir die Hand als Argument übergeben dieser Funktion eine Definition geben, können wir dann eine Hand als Array-Parameter akzeptieren Wir müssen mit einer Variablen durch die Hand iterieren. Nennen wir es Karte eins. Aber wir können aufhören, bevor wir zur letzten Karte kommen. Also gehen wir nur von Null auf die Größe der Hand minus eins. Wir können dann auf die gleiche Weise ein zweites Mal wiederholen , aber dieses Mal beginnen wir mit der Karte nach der anderen und gehen bis zum Ende der Handgröße Innerhalb dieser 24 Schleifen Karte eins und Karte zwei nun jedes einzelne Kartenpaar enthalten Karte eins und Karte zwei nun jedes einzelne Kartenpaar in unserer Hand, sodass wir die beiden Karten leicht vergleichen können , um zu sehen, ob sie zusammenpassen Wenn ja, können sie aus der Hand genommen werden , beginnend mit Karte zwei. Wenn wir zuerst Karte eins entfernen würden, der Index von Karte würde sich dadurch der Index von Karte zwei tatsächlich ändern, da sich alle Karten um eine Position bewegen würden. Wenn wir eine Übereinstimmung finden, wollen wir diese Schleife oder eine der beiden Schleifen nicht fortsetzen, sondern wir wollen den gesamten Vorgang erneut starten. Ein einfacher Weg, dies zu tun, wäre eine while-Schleife, eine boolesche Variable , die angibt, ob wir ein Paar mit dem Standardwert true gefunden haben oder nicht ein Paar mit dem Standardwert true gefunden haben Wenn ein Paar gefunden wurde, können wir es sofort auf false setzen Dies ermöglicht es uns, in die Schleife einzutreten, aber nicht hier zu bleiben, es sei denn, es wurde ein Paar gefunden. In anderen Sprachen könntest du das stattdessen mit einer Do-Wile-Schleife machen Wenn wir ein Paar finden, können wir die Variable auf true setzen dann auch beide Schleifen durchbrechen und die While-Schleife zurücksetzen Wenn beide vier Schleifen abgeschlossen sind, ohne dass ein passendes Paar gefunden wurde, ist das gefundene Paar falsch und die While-Schleife wird unterbrochen Wir können unsere Simulation wiederholt ausführen und sehen, dass keine Hand unserer Spieler jemals passende Paare enthält und die Spieler bereit sind, ihr Spiel Old Maid zu spielen In der nächsten Lektion werden wir eine andere Form der Flusskontrolle verwenden Wir sehen uns in der nächsten Lektion. 8. 0-7 Match und Return: Hallo Freunde. Heute werden wir eine andere Form der Flusskontrolle , um komplexe Bedingungen zu vereinfachen. Ich habe bereits ein Skript mit dem Namen months erstellt und die Basisknoten-Definition der Ready-Funktion Beginnen wir damit, eine Variable für den aktuellen Monat zu deklarieren und sie auf Januar und eine zweite Variable für die Anzahl der Tage im Monat festzulegen Januar und eine zweite Variable , die standardmäßig auf Null gesetzt wird Wir können einen einfachen Satz ausdrucken, der besagt, dass die Anzahl der Tage im Januar 31 ist Aber zuerst wollen wir unsere Variable mit der Anzahl der Tage füllen , die auf dem Wert des Monats basiert Schreiben wir also eine Funktion , die genau das kann. Weisen Sie die Anzahl der Tage im Monat zu, die von einer Funktion zurückgegeben werden sollen, die wir schreiben werden und die den Monat als Argument akzeptiert. Um dieser Funktion eine Definition zu geben den Monat als Parameter vom Typ Zeichenfolge zu akzeptieren, benötigt sie auch eine weitere Information , einen Rückgabetyp. Der von einer Funktion zurückgegebene Wertetyp wird hinter den Klammern mit einem Bindestrich und einem größeren Lansinn in einem Pfeil definiert den Klammern mit einem Bindestrich und einem , gefolgt vom In diesem Fall handelt es sich um eine Ganzzahl, die die Anzahl der Tage im Monat darstellt Wenn wir keinen Rückgabetyp angeben , der Rückgabetyp für jede Funktion ist der Rückgabetyp für jede Funktion, die wir schreiben, standardmäßig Null. Innerhalb unserer Funktion müssen wir eine Ganzzahl zurückgeben, was bedeutet, dass wir eine Ganzzahl über ihr deklarieren sollten , und sie muss die Anzahl der Tage im Monat enthalten. Dann geben wir am Ende der Funktion den Wert zurück, der in dieser Variablen enthalten ist. Zwischen diesen beiden Zeilen müssen wir unsere Variable mit der richtigen Anzahl von Tagen basierend auf dem Monat auffüllen der richtigen Anzahl von Tagen basierend auf dem Monat Wenn der Monat Januar ist, dann ist die Anzahl der Tage 31. Wir haben bereits erfahren , dass wir mit dem Schlüsselwort se eine Alternative anbieten können , aber das bietet uns nur zwei der 12 Optionen, die wir benötigen. Wir können ein anderes Schlüsselwort verwenden, if, kurz für se if, um eine weitere Bedingung anzugeben , die überprüft wird , ob die ursprüngliche Bedingung falsch war. Wenn der Monat also Februar ist, dann ist die Anzahl der Tage 28. Und wir können das so oft wiederholen, wie wir müssen, für jede Möglichkeit ein Argument liefern. Viele dieser Optionen führen jedoch zum gleichen Ergebnis, entweder 30 Tage oder 31 Tage. Wir könnten die Effizienz dieser WF-Anweisung erheblich verbessern , indem wir das häufigste Ergebnis, 31 Tage als Standardfall, kombinieren 31 Tage als und ersetzen am Ende alle durch ein einziges anderes Schlüsselwort Wenn der Monat also nicht Februar oder irgendein Monat mit 30 Tagen ist , dann muss die Anzahl der Tage 31 sein Alle Fälle, die zu 30 Tagen führen , können auch mit dem Operator or zu einer einzigen Aussage zusammengefasst werden . Wenn der Monat September ist oder wenn der Monat April ist oder wenn der Monat Juni ist, oder wenn der Monat November ist, dann ist die Anzahl der Tage 30. Aber die Aussage ist bei mehr Fällen ziemlich lang, sie könnte vom Bildschirm verschwinden. Für einfache, fallweise Anweisungen wie diese gibt es ein klareres und einfacher zu verwendendes Schlüsselwort als die I-Anweisung namens match. Match folgt der Name einer Variablen, ein Doppelpunkt und dann ein eingezogener Codeblock Innerhalb eines Match-Blocks können wir eine beliebige Anzahl von Sonderfällen für den Wert der Variablen angeben Sonderfällen für den Wert der Variablen Fangen wir mit Februar an. die Groß- und Kleinschreibung folgen außerdem ein Doppelpunkt und ein weiterer eingezogener Codeblock Dieser Code wird nur ausgeführt wenn der Wert des Monats Februar ist Wir können Fälle in einer durch Kommas getrennten Liste zusammenfassen. So lässt sich die Bedingung, dass wir nur noch eine Liste von vier Monaten angeben, zusammenfassen Wenn der Wert des Monats September, April, Juni oder November ist, dann wird die Anzahl der Tage auf 30 gesetzt, und unser Block kann durch einen Platzhalter ersetzt werden , der durch einen Unterstrich dargestellt wird, wodurch die Anzahl der Tage auf 31 gesetzt wird, falls der Wert des Monats etwas anderes ist, das oben nicht angegeben wurde Dies entspricht der Verwendung der Standardeinstellung in anderen Sprachen. Jeder dieser Codeblöcke wird als Branches bezeichnet. Und im GD-Skript führt eine Match-Anweisung immer nur den obersten Zweig , dessen Bedingung erfüllt wurde In anderen Sprachen ähnelt dies einer Switch-Anweisung, unterscheidet sich jedoch darin, dass Switch-Anweisungen mehr als einen Zweig ausführen können mehr als einen Zweig ausführen wenn mehrere Bedingungen erfüllt sind Aufgrund dieser Einschränkung ist es nicht erforderlich, Unterbrechungen in Match-Verzweigungen einzufügen. Wenn wir die Anzahl der Tage in jedem Monat ausdrucken wollten , würden wir wahrscheinlich eine Schleife verwenden wollen, aber wir können eine Zeichenfolge wie Januar nicht einfach zählen oder inkrementieren , sodass sie irgendwie Februar wird Daher ist es im Code üblich , Dinge, die in einer sequentiellen Reihenfolge existieren, in eine nummerierte Liste aufzunehmen, die als , Dinge, die in einer sequentiellen Reihenfolge existieren, in eine nummerierte Liste aufzunehmen, Aufzählung bezeichnet wird Eine Aufzählung im GD-Skript ist nur eine Gruppe verwandter Konstanten Wir könnten eine Konstante für Januar mit einem Wert von eins haben, andere für Februar mit einem Wert von zwei usw. Aber mit dem Schlüsselwort Enum können wir die Gruppe von Konstanten benennen, sie Monate gefolgt von geschweiften Innerhalb der geschweiften Klammern können wir die Konstanten gruppieren und ihnen wird jeweils automatisch eine Zahl zugewiesen , die auf ihrer Position in dieser Liste basiert Alles, was in den geschweiften Klammern enthalten , muss nicht in einer Zeile bleiben und kann in ein beliebiges Format aufgeteilt werden , um es lesbarer zu machen Einrückungen spielen hier keine Rolle, aber wenn etwas in geschweiften Klammern geschrieben wird, ziehen die meisten Programmierer normalerweise den Inhalt ein , sodass es Ich bevorzuge zwar, dass die geschweiften Klammern vertikal angeordnet sind, aber viele Programmierer ziehen es vor, die öffnende Klammer so in die Deklarationszeile zu setzen öffnende Klammer so in die Deklarationszeile Genau wie bei Constance werden Aufzählungseinträge üblicherweise Da wir nun eine Aufzählung haben, kann der Monat auf den Typ dieser Aufzählung beschränkt werden Typ dieser Aufzählung beschränkt Wir können ihm auch einen Wert aus der Aufzählung zuweisen, beginnend mit seinem Namen, gefolgt von einem Punkt dann dem Eintrag in der Liste Der Monat, der an die Zeichenkettenausgabe angehängt wird, ist selbst keine Zeichenfolge mehr und muss in eine Zeichenfolge umgewandelt werden , bevor er angehängt werden kann Das Argument, das an die Anzahl der Tage übergeben wird , ist keine Zeichenfolge mehr , sondern ein Monat, und wir können unsere Funktion so ändern ein Monat als Parameter akzeptiert Da Monat jetzt ein Monat und keine Zeichenfolge ist, müssen wir unsere Bedingungen so ändern, dass sie übereinstimmen indem wir den Namen der Aufzählung gefolgt von einem Punkt dann die Einträge in der Liste Aber wenn wir die Ergebnisse ausdrucken, sehen wir, dass unser Monat nicht als Januar, sondern als Zahl Null geschrieben wird Der Typ unserer Variablen ist zwar ein Monat, also eine Aufzählung, der tatsächliche Wert wird als Ganzzahl behandelt, seine Position innerhalb der Aufzählung Da Januar der erste Eintrag ist, ist sein Wert als Ganzzahl Null Februar wäre eins und so weiter. Auf diese Weise können wir den Wert des Monats mit einfacher Arithmetik ändern , sodass aus Januar plus eins Wenn wir diesen Code in eine Schleife einbinden, die sich 12 Mal wiederholt, können wir problemlos durch alle 12 Monate iterieren Aber wie wäre es, den Namen des Monats als Zeichenfolge zu schreiben? Wir könnten das auf verschiedene Arten tun. Unser Aufzählungstyp hat eine Eigenschaft namens keys, bei der es sich um alle unsere Einträge als ein Array von Zeichenketten Wenn wir dieses Array mit unserer Integer-Variablen indizieren , erhalten wir den Eintragsnamen als Zeichenfolge , die dieser Zahl entspricht Aber wenn wir uns an die Namenskonvention für Großbuchstaben halten, möchten wir den Namen vielleicht nicht auf diese Weise ausdrucken. Wir könnten stattdessen all unsere Aufzählungsschlüssel in Pascal-Groß- und Kleinschreibung umbenennen , oder wir könnten eine Konstante deklarieren , die das Array von Zeichenketten enthält all unsere Monatsnamen in einem besser lesbaren Format enthält. Verwenden Sie dann den Monat als Index für dieses Array. Eine andere Sache, die wir mit Aufzählungen tun können, ist die Werte der Einträge manuell mit dem Zuweisungsoperator festzulegen Einträge manuell mit dem Zuweisungsoperator Nehmen wir an, wir möchten , dass der Januar eins statt Null ist. Bei den übrigen Einträgen werden die Werte automatisch aktualisiert, sodass der Wert von eins erhöht wird, sodass der Februar jetzt zwei ist Dies entspricht jedoch nicht mehr den konstanten Array-Indizes. Wenn wir dies also verwenden wollten , um den Namen der Monate zu schreiben, müssten wir entweder einen leeren Eintrag für den Index Null hinzufügen oder einen vom Monat subtrahieren, der Indexierung des Arrays verwendet wird In der nächsten Lektion erfahren wir mehr darüber, wie die Engine unsere Skripte verwendet und ausführt Wir sehen uns in der nächsten Lektion. 9. 0-8 Szenenbaum und Vererbung: Hallo Freunde. Heute erfahren wir wie die Engine den Szenenbaum verwendet, um unsere Skripte auszuführen. Ich habe noch kein Skript an den Stammknoten des Szenenbaums angehängt , aber wir beginnen diese Lektion stattdessen damit, weitere Knoten hinzuzufügen. rechten Maustaste auf den Stammknoten wählen Sie dann „Untergeordneten Knoten hinzufügen“ aus, immer noch ein normaler Knoten Wir können ihn in Präsident umbenennen und ist. Wir können ihn in Präsident umbenennen und so tun, als ob unser Szenenbaum die Struktur eines Unternehmens darstellt Der Präsident-Knoten ist eingerückt , weil er ein untergeordnetes Element des Stammknotens der Szene ist Wenn ein Knoten ausgewählt ist, können wir auch die Tastenkombination Strg A oder Befehl A verwenden , um einen weiteren untergeordneten Knoten hinzuzufügen Nennen wir diesen einen Operations Manager, und er hat eine andere Ebene, weil er ein Kind des Präsidenten ist Lassen Sie uns nun ein neues Skript an den President-Knoten anhängen und es Employee nennen Wenn wir die Basisknoten-Definition der Ready-Funktion außer Kraft setzen, können wir einfach den Namen dieses Knotens ausgeben und append ist Dieses Skript kann an mehr als einen Knoten angehängt werden. Lassen Sie uns also dasselbe Skript an den Operations Manager-Knoten anhängen , indem wir es von der Registerkarte Dateisystem in den Szenenbaum ziehen der Registerkarte Dateisystem in den Szenenbaum Führen Sie dann die Szene aus , um zu sehen, was passiert. Wir können sehen, dass der Betriebsleiter bereit ist, dann ist der Präsident bereit. Beide Knoten, an die das Skript angehängt ist, führen das Skript aus, und da sie unterschiedliche Namen haben, war die Ausgabe unterschiedlich. Wir können auch sehen, dass der Betriebsleiter bereit war, bevor der Präsident bereit war. Um zu verstehen, warum wir mehr Mitarbeiter einstellen müssen. Der Betriebsleiter wird eine Reihe von Betreibern beaufsichtigen Ich füge dem Operations Manager einen weiteren untergeordneten Knoten hinzu und nenne ihn Operator One Hängen Sie dann das Mitarbeiterskript an. Wir können mit der rechten Maustaste auf einen beliebigen Knoten außer dem Stammknoten klicken und Duplizieren auswählen , um eine Kopie davon zu erstellen. Der Name der Duplikate wird automatisch um eine steigende Zahl erweitert, sodass wir Operator zwei, drei und vier usw. verwenden können Da an den Knoten, den wir dupliziert haben, ein Skript angehängt war, ist an die erstellten Kopien auch dasselbe Da die Operatoren dieselbe Einrückungsebene haben und alle dem Operations Manager untergeordnet sind, werden sie als Geschwister bezeichnet, und Geschwister dürfen nicht denselben Namen haben Unser Unternehmen sollte mehr als eine Abteilung haben. Lassen Sie uns also die gesamte Betriebsabteilung duplizieren, indem wir den Betriebsleiter duplizieren Alle untergeordneten Knoten sind ebenfalls dupliziert. Da es sich bei den Operatoren nicht um direkte Geschwister handelt, dürfen sie ihre ursprünglichen Namen behalten Benennen wir den Manager in Marketingmanager um, und dann werden nur noch zwei Marketingexperten in seinem Team arbeiten Übergeordnete Knoten können auch ausgeblendet werden, um ihre untergeordneten Knoten auszublenden, oder erweitert werden, um sie anzuzeigen. Allen Mitarbeitern dieses Unternehmens ist dasselbe Mitarbeiterskript beigefügt. Lassen Sie uns also die Szene durchspielen und uns ein besseres Bild von der Reihenfolge , in der die Skripte ausgeführt werden. Wir können sehen, dass der erste Operator der erste ist, der bereit ist, gefolgt von jedem Operator der Reihe und schließlich der Operations Manager. Das Gleiche gilt für die Marketingabteilung. Dann ist endlich der Präsident des Unternehmens der letzte, der bereit ist. Wie entscheidet Gadot über diese Hinrichtungsreihenfolge? Die Engine startet am oberen Rand des Szenenbaums und arbeitet sich nach unten vor, betrachtet aber keinen Knoten als bereit , bis alle untergeordneten Knoten bereit sind Der Präsident ist also nicht bereit, weil der Betriebsleiter nicht bereit ist. Der Betriebsleiter ist nicht bereit, weil die Bediener nicht bereit sind. Die Bediener sind nacheinander bereit, da sie keine Kinder haben. Sobald alle Bediener bereit sind, ist der Betriebsleiter bereit. Aber der Präsident ist immer noch nicht bereit, weil der Präsident noch ein Kind hat, das noch nicht bereit ist. Der Marketingmanager war erst bereit, als alle Marketingfachleute bereit waren, und schließlich ist der Präsident der Letzte, der bereit Da an den Stammknoten kein Skript angehängt ist, entspricht seine Bereitschaftsfunktion der eines Standardknotens, der leer ist Neben Ready gibt es noch andere Funktionen von Node, die wir überschreiben können, damit sie später ausgeführt werden, wenn ein Node bereit ist. Am gebräuchlichsten ist ein Prozess, ebenfalls ein Unterstrich vorangestellt Die Engine versucht ihr Bestes, um die Prozessfunktion jedes Knotens im Szenenbaum 60 Mal pro Sekunde unter Verwendung der standardmäßigen Projekt-Framerate auszuführen die Prozessfunktion jedes Knotens im Szenenbaum 60 Mal pro Sekunde unter Verwendung der standardmäßigen Projekt-Framerate Daher verwendet der Prozess einen Parameter namens Delta, bei dem es sich um eine Fließkommazahl handelt, die die Anzahl der Sekunden angibt, die seit dem vorherigen Frame vergangen sind. In den meisten Fällen wird es also ein Sechzigstel sein, aber nicht immer. Wir brauchen diesen Parameter heute für nichts zu verwenden, also können wir dem Namen dieses Parameters einen Unterstrich hinzufügen, damit Gudo weiß, dass wir ihn nicht brauchen und uns nicht darum kümmern sollten Aber um die Prozessfunktion zu überschreiben, muss sie dieselbe Anzahl und dieselbe Art von Parametern haben Lassen Sie uns unseren Mitarbeitern sagen, dass sie in jedem Frame etwas Arbeit erledigen sollen, indem eine Erklärung ausdrucken, in der steht, dass ihr Name an funktioniert Beim Betrachten dieser Szene stellen wir fest, dass alle unsere Mitarbeiter sehr hart arbeiten ihre Kontoauszüge 60 Mal pro Sekunde schreiben Das ist nicht dasselbe wie eine Endlosschleife, denn die Arbeit wird tatsächlich so erledigt, wie sie beabsichtigt ist, und nichts ist kaputt. Lassen Sie uns das etwas verständlicher machen, indem wir jedem Mitarbeiter nur erlauben, Arbeitseinheit mit einer Bolan-Variablen zu erledigen , hat Arbeit mit dem Standardwert False erledigt der Mitarbeiter in der Prozessfunktion Wenn der Mitarbeiter in der Prozessfunktion keine Arbeit verrichtet hat, erledigt er seine Arbeit und ändert den Wert auf „Wahr“ Eine 60stelsekunde später, da die Variable wahr ist, werden sie nicht mehr arbeiten. Wenn wir diese Variable jedoch innerhalb der Prozessfunktion deklarieren , dann existiert sie nur innerhalb der Prozessfunktion und nur für eine einzige Iteration derselben Im nächsten Frame, wenn die Prozessfunktion zum zweiten Mal ausgeführt wird, wird die Variable erneut deklariert und hat immer noch den Standardwert False Das wird also keine Wirkung haben. Damit unsere Variable bestehen bleibt, muss sie außerhalb des Kontextes der Prozessfunktion existieren des Kontextes der Prozessfunktion Also deklarieren wir sie außerhalb der Funktion ohne Einrückung hier deklarierte Variablen kann überall im gesamten Skript zugegriffen werden überall im gesamten Skript zugegriffen Dieses Konzept wird als Bereich bezeichnet und ist einer der Hauptgründe, warum wir Einrückungen in unseren Skripten verwenden So können wir sehen, welche Variablen in welchem Bereich existieren. Wenn wir die Szene jetzt betrachten, können wir sehen, dass jeder unserer Mitarbeiter erklärt, dass er bereit ist zu arbeiten Erst wenn alle bereit sind, erledigen sie jeweils eine Arbeitseinheit, aber jetzt in einer anderen Reihenfolge Die Reihenfolge, in der Knoten und der Szenenbaum ihre Prozessfunktionen ausführen , folgt der exakten Reihenfolge des Szenenbaums von oben nach unten. Eltern müssen nicht wie bei der Bereitschaftsfunktion auf ihre Kinder warten . Möglicherweise möchten wir, dass alle Mitarbeiter unseres Unternehmens ähnlich , aber nicht genau gleich sind. Die Arbeit eines Managers ist nicht wirklich die gleiche wie die eines Arbeiters. Wir können Vererbung verwenden, um unterschiedliche Verhaltensweisen für ähnliche Objekte zu erzeugen . Auf die gleiche Weise schreiben wir Skripte, die den Knoten erweitern, aber ändern, wie sie vorbereitet werden und wie sie verarbeitet werden. Zuerst müssen wir diesem Skript einen Namen geben, den wir als Referenz verwenden können, das Schlüsselwort classname verwenden, gefolgt von einem Namen, der das Verhalten des Skripts beschreibt, normalerweise derselbe wie der Skriptname, aber in Pascal-Großbuchstaben geschrieben die Engine nun weiß, dass es sich um einen Mitarbeiter handelt, erstellen wir ein neues Skript und geben diesem einen Namen Manager Aber anstatt vom Knoten zu erben, können wir dieses Mal vom Mitarbeiter erben Da unser Manager-Skript die Erweiterung Employee erweitert, gilt alles, was im Employee-Skript steht , auch für dieses Skript, aber wir können weitere hinzufügen oder Änderungen vornehmen Ein Manager ist immer noch ein Angestellter, aber die Art und Weise, wie er arbeitet, ist anders. Wir sollten das an unsere Manager-Knoten angehängte Skript durch das neue Manager-Skript ersetzen . Lassen Sie uns die Definition der Ready-Funktion durch den Mitarbeiter überschreiben . Wenn also ein Manager bereit ist, wird er nicht nur sagen, dass er bereit ist, sondern er wird auch sagen, dass seine gesamte Abteilung bereit ist. Damit unsere beiden Manager den Namen ihrer Abteilungen ausgeben können, benötigen sie eine Variable, die den Namen ihrer Abteilung als Zeichenfolge enthält. Aber wie können wir diese Variable so auffüllen , dass sie unterschiedliche Werte für verschiedene Abteilungen enthält? Wenn wir unsere Variablendeklaration mit dem Tag beim Export fortsetzen , diese Variable andere Teile der Gadot-Engine auf diese Variable zugreifen, nämlich das Inspektor-Panel Damit eine Variable exportiert werden kann, muss sie auf der Ebene des Skriptbereichs deklariert werden Wenn Sie den Operations Manager und die Szenerie auswählen, gibt es jetzt ein Feld im Inspektorfenster, in dem wir der Abteilungsvariablen einen Zeichenkettenwert geben können Auf diese Weise können der Betriebsleiter und der Marketingleiter und der Marketingleiter jeweils ihren eigenen Wert für diese Variable haben , den wir leicht kontrollieren können die Szene ausführen, können wir sehen, dass die Knoten, die das Skript des Managers angehängt ist, jetzt deklarieren, dass ihre Abteilung bereit ist, während die anderen Mitarbeiter alle die vorherige Definition im Mitarbeiterskript verwenden . Die Prozessfunktion im Mitarbeiterskript wird ebenfalls von den Managern übernommen und wird genauso ausgeführt wie zuvor. Lassen Sie uns also die Prozessfunktion unseres Managers ändern. Manager werden etwas anderes sagen. Name Plus leitet die Mitarbeiter dazu, ihre Arbeit zu erledigen. Die Variable hat Arbeit erledigt aus dem Mitarbeiter-Skript wurde ebenfalls übernommen und muss hier nicht deklariert werden, um verwendet zu werden. Tatsächlich können wir keine Variable mit diesem Namen deklarieren, da dies zu einem Konflikt mit der geerbten Variablen desselben Namens führen würde . Lassen Sie uns die Szene noch einmal durchspielen und sehen, wie unsere Manager ihre Arbeit jetzt anders machen als andere Mitarbeiter. In der nächsten Lektion erfahren wir mehr über die Verwendung von Knoten im Szenenbaum und über die Prinzipien der objektorientierten Gestaltung. Wir sehen uns in der nächsten Lektion. 10. 0-9 Abstraktion und Verkapselung: Hallo Freunde. Heute werden wir untersuchen , wie man Klassen schreibt, die einfacher zu verwenden und zu verstehen sind . Stellen Sie sich ein Auto als Referenzrahmen vor. Lassen Sie uns zwei Knoten in unserer Szene erstellen, einen Fahrer und ein Auto als Kind des Fahrers Hängen Sie dann jeweils ein neues Skript mit demselben Namen an. Autos sind sehr komplexe Maschinen, und die meisten Menschen, die sie fahren, haben keine Ahnung, wie sie tatsächlich funktionieren. Sie verstehen nur, wie man ihr Auto bedient. Beginnen wir mit dem Auto-Skript und geben ihm den Klassennamen Auto Fügen wir dann eine Variable für das Jahr des Autos als Ganzzahl hinzu. Eine weitere für die Marke des Autos als Zeichenfolge und eine weitere für das Modell, ebenfalls als Zeichenfolge. all das exportiere, werde ich mein Auto auf einen Honda Civic von 2007 einstellen. beim Erstellen einer neuen Klasse darauf, das Skript zu speichern, bevor Sie versuchen, es zu verwenden. Im Treiberskript benötigt der Fahrer einen Verweis auf das Auto , den wir in einer Variablen vom Typ Auto speichern können. Knoten können auf andere Knoten im Szenenbaum zugreifen. Meist verwenden ihre untergeordneten Knoten ein anderes Tag, Meist verwenden ihre untergeordneten das dem Export ähnelt, der auf ready aufgerufen wird. Mit dem Tag on ready können wir den Variablenwert zuweisen, nachdem der Knoten bereit ist, was bedeutet, dass alle seine untergeordneten Knoten ebenfalls bereit sind, aber bevor die Ready-Funktion dieses Knotens aufgerufen wird. Wir können ihn dem Rückgabewert eines eingebauten Funktions-G-Knotens zuweisen , der einen Knotenpfad als Parameter akzeptiert. Wenn wir den Namen des untergeordneten Knotens in Anführungszeichen angeben , haben wir jetzt einen Verweis auf den untergeordneten Knoten, der in einer Variablen gespeichert ist, und wir können auf seine Eigenschaften und Funktionen zugreifen, einschließlich der Eigenschaften und Funktionen im angehängten Skript. Wenn wir die Definition der Ready-Funktion außer Kraft setzen, können wir auf den Fahrzeugknoten zugreifen und dessen Jahr, Marke und Modell ausdrucken Die Ready-Funktion wird nach den On-Ready-Tags ausgeführt. gibt es eine Abkürzung für dies zu vereinfachen, gibt es eine Abkürzung für die Funktion get node das Dollarzeichen, gefolgt von demselben Knotenpfad. Gehen wir zurück zum Car-Skript und fügen eine weitere Variable hinzu. Diese gibt als boolescher Wert an, ob der Motor läuft oder nicht Als Fahrer wissen wir, ob der Motor läuft, und wir haben die Kontrolle darüber, ob der Motor läuft oder nicht, da wir mit dem Schlüssel wählen können, ob der Motor gestartet oder gestoppt werden soll mit dem Schlüssel wählen können, ob der Motor gestartet oder gestoppt Wir würden diese Variable also als öffentlich betrachten. Eine weitere Eigenschaft unseres Autos könnte die Anzahl der Zylinder im Motor als Ganzzahl sein, und ich weise ihr einen Wert von vier zu. Dies ist etwas, das der Fahrer nicht wissen muss, nicht einfach darauf zugreifen kann und niemals ändern darf. Im Gegensatz zur öffentlichen Variablen würde diese Variable also als privat betrachtet werden, und wir können sie als privat kennzeichnen, indem wir ihrem Namen einen Unterstrich hinzufügen Im Treiberskript können wir den Wert von Engine is on auf true setzen , indem wir den Schlüssel in die Zündung stecken und sie drehen Aber zuerst sollten wir das Bremspedal drücken. Lassen Sie uns eine Funktion verwenden, um den Druck einzustellen , der auf das Bremspedal wird. Wir gehen davon aus, dass er bis zu einer maximalen Kraft von 20 Kilogramm beträgt. Um unser Auto zu starten, sollten wir also den Bremsdruck wahrscheinlich auf etwa 10 Kilogramm einstellen . Zurück im Auto-Skript müssen wir diese Funktion definieren, müssen wir diese Funktion definieren die den Bremsdruck einstellt. ob die Engine auf einer Variablen steht, würde man dies als öffentliche Funktion bezeichnen, da sie von einem anderen Skript verwendet wird. Diese Funktion akzeptiert eine Fließkommazahl als Parameter, der angibt, wie viel Druck auf das Pedal ausgeübt wird. Aber was macht das Auto eigentlich wenn wir Druck auf das Bremspedal ausüben? Aus Sicht des Fahrers entscheidet sich der Fahrer dafür, einen bestimmten Druck auf das Pedal auszuüben, ohne jemals die genaue Position zu kennen. Aus Sicht des Fahrzeugs wird die Position des Pedals gemessen und verwendet, um das Auto anzuhalten. Das Auto verwendet die Position des Bremspedals, um den Druck einzustellen, der auf Bremssättel ausgeübt wird, die Bremsbeläge an Bremssättel ausgeübt wird, die den Rädern des Fahrzeugs halten, ganz zu schweigen von der Komplexität von Antiblockiersystemen oder anderen Systemen Wenn wir also tatsächlich ein echtes Auto programmieren würden, müssten wir hier mehrere komplexe Funktionen schreiben , die die einfache Aktion des Fahrers, der Druck auf das Bremspedal ausübt, in die komplexe Mechanik des Zusammendrückens der Bremssättel umwandeln Fahrers, der Druck auf das Bremspedal ausübt, in die komplexe Mechanik des Zusammendrückens der Bremssättel komplexe Mechanik des Zusammendrückens der Das ist Teil der internen Funktionen des Fahrzeugs und nichts , was für den Fahrer auf andere Weise als durch Drücken auf das Bremspedal gesteuert oder zugänglich ist Fahrer auf andere Weise als durch Drücken auf das Bremspedal gesteuert oder zugänglich andere Weise als Bremspedal Wir würden diese Funktionen also als private Funktionen betrachten, da sie nur für die Nutzung durch das Auto selbst bestimmt sind. Und wir können unsere privaten Funktionen kennzeichnen indem wir ihre Namen mit einem Unterstrich Beachten Sie, dass dies mit den Funktionen „Prozess“ und „Bereit“ identisch Funktionen „Prozess“ und „Bereit Die Art und Weise, wie GDScript private Variablen und Funktionen verwendet , ähnelt eher der Art und Weise, wie andere Sprachen geschützte Variablen und Funktionen verwenden , da sie für Erben zugänglich sind GD Script setzt diese Datenschutzbestimmungen jedoch nicht wirklich durch, und Skripte können weiterhin auf private Mitglieder zugreifen Diese Konventionen dienen ausschließlich dazu, eine bessere Klassenstruktur und ein besseres Design zu ermöglichen. Eine andere Möglichkeit, Kommentare in GD Script zu verwenden , besteht darin, Bereiche unserer Skripte zu erstellen, die miteinander verwandt sind Verwenden Sie dazu das Schlüsselwort region gefolgt vom Namen der Region. Wir können eine Region mit dem Schlüsselwort und der Region beenden. Lassen Sie uns also in unserem Auto-Skript eine öffentliche Region und eine private Region erstellen und trennen, was für den Fahrer zugänglich sein soll und was nicht. Einfachheit halber an, Nehmen wir der Einfachheit halber an, der Fahrer muss nur in der Lage sein, den Motor ein- oder auszuschalten, Druck auf das Gaspedal auszuüben, Druck auf das Bremspedal auszuüben oder das Lenkrad zu drehen. Was in jeder dieser öffentlichen Funktionen tatsächlich passiert , ist die interne Mechanik des Autos selbst. Der Fahrer muss nicht wissen, wie das funktioniert, um das Auto zu bedienen. Wenn Sie zum Beispiel Gas geben, das Auto tatsächlich öffnet das Auto tatsächlich ein Lufteinlassventil am Motor, wodurch mehr Luft und Sauerstoff in den Motor gelangen. Das Auto muss also einen Sensor verwenden, um die Menge des Luftstroms und die Menge an Sauerstoff zu messen Luftstroms und die Menge an , die jetzt in den Motor fließt Verwenden Sie diesen dann, um die Kraftstoffmenge einzustellen , die in die Zylinder des Motors eingespritzt wird All diese Funktionen sind privat, da wir nicht wissen müssen, was sie eigentlich tun, um das Auto fahren zu können. Weise, wie sich unser Auto bewegt, hängt von der Prozessfunktion ab, und wir benötigen eine weitere private Variable namens phase, um darzustellen, in welcher der vier Phasen sich jeder Zylinder gerade befindet. In der Prozessfunktion des Autos können wir, wenn der Motor läuft, jeden Zylinder des Motors durchlaufen Wenn wir den Zylinder und die Phase zusammenzählen, dann Modul vier, erhalten wir für jeden Zylinder eine andere Phase diese Zahl zuordnen, können wir jedem Zylinder anweisen eine andere Phase durchzuführen, nämlich den Einlasstakt, Kompressionstakt, den Verbrennungstakt oder den Auslasstakt, wobei jeder den Zylinder als Argument akzeptiert Erhöhen Sie dann die Phase und fahren Sie wieder auf Null zurück , wenn sie vier erreicht. Jede dieser Funktionen kann dann die Einlassventile, Auslassventile, Einspritzdüsen und Zündkerzen jedes Zylinders steuern , um den Motor laufen zu lassen Die Kraft, die durch die Verbrennungstakte jedes Zylinders erzeugt wird durch die Verbrennungstakte jedes Zylinders erzeugt , würde das Fahrzeug dann vorwärts bewegen , während die Bremsbeläge versuchen, das Fahrzeug anzuhalten, und die Lenkradposition ihre Richtung ändert Die Position des Fahrzeugs würde dann durch die Richtung, Geschwindigkeit und Delta-Zeit verändert. Sie sich keine Sorgen, wenn das alles für Sie keinen Sinn ergibt , denn genau darum geht es in dieser Lektion. Du musst es nicht verstehen. Da sich all dies im privaten Bereich des Skripts befindet, muss der Fahrer nicht wissen wie das alles funktioniert, um das Auto fahren zu können. Sie müssen nur wissen, wie man den öffentlichen Bereich des Skripts benutzt. Durch die Trennung von öffentlich und privat werden zwei wichtige Prinzipien der objektorientierten Programmierung durchgesetzt zwei wichtige Prinzipien der objektorientierten Programmierung Kapselung ist der öffentliche Bereich, Zugang zu öffentlichen Variablen oder Funktionen ermöglicht, die einfach zu verwenden und leicht zu verstehen sind, und Abstraktion ist der private Bereich, in dem die Details komplexer Systeme oder Mechaniken verborgen werden, die nicht verstanden werden müssen, um effektiv genutzt zu werden verstanden Sie werden wissen, ob Ihre Kurse diese Prinzipien einhalten , wenn Sie alle privaten Inhalte verstecken können und trotzdem leicht verstehen, wie sie verwendet werden sollen Unser Fahrer kann jetzt also das Fahren des Autos simulieren indem er nur auf die öffentlichen Bereiche des Autoskripts zugreift, vom Drücken der Bremse und dem Starten des Motors bis hin zum Lösen der Bremse, dem Drücken des Gaspedals, dem Drehen des Lenkrads usw. Diese Prinzipien sind nicht nur für unsere eigenen Skripte wichtig, sondern ermöglichen es uns auch, Skripte zu verwenden, die von anderen Entwicklern geschrieben wurden , ohne vollständig verstehen, wie sie intern funktionieren Sie machen R-Skripte auch flexibler. Stellen Sie sich vor, wir würden unser Gasauto gegen ein Elektroauto austauschen Müsste irgendwas im Drehbuch des Fahrers geändert werden? Elektroauto-Skript müsste nur das Für ein Elektroauto-Skript müsste nur das Auto-Skript geändert werden, da alle öffentlichen Variablen und Funktionen weiterhin im Elektroauto-Skript existieren würden. Ebenso könnten wir das Treiberskript in ein Autopilot-Skript umwandeln, dem lediglich ein Ziel zugewiesen werden muss und das Auto dann automatisch bedienen kann In der nächsten Lektion werden wir noch mehr über die Prinzipien des objektorientierten Designs lernen über die Prinzipien des objektorientierten Designs Wir sehen uns in der nächsten Lektion. 11. 0-10-Polymorphismus: Hallo Freunde. Heute behandeln wir das letzte Prinzip der objektorientierten Programmierung, den Polymorphismus erweitern die Konzepte der Vererbung und Abstraktion und können Klassen schreiben, Wir erweitern die Konzepte der Vererbung und Abstraktion und können Klassen schreiben, die abstrakteres Konzept repräsentieren, eine Sammlung von spezifischeren Klassen, die Lassen Sie uns Tiere als Beispiel verwenden, indem wir ein Skript mit dem Namen animal erstellen , das den Knoten erweitert, aber wir müssen dieses Skript nicht an irgendwelche Knoten im Szenenbaum anhängen dieses Skript nicht an irgendwelche Knoten im Szenenbaum Hier können wir dem Skript einen Klassennamen geben dann Eigenschaften und Verhaltensweisen definieren , die allen Tieren gemeinsam sind, wie eine Variable, die den Plural des Tieres als Zeichenfolge enthält, und eine weitere für den Namen einer Gruppierung dieses Und lassen Sie uns auch eine Funktion definieren, mit der sich das Tier bewegen, essen oder Wir können den Plural von Tier zwar leicht als Tiere definieren , es gibt kein Wort für eine Gruppe von Tieren Wir können auch nicht definieren, wie sich ein Tier bewegt oder frisst, ohne zu wissen, um welche Art von Tier es sich handelt Die Körper dieser Funktionen können also leer bleiben. Wir könnten jedoch davon ausgehen, dass einige Verhaltensweisen so häufig vorkommen , dass sie eine Standardeinstellung haben sollten, z. B. das Sprechen. Es gibt zwar viele verschiedene Säugetiere , die eine Vielzahl von Geräuschen machen, die meisten Tiere, einschließlich Fische und Insekten, tun dies nicht einschließlich Fische und Insekten Die meisten Menschen würden sie nicht als sprechen beschreiben. Wenn wir also einem zufälligen Tier sagen, dass es sprechen soll könnten wir das Standardverhalten als Schweigen betrachten. Fügen wir also verschiedene Tiere zu unserem Szenenbaum hinzu, angefangen mit einer Katze. Wir können jetzt wie zuvor Vererbung verwenden, um eine beliebige Anzahl verschiedener Tierskripte zu erstellen , die von Tieren wie Katzen erben Wir überschreiben dann die Ready-Funktion , um den Variablen, die von animal geerbt wurden, einen Wert zu geben von animal geerbt wurden , der für eine Katze geeignet ist Der Plural wäre Katzen, und eine Gruppe von Katzen wird Clouder genannt Die Verhaltensfunktionen können auch überschrieben werden um das Verhalten beim stillen Sprechen in Miauen Katzen laufen auf vier Beinen, um sich fortzubewegen, und ich würde sagen, dass sie Fisch fressen Der tatsächliche Inhalt dieser Variablen und Funktionen ist nicht relevant, aber der Schwerpunkt liegt darauf, wie sie vom abstrakten Konzept eines Tieres auf ein spezifischeres Beispiel einer Katze vererbt werden vom abstrakten Konzept eines Tieres auf ein . Wir können diesen Vorgang wiederholen , um viele weitere verschiedene Tierarten zu erstellen , die wir unserem Szenenbaum hinzufügen können, z. B. einen Vogel oder einen Fisch. Und indem sie jedem ein neues Skript geben, das von Animal geerbt wurde, können sie jeweils ihre eigenen eindeutigen Werte für die Variablen und Implementierungen der Funktionen angeben die Variablen und Implementierungen der , die sie Der Plural von Vogel ist Vögel. Eine Gruppe von Vögeln wird Herde genannt. Sie fliegen, um sich fortzubewegen, fressen Würmer und zwitschern, um zu sprechen Ich verschaffe mir einen Vorsprung bei meinem Fish-Skript indem ich den Inhalt des Cat-Skripts kopiere Und der Plural von Fisch ist Fisch Eine Gruppe von Fischen wird Schule genannt. Sie schwimmen, um sich fortzubewegen, sie fressen Algen, aber sie sprechen nicht. Wenn die Sprechfunktion weggelassen wird, verwenden Fische die ererbte Definition aus der Tierschrift zum Bisher haben wir nur die objektorientierten Prinzipien verwendet, die wir bereits kennen, um die Eigenschaften und Verhaltensweisen von Tieren zu erben, zu abstrahieren und wir bereits kennen, um die Eigenschaften und Verhaltensweisen von Tieren zu erben, zu abstrahieren und zusammenzufassen. All dies ermöglicht es uns jedoch, Polymorphismus zu verwenden, indem alle Tiere so behandeln, als ob sie wir alle Tiere so behandeln, als ob sie gleich und austauschbar wären. Zuerst fügen wir dem Wurzelknoten unserer Szene ein Skript hinzu und nennen es Zoo, das vom Knoten erbt Unser Zoo ist voller verschiedener Tiere, aber es spielt keine Rolle, um welche Tiere es sich tatsächlich handelt wir die Definition der Ready-Funktion für unseren Zoo außer Kraft setzen, können wir ganz einfach unsere Tierliste durchgehen und sie alle so behandeln, als ob sie nur Tiere wären Eine schnelle und einfache Möglichkeit, all unsere Tiere in einer einzigen Variablen zu speichern unsere Tiere in einer einzigen Nennen wir es Tiere, indem wir eine Funktion des Knotens namens Get children verwenden . Dies gibt ein Array von Knoten zurück, wobei alle untergeordneten Knoten dieses Knotens praktischerweise in derselben Reihenfolge wie der Szenenbaum in einem Array angeordnet sind. Da dies von den untergeordneten Elementen abhängt, müssen wir das Tag bei on ready verwenden. Da wir wissen, dass alle Tiere dieselben Eigenschaften und Verhaltensweisen haben , können wir jedes Tier in unserer Tiergruppe wiederholen und jedem Tier sagen, dass es sprechen soll Und obwohl sie alle wie Tiere behandelt werden, spricht jedes auf seine eigene Art und Weise, wie es in seinen eigenen Skripten definiert ist, oder verwendet die vom Tier übernommene Definition , wenn es keine eigene hat Wir können so viele Vererbungsstufen schaffen , wie wir möchten. Lassen Sie uns also ein weiteres abstraktes Skript für Säugetiere erstellen , die vom Tier erben Säugetiere sind eine Unterkategorie von Tieren, zu denen alle Tiere gehören, die Brustdrüsen haben und diese zum Stillen ihrer Jungen verwenden. Dies sind einzigartige Eigenschaften und Verhaltensweisen von Säugetieren, die auf andere Tiere nicht zutreffen So können wir dem Säugetier-Skript eine neue Variable für die Anzahl der Brustdrüsen dieses Tieres hinzufügen dem Säugetier-Skript eine neue Variable für die Anzahl der Brustdrüsen dieses Tieres und eine neue Funktion namens Krankenschwester schreiben Auch hier ist der Inhalt der Funktionen für diese Lektion nicht relevant Dieses Skript benötigt außerdem einen Klassennamen um vererbt zu werden. wechseln zum Katzen-Skript, da Katzen Säugetiere sind, und so können wir der Anzahl der Brustdrüsen für Katzen einen Wert geben , der acht sein sollte Und wir können unserem Zoo auch neue Säugetiere hinzufügen, wie einen Affen Affen sind auch Säugetiere, aber sie haben nur zwei Brustclans Ich kopiere noch einmal den Inhalt eines anderen Skripts, um die Dinge zu beschleunigen Der Plural von Affen ist Affen. Eine Gruppe von Affen wird Truppe genannt. Sie bewegen sich, indem sie auf Bäume klettern. Sie essen Bananen und ich sage, sie sagen oh. Unser Zoo-Skript kann nun diese neue Vererbungsstruktur nutzen , um einzigartige Bedingungen speziell für Tiere, die Säugetiere sind, anzuwenden . Wir können Klassennamen direkt in bedingten Anweisungen verwenden , um zu sagen, dass ist wir zusätzlichen Code ausschließlich für Säugetiere ausführen werden , wenn das aktuelle Tier ein Säugetier Ich drucke einfach ein paar zusätzliche Zeilen aus die unsere Säugetiere beschreiben Und wir können sehen, dass unsere Ergebnisse sowohl für alle Tiere einheitlich sind, auch etwas Einzigartiges speziell für die beiden Säugetiere bieten. Sie können sich vorstellen, wie wir unsere Liste der Tiere in unserem Zoo so ändern könnten , dass sie beliebige Tierarten enthalten, und wir könnten unsere Erbschaftsstruktur ändern um sie so genau wie nötig zu kategorisieren In der nächsten Lektion lernen wir eine weitere Datensammlung kennen, mit der wir verwandte Informationen gruppieren können verwandte Informationen gruppieren können Wir sehen uns in der nächsten Lektion. 12. 0-11-Wörterbuch: Hallo Freunde. Heute werden wir eine Alternative zu dem Array verwenden, die manchmal wie eine Klasse ohne Funktionen verwendet wird , die als Wörterbuch bezeichnet wird. Stellen Sie sich eine Reihe von Schließfächern vor, wie Sie sie in einer High School oder einem Gymnasium finden würden Wenn wir ein Array von Variablen deklarieren, könnten wir den Array-Index jeder Variablen als die Zahl der Schließfächer betrachten jeder Variablen als die Zahl der Schließfächer Nehmen wir an, es gibt zehn Schließfächer, und wir können auf jedes einzelne Schließfach zugreifen um etwas hineinzulegen, angefangen bei Schließfach Null, Eins usw. Was wir in jedes Schließfach legen, spielt keine Rolle. Es kann sich um eine Ganzzahl, eine Fließkommazahl, eine Zeichenfolge, booleschen Wert, eine Null oder eine Instanz einer Klasse handeln Und wir können den Inhalt der Schließfächer ausdrucken , um sie zu sehen Stellen Sie sich nun vor, wenn wir etwas in einen der Schränke legen, schließen wir nicht nur die Tür des Schließfachs, sondern befestigen auch ein Vorhängeschloss daran Dieses Vorhängeschloss benötigt Öffnen eine dreistellige Zahlenkombination Bisher mussten wir, wenn wir den Inhalt des Schließfachs abrufen wollten, den Inhalt des Schließfachs abrufen wollten, nur die Nummer des Schließfachs kennen, dorthin gehen und den Inhalt herausnehmen Jetzt können wir die Nummer des Schließfachs ignorieren und müssen stattdessen die Kombination kennen, mit der das Vorhängeschloss geöffnet Nehmen wir an, die Kombination ist 149. Als Array würde die Zuweisung von etwas zur Zahl 149 bedeuten, dass das Array 150 Schließfächer haben müsste Wenn wir den Typ unseres Arrays in ein Wörterbuch ändern würden , würde das immer noch funktionieren, außer dass wir keine Größe für das Wörterbuch festlegen müssen Größe für das Wörterbuch bevor wir auf seinen Inhalt zugreifen können Beachten Sie, wie sich die Ausgabe geändert hat. Wörterbücher werden durch geschweifte Klammern statt durch eckige Klammern dargestellt , und jeder Eintrag ist eine Zahl, die einen Schlüssel darstellt, gefolgt von einem Wert dessen, was in dem durch diesen Schlüssel gesperrten Schließfach enthalten ist in dem durch diesen Schlüssel gesperrten Schließfach enthalten Das Wörterbuch enthält auch keine Einträge für Schlüssel, denen kein Wert zugewiesen wurde Als Wörterbuch ist diese Zahl weder ein Index noch eine Adresse. Es ist ein Schlüssel, mit dem wir ein Schloss öffnen. Und so wie der Inhalt des Schließfachs einen beliebigen Datentyp haben kann, können die Schlüssel, die wir zum Sperren verwenden, auch einen beliebigen Datentyp haben, mit Jeder Schlüssel muss einzigartig sein. Andernfalls können wir das Schließfach, das dem Schlüssel entspricht, nicht finden. Versuchen wir also, ein Schließfach mit einer anderen Art von Schloss zu verschließen, eines, das Buchstaben anstelle von Zahlen verwendet. Der Schlüssel dieses Wörterbucheintrags ist also eine Zeichenfolge, aber sein Wert ist eine Zahl. Das komplette Gegenteil dieses Schließfachs, dessen Schlüssel eine Zahl und dessen Wert eine Zeichenfolge ist. Sperren wir das nächste Schließfach mit einem Drehschloss, dessen Entsperrung drei Zahlen erforderlich sind, die wir in einem Array speichern könnten. Unser Schlüssel für Wörterbucheinträge ist also ein durch eckige Klammern dargestelltes Array , das eine durch Kommas getrennte Liste von drei ganzen Zahlen enthält eine durch Kommas getrennte Liste von drei ganzen Zahlen Vielleicht enthält diese Schlossnummer einen Dezimalpunkt, der Schlüssel ist also eine Und irgendwie ist dieses Schließfach durch Lichtempfindlichkeit verriegelt und kann nur geöffnet werden, wenn das Licht aus Sein Schlüssel ist also ein boolescher Wert. Wir können sogar benutzerdefinierte Klassen entweder als Schlüssel oder als Werte in Wörterbüchern verwenden entweder als Schlüssel oder als Werte in Schreiben wir eine neue Klasse für Schlüssel, die von nichts erben muss , da sie weder an einen Knoten angehängt noch vererbt wird Unsere Schlüsselklasse benötigt einen Klassennamen und wird eine Variable haben , die ihre Zähne beschreibt Die Implementierung dieser Klasse ist nicht relevant, aber wir können so tun, als wäre es ein Schlüssel Zurück im Locker-Skript können wir eine Instanz unseres Schlüssels in einer Variablen speichern Nennen wir es Schlüssel eins vom Typ Schlüssel, indem es dem Klassennamen des Schlüssels zuweisen . Nunu erzeugt einen neuen Schlüssel , der unserer Variablen zugewiesen wird Wir können diesen Schlüssel jetzt verwenden, um einen Eintrag im Wörterbuch zu erstellen Wir können auch mehr Schlüssel erstellen , um mehr Einträge zu erstellen. Da jeder Schlüssel, den wir erstellen, als einzigartig angesehen wird. In der Ausgabe werden die Schlüssel nun als Riffzählung gefolgt von einer langen Zahl angezeigt . Die Namen, die wir in anderen Klassen verwendet haben , wurden von Node übernommen. Da der Schlüssel jedoch nicht vom Knoten erbt, hat er keinen Namen Ref Counted ist die Abkürzung für Reference Counted Object und die Basisklasse für GD-Skripte Wenn wir eine Klasse schreiben , die von nichts erbt, erbt sie von Reef Counted und ihr wird eine zufällige lange Zahl zugewiesen Wir können das ignorieren und einfach verstehen , dass es sich bei unseren Schlüsseln um Objekte mit Referenzzählung handelt, was bedeutet, dass Gadot automatisch jede einzelne Instanz jedes Objekts verfolgt jede einzelne Instanz jedes Objekts Aber was wollen wir in den Schließfächern aufbewahren? So wie Arrays andere Arrays enthalten können, können Wörterbücher auch andere Wörterbücher Entsprechend der Art und Weise, wie Wörterbücher gedruckt werden, können wir mithilfe von geschweiften Klammern im Handumdrehen unsere eigenen Wörterbücher erstellen . Jeder Eintrag beginnt mit einem Schlüssel, gefolgt von einem Doppelpunkt und dann dem Wert , der diesem Wörterbücher werden häufig nicht verwendet, um so etwas wie dieses Locker-Szenario zu erstellen, sondern eher darin, so etwas wie eine Klasse zu erstellen, wenn auch eine ohne Funktionen, nur Variablen Nehmen wir an, dieser Schrank enthält ein Plüschtier, das wir mit einem Wörterbuch darstellen werden Und dieses Plüschtier gehört zu einer Reihe von Plüschtieren zum Sammeln, die sich ähneln, aber auf ihre Art unterschiedlich sind ähneln, aber auf ihre Art unterschiedlich Jedes der Plüschtiere ist eine andere Tierart mit einer Farbe und einem Namen Jeder dieser Schlüssel kann ein Schlüssel im Wörterbuch sein. Nehmen wir an, in diesem Schließfach befindet sich Bruno, der Braunbär. Und das nächste Schließfach enthält Arthur die weiße Ziege. Wir können unser Wörterbuch Plüschtiere im Wörterbuch der Schließfächer sehen im Wörterbuch der Schließfächer Zufällig ist Farbe auch eine bereits definierte Klasse in Anstatt unsere Farben also als Zeichenketten zu speichern, können sie unter Verwendung des Klassennamens color als Farben gespeichert werden Wie Sie sehen können, gibt es viele vordefinierte Farben, die wir verwenden können, und wir können anhand ihrer Benennung in Schlangengroßbuchstaben erkennen , dass dies Konstanten der Farbklasse sind Wir könnten das sogar umdrehen und so tun, als ob die Plüschtiere ein NFC- oder Nahfeldkommunikationsetikett enthalten, was sie zum Schlüssel für den Zugang zum Schließfach macht Und wir können nach wie vor alles, was wir wollen, in den Schrank legen , einschließlich Lassen Sie uns ein weiteres Plüschtier herstellen , das wir im Schließfach aufbewahren können, das mit Arthur als Schlüssel entriegelt wird Diesmal ist es Cutie, der graue Elefant. Stellen Sie sich dieses Szenario noch einmal vor: In der Nähe der Schließfächer steht ein NFC-Lesegerät und wir halten einen Plüsch mit einem NFC-Tag in der Hand, so etwas wie das, was Sie in einem Escape Room finden könnten Wenn wir das Plüschtier gegen das Lesegerät halten, müssen wir überprüfen, welches Schließfach zum Plüschtier passt, und es öffnen, falls ein Schließfach überhaupt Wenn wir jedoch versuchen, auf einen Schlüssel in einem Wörterbuch zuzugreifen , dem kein Wert zugewiesen wurde, verursachen wir einen Fehler Ähnlich wie wir es tun würden, wenn wir versuchen würden, auf einen Array-Index zuzugreifen, der sich außerhalb des zulässigen Bereichs befindet. Wir können mit der Funktion has überprüfen, ob ein Wörterbuch einen Eintrag enthält , der einem bestimmten Schlüssel entspricht, den Schlüssel dann als Parameter übergeben. Auf diese Weise können wir überprüfen, ob ein Wörterbucheintrag existiert, bevor wir versuchen auf seinen Wert zuzugreifen, wodurch der Fehler vermieden wird. Wenn das Wörterbuch den Schlüssel nicht enthält, drucke ich eine andere Nachricht aus. Anstatt dasselbe Wörterbuch zweimal zu definieren, wäre es besser, es in einer Variablen zu speichern und die Variable zweimal zu verwenden. In der nächsten Lektion werden wir einige verschiedene Techniken untersuchen , die Sie verwenden können wenn Sie nicht weiterkommen oder weitere Informationen benötigen. Wir sehen uns in der nächsten Lektion. 13. 0-12 Debugging: Hallo Freunde. Heute werden wir einige verschiedene Strategien durchgehen, mit denen Sie Ihnen helfen können , wenn Sie unweigerlich nicht weiterkommen. Ich habe bereits ein Skript mit dem Namen debug an den Stammknoten der Szene angehängt Namen debug an den Stammknoten der Szene Sie haben wahrscheinlich die Funktion zur automatischen Vervollständigung bemerkt, die verfügbar ist, wenn Sie den Typ Ihrer Variablen angeben diese Weise können Sie nicht nur alle Eigenschaften und Funktionen der Klasse sehen , sondern nach der Auswahl einer Funktion auch die Typen aller Funktionsparameter sehen, auch die Typen aller Funktionsparameter sehen aller Funktionsparameter sodass Sie passende Argumente angeben können A: Wenn Sie die Typen all Ihrer Variablen kennen, Fehlpaarungen deutlich sichtbar, und Sie werden vor dem Fehler gewarnt , ohne ihn ausführen zu müssen Ohne strikte Typen weiß die Engine erst, was falsch ist, wenn sie versucht, die Zeile auszuführen Wenn Sie in einer integrierten, klassenähnlichen Farbe blättern möchten , können wir ganz einfach auf die Informationen zugreifen, indem Sie auf eine der Schaltflächen in der oberen rechten Ecke des Bedienfelds Online Docs öffnet in Ihrem Standard-Webbrowser eine Registerkarte zur GADO-API, die der Version des Editors entspricht , die Sie verwenden Hier findest du grundlegende Informationen zu Gdo, Tipps für den Einstieg, ausführliche Tutorials zu den Grundlagen, Community-Links, in denen du zusätzliche Ressourcen findest, und eine vollständige Kursreferenz Wie du siehst, gibt es viele Klassen. Und wenn wir eine von ihnen auswählen, können wir sehen, von was sie erben und von welchen anderen Klassen sie geerbt werden Jeder hat eine Beschreibung dessen, was er tut. Links zu Tutorials zur Verwendung, eine Liste von Eigenschaften und Methoden. Wenn wir über Klassen sprechen, neigen wir dazu, Variablen als Eigenschaften und Funktionen als Methoden zu bezeichnen . Es gibt auch Signale, etwas, das Gadot für die automatische Kommunikation zwischen Knoten, Aufzählungen und Konstanten verwendet automatische Kommunikation zwischen Knoten, , wie wir All diese haben ihre eigenen Unterabschnitte und Beschreibungen Zurück im GDA-Editor öffnet die Suchhilfe ein Fenster in GDA, in dem Sie eine Liste aller Klassen sehen können eine Klasse auswählen, können wir in unserem Editor dieselben Informationen sehen , die auf der GDA-Website verfügbar sind , sodass wir offline darauf zugreifen können zu unserem Skript zurückkehren, können wir sogar einfacher auf diese Informationen zugreifen , indem wir die Strg- oder Befehlstaste gedrückt halten , als auf einen Klassennamen zu klicken wir direkt zu den Referenzinformationen für diese Klasse Das Gleiche kann für bestimmte Funktionen und Variablen gemacht werden. Wenn Sie darauf klicken, wird nicht nur die Referenzseite zur Klasse geöffnet, sondern wir gelangen auch zu der Funktion oder Variablen, auf die wir geklickt haben Es gibt auch globale Funktionen , mit denen wir hauptsächlich mathematische Operationen ausführen können , wie zum Beispiel Clamp Wenn wir diese Funktion verwenden, können wir die Parameter sehen, die sie erwartet und wir können sie verwenden, um unsere Variable auf 0-1 zu begrenzen die Strg- oder Befehlstaste gedrückt halten und auf den Namen der globalen Funktion klicken , können wir auf die Referenz für diese Funktion zugreifen, einschließlich einer Beschreibung und ihrer Verwendung Diese sind alle in der globalen Scope-Klasse enthalten. Ich füge meinem Skript eine weitere Variable und eine weitere Zeile hinzu. Wenn wir unsere Szene ausführen, können wir uns den Szenenbaum der laufenden Simulation über das Szenenfenster ansehen laufenden Simulation über das , indem wir auf den Fernschalter Dies ist nicht derselbe Szenenbaum in der lokalen Registerkarte, den wir erstellen, um die Szene wie eine Blaupause zu definieren Dieser Szenenbaum wurde von der Engine für die Ausführung der Szene erstellt Wenn wir einen Knoten auswählen, können wir seine Eigenschaften im Inspektor sehen und wir können sehen, dass die Ready-Funktion bereits ausgeführt wurde , da die Farben unterschiedliche Werte haben. Wir können auch die Werte jeder dieser Eigenschaften ändern. Wir können print auch verwenden , um zu jedem Zeitpunkt auszudrucken, wann immer wir sehen möchten, was unsere Variablen enthalten. Und es hilft, Ihre Print-Statements so aussagekräftig wie möglich zu gestalten, damit keine Verwirrung darüber entsteht , woher sie kommen Aber wenn wir die Dinge ändern und die Prozessfunktion verwenden, ändere ich die Farbe einfach schrittweise im Laufe der Zeit füge dann hier eine Druckaussage Da diese Prozessfunktion 60 Mal pro Sekunde ausgeführt wird, ist 60 Mal pro Sekunde ausgeführt wird, der Wert von Druckanweisungen als Debugging-Tool stark reduziert, da das Ausgabelog dieselbe Nachricht nur schneller wiederholt , als wir sie lesen oder darauf reagieren können Wir können die Simulation unterbrechen, während sie läuft, indem wir die Pause-Taste verwenden oder F 7 drücken Auf diese Weise können wir den Remote-Szenenbaum so sehen, wie er gerade ist , und den Inhalt des Ausgabefensters überprüfen , während die Simulation angehalten Dies ist jedoch immer noch nicht sehr nützlich, da zwischen dem Start der Simulation und dem Zeitpunkt, an dem wir sie anhalten können, mehrere Frames abgeschlossen werden der Simulation und dem Zeitpunkt, an dem Start der Simulation und dem Zeitpunkt, an dem wir sie anhalten können Wenn wir links neben eine Codezeile klicken, können wir einen automatischen Breakpoint hinzufügen durch einen roten Kreis gekennzeichnet Wenn wir die aktuelle Szene ausführen, wird die Simulation angehalten, wenn sie diese Zeile erreicht , bevor sie ausgeführt Dies ist viel hilfreicher, wenn wir möchten , dass unsere Simulation Frame für Frame ausgeführt wird. Jetzt können wir sehen, wie sich bei jedem Bild die Farbe von Bild zu Bild allmählich ändert. Lassen wir unsere Prozessfunktion eine andere Funktion aufrufen, um eine einfache Aufgabe auszuführen. Ich ändere die Farbe einfach schrittweise indem ich den Rotwert reduziere. Jetzt sollten wir also sehen, dass sich die Farbe bei jedem Frame allmählich ändert und weniger rot und mehr blau wird. Wenn sich der Breakpoint immer noch in der ersten Zeile der Prozessfunktion befindet, führe ich die Szene Es hört hier auf, und wir können sehen , dass die nächste Codezeile ausgeführt werden soll, mit einem gelben Dreieck gekennzeichnet ist Während die Simulation auf diese Weise angehalten wird, können wir sie anweisen , jeweils nur eine einzige Codezeile und nicht einen ganzen Frame auszuführen , indem wir im Debug-Menü die Option Step over wählen oder die Tastenkombination F ten verwenden Dadurch wird nur die Codezeile ausgeführt , auf die das gelbe Dreieck zeigt, und dann sofort wieder angehalten dann sofort wieder angehalten Wir können also die Änderungen sehen, die nur durch diese einzelne Codezeile vorgenommen wurden, und wir können sehen, dass das gelbe Dreieck die nächste Zeile zeigt, die darauf wartet, ausgeführt zu werden. Wir können unser Skript Zeile für Zeile weiter ausführen , indem wir Schritt für Schritt weitermachen, bis die Prozessfunktion beendet und der Frame abgeschlossen ist, und dann Schritt weitermachen, bis die Prozessfunktion zum Anfang der Prozessfunktion zurückkehren, zum Anfang der Prozessfunktion zurückkehren um sie ein zweites Mal auszuführen Jetzt können wir beobachten, wie sich jede einzelne Farbe ändert ihr Blauwert erhöht wird wenn ihr Blauwert erhöht wird, unabhängig davon, ob der Rotwert gesenkt wird, obwohl sie während desselben Frames auftreten Bei Funktionsaufrufen gibt es eine weitere Möglichkeit, in die Funktion einzusteigen. Wenn wir diese Option wählen oder die Tastenkombination F 11 verwenden, springt der gelbe Pfeil stattdessen in die aufgerufene Funktion und führt diese Zeile für Zeile bis sie abgeschlossen ist. Wenn die Funktion abgeschlossen ist, kehrt der gelbe Pfeil zur ursprünglichen Funktion zurück, um mit der Ausführung dieser Funktion fortzufahren. Mit diesen Tools haben wir einen sehr konzentrierten Überblick darüber, einen sehr konzentrierten Überblick was unsere Klassen tun und wann, wie sie sich verhalten, und wir können sie in Zeitlupe beobachten um herauszufinden, was zu welchem bestimmten Zeitpunkt schief läuft welchem bestimmten Zeitpunkt schief läuft Wenn Sie ein Problem nicht selbst lösen können, ist die GDA-Community sehr hilfreich und immer bereit, Ihnen unter die Arme zu greifen Es gibt Discord-Server für GDA-Entwickler, einschließlich meines Servers, auf dem sich meine Schüler gegenseitig helfen Der Link zum Beitritt befindet sich in meinem Profil. Es gibt auch Online-Foren auf Websites wie Redit, in denen Sie auch Fragen stellen können Sie haben jetzt ein grundlegendes Verständnis der meisten GDScript-Syntax und der Tools, die benötigen, um diese Konzepte weiter zu untersuchen Wenn du bereit bist, frage mich bitte nach einem Rabattcode für einen meiner Spielprojekt-Kurse, und viel Glück 14. 1 3 Setup: Oh Freunde, willkommen zu meinem Kurs. Ich mache in Godot einen kompletten Plattformer mit zwei D-Pixeln. Um mit der Cado-Engine zu beginnen, musst du sie zuerst von ihrer Website herunterladen, zu GodoEngine.org gehen und Für diesen Kurs werde ich God Version 4.2 verwenden . Sobald der Download abgeschlossen ist, entpacke einfach den Ordner und führe die EX-Datei Stellen Sie sicher, dass Sie diese entpackten Dateien an einen geeigneten Speicherort auf Ich möchte, dass die Engine an meine Taskleiste angeheftet ist, meine Taskleiste Es gibt keine komplizierten Installationsprogramme, Hubs oder Speicherschnittstellen, durch die man sich Wenn Sie jemals mit anderen Game-Engines gearbeitet haben, Sie wahrscheinlich überrascht sein wie einfach und leicht es ist, Good zu verwenden Zum Vergleich: Wenn Sie bereit sind, klicken Sie auf die Schaltfläche Neues Projekt. Geben Sie Ihrem Projekt einen Namen. Dies ist oft derselbe wie der Titel Ihres Spiels, aber oft beginnen Spiele, ohne dass es noch einen offiziellen Titel gibt. Entwickler verwenden Dinge wie Untitled Platform oder Untitled Pirate bis ein offizieller Titel ausgewählt ist Wählen Sie aus, wo auf Ihrer Festplatte das Projekt gespeichert werden soll Ich empfehle, in Dokumenten einen Unterordner mit dem Namen Godot Projects zu erstellen und jedem Ihrer Projekte einen eigenen Ordner innerhalb dieses Ordners zuzuweisen, um sie zu organisieren Da das Spiel, das wir entwickeln werden, einfache Grafiken mit zwei D-Pixeln in zwei D-Szenen verwendet , können wir den Kompatibilitätsrenderer verwenden , der Desktop-, Mobil- und Webplattformen unterstützt und einfache Szenen wie unsere am schnellsten rendert Schließlich wird Gott standardmäßig die Kompatibilität mit der Github-Versionskontrolle optimieren , was sehr nützlich ist. Wenn Sie fertig sind, klicken Sie auf Create and It, um das Projekt zu erstellen und es zur Bearbeitung zu öffnen Das Projekt wird in einer leeren Drei-D-Szene geöffnet, aber wir machen ein 2-D-Spiel. Unter der Registerkarte Szene, die sich in der oberen linken Ecke befindet. Standardmäßig klicken Sie auf Zwei-D-Szene, um eine neue Zwei-D-Szene zu erstellen. Dadurch wird unsere Editor-Ansicht automatisch in den Zwei-D-Modus umgeschaltet . Wenn Sie jemals feststellen, dass sich Ihr Editor im Drei-D-Modus befindet, können Sie jederzeit mit den Schaltflächen oben im Editorfenster wechseln . Cado. Jede Szene ist als ein Baum von Knoten definiert Die Szene selbst ist als Knoten zwei definiert. Es ist ein Knoten zwei D, das ist der Stammknoten der Szene. Wir erstellen unsere Szenen, indem wir dem Szenenbaum Zweige hinzufügen. Klicken Sie auf die Plus-Schaltfläche unter der Registerkarte Szene, um dem Szenenbaum einen Knoten hinzuzufügen. Wie Sie sehen können, gibt es viele verschiedene Knotentypen. Geben Sie ein, beschriften Sie es in die Suchleiste und fügen Sie Ihrer Szene einen Labelknoten hinzu. Wählen Sie Ihren neuen Knoten aus. Die Eigenschaften von A-Knoten können im Inspektor-Tab bearbeitet werden, das sich auf der rechten Seite des Editorfensters befindet. Geben Sie standardmäßig eine beliebige Nachricht in den Textbereich ein. Wenn Sie fertig sind, speichern Sie Ihre Szene, indem Sie in der Menüleiste Szene auswählen und dann Szene speichern. Sie können auch die Tastenkombination Cart Control S oder den Befehl S verwenden , um Ihrer Szene einen Namen zu geben. Die Benennungskonvention für Godot besteht darin, Schlangenbuchstaben zu verwenden, was ausschließlich aus Kleinbuchstaben besteht Unterstriche anstelle von Klicken Sie auf die Schaltfläche Speichern, um Ihre erste Szene zu speichern. Wenn Sie fertig sind, klicken in der oberen rechten Ecke des Editorfensters auf die Schaltfläche Aktuelle Szene ausführen . Es ist das mit dem Play-Symbol auf einem Klapperbrett. Das ist noch keine sehr aufregende Szene, aber sie funktioniert. Klicken Sie auf das Stoppsymbol , um die Szene zu beenden. der Registerkarte Dateisystem, die sich standardmäßig in der unteren linken Ecke befindet , können Sie eine Liste aller Dateien sehen , aus denen Ihr Projekt besteht. Für jedes neue Godot-Projekt nur eine Ressourcendatei wird standardmäßig nur eine Ressourcendatei bereitgestellt, das Godot-Logo Klicken Sie auf das Logo und ziehen Sie es in Ihre Szene. Dadurch wurde dem Szenenbaum ein Sprite-2-D-Node mit dem Namen icon hinzugefügt und das Symbol als Sprites-Textur festgelegt Dies ist nur ein Bild, das auf den Bildschirm gezeichnet wird. Bereiten wir uns auf den nächsten Abschnitt des Kurses vor, indem wir einen festen Boden auf dem unser Charakter laufen und springen kann. Dafür müssen wir eine Kollision hinzufügen. Klicken Sie mit der rechten Maustaste auf den Symbolknoten und wählen Sie Untergeordneten Knoten hinzufügen. Suchen Sie in der Suchleiste nach dem Knoten Static Body Two D. Dadurch wird der neue Knoten als untergeordnetes Element des Sprites hinzugefügt, es wird jedoch eine Warnung angezeigt Wenn wir den Mauszeiger über das Warnsymbol bewegen , erhalten wir weitere Informationen Dieser Knoten kann mit nichts kollidieren , weil er nicht weiß, welche Form er Dazu benötigt der statische Body-Two-D-Knoten einen weiteren untergeordneten Knoten wie zuvor einen weiteren Knoten hinzufügen , suchen Sie dieses Mal nach Collision Shape Two D Node Das Warnsymbol auf dem statischen Körper Tu T Note ist verschwunden. Für den neu hinzugefügten Tut-Knoten mit Kollisionsform gibt es jedoch eine weitere Warnung. Es bittet uns Pole, dafür bitte eine Shape-Ressource zu erstellen. Dies erfolgt im Inspektorfenster über das Drop-down-Menü Shape Select New Rectangle Shape. Damit wurde die Warnung erfüllt. Aber wenn wir uns die Szene ansehen, können wir sehen, dass die Kollisionsform nicht mit dem Symbol übereinstimmt. Wenn wir möchten, dass die Kollision das gesamte Symbol abdeckt , müssen wir sie anpassen. Sie können auf die roten Kreise klicken und sie ziehen , um die Größe der Kollisionsform Wenn Sie eine genauere Steuerung wünschen, können Sie auf die Ressource Rechteck mit zwei D klicken , um sie zu erweitern. Dadurch werden Textfelder angezeigt, in die Sie exakte Werte für die Größe eingeben können Wenn die Kollisionsform außerhalb der Mitte liegt, können Sie den Transformationsabschnitt unter Knoten 2 D erweitern , um seine Position anzupassen Sie können diesen Wert auch manuell anpassen, indem Sie auf das Rote Kreuz klicken und es in die Mitte der Kollisionsform ziehen die Mitte der Kollisionsform Wählen Sie den Symbolknoten aus und benennen Sie ihn in Floor um. Da wir keine Anpassungen mehr an den untergeordneten Knoten vornehmen müssen , können wir diesen Knoten reduzieren indem wir auf den Kollapspfeil klicken. Lassen Sie uns nun eine tatsächliche Etage daraus machen. Passen Sie Ihre Ansicht im Viewport an, bis Sie den gesamten blauen Rand sehen können Da er sich mit der roten X-Achse überschneidet, erscheint der obere Rand des Felds magentafarben und die linke Seite, die sich mit der grünen Y-Achse überschneidet Kann dieses blaue Feld die Grenzen des Bildschirms bilden, wenn wir das Spiel mit dem ausgewählten Bodenknoten starten , seine Position, Größe und Form so anpassen, dass er den unteren Bildschirmrand bedeckt Wenn Sie die Alt - oder Optionstaste gedrückt halten, werden nur der ausgewählte Knoten und seine untergeordneten Knoten verschoben. Wir haben gerade aus nichts anderem als dem Godot-Symbol eine funktionale Etage für unsere Testumgebung für Spiele geschaffen aus nichts anderem als dem Godot-Symbol eine funktionale Etage für unsere Testumgebung nichts anderem als dem Godot-Symbol Diese Art von Arbeitsablauf ist in der Spieleentwicklung üblich. Verwenden von Platzhalter-Assets zur Erstellung eines Minimalprojekts, das für Prototypen und Demonstrationen von Spielmechaniken verwendet werden kann und Demonstrationen von Spielmechaniken Aber um ein Spiel zu machen, das gut aussieht, benötigen wir Ressourcen Ich habe diesen Kurs mit einem kostenlosen Asset-Paket namens Treasure Hunters erstellt, das von Pixel Frog erstellt wurde. Davon ausgehend werden diese Inhalte unter einer Creative Common Zero-Lizenz veröffentlicht. Sie können das Material in jedem Medium oder Format verteilen, remixen, anpassen und darauf aufbauen, auch für kommerzielle Zwecke Eine Quellenangabe ist nicht erforderlich. Sie können das gesamte Asset-Paket kostenlos herunterladen oder den Künstler optional unterstützen indem Sie einen beliebigen Geldbetrag zahlen Sobald der Download abgeschlossen ist, entpacken Sie den Ordner. Das Importieren der Assets ist so einfach wie das Klicken und Ziehen der Elemente in das Projektfenster Ich werde auch Soundeffekte und Musik verwenden , die von FreeSound.org heruntergeladen wurden . Die Loop-Bibliothek Victory War and Battle Music wurde von Little Robot Sound Factory komponiert Das Battle Sounds Pack wurde von Luke Sharpals erstellt. Diese Sound- und Musikdateien unterliegen einer Attributionslizenz Sie können weiterhin kostenlos für jeden Zweck verwendet werden, aber Sie müssen den Urheber dieser Inhalte angemessen den Urheber dieser Inhalte und einen Link zur Lizenz angeben Achte genau auf die Lizenzierungs- und Zuordnungsanforderungen der Inhalte, die du in deinen Spielen verwendest Das Importieren dieser Elemente funktioniert genauso wie das Artwork. Klicken Sie sie einfach an und ziehen Sie sie in den Editor. Diese Audiodateien sind jedoch viel größer als die Bilder und wir werden nicht viele davon verwenden. Ich empfehle, diese Assets nur zu importieren , wenn Sie sich entscheiden , jedes einzelne zu implementieren. Jetzt haben wir eine funktionsfähige Etage mit Kollision und allen Kunst-Assets, die wir benötigen, um mit dem nächsten Abschnitt zu beginnen, in dem es um die Implementierung eines Charakters geht. Wir sehen uns im nächsten Abschnitt. 15. 2 1 Charakter: Hallo Freunde. Im ersten Abschnitt haben wir das Projekt gestartet, einige Objekte importiert und eine funktionale Etage mit Kollision erstellt . In diesem Abschnitt konzentrieren wir uns darauf, einen Charakter zu erstellen , den der Spieler kontrollieren und mit dem er spielen kann. Zu Beginn erstellen wir zunächst die Knotenstruktur eines typischen Charakters im Szenenfenster. Klicken Sie auf die Plus-Schaltfläche, um dem Szenenbaum einen neuen Knoten hinzuzufügen. Suchen Sie nach einem Charakterkörper, Knoten zwei D, und erstellen Sie ihn. Ich benenne diesen Knoten in den Namen meines Charakters um. Genau wie beim Boden gibt es eine Warnung. Dieser Knoten hat keine Form. Er kann also nicht mit anderen Objekten kollidieren oder interagieren. Wir wissen bereits, wie wir dieses Problem beheben können. Fügen Sie einfach eine Kollisionsform zwei D-Knoten hinzu und definieren Sie deren Form. Die Warnung erinnert uns daran, dass wir im Inspektor eine Shape-Ressource erstellen müssen . Die meisten Charaktere in Spielen verwenden Kapseln als Kollisionsformen, weil sie sich leicht an die Gesamtform eines Humanoiden anpassen lassen an die Gesamtform eines Humanoiden anpassen und für die Engine einfach zu handhaben sind. Standardmäßig werden neue Knoten am Szenenursprung in der oberen linken Ecke hinzugefügt Szenenursprung in der oberen linken Lassen Sie uns die neuen Knoten vergrößern. Wir müssen auch sehen können, wie der Charakter aussieht. Dazu fügen wir der Figur einen weiteren untergeordneten Knoten hinzu, ein Sprite, zwei D. Wir haben in der vorherigen Lektion gesehen , dass es im Inspektorfenster eine Textureigenschaft für Sprites gibt , aber diese ist leer, wenn man das Asset-Paket für Schatzjäger durchsucht das Asset-Paket für Schatzjäger durchsucht Wählen Sie ein Charakter-Sprite aus, das Sie verwenden möchten. Standardmäßig möchte ich nicht, dass mein Charakter standardmäßig mit dem Schwert ausgestattet Ich wähle aus dem Ordner „Ohne Schwert“ und wähle dann den Ordner „Inaktiv“. Jetzt können wir den Charakter so sehen, wie er im Spiel gezeichnet wird , aber er ist verschwommen liegt daran, dass die Standard-Projekteinstellungen von Godo nicht für Pixelkunst optimiert sind Um dieses Problem zu beheben, wählen Sie in der Menüleiste ein Projekt und dann Projekteinstellungen aus der Menüleiste ein Projekt und dann Projekteinstellungen Es gibt viele Projekteinstellungen und je nach Ihrer Version von Godot sie möglicherweise nicht auf die gleiche Weise organisiert oder benannt Wenn Sie Probleme haben, Projekteinstellungen zu finden , befindet sich oben im Fenster eine Suchleiste mit der Bezeichnung Filtereinstellungen Wir müssen die Einstellungen für das Rendern von zwei D-Texturen finden Rendern von zwei D-Texturen dann den Standard-Texturfilter von linear auf nächstliegende ändern . Dadurch wird verhindert, dass die Grafik-Engine versucht, die Textur zu glätten und einfach so zu zeichnen, wie es auf dem Bildschirm ist. Mit den vorgenommenen Änderungen können wir das Fenster schließen und der Charakter wird jetzt in perfekt definierten Pixeln gezeichnet. Bei der Arbeit mit Pixelkunst ist dies im Allgemeinen die bevorzugte Ästhetik. Dabei markieren die rote X- und die grüne Y-Achse den Ursprung der Szene. Wir sollten davon ausgehen , dass der Ursprung des Charakters zu seinen Füßen liegt. Ziehen wir den Spread nach oben, bis die rote X-Achse als Boden dient , auf dem der Charakter stehen wird. Achten Sie darauf, dass sie auch auf der grünen Y-Achse zentriert sind. Um das Anpassen der Kollisionsform zu vereinfachen, ordne ich sie neu an, sodass sie sich im Szenenbaum unter dem Sprite befindet, der Charakter aber trotzdem aus der Kindheit Dadurch wird auch bestimmt, in welcher Reihenfolge die Knoten auf dem Bildschirm gezeichnet werden Wenn sich die Kollisionsform vor dem Sprite befindet, ist es einfacher, ihn zu bewegen und seine Größe an den Charakter anzupassen seine Größe an den Charakter Denke daran, dass der untere Punkt der Kollisionskapsel mit den Füßen und der roten X-Achse des Charakters übereinstimmen sollte den Füßen und der roten X-Achse des Charakters roten X-Achse damit der Charakter sauber auf dem Boden stehen Und sollte auch um die grüne Y-Achse zentriert sein. In zwei D-Spielen wie diesem wird es allgemein als gute Praxis angesehen, die Kollisionsform kleiner als den Charakter zu machen . Dadurch wird verhindert, dass der Spieler von Angriffen getroffen wird, von denen er annehmen würde, dass er sich in der Nähe von Mrs. befindet, und ermöglicht es ihm, näher an die Umgebung heranzukommen. vor dem nächsten Schritt sicher, dass Ihr Dateisystem-Panel auf den Root-Ressourcenordner ausgerichtet ist . Neue Ressourcen werden in dem Ordner erstellt , mit dem Sie zuletzt interagiert haben Im Dateisystemfenster können Sie alle geöffneten Ordner reduzieren und auf das leere Feld klicken Wenn dein Versicherer das richtig gemacht hat, klicke auf deinen Charakter Wir können jeden Zweig in unserem Szenenbaum nehmen und ihn als eigene Szene speichern Ich benenne diese neue Szene nach dem Charakter, den sie bereits erstellt hat, da sie standardmäßig den Namen des Knotens als neuen Szenennamen verwendet. Jetzt ist Roger ihre eigene Szene getrennt von der Szene, an der wir gearbeitet haben. Rogers Knoten im Szenenbaum hat eine Klapperboard-Schaltfläche und die untergeordneten Knoten wurden ausgeblendet Ein Klick auf die Klappe öffnet Rogers Szene. Dadurch können wir Roger isoliert bearbeiten. Alle Änderungen, die wir hier vornehmen werden auf alle Szenen übertragen , die Roger in der Hauptszene enthalten. Wir können Roger jetzt vom Ursprung der Szene auf den Boden verschieben Ursprung der Szene auf , wo sie auf dem Bildschirm gezeichnet werden. Wenn wir die aktuelle Szene durchspielen, können wir Roger über dem Boden schweben sehen, aber er sollte wahrscheinlich aufgrund der Schwerkraft auf den Boden fallen Schwerkraft auf den Boden fallen Damit Roger sich wie ein Charakter verhält, müssen wir der Rogers-Szene einen Skriptschalter hinzufügen und den Root-Node auswählen Klicken Sie dann auf das Scrollfeld mit Plus-Schaltfläche, um ein neues Skript hinzuzufügen Es empfiehlt sich, allgemeine Verhaltensweisen so allgemein wie möglich zu schreiben allgemeine Verhaltensweisen so allgemein wie möglich Dieses Drehbuch sollte nicht Roger sein. Stattdessen benenne ich den Skriptcharakter und schreibe das Skript so , dass es auf jedes Zeichen angewendet werden und schreibe das Skript so kann. Roger Godot bietet nicht nur eine Standardvorlage für Skripte, Roger Godot bietet nicht nur eine Standardvorlage für die an bestimmte Knoten angehängt Wir werden sehen, was in dieser Vorlage enthalten ist. Standardmäßig erbt das Skript das Verhalten des Knotentyps, an den es angehängt ist, in diesem Fall einen Zeichenkörper zwei D. Wir werden alle unsere Skripte in Goidos Muttersprache, dem Godot-Skript, schreiben Goidos Muttersprache, dem Godot-Skript, Klicken Sie auf Erstellen, um das neue Skript zu erstellen und es an den Knoten anzuhängen Das Hauptfenster wechselt automatisch zur Skriptansicht und öffnet das Skript zur Bearbeitung. Wie Sie sehen können, verfügt die Vorlage bereits über mehrere Funktionen. Der Charakter hat eine Geschwindigkeit und eine Sprunggeschwindigkeit. Diese werden in Pixeln pro Sekunde gemessen. Es gibt auch eine Gravitationskraft , die durch die Projekteinstellungen festgelegt wird In der physikalischen Prozessfunktion können wir sehen, dass die Schwerkraft auf den Charakter wirkt, wenn er sich nicht auf dem Boden befindet Eine Sprungtaste wurde implementiert, um die Sprunggeschwindigkeit zu erhöhen. Beim Drücken der Benutzeroberfläche , mit Ausnahme der Leertaste, gibt es eine Richtungssteuerung für Richtung nach links und rechts, sodass der Charakter bewegen und anhalten Nach innen bewegen“ ist eine integrierte Funktion , die die Position, Geschwindigkeit und äußere Kräfte des Charakters berücksichtigt , Geschwindigkeit und äußere Bestimme dann, wo sich der Charakter nach Ablauf der Delta-Zeit befinden wird nach Ablauf der Delta-Zeit befinden Mit den Standardeinstellungen wird dieser Code 60 Mal pro Sekunde ausgeführt Wenn wir die aktuelle Szene ausführen, werden wir sehen, wie Roger vom Ursprung der Szene fällt. Aber das ist Rogers-Szene, sie ist nicht dafür gedacht, gespielt zu werden Wechseln Sie zurück zur Hauptszene und schalten Sie die Ansicht auf zwei D. Wenn wir diese Szene abspielen, können wir sehen, wie Roger sofort zu Boden fällt Durch Drücken der Leertaste springt Roger. Durch Drücken der linken und rechten Pfeiltasten bewegt sich Roger nach links und rechts Diese Implementierung der Steuerung ist nicht sehr gut, bietet aber einen Ausgangspunkt von dem aus wir unser Spiel aufbauen können. Jetzt wird ein einfacher Charakter mit grundlegenden Steuerelementen und Physik auf den Bildschirm gezeichnet . In der nächsten Lektion werden wir uns darauf konzentrieren, unsere Spielersteuerung zu verbessern. Wir sehen uns in der nächsten Lektion. 16. 2 2 Input: Hallo Freunde. In der vorherigen Lektion haben wir einen einfachen Charakter mit einer Spraykollisionsphysik und grundlegenden Eingaben erstellt. In dieser Lektion richten wir eine bessere Eingabeverarbeitung ein, um unseren Charakter steuern zu können. Lassen Sie uns diese Lektion mit etwas Hausarbeit beginnen. Wie Sie sich vorstellen können, wird unser Spiel viele verschiedene Ressourcen enthalten. Und es ist wichtig, sie zu organisieren, damit wir schnell und einfach alle Ressourcen finden können , die wir benötigen, oder? Kochen im Stammordner oder in einer leeren Stelle. Erstellen Sie einen neuen Ordner und geben Sie ihm einen Namen. Skripten und ziehen Sie dann das Zeichenskript in den Ordner. Dann wiederhole den Vorgang mit den Szenen. Aber wir haben zwei verschiedene Arten von Szenen. Wir können sie mit einem Unterordner innerhalb des Szenenordners mit dem Namen Charaktere weiter unterscheiden einem Unterordner innerhalb des Szenenordners und Roger in diesem Unterordner platzieren Wenn Sie fertig sind, wechseln Sie zur Skriptansicht. Ein weiterer Blick auf die Standardvorlage für das D-Skript Character Body Two nicht wirklich unseren Bedürfnissen. Wir haben dieses Skript Character genannt und planen, dies auf jeden Charakter in unserem Spiel anzuwenden, von denen die meisten nicht vom Spieler gesteuert werden. Es ist wichtig, die Funktionalität für dieses Skript zu isolieren und in verschiedene Skripte zu unterteilen, die wir verwenden, um die Eigenschaften und das Verhalten von Charakteren zu beschreiben . Wir sollten jegliche Eingabebehandlung entfernen. Ich kommentiere diese Zeilen, indem K oder Befehl K drücke Anwenden von Schwerkraft - und Bewegungseingaben während des physikalischen Prozesses ist immer noch nützlich. Aber lassen Sie uns dem Skript einige öffentliche Methoden hinzufügen, um genau zu beschreiben, was ein Charakter tun kann. In unserem Spiel kann ein Charakter nach links oder nach rechts schauen. Vorerst lassen wir den Hauptteil dieser Methoden einfach leer, indem wir schreiben, übergeben oder zurückgeben. Ein Charakter kann rennen, was eine Richtung erfordert , um zu wissen, ob er sich nach links oder rechts bewegt. Wir können die Richtung als Gleitkommazahl darstellen, was eine Zahl ist, die Dezimalwerte erlaubt. Dies ist nicht nur nützlich, um die Richtung zu kennen, sondern ermöglicht auch eine variable Geschwindigkeit. Wir müssen diesen Wert in einer Variablen speichern , damit er beim nächsten physikalischen Prozess verwendet werden kann . Definieren wir in unserem Skript eine private lokale Variable namens underscore direction legen dann ihren Wert in der Run-Funktion Wir können den physikalischen Prozess auch so bearbeiten, dass diese Variable anstelle der zuvor verwendeten verwendet wird Ein Charakter kann auch springen, aber dafür benötigen wir keine Parameter. Befindet sich die Figur auf dem Boden, addieren Sie die Sprunggeschwindigkeit zur Y-Geschwindigkeit der Figur. Dies werden unsere öffentlichen Methoden sein, mit denen andere Skripte jeden Charakter in unserem Spiel steuern können . Wir werden dem Skript weitere Methoden hinzufügen, wenn wir unseren Charakteren zusätzliche Verhaltensweisen hinzufügen. Andere Methoden wie Physics Process, die sich nicht auf andere Skripte beziehen, sind mit einem vorangestellten Unterstrich gekennzeichnet, genau wie die Richtungsvariable des Unterstrichs Diese sind nicht dafür gedacht, von anderen Skripten verwendet zu werden, sie sind nur für dieses Wenn ein anderes Skript die Richtung eines Charakters steuern möchte , sollte es stattdessen die Run-Methode aufrufen, da die Run-Methode öffentlich ist. Dadurch entsteht ein universeller Satz klar benannter Verhaltensweisen, die beschreiben, wie sich ein Charakter zu unserem Vorteil verhalten wird. Eine Praxis, die in der Programmierung als Kapselung bekannt ist. Der Inhalt dieser Methoden, Variablen und des physikalischen Prozesses andere Skripte nicht wichtig Die anderen Skripte müssen nicht wissen, wie der Charakter springt, sie müssen nur wissen, dass es sich um einen Charakter handelt und er sich verstecken kann Die Einzelheiten der Implementierung von Funktionen werden in der Programmierung als Abstraktion bezeichnet Durch diese Methoden werden Ihre Skripte viel besser organisiert, leichter zu verstehen, zu verwenden und für andere Zwecke anzupassen Das sieht langsam nach einem besseren Charakterskript aus, aber wir haben dem Spieler die Möglichkeit genommen , den Charakter zu kontrollieren, weil wir wollen, dass das durch einen separaten Drehbuchwechsel zur Hauptszene erledigt wird . Falls du noch nicht da bist, klicke mit der rechten Maustaste auf deinen Charakter und füge einen untergeordneten Knoten hinzu. Dieser Knoten benötigt keinen Typ. Es kann einfach ein einfacher Knoten sein und ihn Player nennen. Wir verwenden ihn nur, um dem Charakter ein zusätzliches Skript anzuhängen. Als Nächstes schreiben wir im Dateisystemfenster, klicken wir auf den Skriptordner, um ein neues Skript zu erstellen und es Player zu nennen. Hängen Sie es dann an den neuen Knoten an. Klicken Sie auf das Skriptsymbol, um das Skript zur Bearbeitung zu öffnen. Der Zweck des Skripts darin, Eingaben entgegenzunehmen und daraufhin die entsprechenden Methoden im Zeichenskript aufzurufen daraufhin die entsprechenden Methoden im . Das bedeutet, dass wir auf den Charakter verweisen müssen . Wenn Sie sich erinnern, hängen wir dieses Skript an einen untergeordneten Knoten des Charakterknotens an. Wir können leicht einen Verweis auf den Zeichenknoten erhalten , indem oben im Skript eine Variable deklarieren Wir werden diese Variable Unterstrichzeichen nennen, weil nur dieses Skript auf sie zugreifen und ihren Wert zuweisen muss, um das übergeordnete Element zu erhalten die Deklaration mit on ready beginnen, können wir dieser Variablen einen Wert zuweisen , nachdem der Knoten erstellt wurde, den Szenenbaum betreten hat und bereit ist, mit der Ausführung zu beginnen bedeutet, dass der Knoten zu diesem Zeitpunkt weiß, wer sein übergeordneter Knoten ist. Um Eingaben zu empfangen und zu verarbeiten, werden wir zwei verschiedene Methoden verwenden Underscore-Prozess und Underscore-Eingabe Die Eingabemethode ist effizienter , wenn es darum geht, Ereignisse beim Drücken und Loslassen von Tasten zu verarbeiten Diese Methode verwendet einen Parameter, der normalerweise als Ereignis bezeichnet wird, und sein Typ ist Eingabeereignis. Wir müssen lediglich das Ereignis überprüfen, um zu sehen, ob der Spieler die Sprungtaste gedrückt hat. Wenn sie das getan haben, werden wir dem Charakter sagen, dass er springen soll , wie der physikalische Prozess. Underscore Process Delta als Parameter. Dabei handelt es sich um einen Float-Typ, der die Zeit angibt , die seit dem letzten Vorgang vergangen Normalerweise eine 60stel-Sekunde. Aber da wir hier nicht den Wert von Delta verwenden werden, können wir seinem Namen einen Unterstrich voranstellen, sodass die Goodot-Engine weiß, dass wir diesen Wert nicht in der Prozessmethode benötigen , die jeden Frame ausführt, unabhängig davon , ob eine Eingabe gegeben oder geändert wurde oder nicht In jeder Weise können wir den Status unserer Bewegungseingaben überprüfen Auf diese Weise können wir sowohl Tastendrücke als auch analoge Stickachsen einfacher und austauschbarer handhaben analoge Stickachsen einfacher und austauschbarer Wir rufen hier character do run übergeben das Argument der Eingabe get axis, run left als negativen Wert und run right als positiven Sie haben vielleicht bemerkt, dass die Standardeingaben „Ich akzeptiere“, Benutzeroberfläche links“ und „Benutzeroberfläche rechts“ lauteten. Dabei handelt es sich um integrierte Eingabezuordnungen zur Steuerung von Benutzeroberflächen Da wir unterschiedliche Namen für die Eingabe-Mappings verwendet haben , müssen wir diese zu den Projekteinstellungen hinzufügen , bevor sie funktionieren Öffnen Sie die Projekteinstellungen und wechseln Sie zur Registerkarte zur Eingabemap Wenn Sie auf den Schalter Integrierte Aktionen anzeigen klicken, können Sie die Eingabeaktionen sehen, die zuvor verwendet wurden Sie können diese Zuordnungen mit demselben Umschalttyp wieder ausblenden. Gehen Sie nach links in das Feld Neue Aktion hinzufügen und klicken Sie auf die Schaltfläche Wiederholen Sie den Vorgang für „Nach rechts ausführen“ und Springen“, um jede dieser Optionen einer Schaltfläche zuzuordnen. Klicken Sie auf die Plus-Schaltfläche auf der rechten Seite. Dadurch wird ein Popup-Fenster geöffnet, in dem Sie eine beliebige Eingabe für Tastatur, Maus oder Joypad auswählen können beliebige Eingabe für Tastatur, Maus oder Joypad auswählen Sie können die Suchleiste verwenden, um die Optionen zu filtern, oder ein Listening-Feld verwenden , um sie automatisch zu erkennen Für „Nach links laufen“ verwende ich die A-Taste. Dann wiederhole den Vorgang, um eine Taste für „Nach rechts laufen“ und „springen“ hinzuzufügen . Du kannst jeder Zuordnung auch mehrere Buttons hinzufügen , damit deine Spiele reibungslos funktionieren. Bei einem Gamepad verwende ich den linken Stick zum Laufen und die untere Taste zum Springen. Wenn du fertig bist, versuche, die Szene auszuführen und deine neuen Eingabezuordnungen zu testen , um den Charakter zu steuern Alles sollte genauso funktionieren wie zuvor, aber jetzt werden die Eingabeverarbeitung und die Charaktersteuerung von separaten Skripten behandelt Mit dieser Methode können Sie sich vorstellen, wie der Charakter den der Spieler kontrolliert, austauschbar werden kann Das Skript zur Eingabeverwaltung könnte auch durch ein KI-Skript ersetzt werden , um andere Charaktere in Ihrem Spiel ganz einfach zu steuern andere Charaktere in Ihrem Spiel ganz einfach Wir haben jetzt eine bessere Eingabeverwaltung für die Steuerung eines Charakters in deinem Spiel. In der nächsten Lektion werden wir uns darauf konzentrieren, das Gefühl der Fortbewegungs - und Sprungmechanik zu verbessern das Gefühl der Fortbewegungs - und Sprungmechanik Wir sehen uns in der nächsten Lektion. 17. 2 3 Fortbewegung: Hallo Freunde. In der vorherigen Lektion haben wir die Eingabeverarbeitung unseres Charakters verbessert, indem ihn in einem eigenen, von unserem Charakter getrennten Skript isoliert von unserem Charakter getrennten Skript In dieser Lektion wird dafür gesorgt, dass sich die Bewegungssteuerung des Charakters für den Spieler besser anfühlt Wenn du die Hauptszene durchläufst und darauf achtest, wie die linke und rechte Bewegung anfühlt, ist sie sehr starr Die Bewegungsgeschwindigkeit ist augenblicklich und konstant, was nicht der Art entspricht, wie sich Menschen oder andere Objekte wirklich bewegen Öffne das Charakterskript , um realistischere Bewegungen zu simulieren Wir können tatsächlich Variablen aus der realen Physik verwenden . In Wirklichkeit beschleunigt ein Objekt allmählich bis zu seiner Höchstgeschwindigkeit und beschleunigt auch. Hier oben im Skript hat Godot einen konstanten Wert für die Geschwindigkeit der Charaktere definiert Wert für die Geschwindigkeit der Charaktere Fügen wir hier zwei neue Variablen hinzu, um die Beschleunigung und Verzögerung darzustellen, die wir in Pixeln pro Quadratsekunde messen Diese können privat sein, denen ein Unterstrich vorangestellt wird, und sie werden Wir geben ihnen vorerst Anfangswerte. Ich verwende einfach denselben Wert als Geschwindigkeit und passe sie später an, nachdem ich getestet habe, wie sie sich anfühlen. Jetzt muss der Physikprozess diese Werte verwenden, um die Geschwindigkeit des Charakters zu berechnen. Wenn wir uns zuerst den Else-Block ansehen, der Charakter hier ab bremst der Charakter hier ab, wenn der Spieler keine Eingaben macht Alles, was wir hier tun müssen, ist Geschwindigkeit auf Verlangsamung umzustellen. Diese nützliche Funktion namens Move Toward beginnt beim Wert der Geschwindigkeit x und bewegt sich um ein gewisses Maß an Verzögerung in Richtung Null Dies funktioniert sowohl für die linke als auch für die rechte Richtung gut, da das Erreichen eines Stillstands bedeutet, dass die Geschwindigkeit gegen Null bewegt wird die Geschwindigkeit gegen Null bewegt Wenn Sie jedoch nach oben schauen, wird der Gravitationswert mit Delta multipliziert Denken Sie daran, dass dieser Code 60 Mal pro Sekunde ausgeführt wird. Und wir geben unsere Verzögerungsrate in Einheiten von Pixeln pro Quadratsekunde Wir können den Wert der Verzögerung mit Delta multiplizieren , um seinen Wert an die Zeit anzupassen , die seit dem letzten physikalischen Prozess vergangen ist Dann können wir den F-Block so umschreiben, dass er dieselbe Funktion verwendet und die Beschleunigung Diesmal beginnen wir mit Geschwindigkeit x bewegen uns mit einer Geschwindigkeit multipliziert mit Delta in Richtung Geschwindigkeit mal Richtung einer Geschwindigkeit multipliziert mit Delta in Denken Sie daran, dass wir dieses Skript für jeden Charakter in unserem Spiel verwenden können und wir möglicherweise nicht möchten, dass jeder Charakter die exakt gleiche konstante Geschwindigkeit hat Lassen Sie uns zunächst die Geschwindigkeit von einer konstanten in eine private Variable ändern und die Beschleunigungsformel entsprechend bearbeiten . Als Nächstes können wir am Anfang dieser Variablendeklarationen at export hinzufügen , um sie für andere Teile der Godot-Engine, nämlich den Inspektor, zugänglich zu machen andere Teile der Godot-Engine, nämlich den Inspektor, Wenn wir zur Charakterszene wechseln und den Wurzelknoten auswählen, werden Sie diese Variablen jetzt im Inspektor sehen und können ihre Werte bearbeiten Auf diese Weise kann jeder Charakter seine eigenen Bewegungs-, Geschwindigkeits-, Beschleunigungs- und Verzögerungswerte definieren Geschwindigkeits-, Beschleunigungs- und Verzögerungswerte Sie müssen nicht alle dieselben konstanten Werte haben. Kehren Sie zur Hauptszene zurück und versuchen Sie, mit diesen neuen Werten zu spielen. Du kannst sehen, wie der Charakter allmählich beschleunigt und sich ebenfalls verlangsamt Da wir für die Beschleunigung und Verzögerung den gleichen Wert wie die Geschwindigkeit des Charakters verwendet haben, wissen wir, dass die Zeit, die benötigt wird, um die Höchstgeschwindigkeit zu erreichen, genau 1 Sekunde beträgt Ebenso beträgt die Zeit, die der Charakter benötigt vollständig zum Stillstand zu kommen, ebenfalls 1 Sekunde Wir können diese Werte schnell und einfach vom Inspektor aus anpassen einfach vom Inspektor aus auch wenn die Szene abgespielt wird. Auf diese Weise können wir schnell testen und ausprobieren, wie sich unterschiedliche Werte für unsere Variablen auf das Spiel auswirken, und herausfinden , welche Werte am besten funktionieren. Ich denke, dass der Charakter in einer halben Sekunde die Höchstgeschwindigkeit erreichen und in einer Viertelsekunde zum Stillstand kommen sollte in einer halben Sekunde die Höchstgeschwindigkeit erreichen . Wir werden die Werte für Beschleunigung und Verzögerung entsprechend um den Faktor 2,4 erhöhen Beschleunigung und Verzögerung entsprechend um den Faktor , probieren wir es aus Das fühlt sich für mich besser an, wenn Sie Ihre Beschleunigungsrate niedriger eingestellt haben Ihre Beschleunigungsrate als Ihre Verzögerungsrate Wenn Sie jedoch versuchen, während der Bewegung die Richtung zu wechseln, fühlt sich die Umleitung sehr unnatürlich an Das liegt daran, dass du erwartest, dass der Charakter auf Null abbremst und dann in die entgegengesetzte Richtung beschleunigt Der geschriebene Code besagt jedoch , dass sie einfach von der falschen Richtung in die richtige Richtung beschleunigen sollten von der falschen Richtung in die richtige Richtung beschleunigen Richtung in die richtige Richtung Damit sich das besser anfühlt, können wir die if-Anweisung so ändern, dass zuerst prüft, ob die Richtung Null ist . In diesem Fall sollte das Zeichen langsamer werden Als Nächstes können wir, da wir wissen, dass die Richtung nicht Null ist, überprüfen, ob die Geschwindigkeit x Null ist, was bedeutet, dass der Charakter stationär ist und ihm sagen, dass er beschleunigen soll Wir benötigen auch die Bedingung, dass der Richtungssinus dem Sinus der Geschwindigkeit x entspricht, was bedeutet, dass sie sich bereits bewegen und der Spieler sich weiterhin in dieselbe Richtung bewegen möchte. Unsere letzte Möglichkeit ist, wenn weder Richtung noch Geschwindigkeit Null sind und ihre Sinus nicht übereinstimmen, was bedeutet, dass der Spieler sich in die entgegengesetzte Richtung bewegen möchte, in die sich der Charakter bewegt In diesem Fall können wir uns stattdessen mit einer verlangsamten Geschwindigkeit in Richtung Geschwindigkeit bewegen einer verlangsamten Geschwindigkeit in Richtung Geschwindigkeit Dies wird sich viel natürlicher anfühlen, wenn der Spieler versucht, sich umzudrehen, während Lass es uns viel besser ausprobieren, bevor wir weitermachen. Ich persönlich mag es nicht wirklich , in Pixeln zu denken, vor allem, weil es sich dabei nur um Platzhalter-Assets handeln könnte nur um Platzhalter-Assets handeln Was wäre, wenn du dich dafür entscheiden würdest , dieses Spiel mit einem anderen Asset-Paket zu machen , das 64-Pixel-Kacheln anstelle von 32 Pixeln verwendet 64-Pixel-Kacheln anstelle von 32 Pixeln Jetzt werden nicht alle deine Mechaniken gleich funktionieren, und jeder Wert muss an die neue Pixelgröße deiner Objekte angepasst werden . Stattdessen ziehe ich es vor, mir meine Mechanik in Einheiten von Kacheln pro Sekunde, in Pixeln pro Sekunde vorzustellen. Das wäre ein projektweiter konstanter Wert , auf den viele verschiedene Skripte schnell und einfach zugreifen müssen. Dazu können wir einen neuen Skriptordner namens auto loads erstellen und dann in diesem Ordner ein neues Skript namens global erstellen. Dieses Skript muss keinen Code ausführen. Es wird nur zum Speichern von Variablen verwendet , wenn sie vom gesamten Projekt verwendet werden. Wie in diesem Beispiel können wir unsere Variable in diesem Skript, PPT oder Pixel pro Kachel deklarieren . Es ist eine Ganzzahl, eine Zahl ohne Dezimalstellen, und ihr Wert wird 32 sein. Aber wie greifen andere Skripte auf diesen Wert zu? Öffnen Sie die Projekteinstellungen und wechseln Sie zur Registerkarte Automatisches Laden. Dies ist eine Liste von Skripten , die beim Start Ihres Spiels automatisch geladen werden und dort bleiben, bis es geschlossen wird. Sie können auch von allen anderen Skripten über ihren Knotennamen aufgerufen werden. Klicken Sie auf das Ordnersymbol, um einen Browser zu öffnen und Ihr globales Skript zu finden. Der Name des Skripts wird verwendet, um den Knotennamen automatisch zu generieren. Klicken Sie auf die Schaltfläche Hinzufügen und fügen Sie sie der Liste der automatisch geladenen Knoten im Zeichenskript hinzu. Wir können die Werte unserer neuen Variablen so anpassen, dass sie in Einheiten von Kacheln statt in Pixeln definiert werden . Meiner Meinung nach ist es sinnvoller, dass sich der Charakter einer Geschwindigkeit von acht Kacheln pro Sekunde bewegt, anstatt mit 300 Pixeln pro Sekunde. Wenn ich mich dafür entscheide , zu einem Asset-Paket zu wechseln das 64-Pixel-Kacheln verwendet, funktionieren alle meine Mechaniken immer noch gleich. Alles, was ich ändern müsste, ist der eine Wert im globalen Autoload-Skript. Wenn Sie es vorziehen, Pixel als Haupteinheit zu verwenden, gerne weiterhin tun. Wenn wir unser Spiel beginnen. Cado führt automatisch eine Methode auf jedem Knoten aus , wenn er bereit ist. Sie trägt den treffenden Namen underscore ready treffenden Namen underscore Bei dieser Methode multiplizieren wir einfach jeden dieser Werte mit einem globalen Punkt, um sie in Pixeleinheiten umzurechnen Unser Charakter beschleunigt jetzt und läuft realistischer In der nächsten Lektion werden wir die Sprung- und Schwerkraftmechanik verbessern Sprung- und Schwerkraftmechanik Wir sehen uns in der nächsten Lektion. 18. 2 4 Jump: Hallo Freunde. In der vorherigen Lektion haben wir die Bewegungsmechanik des Charakters verbessert In dieser Lektion werden wir ähnliche Anpassungen am Springen und an der Schwerkraft des Charakters Wenn wir die Hauptszene durchspielen und versuchen zu springen, werden Sie feststellen, dass der Charakter sehr hoch springt und lange in der Luft schwebt Es fühlt sich nicht wirklich gut sich das Charakterskript anzusehen Die Sprunggeschwindigkeit ist ein weiterer beliebiger konstanter Wert , der nicht wirklich unseren Bedürfnissen entspricht. Definieren wir stattdessen, dass unsere Charaktere so springen wie viele Steine sie springen können sollen. Dabei handelt es sich um eine exportierte private Variable mit dem Namen underscored jump height vom Typ float Und ich werde einen Standardwert von 2,5 verwenden , obwohl das nicht gerade realistisch Auf diese Weise kann der Spieler auf eine Plattform springen, unter der er auch hindurchgehen könnte. Wir müssen dies auch mit dem globalen Bt multiplizieren. Bei der Ready-Methode müssen wir vor Spielbeginn die Geschwindigkeit berechnen, die der Charakter benötigt, um diese Sprunghöhe zu erreichen. Wir können die Sprunggeschwindigkeitskonstante durch eine private Variable ersetzen , um diesen Wert zu speichern. Da sie zur Laufzeit berechnet wird, muss sie nicht exportiert werden. Diese Berechnung kann der Ready-Methode hinzugefügt werden. Zweitens kann die Sprunggeschwindigkeit anhand der Quadratwurzel der Sprunghöhe multipliziert mit der Schwerkraft multipliziert mit zwei berechnet Quadratwurzel der Sprunghöhe multipliziert mit der werden Wir können die Quadratwurzel nicht für eine negative Zahl verwenden , sie muss positiv sein Zum Glück ist in zwei D-Spielen die Y-Achse invertiert. Die Schwerkraft wird bereits als positiver Wert ausgedrückt. Unser Ergebnis für die Sprunggeschwindigkeit ist jedoch ebenfalls eine positive Zahl. Folglich müssen wir mit minus eins multiplizieren , damit der Charakter nach oben und nicht nach unten springt. Jetzt können wir die Sprungmethode bearbeiten , um diese neue Variable zu verwenden. Wenn wir es testen, springt der Charakter genau 2,5 Kacheln hoch, wenn wir die Sprungtaste drücken, aber der Sprung ist immer noch langsam und schwebt. Um das zu beheben, können wir die Projekteinstellungen öffnen und den Wert der Schwerkraft ändern. Entweder durch Filtern der Einstellungen oder durch Klicken auf Physik zwei D können wir die Standardeinstellung für die Schwerkraft finden. Diese ist auf 980 Pixel pro Quadratsekunde eingestellt. Stattdessen gebe ich die Berechnung direkt in das Feld beginnend mit 9,8, was der Schwerkraft auf der Erde entspricht, multipliziert mit einer Kachelgröße von 32 Pixeln, dann mit acht multipliziert, was mir einen Wert von 2508 0,8 ergibt, mir einen Wert von 2508 0,8 ergibt was ungefähr dem 2,5-fachen Dadurch fühlt sich alles im Spiel schwerer an und fällt schneller, was dem Spieler realistischer erscheint Jetzt fühlt sich der Sprung viel besser an, aber ich möchte dem Spieler die Möglichkeit geben kontrollieren, wie hoch der Charakter springt Es gibt viele verschiedene Möglichkeiten Spiele diese Funktion implementieren , zum Beispiel zu messen, wie lange die Sprungtaste gedrückt gehalten wurde, bevor sie losgelassen wurde Das Hinzufügen einer anfänglichen Sprungkraft, einer zusätzlichen Kraft in jedem Frame für kurze Zeit nach einer schlechten Ausführung usw. kann dazu führen, dass die Steuerung frustrierend ist, nicht reagiert oder Charaktere das Gefühl haben, ein Jetpack zu tragen Meine persönliche Lieblingslösung dafür ist sehr einfach und fühlt sich sehr gut an, wenn der Spieler reagiert Halte den Spieler einfach davon ab sich nach oben zu bewegen, wenn die Sprungtaste im Charakterskript losgelassen wird . Unter der Jump-Methode können wir eine Stop-Jump-Methode hinzufügen. Denken Sie daran, dass die Y-Achse invertiert ist. In zwei D-Spielen befindet sich der Nullwert für Y oben auf dem Bildschirm, und positive Werte bewegen sich nach unten Wenn die Geschwindigkeit y der Charaktere kleiner als Null ist, was bedeutet, dass sie sich nach oben bewegen, können wir sie auf Null setzen, um zu verhindern, dass sie sich nach oben bewegen. Dann beginnt die Schwerkraft , sich nach unten zu bewegen. Der Spieler nimmt dies so wahr, als ob er seine Sprungstange steuert , indem er die Sprungtaste gedrückt hält und wieder loslässt. Wir müssen nur diese neue Methode aus dem Player-Skript aufrufen . Wenn der Spieler die Sprungtaste loslässt, wenn das Ereignis ausgelöst wird, springen, dann stoppt der Charakter den Sprung. Lass es uns jetzt ausprobieren. Wir können leicht kontrollieren, wie hoch der Charakter springt, indem wir die Sprungtaste loslassen , bevor er seine maximale Spitze erreicht Dies ist einfach zu implementieren und effektiv, damit der Spieler das Gefühl hat, die volle Kontrolle zu haben Das Letzte, worauf ich in dieser Lektion eingehen möchte , ist, dass der Spieler genauso viel Kontrolle über die Bewegung des Charakters in der Luft hat genauso viel Kontrolle über die Bewegung des Charakters in der wie am Boden. Realistisch gesehen gäbe es beim Springen so etwas wie eine Luftzirkulation In den meisten Videospielen gibt es jedoch eine Luftregelung, um dem Spieler die Kontrolle über den Charakter Dies kann vor allem bei Plattformspielen nützlich sein, da es dem Spieler ermöglicht , Fallstricke zu vermeiden oder umzuleiten, um auf Plattformen zu landen Ein gewisses Maß an Luftregulierung kann gut sein, sollte aber nicht dasselbe sein wie Bewegung am Boden Um unserem Charakter eine spezifischere Luftkontrolle zu verleihen, können wir oben im Skript eine weitere exportierte Variable als Float-Typ definieren oben im Skript eine weitere exportierte Variable und ihr einen Standardwert von 0,5 geben . Wir müssen diesen Wert nur mit der Beschleunigung multiplizieren , wenn der Spieler den Boden nicht berührt. Um die physikalische Prozessmethode zu vereinfachen, teilen wir sie in zwei separate Methoden Physik und Bodenphysik. Bei beiden kann es sich um private Methoden im physikalischen Prozess handeln. Wenn der Charakter auf dem Boden liegt, wenden Sie Bodenphysik an, andernfalls wenden Sie Luftphysik an. Fahren Sie dann mit Bewegen und Schieben fort. Bodenphysik wird sich gegenüber dem, was wir bereits bei der Methode der Luftphysik haben, nicht ändern . Wenn die Richtung nicht Null ist, können wir Geschwindigkeit x in Richtung Geschwindigkeit mal Richtung bewegen , und zwar mit einer Geschwindigkeit von Beschleunigung mal Luftkontrolle mal Delta. Dadurch hat der Spieler immer noch eine gewisse Kontrolle über die Luft, aber das wird um die Hälfte reduziert. Lassen Sie uns diese Variablen von den oben genannten trennen, indem wir auch Kategorien für sie exportieren. Diese Variablen werden in die Jump-Kategorie exportiert. Die oben genannten Variablen werden in die Kategorie Fortbewegung exportiert Lass es uns ausprobieren. Wie bei den anderen Variablen können Sie den Wert anpassen und sehen, wie er sich für Sie gut anfühlt. Unser Charakter springt und fällt jetzt realistischer und bessere Kontrolle für den Spieler In der nächsten Lektion animieren wir den Charakter so, dass er seiner Bewegung entspricht Wir sehen uns in der nächsten Lektion. 19. 2 5 Animation: Hallo Freunde. In der vorherigen Lektion haben wir das allgemeine Gefühl der Sprungmechanik des Charakters verbessert Sprungmechanik des Charakters und dem Spieler eine bessere Kontrolle über seine Sprunghöhe und Flugbahn gegeben seine Sprunghöhe und Flugbahn In dieser Lektion fügen wir der Charakterszene Animationen hinzu , öffnen die Charakterszene und verschaffen uns einen guten Überblick über den Lassen Sie uns zunächst dafür sorgen, dass der Charakter in die Richtung schaut, in die er sich bewegt. Wenn Sie den Sprite-Two-D-Knoten auswählen und im Inspektor nachschauen, erweitern Sie den Bereich Offset unter Sprite Two D. Die Eigenschaft, die wir ändern möchten , ist Flip H. Wenn Sie horizontal auf das Kontrollkästchen klicken, können wir sehen, dass das Sprite mit der Maus über den Namen erfahren Sie, wie Sie auf diese Eigenschaft zugreifen In unserem Skript lautet der Eigenschaftsname umgekehrter Unterstrich H, wodurch das Zeichenskript geöffnet wird das Zeichenskript geöffnet Wir haben Methoden für Gesicht links und Gesicht rechts entwickelt, aber wir haben sie noch nicht verwendet Wir müssen lediglich den Wert der Eigenschaft Flip H des Sprite-Two-D-Knotens ändern Eigenschaft Flip H des Sprite-Two-D-Knotens können wir einen Verweis auf den Sprite-Two-D-Knoten am Anfang des Skripts abrufen Sprite-Two-D-Knoten am Anfang des on ready var können wir einen Verweis auf den Sprite-Two-D-Knoten am Anfang des Skripts abrufen Wir nennen ihn underscore-sprite Dieser wird vom Typ Sprite Two D sein . Dann weisen Sie dem Wert dieser Variablen das Dollarzeichen Sprite zwei D zu Dollarzeichen Sprite . An welchen Knoten auch immer dieses Zeichenskript angehängt ist, es durchsucht die untergeordneten Knoten nach einem mit dem Namen Sprite Two D und weist ihn dieser Variablen zu Namen Sprite Two D Beachten Sie, dass jedes von uns erstellte Zeichen einen untergeordneten Knoten namens Sprite Two D haben muss, damit dieses Skript wie vorgesehen funktioniert jedes von uns erstellte Zeichen einen untergeordneten Knoten namens Sprite Two D haben muss . Andernfalls enthält diese Variable keinen Wert In den Methoden face left und face right können wir nun diesen Verweis auf die beiden Sprites D verwenden, um die Eigenschaft Flip H zu ändern Wenn das Zeichen nach links zeigt, sollte die Eigenschaft Flip H den Wert true Wenn sie nach rechts zeigen, sollte der Wert falsch sein. Diese Funktionen werden jedoch nirgends aufgerufen. Der beste Ort, sie aufzurufen, wäre zu Beginn des physikalischen Prozesses. Es spielt keine Rolle, ob sich der Charakter am Boden oder in der Luft befindet. Wenn der Richtungssinus negativ ist, sollte der Charakter schließlich nach links zeigen. Wenn der Richtungssinus eins ist, sollte das Zeichen nach rechts zeigen. Wir müssen nichts tun, wenn der Richtungssinus Null ist. Wenn wir jetzt die Hauptszene abspielen, schaut der Charakter in die Richtung, in die der Spieler eingibt. Das ist ein guter Anfang, aber lasst uns auch damit beginnen, den Charakter zu animieren Klicken Sie mit der rechten Maustaste auf den Sprite-Two-D-Knoten im Szenenbaum und fügen Sie einen untergeordneten Der Knoten, nach dem wir suchen müssen, ist ein Animations-Player-Knoten Dieser Knoten ermöglicht es uns, Aspekte des Charakters im Laufe der Zeit zu ändern, insbesondere die Sprite-Textur Wenn Sie diesen Knoten hinzufügen, wird automatisch das Animationsfenster am unteren Rand des Editorfensters geöffnet. Klicken Sie auf die Animationsschaltfläche und dann auf Neuer Name, das neue Animationsidol Jetzt können Sie im Animationsfenster eine Zeitleiste sehen. Jeder Aspekt des Charakters , der durch die Animation verändert wird , wird auf dieser Zeitleiste aufgelistet. Klicken Sie auf die Plus-Schaltfläche, um der Animation eine neue Eigenschaft hinzuzufügen . Die Eigenschaft, die wir ändern müssen, ist die Sprite Two TS-Textur Um die Positionen innerhalb der Timeline zu markieren , an denen sich das Sprite ändern wird Wir können einen Keyframe hinzufügen, indem wir mit der rechten Maustaste auf den Eigenschaften-Track klicken und Key einfügen auswählen Sobald ein Keyframe zur Timeline hinzugefügt wurde, können wir ihn einfach verschieben Klicken und ziehen, wenn es nicht an der richtigen Stelle ist. auf ein Schlüsselbild klicken, können wir seinen Wert im Inspektor festlegen Das Sprite Idle 01 ist bereits in das Texturfeld eingetragen Da das der aktuelle Wert ist, denke ich, dass diese Vermögenswerte am besten aussehen Bei einer Bildrate von zehn Bildern pro Sekunde möchte ich die Textur des Sprites alle eine Zehntelsekunde ändern , was bedeutet, dass die gesamte Animationslänge 0,5 Sekunden beträgt Die Timeline zeigt derzeit 15 Sekunden an, was es schwierig macht, nur das erste Segment der gesamten Timeline zu bearbeiten schwierig macht, nur das erste Segment der gesamten Timeline zu Zoomen wir mit dem Schieberegler unten rechts hinein, bis wir problemlos alle 0,1 Sekunden auf der Timeline sehen können. Lassen Sie uns also vier weitere Keyframes hinzufügen und jedes mit den verbleibenden Sprites füllen Damit müssen wir die Länge der Animation, die derzeit auf 1 Sekunde eingestellt ist, auf 0,5 Sekunden reduzieren 1 Sekunde eingestellt ist, auf 0,5 Wir möchten, dass diese Animation in einer Schleife läuft. Klicken Sie rechts auf die Schaltfläche Animation Looping. Wir können eine Vorschau dieser Animation anzeigen, indem wir oben im Animationsfenster auf das Abspielsymbol klicken. Das sieht ziemlich gut aus. Als Nächstes müssen wir die Animation ausführen. Klicken Sie auf die Animationsschaltfläche und wählen Sie Duplizieren. Geben Sie dann dem neuen Animationslauf einen Namen. den Asset-Ordner erweitern , der die Run-Animation enthält, können wir sehen, dass er sechs Sprites enthält Wir müssen die Länge der Animation auf 0,6 Sekunden erhöhen und ein weiteres Schlüsselbild hinzufügen Füllen Sie dann jedes Schlüsselbild der Reihe nach mit den richtigen Sprites Wenn Sie fertig sind, sehen Sie sich eine Vorschau der Animation an, um sicherzustellen, dass sie gut aussieht Wiederhole den Vorgang noch dreimal, um die Animationen für Sprung, Fall und Boden zu erstellen die Animationen für Sprung, Fall und Achten Sie dabei auf die Länge der einzelnen Animationen, basierend auf der Anzahl der im Asset-Paket enthaltenen Sprites Diese Animationen sind jedoch nicht für Wiederholungen vorgesehen. Stellen Sie daher sicher, dass Sie das Looping für diese Animationen ausschalten Wir haben jetzt alle unsere Charakteranimationen eingerichtet. In der nächsten Lektion bauen wir eine Zustandsmaschine, um die Animationen mit dem zu synchronisieren was der Charakter gerade tut. Wir sehen uns in der nächsten Lektion. 20. 2 6 State Machine: Hallo Freunde. In der vorherigen Lektion haben wir Animationen für die Bewegung unserer Charaktere eingerichtet. In dieser Lektion werden wir diese Animationen implementieren und sie mit dem Verhalten des Charakters synchronisieren . Aber bevor wir das tun, fügen wir der Hauptszene schnell einen weiteren Knoten hinzu. Ein Kamera-Zwei-D-Knoten. Auf diese Weise können wir uns schnell einen besseren Überblick über unseren Charakter verschaffen, da wir ihn neu positionieren und vergrößern können ihn neu positionieren und vergrößern indem wir seine Eigenschaften im Inspektor bearbeiten Wenn wir nun die Szene testen, haben wir einen besseren Überblick über die Ergebnisse dieser Animationen Um nun die Animationen zu implementieren, öffnen wir die Charakterszene und fügen Animations-Player einen weiteren untergeordneten Knoten hinzu . Dieser Knoten wird Animationsbaum genannt. Der Animationsbaumknoten gibt uns eine Warnung, dass kein Root-Animationsknoten für das Diagramm festgelegt ist. Wenn Sie im Inspektorfenster nachschauen, Sie ein Feld mit der Bezeichnung Anim-Player Stelle klicken, an der ein Schild steht, können wir den Animations-Player auswählen wir in der vorherigen Lektion erstellt haben Der Zweck dieses Animationsbaums besteht darin, zu steuern , welche Animation zu einem bestimmten Zeitpunkt abgespielt wird. Sie mithilfe der Drop-down-Liste mit der Bezeichnung Baumwurzel Wählen Sie mithilfe der Drop-down-Liste mit der Bezeichnung Baumwurzel einen neuen Animationsknoten (State Machine) aus. Dadurch wird die neu erstellte Zustandsmaschine im Animationsbaumbereich am unteren Rand des Editorfensters geöffnet. Bevor wir jedoch mit der Bearbeitung der Zustandsmaschine beginnen, werfen wir einen Blick auf den Asset-Ordner für unseren Charakter. Die Animationen sind in zwei Ordner aufgeteilt mit Schwert und ohne Schwert beschriftet sind. Die Inhalte dieser Ordner sind alle dieselben Animationen, mit Ausnahme des Charakters, der ein Schwert hält. Oder um überflüssigen Aufwand zu vermeiden, werde ich die Struktur dieses Animationsbaums im Voraus planen , um Funktionen zu berücksichtigen, die erst später im Kurs implementiert werden. Um mit unserer Zustandsmaschine zu beginnen, klicken wir zunächst mit der rechten Maustaste auf eine leere Stelle im Animationsbaum und wählen Zustandsmaschine hinzufügen aus. Benennen Sie dann diese neue Zustandsmaschine ohne Schwert. Wir können das auch noch einmal machen und eine weitere Zustandsmaschine namens With Sword erstellen . Wir können dann auf die Übergangsschaltfläche in der oberen linken Ecke klicken und einen Übergang von Start zu ohne Schwert hinzufügen . Wenn das Spiel jetzt zum ersten Mal startet, werden im Animationsbaum standardmäßig Animationen für unseren Charakter ohne Schwert abgespielt . Wir können die Sword State Machine vorerst ignorieren, zurück in den Auswahlmodus wechseln und auf das Stiftsymbol klicken , um die Maschine ohne Schwert zur Bearbeitung zu öffnen . Innerhalb der Zustandsmaschine können wir eine weitere Zustandsmaschine namens Bewegung erstellen. Fügen Sie dann den Übergang vom Start zur Bewegung als Standard hinzu. Diese Ebene des Baums wird später für einen anderen Zweck verwendet. Öffnen Sie die Bewegungszustandsmaschine erneut zur Bearbeitung. Erstellen Sie eine weitere Zustandsmaschine, diesmal mit dem Namen Locomotion, und erstellen Sie einen Übergang vom Start zur Fortbewegung Öffnen Sie dann die Locomotion State Machine zur Bearbeitung. Schließlich können wir der State Machine Animationen hinzufügen. rechten Maustaste auf Animation hinzufügen, dann auf Leerlauf und wiederholen Sie den Vorgang, um die Ausführung hinzuzufügen. Erstellen Sie einen Übergang von Start zu Inaktivität und machen Sie ihn zur Standardanimation. Fügen Sie dann einen Übergang von Idle zu Run und von Run Back zu Idle hinzu. Der Zweck dieser Zustandsmaschine wird darin bestehen, die Animation zwischen diesen beiden Zuständen zu ändern. Wir können die Bedingungen festlegen, unter denen diese Übergänge stattfinden, indem wir sie anklicken und sie dann im Inspektor bearbeiten, wobei der Übergang von „ Leerlauf“ zu „Ausführen“ ausgewählt Erweitern Sie den Bereich „Weiter“ und wählen Sie den Textbereich für den Ausdruck aus. Der in diesen Textbereich eingegebene Ausdruck muss einen booleschen Wert erzeugen, entweder wahr oder falsch Die Bedingung , unter der die Figur vom Leerlauf in den Laufmodus wechseln soll, ist, wenn die Geschwindigkeit nicht Null ist Ebenso ist die Bedingung für den Übergang von „Run“ zu Idle“, wenn die Geschwindigkeit x gleich Null ist Wir müssen dem Animationsbaum auch mitteilen , welcher Knoten diese erweiterten Ausdrücke steuert Den Baum im Szenenbaum auswählen. Dann können wir im Inspektorfenster das Basisfeld für erweiterte Ausdrücke auf den Stammknoten des Charakters ändern . Jetzt können wir die Hauptszene abspielen und sehen, wie der Animationsbaum funktioniert. der X-Geschwindigkeit des Charakters wird die Charakteranimation zwischen „Leerlauf“ und „Ausführen“ umgeschaltet nach der X-Geschwindigkeit des Charakters wird die Charakteranimation zwischen „Leerlauf“ und „Ausführen“ umgeschaltet. Um die restlichen Animationen zu integrieren. zum Animationsbaum zurück und navigieren Sie zur Bewegungsebene der Zustandsmaschine. Klicken Sie mit der rechten Maustaste, um die Sprung-, Fall- und Bodenanimationen hinzuzufügen Fall- und Bodenanimationen Übergänge von Fortbewegung zu Sprung, Sprung zu Fall, Fall zu Boden, Boden zu Fortbewegung und Fortbewegung zum Fall zu erstellen Sprung zu Fall, Fall zu Boden, Boden zu Fortbewegung und Fortbewegung zum Dann können wir die Bedingungen für jeden dieser Übergänge festlegen für jeden dieser Die Animation der Charaktere sollte sich so ändern, dass sie springt wenn ihre Geschwindigkeit y kleiner als Null ist, dann auf Fall umschalten, wenn ihre Geschwindigkeit größer oder gleich Null wird , gefolgt von Boden, wenn sie sich auf dem Boden befindet. Da es sich um eine eingebaute Methode handelt, bei der der Körper der Figur zwei Knoten hat, können wir darauf zugreifen und sie gibt einen booleschen Wert zurück Es gibt keine Bedingung für den Übergang vom Boden Erweitern Sie stattdessen den Switch-Bereich und wählen Sie im Drop-down-Menü die Option „Ende“ aus Auf diese Weise kann die Bodenanimation abgeschlossen werden, bevor zur Fortbewegung übergegangen wird, jedoch keine weiteren Bedingungen Wenn der Spieler von einem Felsvorsprung heruntergeht, wollen wir schließlich, dass die Animation von der Fortbewegung zum Fallen übergeht Das wird wahr sein, wenn es nicht auf dem Boden ist. Aber die Übergänge von der Fortbewegung zum Springen und zum Sturz werden immer dann zutreffen, wenn der Spieler springt Wir können dem Sprung Priorität einräumen, indem wir seine Priorität auf 1-0 ändern . Wir wechseln zurück zur Hauptszene und lassen die aktuelle Szene laufen Wir können jetzt den Animationsbaum bei der Arbeit beobachten, da er den Charakter automatisch zwischen den verschiedenen Zuständen Jetzt haben wir die Grundbewegungen des Charakters animiert. In der nächsten Lektion werden wir einigen dieser Animationen Staub- und Soundeffekte hinzufügen . Wir sehen uns in der nächsten Lektion. 21. 2 7 Effekte: Hallo Freunde. In der vorherigen Lektion haben wir eine Zustandsmaschine verwendet, um die Animation der Charaktere mit ihrem Verhalten zu synchronisieren. In dieser Lektion werden wir einige Ton- und visuelle Effekte hinzufügen, um den Animationen den letzten Schliff zu verleihen. Beginnen wir mit der Charakterszene, fügen wir einen neuen Knoten hinzu, einen animierten Sprite mit zwei D, und benennen ihn in Staubpartikel um Eine Warnung weist uns darauf hin, dass wir eine Sprite-Frames-Ressource erstellen müssen eine Sprite-Frames-Ressource erstellen damit dieser Knoten mit dem neu ausgewählten Knoten funktioniert Sie im Inspektor Erweitern Sie im Inspektor den Animationsbereich Klicken Sie auf das Drop-down-Menü mit der Bezeichnung Sprite-Frames, wählen Sie neue Sprite-Frames klicken Sie dann auf die Sprite-Frames-Ressource , um sie zur Bearbeitung zu öffnen . Diese wird unten im Editorfenster angezeigt Hier sehen wir eine neu erstellte Sprite-Frame-Animation namens Default mit einer Bildrate von fünf im Dateisystemfenster Suchen Sie im Dateisystemfenster im Asset-Paket nach der Ordnergruppe Staubpartikel, wählen Sie die Herbst-Sprites und ziehen Sie sie in den Bereich mit den Animationsframes Wenn Sie auf Play drücken, um eine Vorschau der Animation anzuzeigen, können wir sehen, wie sie aussehen wird Wir möchten nicht, dass diese Animation wiederholt wird. Schalten Sie das Looping aus, indem Sie die Animationslooping-Schaltfläche kochen Erweitern Sie den Offset-Bereich und passen Sie den Y-Offset bis er auf gleicher Höhe mit der roten X-Achse liegt, die dann unser Grundriss sein wird Es ist wichtig, das Offset-Feld und nicht die Position der Transformationen zu verwenden , damit die Partikel auf dem Boden erscheinen Ich werde auch die Bildrate an meine Charakteranimationen anpassen, die eine Bildrate von zehn Bildern pro Sekunde hatten Wenn wir jetzt auf Play klicken, wird die Animation nur einmal abgespielt. Und wir können sehen, wie es im Spiel in Bezug auf den Charakter aussehen wird . Der Zweck dieser Animation besteht darin, einmal abzuspielen, wenn der Charakter auf dem Boden landet und zu verschwinden, wenn er fertig ist. Diese Effekte sehen am besten aus, wenn sie unabhängig vom Charakter existieren, als ob der Staub Teil der Welt wäre und dem Charakter nicht folgen sollte. Klicken wir mit der rechten Maustaste auf den Staubpartikelknoten und speichern wir diesen Zweig als eigene Szene. Das gehört eigentlich zu keinem unserer bestehenden Ordner. Lass uns dafür einen neuen Ordner mit dem Namen Dust erstellen. Nennen Sie diese besondere Szene, herabfallender Staub, der auf der Klöppel kocht , Symbol im Szenenbaum Wir können die Herbststaubszene öffnen , damit die Partikel verschwinden Nachdem die Animation abgeschlossen ist, müssen wir ein Skript an den Stammknoten anhängen. Klicken Sie auf die Schaltfläche für das Anzeigenskript und benennen das neue Skript dust. Wir müssen keine der Standardvorlagen verwenden. Deaktivieren Sie das Kontrollkästchen für die Vorlage und stellen Sie sicher, dass das Skript im Skriptordner gespeichert ist Dadurch wird das Skript mit nichts weiter als der Erweiterung der animierten Sprite-Zeile um zwei D-Zeilen oben gestartet animierten Sprite-Zeile um zwei D-Zeilen oben Aber bevor wir tatsächlich Code schreiben, bei der animierte Sprite-2-D-Node ausgewählt ist, schauen wir uns das Inspektor-Panel an und wechseln zum Node-Panel Signale sollten standardmäßig ausgewählt sein. Dies ist eine Liste von Signalen , die der Knoten verwenden kann, um Verhalten entweder in seinem eigenen Skript oder in anderen Skripten auszulösen . Wir können das Signal „ Animation abgeschlossen“ verwenden , um zu wissen, wann die Animation beendet ist. Und führe eine Methode in unserem Skript aus. Klicken Sie mit der rechten Maustaste auf die fertige Animation. Stellen Sie eine Verbindung her, um ein neues Fenster zu öffnen. Stellen Sie sicher, dass die Staubpartikel als Empfänger des Signals ausgewählt sind . Klicken Sie anschließend auf Verbinden. Sie werden feststellen, dass Do im Skript automatisch eine Methode generiert hat , die ausgelöst wird, wenn die Animation beendet ist. Links neben der Methodendeklaration befindet sich ein grünes Verbindungssymbol , das uns darüber informiert, dass diese Methode durch ein Signal ausgelöst wird. Ebenfalls im Szenenbaum wird das Signalsymbol neben dem Staubpartikelknoten angezeigt , um uns mitzuteilen , dass dieser Knoten über eine Signalverbindung verfügt. Das einzige, was wir im Skript tun müssen , wenn die Animation fertig ist, ist der Engine mitzuteilen, dass wir mit diesem Knoten fertig sind und er entfernt werden kann. Dies geschieht mit einer eingebauten Methode namens free. Wir möchten dem Skript auch mitteilen, dass die Animation automatisch abgespielt wird, wenn sie der Szene hinzugefügt wird. die Methode underscore ready überschreiben, können wir einfach aufrufen, wenn dieser Knoten zum Baum hinzugefügt wird. Er wird einmal abgespielt und entfernt sich selbst, wenn er fertig ist Wir können diese Szene jetzt duplizieren, um ähnliche Staubpartikel-Szenen für Jump-and-Run-Partikel in diesen neuen Szenen zu erstellen ähnliche Staubpartikel-Szenen für Jump-and-Run-Partikel . Wir können die Sprites in der Animation durch die richtigen Sprites aus dem Asset-Paket ersetzen der Animation durch die richtigen Sprites aus dem Asset-Paket Wir haben jetzt drei verschiedene Staubpartikeleffekte , die wir unter verschiedenen Bedingungen für unseren Charakter erzeugen wollen , aber sie können alle eine Methode verwenden Wenn wir zur Charakterszene zurückkehren, können wir jetzt den Staubpartikelknoten löschen , da er nicht Teil der Szene sein soll. Wechseln Sie dann zur Skriptansicht und öffnen Sie das Zeichenskript. Fügen wir eine neue private Funktion namens spawn dust hinzu, die einen Parameter namens dust akzeptiert Der Typ dieses Parameters wird eine gepackte Szene sein sodass wir die Szenen, die wir gerade erstellt haben, als Argument für die Methode verwenden gerade erstellt haben, als Argument für die Methode Zuerst müssen wir die Szene instanziieren und dann ihre Position ändern, dann ihre Position ändern sodass sie sich an derselben Stelle wie die Figur befindet Als Nächstes fügen Sie sie dem Szenenbaum hinzu, indem Sie zuerst den übergeordneten Knoten der Figur abrufen und dann den Staub als untergeordneten Knoten hinzufügen Indem du den Staub zu einem Geschwister des Charakters machst, wird er unabhängig vom Charakter in der Welt existieren und ihm nicht folgen Sobald es dem Szenenbaum hinzugefügt wird, spielt das animierte Sprite seine Standardanimation ab. Q selbst wird entfernt, wenn die Animation nur einen Bruchteil einer Sekunde später fertig ist nur einen Bruchteil einer Sekunde Um die Sprungstaubpartikel auszulösen, können wir diese Methode direkt von der Jump-Methode aus aufrufen und dabei Sprungstaub als Argument übergeben Deklarieren Sie dann, was der Sprungstaub am Anfang des Skripts ist , als exportierte Variable vom Typ gepackte Szene. Wählt den Stammknoten der Figur und wechselt zurück zum Inspektorfenster. Wir können ihn dann im Inspektor auffüllen, indem wir auf die Szene klicken und sie in das exportierte Feld ziehen Die Partikel „Lauf und Fall“ haben in unserem Skript keine einfache Stelle, an der sie erzeugt werden können können wir jedoch Stattdessen können wir jedoch den Animationsspieler unseres Charakters auswählen, die Bodenanimation öffnen und eine neue Spur hinzufügen Diesmal ein Track mit der Aufrufmethode. Dann können wir auf den Wurzelknoten der Figur zugreifen und Methode spawn particles aufrufen Beginn der Animation die Durch Hinzufügen eines Keyframes. den Schlüsselrahmen auswählen, können wir Argumente an die Methode übergeben , die wir dann auffüllen können Indem Sie auf den Herbststaub klicken und ihn ziehen. Wir können dasselbe mit den Staubpartikeln des Laufs machen und sie der Laufanimation hinzufügen Denken Sie daran, dass sich die Laufanimation in einer Schleife wiederholt, sodass jedes Mal, wenn die Animation wiederholt wird, neue Partikel erscheinen Bei den herabfallenden und springenden Partikeln ist es eigentlich egal, in welche Richtung der Charakter schaut Bei den Laufpartikeln ist es jedoch wichtig, dass sie sich scheinbar hinter der Figur bewegen. Wir können die animierte Steph-Eigenschaft so einstellen , dass sie der Eigenschaft des Charakters zum Zeitpunkt seiner Erstellung entspricht zum Zeitpunkt seiner Erstellung Lass es uns ausprobieren. Beim Laufen entsteht alle 0,6 Sekunden Staub. Springen und Landen erzeugen auch ihre eigenen einzigartigen Staubwolken. Für einen weiteren Feinschliff können wir unseren Animationsspuren auch Sounds hinzufügen , zur Charakterszene zurückkehren und dem Szenenbaum einen neuen Knoten hinzufügen, einen Audio-Stream-Player mit zwei D-Knoten. Mit diesem Knoten im Baum können wir jetzt die Sprunganimation öffnen und eine neue Audiowiedergabe hinzufügen. Wählen Sie den Audio-Stream-Player-Knoten als Ziel aus. Platzieren eines Keyframes am Anfang der Animation. Wir können diesen Keyframe dann mit einem Audiostream füllen. Durchstöbern Sie die Sounds, die in den Kampfsounds von Luke Sharps bereitgestellt die in den Kampfsounds von Luke Sharps Es stehen ein paar passende Sounds zur Auswahl, die gut zu diesem Charakter passen Importieren Sie die Sounds, die Ihnen gefallen, und platzieren Sie sie in einem dafür vorgesehenen Ordner für Soundeffekte , um Ihr Projekt zu organisieren. Füllen Sie dann Ihren Animations-Keyframe entsprechend aus. Damit die Laufanimation über die Geräusche der Schuhe läuft. Stellen Sie sicher, dass Sie den Startversatz und den Endversatz ändern , um ein Beispiel auszuwählen , das kürzer als die Animation ist Lass es uns jetzt ausprobieren. Die Figur macht beim Springen ein grunzendes Geräusch, Landen ein Aufprallgeräusch und beim Laufen Schrittgeräusche In diesem ersten Abschnitt des Kurses haben wir einen vollständig animierten Charakter mit sowohl Audio- als auch visuellen Effekten und unterhaltsamen Plattformmechaniken erstellt sowohl Audio- als auch visuellen Effekten und unterhaltsamen Im nächsten Abschnitt werden wir mit der Erstellung von Levels für unser Spiel beginnen Erstellung von Levels für unser Spiel Wir sehen uns im nächsten Abschnitt. 22. 2-1 Tilemap: Hallo Freunde. Im letzten Abschnitt haben wir einen vollständig animierten Charakter mit Plattformmechanik erstellt mit Plattformmechanik Wenn du die Aufgabe abgeschlossen hast, solltest du jetzt eine vollständige Besetzung von vier Charakteren haben Und wir haben herausgefunden , dass du den Spielerknoten duplizieren kannst , um mehr als einen Charakter gleichzeitig zu kontrollieren . Wenn ihr die Zwischenherausforderung abschließen konntet, werdet ihr auch über einige KI-Skripte verfügen die einen oder mehrere Charaktere steuern. Bei der fortgeschritteneren Herausforderung wirst du wahrscheinlich alle Charakterknoten, vom Kind bis zum Spielerknoten, denen der Charakter gesteuert wird, per Knopfdruck umschalten können. In diesem Abschnitt werden wir ein Level für unser Spiel erstellen. unserer ersten Lektion beginnen wir mit dem Bau des ebenen Geländes. Fügen Sie der Hauptszene einen weiteren Knoten hinzu. Der Knoten, nach dem wir diesmal suchen, ist die Kachelkarte. Eine Kachelkarte ermöglicht es uns, schnell Sprites in unserem Level hinzuzufügen und zu ändern, die dann in Kacheln einer bestimmten Größe angeordnet werden Damit eine Kachelmap funktioniert, benötigt sie ein Kachelset Wie Sie im Inspektor im Drop-down-Menü sehen können, Kachelsatz beschriften “ aus, wählen Sie einen neuen Kachelsatz klicken Sie dann auf die Kachelsatzressource, um sie zu erweitern werden einige Felder angezeigt, die wir zur Bearbeitung benötigen . Unsere Kacheln sind quadratisch Sie können jedoch sehen, dass es eine Reihe weiterer Optionen gibt , die das Arbeiten mit anderen Kachelformen genauso einfach machen Das erste, was wir ändern müssen, ist die Kachelgröße. Die Kachelgröße des von mir verwendeten Asset-Pakets beträgt sowohl in der Breite als auch in der Höhe 32 Pixel. Es ist wichtig, dass Sie diese Eigenschaft festlegen bevor Sie dem Kachelsatz Kacheln hinzufügen. Da wir diese Kachelkarte für Terrain verwenden, müssen wir auch eine Physikebene für Kollisionen hinzufügen. Ein Gelände-Set erleichtert die Bearbeitung von Terrains erheblich. Das Gelände-Set kann mehrere Terrains enthalten. Wir müssen dem Gelände-Set ein Terrain hinzufügen. Sie können sich jedes Terrain als ein anderes Biom oder Baumaterial vorstellen ein anderes Biom oder Baumaterial Nennen wir diese erste Geländeinsel. Jedem Geländetyp kann eine andere Farbe zugewiesen werden , um sie voneinander zu unterscheiden. Da wir momentan nur einen Geländetyp verwenden werden , können wir einfach die Standardfarbe verwenden. Diese Farbe wird im Spiel nicht nur verwendet , während wir das Terrain bearbeiten. Es ist nur zu unserem Vorteil als Entwickler. Nachdem diese Änderungen vorgenommen wurden, können wir unsere Aufmerksamkeit auf den unteren Rand des Editorfensters richten , wo sich ein neuer Tab für die Kachelmap geöffnet hat. Die Meldung teilt uns mit, dass wir zuerst ein Kachelset konfigurieren müssen und zur Registerkarte „Kachelsatz“ unten wechseln müssen. Hier können wir die im Asset-Paket enthaltenen Kacheln zu diesem Kachelsatz hinzufügen . Entweder durch Klicken auf die Plus-Schaltfläche oder Anklicken und Ziehen der Bilddatei aus dem Dateisystem Der Tab-Code bietet an, automatisch Kacheln für uns zu erstellen. Wählen Sie Ja aus. Wenn Sie sicher sind, dass Sie die Kachelgröße richtig eingestellt haben , wählen Sie andernfalls Nein. Die Kacheln sollten jetzt heller sein und einen orangefarbenen Rand haben. Wenn Sie das Radierwerkzeug auswählen, können Sie Kacheln aus dem Kachelset entfernen, indem Sie darauf klicken Ebenso können Sie durch Ausschalten des Radierwerkzeugs Kacheln zum Kachelsatz hinzufügen , indem Sie darauf klicken zurück zur Registerkarte „Kachelkarte“ wechseln, können wir nun eine beliebige Kachel aus dem Kachelsatz auswählen und in die Two-D-Ansicht ziehen , indem klicken. Goode bietet zur Vereinfachung ein orangefarbenes Gitter , das der Kachelgröße entspricht Der Tilemap-Editor bietet außerdem alle üblichen Werkzeuge zum Auswählen von Mallinien, Rechtecken und zum Füllen von Eimern Sie können Kacheln auch per Mausklick auswählen, löschen, drehen, spiegeln und nach dem Zufallsprinzip anordnen. Erstelle einen Grundboden, platziere deinen Charakter darauf und positioniere die Kamera , um die Ergebnisse zu sehen Spielen Sie dann die Szene ab. Sie werden feststellen , dass es im Gelände noch keine Kollision gibt. Wechseln Sie zurück zur Registerkarte „Kachelset“. Wechseln Sie in den Auswahlmodus und wählen Sie alle Kacheln in einer Gruppe aus, indem Sie sie anklicken und mit der Maus darüber ziehen Fügen wir unseren Kacheln zunächst Kollisionen hinzu, indem wir den Physik-Bereich erweitern Dann Physik-Ebene Null. diesem Tool können Sie komplexe Kollisionsformen für jede Kachel erstellen , aber wir benötigen nur einfache Quadrate. Klicken Sie auf das Ellipsensymbol wählen Sie Auf Standardkachelform zurücksetzen oder drücken Sie alternativ die Taste, um die Kollisionsform einfach an die Form der quadratischen Kacheln anzupassen Jetzt wird es bei allen unseren Kacheln zu Kollisionen kommen, genau wie beim Codell-Symbol, das wir als Szenenboden verwendet haben Das ist großartig, aber es wird extrem mühsam sein, Level zu bauen, indem einzelne Kacheln in die Kachelkarte man einzelne Kacheln in die Kachelkarte einfügt Zum Glück bietet Godel einen sehr einfach zu bedienenden Geländeeditor Wechseln Sie in den Malmodus. Dadurch können wir Eigenschaften auf die Fliesen malen. Die Immobilie, die wir malen wollen, ist die Geländeeigenschaft. Vor allem im Terrain to Zero, dem Inselgelände. Möglicherweise möchten Sie das Bedienfeld erweitern oder den Kachelbereich vergrößern. Für diesen Teil ist jede Kachel in neun kleinere Quadrate unterteilt , die wir durch Anklicken der Geländefarbe anpassen oder mit der rechten Maustaste löschen können . Für jedes Feld, das Teil dieses Geländes ist , sollte das mittlere Quadrat ausgefüllt sein. Damit der Terrain-Editor wie vorgesehen funktioniert, müssen wir die Kanten jeder Kachel, die neben einer anderen Kachel gezeichnet werden sollen, malen jeder Kachel, die neben einer anderen Kachel gezeichnet werden sollen . Wenn du fertig bist, sollte es keine Duplikate in diesem Kachelset geben keine Duplikate in diesem Kachelset Jede Kachel sollte ein einzigartiges Muster haben. Wechseln Sie zurück zur Registerkarte „Kachelkarte“. Wechseln Sie oben zur Registerkarte „Terrains“. Und unser Inselgelände sollte als Option aufgeführt werden , indem du auswählst, dass du alle Kacheln aus dem aufgelisteten Kachelsatz zusammen mit zwei zusätzlichen Optionen, dem kontinuierlichen Modus und dem Pfadmodus, siehst zusammen mit zwei zusätzlichen Optionen, kontinuierlichen Modus und dem Pfadmodus Wählen Sie den kontinuierlichen Modus und zeichnen Sie dann das Terrain in der Ansicht mit zwei D-Elementen nach Belieben , indem Sie darauf klicken und löschen Sie es mit der rechten Maustaste Jede Kachel wird automatisch korrekt mit den benachbarten Kacheln verbunden Sie sollten in der Lage sein, Gelände in jeder erdenklichen Form zu zeichnen , und Kachelposition werden automatisch die richtigen für jede Kachelposition werden automatisch die richtigen Kacheln ausgewählt. Falls es irgendwelche Inkonsistenzen gibt, überprüfe die Bemalung deiner Geländeeigenschaften Mit diesem Tool können wir schnell und einfach das Terrain für jedes Level in unserem Spiel generieren Wir haben jetzt grundlegendes Terrain in unserem Spiel, das wir verwenden können, um die Grundlage für unsere Level zu schaffen. In der nächsten Lektion werden wir etwas dekorative Vegetation hinzufügen , damit sich die Umgebung lebendiger anfühlt. Wir sehen uns in der nächsten Lektion. 23. 2-2 Dekorationen: Hallo Freunde. In der letzten Lektion haben wir grundlegendes Terrain mit Kollisionen und Geländebearbeitung eingerichtet Kollisionen und Geländebearbeitung In dieser Lektion werden wir unserem Terrain einige Dekorationen hinzufügen , um es interessanter zu gestalten Wechseln Sie wie bei der Kachelkarte unten im Editorfenster zur Registerkarte „Kachelset“. Im Asset-Paket befindet sich eine weitere Kachelsatzgrafik mit den Namen Front, Palm, Bottom und Gras, die zu diesem Kachelsatz gehört . Fügen wir das dem Atlas hinzu. Diese dekorativen Elemente benötigen eigentlich keine Physik oder Geländebearbeitung. Das Gras kann einfach nach dem Zufallsprinzip über Bereiche in deinem Level gezogen werden Zufallsprinzip über Bereiche in deinem Level denen du denkst, dass es gut aussehen wird. Die Wurzeln sind jedoch dafür vorgesehen, über Geländeplättchen gezogen zu werden. Aber wenn wir das versuchen, wird es stattdessen das Terrain ersetzen. Um dies zu erreichen, müssen wir unserer Kachelkarte eine weitere Ebene für diese Wurzeln hinzufügen . die Kachelkarte im Szenenbaum auswählen, können wir die Kachelsatzressource reduzieren und den Bereich „Ebenen“ erweitern. Hier haben wir eine Ebene , die keinen Namen hat. Nennen wir diese Ebene Terrain, klicken dann auf die Schaltfläche „ Element hinzufügen“, „ Weitere Ebene hinzufügen“ und geben dieser Ebene den Namen Roots Damit diese Ebene vor dem Terrain gezeichnet wird, können wir den Z-Index bearbeiten und ihn auf eins erhöhen Da sich das Terrain auf Ebene Null befindet, werden die Wurzeln auf Ebene eins immer überlagert. Das Drop-down-Menü oben rechts auf der Registerkarte „Kachelkarte“ enthält jetzt unsere beiden verschiedenen Ebenen. Auf diese Weise können wir der Stammebene Wurzelkacheln hinzufügen, die wir dann über die Geländekacheln auf der Terrain-Ebene malen können . Wenn jede Ebene bearbeitet wird, erscheint sie in voller Farbe, während alle anderen Ebenen verblasst werden Aber diese Wurzeln brauchen auch Bäume. Lasst uns auch die Bäume bauen. Wenn Sie möchten, dass Bäume kollidieren und ein unbewegliches Objekt sind, das sich wie Terrain verhält, der geeignetste dann ist der Knotentyp Static Body Two D, den wir Palm Tree nennen werden , wir Palm Tree nennen werden , Dies ist derselbe Knotentyp, den wir ursprünglich für das Godot-Symbol verwendet Dieser spezielle Knoten kann immer noch Kollisionen haben, wird aber nicht durch Kollisionen mit anderen Objekten bewegt Er wird statisch bleiben. Dieser Baum wird eine Animation haben. Fügen wir also ein animiertes Sprite hinzu, zwei D als untergeordneten Knoten der Palme Erstellen Sie eine Sprite-Frames-Ressource für das animierte Sprite. Öffnen Sie dann die Ressource zur Bearbeitung. Klicken Sie auf die Palmenbilder und ziehen Sie sie in die Animation. Ändern Sie die Bildrate und klicken Sie auf Abspielen, um eine Vorschau der Animation anzuzeigen. Das sieht gut aus. Stellen wir sicher, dass diese Animation standardmäßig automatisch abgespielt wird, indem wir oben im Bedienfeld auf die Schaltfläche Autoplay Speichern wir den Palm Tree-Knoten als eigene Szene und sortieren ihn in einen neuen Szenenordner für Dekorationen Jetzt kann der Palmenknoten isoliert bearbeitet werden, und alle an der Palmenszene vorgenommenen Änderungen gelten für alle Kopien der Palme . Wenn der Palmenknoten ausgewählt ist, klicken Sie darauf und ziehen Sie ihn, um ihn um die Ebene zu verschieben und über den Wurzeln zu positionieren . Wir können dies erheblich vereinfachen, indem wir mit der Schaltfläche oben in den beiden D-Ansichten die Rasterausrichtung mit der Schaltfläche oben in den beiden D-Ansichten die Rasterausrichtung Wir können die Fangoptionen auch konfigurieren indem wir auf das Ellipsensymbol klicken Stellen wir sicher, dass die Objekte auf ein Vielfaches von 32 Pixeln ausgerichtet werden, damit sie der Kachelgröße entsprechen Aber die Palme will nicht in einer Reihe stehen weil der Ursprung des Baums in ihrer Mitte liegt Damit der Baum auf einer Linie mit den Kacheln steht, muss sich der Ursprung in der Ecke befinden und das animierte Sprite, zwei D-Knoten, auswählen Passen Sie den Versatz so an, dass das Sprite 16 Pixel oder eine halbe Kachel rechts vom Ursprung nach unten zeichnet oder eine halbe Kachel rechts vom Ursprung nach unten Jetzt kann die Palme einfach so verschoben werden , dass sie zu den Geländekacheln passt Der statische Körper benötigt eine Kollisionsform. Um mit irgendetwas zu kollidieren, müssen wir einen weiteren untergeordneten Knoten hinzufügen, eine Kollisionsform, zwei D. Um diese Palme interessanter zu machen Lassen Sie uns auch dafür sorgen, dass es als Plattform dient, auf die der Spieler springen kann Stellen Sie die Kollisionsform auf eine Segmentform mit zwei D Dies ist nur eine Linie, die wir bearbeiten können, indem wir die beiden Punkte verschieben. Sie das Liniensegment auf eine Linie mit der Spitze der Palme aus. Lass es uns ausprobieren. Es funktioniert wie eine Plattform, aber es wäre schön , durch den Boden springen zu können , anstatt damit zu kollidieren Ich möchte, dass der Spieler nicht so weit vom Rand entfernt schwebt, bevor Einstellungen für die Rasterausrichtung werden auf acht Pixel oder Viertelkacheln angepasst auf acht Pixel oder Viertelkacheln Ich werde dafür sorgen, dass das Liniensegment nur die Hälfte der gesamten Länge der Kachel bedeckt Wenn du willst, dass der Spieler den Boden der Plattform durchqueren und darauf landen kann. gibt es eine einfache integrierte dieses Verhalten gibt es eine einfache integrierte Implementierung. in Godot einfach das Kontrollkästchen Einwegkollision in den beiden D-Eigenschaften der Kollisionsform Dadurch wird im Editor ein Pfeil gezeichnet, der uns zeigt, in welche Richtung die Kollision angewendet wird Das ist viel besser. Jetzt kann ich durch den Boden der Palmenplattform springen und von der Kante rutschen , anstatt auf einer unsichtbaren Barriere zu stehen. Etwas, das einigen Spielern, denen der pixelige Kunststil besonders gefällt, lästig sein könnte einigen Spielern, denen der pixelige Kunststil besonders gefällt, , ist, dass der Spieler nicht genau auf den gleichen Pixelversätzen wie die Umgebung gezeichnet wird genau auf den gleichen Pixelversätzen wie die Wenn ich den Charakter neben etwas Gras positioniere, kannst du sehen, dass die Pixel meines Charakters in den Projekteinstellungen nicht immer mit den Pixeln des Grases übereinstimmen Wir können diese Rendereinstellungen so anpassen , dass alle Bilder , die auf dem Bildschirm gezeichnet werden , mit exakten Pixelkoordinaten gezeichnet werden, was die Fans von Pixelkunst bevorzugen würden. Diese Einstellungen sind standardmäßig ausgeblendet. Klicken Sie unter Rendern auf den Umschalter für erweiterte Einstellungen. Eine neue Option für zwei D wird vorgestellt. Hier haben wir Optionen zum Ausrichten von Transformationen und Scheitelpunkten Dies kann dazu führen, dass der Spieler ein Pixel über dem Boden schwebt Wenn das der Fall ist, stellen Sie ihren Collider so ein, dass sie sauber auf dem Boden stehen Wenn wir jetzt auf Play klicken, der Charakter und alles andere in unserem Spiel werden der Charakter und alles andere in unserem Spiel immer in Pixelkoordinaten gezeichnet Wir haben jetzt Gras und animierte Palmen unsere pixelgenaue Insel schmücken In der nächsten Lektion fügen wir unserer Kamera ein Skript hinzu, das dem Spieler folgt und es uns ermöglicht, Level zu erstellen, die größer als ein Bildschirm sind. Wir sehen uns in der nächsten Lektion. 24. 2-3 Kamera: Oh Freunde. In der vorherigen Lektion haben wir unsere Insel mit Vegetation geschmückt. In dieser Lektion folgt die Kamera dem Spieler durch das Level. Der einfachste Weg, dies zu erreichen , besteht darin, die Kamera einfach dem Spieler zuzuordnen. Dieser Ansatz ist jedoch sehr restriktiv und kann zu Reisekrankheit führen Kamerabewegungen sollten subtiler sein und dem Spieler zeigen, was vor seinem Charakter ist den Spielercharakter als Geschwister in der Kamera haben, brauchen wir die Kamera, um auf die Aktionen des Spielers zu reagieren und ihr eigenes skriptbasiertes Verhalten als Reaktion darauf zu haben ihr eigenes skriptbasiertes Verhalten Beginnen wir mit der Erstellung eines neuen Skripts für die Kamera. Wir können es einfach Kamera nennen und sicherstellen, dass es im Skriptordner gespeichert ist. Diese Kamera muss wissen, was sie verfolgt. Lassen Sie uns eine private Variable exportieren, die wir Underscore Subject nennen werden Dabei muss es sich nicht um einen Charakterkörper zwei D handeln. Stattdessen kann es etwas generischeres sein, wie ein Knoten zwei D. Wenn Sie in den Szenenbaum schauen, werden Sie feststellen, dass die Knoten unterschiedliche Farben haben , von denen die meisten blau sind Bei diesen blauen Knoten handelt es sich allesamt um D-Knoten, aber es handelt sich um spezifischere Typen von Knoten zwei D, einschließlich der Kamera selbst. Es gibt zwei D-Charaktere, zwei statische D-Körper, zwei animierte D-Sprites usw. eines von ihnen auswählen, werden Sie im Inspektor sehen , dass sie die Eigenschaften haben, die mit Knoten zwei D bezeichnet werden, sowie die Transformationseigenschaft, die ihre Position, Drehung, Skalierung und Neigung enthält Drehung, Skalierung und Neigung den Typ unseres Motivs auf Knoten zwei D setzen, kann die Kamera alles in unserer Szene verfolgen , was als Knoten zwei D gilt. Da wir nur wissen müssen, dass es eine Position hat, an der die Kamera ihm folgen kann, klicken Sie auf den Spielercharakter und ziehen Sie ihn in das exportierte Feld für unser Kameramotiv. Bei der Prozessmethode, die 60 Mal pro Sekunde ausgeführt wird, können wir die Position der Kamera einfach an die Position des Motivs Das ist das gleiche Verhalten, als die Kamera noch in der Kindheit war , ohne dass die Figur vertikal bewegt wurde, Reisekrankheit erheblich reduziert Es wäre jedoch hilfreicher, wenn die Figur nicht mittig im Blickfeld der Kamera Stattdessen sollte es vor dem Charakter und leicht nach oben schauen , damit der Spieler relevantere Teile des Levels sehen kann . Wie bei den animierten Sprites können wir unserem Kameraskript einen Offset hinzufügen , um es von seiner ursprünglichen Position zu verschieben Wir machen daraus eine exportierte private Variable unterstreichen den Offset-Wert mit dem Typ von Vector Ein Vektor zwei enthält zwei Gleitkommazahlen, einen X- und einen Y-Wert. Er wird verwendet, um alles in zwei Dimensionen zu definieren, einschließlich der Positionsvariablen , mit denen wir gearbeitet haben Jetzt kann die Prozessmethode einfach den X-Teil des Offsets zur X-Position der Kamera hinzufügen . Wenn wir die Figur genau am Ursprung der Szene positionieren, können wir die Kamera bewegen, um uns eine Vorstellung davon zu geben , wo sie unserer Meinung nach gut aussehen wird. Verwenden Sie dann die aktuelle Position der Kamera als Offset-Wert. Alternativ können Sie den Offset in Kacheln definieren und ihn mit Google Ppt in der Ready-Methode multiplizieren. Jetzt folgt die Kamera der horizontalen Bewegung des Spielers und schaut dabei nach vorne nach rechts. Aber was ist, wenn wir nicht wollen, dass unsere Level so linear sind? Was ist, wenn der Spieler nach links gehen möchte? Die Kamera sollte auch nach links des Charakters schauen. Die Kamera muss auf eine von der Figur ausgeführte Aktion reagieren . Wir haben zwei Funktionen in unserem Charakterskript, die immer dann aufgerufen werden, wenn der Spieler nach links oder rechts schaut, aber diese werden bei jeder Eingabe ständig aufgerufen. Rufen wir diese Funktionen nur auf, wenn der Charakter tatsächlich die Richtung ändert. Dazu können wir eine private Variable exportieren, um zu speichern, ob das Zeichen gerade nach links zeigt oder nicht . Als boolescher Wert. Bei den Methoden face left und face right wird dieser Wert entsprechend auf true oder false gesetzt dieser Wert entsprechend auf true oder false Dann können wir zu Beginn des physikalischen Prozesses Bedingungen hinzufügen, die festlegen, dass Face Left nur aufgerufen wird, wenn der Charakter noch nicht nach links schaut, wenn er nach links schaut. Jetzt haben wir unsere Methoden „Gesicht links“ und „Gesicht rechts nur dann aufgerufen werden, wenn der Spieler beschließt, seine Richtung zu ändern. Wir sollten während der Ready-Methode auch die entsprechenden Methoden „Gesicht links“ oder „Gesicht rechts“ aufrufen während der Ready-Methode auch die entsprechenden Methoden „Gesicht links“ oder „Gesicht rechts basierend auf dem Wert der exportierten Variablen. Dies hat auch den Vorteil , dass diese Funktion mit den Charakteren funktioniert, deren Sprites nach links zeigen Standardmäßig kann das Kameraskript nun mithilfe von Signalen auf Richtungsänderungen des Charakters reagieren mithilfe von Signalen auf Richtungsänderungen Am Anfang des Zeichenskripts können wir ein benutzerdefiniertes Signal erstellen, das wir Richtungsänderung nennen, und einen Parameter hinzufügen, der der Kamera mitteilt , ob der Charakter gerade nach links schaut. Jetzt können die Methoden face left und face right diesem Signal mitteilen, dass es als Argument angeben soll, ob das Zeichen jetzt nach links zeigt oder nicht. Wenn die Charakternotizen im Szenenbaum ausgewählt sind. Wechseln Sie zum Knotenbereich, klicken Sie mit der rechten Maustaste auf unser neues Signal und wählen Sie Verbinden. Wählen Sie dann die Kamera aus. Notiz aus der Liste. Die Kamera wird auf dieses Signal warten. Wir können die Methode umbenennen , die daraufhin aufgerufen wird. Um sie in Begriffe zu bringen , die im Kontext der Kamera leichter zu verstehen sind , nennen wir sie „Motiv hat Richtung geändert“. Die Methode wird dem Kameraskript automatisch hinzugefügt. Jetzt können wir den Offset der Kamera so ändern , dass er nach links oder rechts schaut. Da wir wissen, in welche Richtung der Charakter zeigt. Um den Wert des Offsets beizubehalten, erstellen wir eine weitere private Variable mit dem Namen Look Ahead distance. Dies beginnt mit einer Kopie des Unterstrich-Offsets X, der während der Bereitschaftsphase mit der Einstellung „Bereit“ festgelegt während der Bereitschaftsphase mit der Einstellung „Bereit Dann können wir den Abstand für den Blick nach vorne als X-Offset festlegen , aber mit minus eins multipliziert, wenn das Motiv nach links schaut, oder mit einem positiven Wert, wenn dies nicht der Fall ist links schaut, oder mit einem positiven Wert, wenn dies nicht der Verwenden Sie dann die Entfernung mit Blick nach vorne in der Prozessfunktion, um die Position der Kamera festzulegen Jetzt schaut die Kamera dem Charakter voraus , egal in welche Richtung er schaut. Aber was ist, wenn wir wollen , dass auch unsere Level steigen und fallen? Wir können eine ähnliche Methode verwenden, um die Kamera darauf reagieren zu lassen , dass das Objekt ein Signal aussendet. Diesmal bewegt man die Kamera, wenn der Charakter am Ende seines Sprungs landet, passt die Kamera so an eine neue Höhe im Zeichenskript an. Fügen wir ein weiteres Signal namens Landed hinzu und übergeben einen Parameter namens Floor Height, der ein Float sein wird. Woher wissen wir, wann der Charakter landet? Nun, wir haben die Methode „Praktisch ist auf dem Boden“. Wenn wir diesen Wert in einer privaten Variablen speichern, nennen wir ihn was on floor als booleschen Wir werden ihn hier aufnehmen. Oben bewegen und rutschen. Nachdem wir die Folie bewegt haben, können wir überprüfen, ob der Charakter nicht auf dem Boden war und sich jetzt auf dem Boden befindet, was bedeutet, dass er genau in diesem Moment gelandet ist. Rufen wir hier eine neue private Methode namens underscore landed auf eine Definition für diese Methode schreiben, müssen wir hier im Moment eigentlich nichts weiter tun, außer das Landing-Signal, das in unserer Y-Position vorbeigeht, als neue Bodenhöhe auszugeben in unserer Y-Position vorbeigeht, als neue Bodenhöhe Wenn die Kamera angewiesen wird, auf das Signal zu warten, kann die Kamera dann eine neue Methode aufrufen , die aufgerufen wird , wenn das Objekt gelandet ist. Wir müssen lediglich den Wert der Y-Position der Kamera so anpassen , dass er der neuen Bodenhöhe zuzüglich des Y-Offsets entspricht. Wir haben jetzt die Kamera, die dem Spieler folgt, sodass wir Ebenen erstellen können, die größer sind als das, was wir auf einem einzigen Bildschirm unterbringen können, aber die Bewegungen sind ruckelig. In der nächsten Lektion werden wir die Kamera mithilfe von Tweens sanft zwischen diesen Positionen bewegen lassen mithilfe von Tweens sanft zwischen diesen Positionen Wir sehen uns in der nächsten Lektion. 25. 3 4 Tween: Hallo Freunde. In der letzten Lektion bewegen wir die Kamera und folgen dem Spieler, wie er sich nach rechts, links, oben und unten bewegt . In dieser Lektion lassen wir die Kamera sanft zwischen diesen Positionen hin- und Die einfachste Methode, Werte im Laufe der Zeit schrittweise anzupassen , ist die Verwendung eines Tweens Lassen Sie uns zwei neue private Variablen deklarieren. Ganz oben in unserem Kameraskript haben wir zwei verschiedene Signale, die zwei unterschiedliche Verhaltensweisen in unserem Kameraskript auslösen zwei unterschiedliche Verhaltensweisen in unserem Kameraskript Wir möchten, dass diese voneinander getrennt bleiben. Die erste Variable wird Look Ahead Tween heißen, die zweite Floor Height Tween Beide sind vom Typ Tween. Beginnend mit dem Look-Ahead-Tween können wir, wenn unser Motiv die Richtung ändert, wenn unser Motiv die Richtung ändert, den Wert von Look-Ahead-Tween festlegen, um ein Tween zu erstellen Dies ist eine integrierte Methode, mit der wir unser Tweening-Verhalten schnell und einfach erstellen können unser Tweening-Verhalten schnell und einfach erstellen Dann weisen wir dieses Look-Ahead-Tween an, um eine Eigenschaft miteinander zu verbinden beginnen wir damit, zu welchem Knoten die Eigenschaft gehört, welcher sie selbst Dann geben wir den Namen der Eigenschaft in Anführungszeichen an Wir werden den Wert der vorausschauenden Entfernung zu Wert verrechnen, den wir bereits über einen bestimmten Zeitraum berechnet Vorerst sagen wir 1 Sekunde. Das sieht besser aus. Aber wenn der Spieler die Richtung ändert , während die Kamera keucht, sollten wir nicht zwei Tweens gleichzeitig erzeugen , die um die Kontrolle über die Kamera konkurrieren Es scheint keine Probleme zu verursachen. Wir können die Möglichkeit jedoch ausschließen, indem wir zunächst prüfen ob der Tween bereits existiert und ausgeführt wird Wenn das stimmt, sollten wir es beenden, bevor wir ein anderes starten Dieses Tween ist derzeit linear und hat eine Dauer von 1 Sekunde Wir können es jedoch leicht anpassen , um eine Vielzahl von Effekten zu erzielen Exportieren wir zunächst eine Float-Variable namens underscore duration und geben ihr den Standardwert eins Dann fügen Sie diese Variable in den Tween-Methodenaufruf ein. Wir können jetzt die Geschwindigkeit anpassen, mit der die Kamera geschwenkt wird , indem wir einfach den Wert dieser Variablen im Inspektor ändern den Wert dieser Variablen im Inspektor Denken Sie daran, dass Sie das Spiel nicht beenden müssen , um die Werte im Inspektor anzupassen. Ich denke, das sollte etwas langsamer sein, falls der Spieler einem Feind den Rücken zukehrt, aber nicht möchte, dass er sofort aus dem Blickfeld genommen wird. zum Beispiel zu ändern, wie sich die Kamera im Laufe der Zeit bewegt, können wir dem Tween Beschleunigungs- und Übergangstypen hinzufügen, sodass es sich am Anfang oder Ende langsamer oder schneller bewegt am Anfang oder Ende langsamer oder schneller Sie können sogar abprallen oder sich über die definierten Grenzen hinaus bewegen. Lassen Sie uns eine neue private Variable namens trans type exportieren. Der Typ dieser Variablen wird vom Typ Tween Transition sein. Wenn wir dann das Tween erstellen, können wir auch eine andere Methode aufrufen settrans übergeben unseren Übergangstyp als Argument für diese Wir können das tun, weil sowohl die Methode create tween Methode set trans das Tween zurückgeben Infolgedessen erstellt die Methode create tween das Tween und gibt es zurück, was dann verwendet wird, um das Set trans aufzurufen und das Tween wieder zurückzugeben, das dann unserer Variablen zugewiesen wird. Wenn Sie die Kamera im Szenenbaum auswählen und sich den Inspektor ansehen, werden Sie feststellen, dass der Standard für den Übergangstyp linear ist, was bedeutet, dass der Wert dann unserer Variablen zugewiesen wird. Wenn Sie die Kamera im Szenenbaum auswählen und sich den Inspektor ansehen, Kamera im Szenenbaum auswählen und sich den werden Sie feststellen, dass der Standard für den Übergangstyp linear ist, was bedeutet, gleichmäßig über dem Dauer aus dem Drop-down-Menü Es gibt eine Vielzahl von Optionen, mit denen Sie festlegen können, wie sich der Wert im Laufe der Zeit ändern wird. Wir können auch eine weitere Variable namens Easing Type hinzufügen, ähnlich wie Tween Ease Type Dadurch wird der Übergang so geändert, dass er nur den Anfang oder das Ende des Tweens oder beides betrifft nur den Anfang oder das Ende des Tweens oder beides Genau wie beim Übergangstyp können wir auch den Beschleunigungstyp in derselben Codezeile festlegen bei der Erstellung des Tweens mit verschiedenen Dauern, Experimentieren Sie bei der Erstellung des Tweens mit verschiedenen Dauern, Übergängen und Beschleunigungstypen, um zu sehen, wie sie sich anfühlen Wir können dieselbe Technik verwenden, um die aktuelle Bodenhöhe der Kamera im Laufe der Zeit schrittweise anzupassen , nachdem das , nachdem Anstatt einen harten Schnitt zu verwenden, müssen wir zunächst die aktuelle Bodenhöhe in einer privaten Variablen speichern . Wenn der Betreff dann landet, können wir den Großteil desselben Codes aus dem Moment kopieren , in dem die Richtung geändert wurde. Dabei ändern nur die Tween-Variable von „Blick voraus“ auf Stockwerkhöhe“ und ändern auch den Eigenschaftsnamen , mit dem wir den Wert tweeten We will Tween Tween Two ist das Gleiche wie der Methodenparameter. Anschließend können wir die Prozessmethode so bearbeiten, dass die Y-Position der Kamera der Bodenhöhe plus dem Versatz Y entspricht. Jetzt schwenkt die Kamera nach der Landung des Motivs sanft nach oben oder unten und passt sich an die neue Bodenhöhe Wenn Sie möchten, dass diese beiden Verhaltensweisen unterschiedliche Dauern, Übergangstypen oder Beschleunigungstypen haben , müssen Sie lediglich weitere Variablen für sie exportieren Ich möchte, dass das horizontale Malen langsamer und sanfter ist, das vertikale aber schneller und reaktiver Ich wünsche mir eine längere Dauer für das Horizontale, aber auch den Easetyp, um sowohl rein als auch raus zu sein. Für die vertikale Variante habe ich eine kürzere Dauer und nur die Lockerung. Die Kamera bewegt sich zuerst schneller und nach uns langsamer. Je nachdem, welche Version von du verwendest, kann es ein Problem geben, wenn du sowohl die Kamera als auch den Charakter gleichzeitig bewegst , was zu einem zitternden Effekt führt Versuchen Sie, die Projekteinstellungen zu öffnen , um dieses Problem zu beheben. Suchen Sie unten im Displayfenster nach V Sync und deaktivieren Sie die Einstellung. Jetzt haben wir unsere Kamera, die dem Spieler auf sanfte und sanfte Weise genau das zeigt , was er sehen muss. In der nächsten Lektion fügen wir unserer Szene einen animierten Hintergrund hinzu. Wir sehen uns in der nächsten Lektion. 26. 2-5 Hintergrund: Hallo Freunde. In der vorherigen Lektion haben wir das Verhaltensskript unserer Kamera fertiggestellt, sodass es dem Spielercharakter folgt. In dieser Lektion fügen wir unserem Level einen animierten Hintergrund hinzu. Der Hintergrund des Levels muss den Eindruck erwecken, dass er sehr weit weg ist. Andernfalls erscheint die Umgebung Spieler sehr flach und zweidimensional. Wir können eine Illusion von Tiefe erzeugen, Wir können eine Illusion von Tiefe erzeugen indem wir der Kamera einen untergeordneten Knoten hinzufügen. Ein Knoten mit zwei D hat einen Positionswert sowie einen Z-Index, einen Namenshintergrund. Erweitern Sie dann den Bestellbereich unter dem Canvas-Element und legen Sie den Z-Index dieses Knotens auf einen negativen Wert fest. Das ebene Terrain verwendet den Standard-Z-Index Null. eingezeichnet Je nachdem, wie viele Tiefenebenen Sie in Ihrer Umgebung haben möchten, wird eine negative Zahl dahinter . Möglicherweise möchten Sie den Z-Index des Hintergrunds weiter hinten platzieren als nur den negativen Ich setze den Hintergrund auf minus zehn und lasse negative Eins bis minus Neun für alles verfügbar , was sich zwischen Hintergrund und Terrain befinden muss zwischen Hintergrund und Terrain Auch wenn ich nicht vorhabe, das zu tun, ist es besser, die Möglichkeit dabei zu belassen. Jetzt folgt jeder untergeordnete Knoten, den wir zu diesem Knoten hinzufügen , automatisch der Kamera und wird , automatisch der Kamera und wird hinter alles andere im Level gezogen. Das Asset-Paket enthält mehrere Sprites, mit denen wir eine Hintergrundumgebung zusammenstellen können eine Hintergrundumgebung zusammenstellen Wir können einfach auf die Bilder für den Hintergrund klicken und sie in unsere Szene ziehen die Bilder für den Hintergrund klicken und sie in unsere Szene Und Godot verwandelt sie automatisch in eine Sprite-Gruppe mit zwei D-Knoten und wählt alle neuen Machen Sie sie alle zu Kindern des Hintergrundknotens. Indem ich sie hineinziehe, dehne ich einfach die Sonnenuntergangs-, Himmels- und Wasserbilder sodass sie das gesamte Ansichtsfenster der Kamera abdecken Lassen Sie uns den Hintergrund zu einer eigenen Szene machen, sodass er isoliert bearbeitet werden kann , und speichern wir ihn im Szenenordner Klicken Sie dann auf das Clapper Board-Symbol, um es zu öffnen. Im selben Ordner befinden sich einige Sprite-Animationen, die das Wasser zum Funkeln bringen Fügen wir drei animierte Sprites mit zwei D in unsere Naht ein. Wir können dann jedes davon mit einer Sprite-Frames-Ressource füllen davon mit einer Sprite-Frames-Ressource Und die Sprite-Frames mit jeder der drei Sprite-Animationen füllen mit jeder der drei Sprite-Animationen Stellen Sie außerdem sicher, dass sie ihre Animationen automatisch in der Endlosschleife mit der richtigen Bildrate abspielen, positionieren Sie sie dann jeweils so im und positionieren Sie sie dann jeweils so im Wasser Wenn Sie fertig sind, können Sie Ihre Arbeit speichern und sehen, wie sie aussehen wird, indem Sie die Hauptszene ausführen Als Nächstes fügen wir dem Himmel einige Wolken hinzu. Diese sind nicht animiert, also können wir sie einfach in die 2-D-Ansicht ziehen , um Sprite zu zwei D-Knoten zu machen Wenn Sie anpassen möchten, wie die Sprites geschichtet werden, können wir, anstatt den Z-Indexwert jedes Sprites anzupassen, anstatt den Z-Indexwert jedes Sprites anzupassen, auch den Szenenbaum verwenden, um die Knoten neu anzuordnen Knoten mit demselben Z-Index werden vom oberen Rand des Szenenbaums nach unten gezogen die Liste der Wolken einfach nach ihrer Größe organisieren wird auch ihre Reihenfolge sortiert und die kleinste Wolke hinten und die größte Wolke vorne platziert. Wow, wow. Diese größte Wolke ist auch schon größer als das Sichtfenster der Kamera und hat diese harten Kanten Sie ist so konzipiert , dass sie mithilfe einer Technik namens Parallax-Scrolling in sich selbst herumläuft mithilfe einer Technik namens Parallax-Scrolling in sich selbst dupliziert Wir können zwei davon in unserer Szene platzieren und sie nach und nach zur Seite bewegen. Wenn sich einer dann vom Bildschirm bewegt, können wir ihn auf die andere Seite verschieben, sodass er sich unendlich im Hintergrund wiederholt Dadurch wird die Illusion von Tiefe , dass der Hintergrund weit entfernt ist, weiter verstärkt, aber es entsteht auch die Illusion, dass Wind weht Fügen wir dem Stammknoten dieser Szene ein Skript hinzu, das den Parallax-Scrolling-Effekt erzeugt Zuerst benötigen wir einen Verweis auf die untergeordneten Knoten, die wir verschieben möchten. Wir können at und ready verwenden, um einen Verweis auf die untergeordneten Knoten, die wir verschieben möchten. Wir können at und ready verwenden, diese in Variablen zu speichern, wobei wir sicherstellen müssen, dass wir die genauen Namen der Knoten nach dem Dollarzeichen in ihren Lassen Sie uns auch eine Variable für die Scrollgeschwindigkeit exportieren. Dabei handelt es sich um einen Float, der auf der Palmenanimation basiert Es wird impliziert, dass der Wind nach links weht. Verwenden wir in der Prozessmethode einen Standardwert von minus 100 Wir können dann der Exposition der Wolken eine Scrollgeschwindigkeit multipliziert mit Delta hinzufügen , sodass sie sich mit konstanter Geschwindigkeit nach links bewegen Aber wir werden das mit fünf verschiedenen Wolken machen. Es wäre also besser, diese Methode so zu gestalten, dass ein Knoten zwei D als Parameter zusammen mit der Entfernung, über die gescrollt wird, als Float Dann können wir einfach die Entfernung zu seiner Position hinzufügen. Jetzt kann die Prozessmethode diese Methode aufrufen jede Wolke zusammen mit der Scrollgeschwindigkeit multipliziert mit Delta übergeben der Scrollgeschwindigkeit multipliziert mit Delta Um die Entfernung pro Bild zu berechnen, können wir die Illusion von Tiefe weiter verbessern indem wir die Wolken auch mit unterschiedlichen Geschwindigkeiten bewegen. Dabei bewegen sich die größeren Wolken, die dem Spieler am nächsten schneller und die kleineren Wolken, die weiter entfernt sind, langsamer Vermeiden Sie es jedoch, Geschwindigkeitsmultiplikatoren zu verwenden , die ein Vielfaches voneinander sind Dadurch entsteht ein sehr offensichtliches Muster und die Illusion wird durchbrochen , wenn eine Wolkengeschwindigkeit genau der Hälfte einer anderen entspricht Zum Beispiel wird der Spieler feststellen, dass es hilfreich ist, Primzahlen für zu verwenden. Das Letzte, was wir tun müssen , ist zu überprüfen, ob sich eine unserer Wolken vollständig von der Kamera entfernt hat, sie dann auf die andere Seite bewegen. Wenn wir eine große Wolke in der Mitte positionieren, befindet sich die andere jetzt dort, wo sie sich befinden wird , wenn sie sich umrunden soll Das entspricht auch der Pixelbreite des Bildes. Lassen Sie uns diesen exportierten Breitenwert variable Variable vom Typ Float mit dem Standardwert 448 geprüft, ob die Position x einer Wolke kleiner ist als mit minus Eins Wir können es dann um die Breite multipliziert mit zwei nach rechts verschieben , um es auf die andere Seite der zweiten großen Wolke zu legen Dadurch drehen sich auch die anderen Wolken regelmäßigen Abständen um sich selbst. Mal sehen, wie schön das aussieht. Sobald Ihr Spieler jedoch die Größe des Spielfensters ändert, ist die Illusion gebrochen Wenn wir die Projekteinstellungen unter dem Anzeigefenster öffnen, können wir die gewünschte Auflösung für unser Spiel einstellen Noch wichtiger ist, dass wir den Stretch-Modus auf Stretch-Canvas-Objekte umstellen können den Stretch-Modus auf Stretch-Canvas-Objekte Das ist alles in unserem Two-D-Spiel. Wir wollen auf jeden Fall unser Seitenverhältnis beibehalten , auch wenn der Spieler die Fenstergröße ändert Eine neue Funktion wurde kürzlich hinzugefügt Wir können das Dehnen auch so einschränken , dass es nur um ganzzahlige Werte skaliert wird. Dadurch kann verhindert werden, dass unsere Pixel in inkonsistenten Größen gezeichnet werden Sobald Sie sich für eine Auflösungseinstellung entschieden haben, stellen Sie sicher, dass Ihr Hintergrund den neuen Einstellungen entspricht und dass es unmöglich sein sollte, und dass es unmöglich sein sollte außerhalb Ihres Hintergrunds zu sehen Jetzt haben wir einen schönen bewölkten Sonnenuntergang im Hintergrund unseres Levels. In der nächsten Lektion werden wir Wasser in den Vordergrund stellen. Wir sehen uns in der nächsten Lektion. 27. 2-6 Wasser: Hallo, Freunde. In der vorherigen Lektion haben wir unserer Szene einen animierten Hintergrund hinzugefügt. In dieser Lektion fügen wir Wasser in den Vordergrund ein. Für diese Lektion habe ich einen weiteren Soundeffekt für Spritzwasser heruntergeladen und geändert Dieser Soundeffekt wurde von Yin Yang Jake 007 auf FreeSound.org erstellt . Genau wie der Hintergrund können wir damit beginnen, einen Wurzelknoten für den Vordergrund zu erstellen Diesmal verwenden wir einen D-Node im Bereich zwei und nennen ihn Wasser. Setzen Sie dann den Z-Index auf eine positive Zahl, sodass er immer im Vordergrund gezeichnet wird, sodass Platz für zusätzliche Ebenen dazwischen bleibt. Die Objekte für Wasser im Asset-Paket haben eine Animation für Wellen und ein flaches Quadrat für alles andere. Fügen wir nun einen animierten Sprite-Zwei-D-Knoten für die Wasseroberfläche Erstellen Sie eine neue Sprite-Frames-Ressource. Fügen Sie die Autoplay-Schleife für Sprite-Frames hinzu und legen Sie dann die Framerate fest, fügen Sie einen Offset hinzu oder verschieben Sie die animierte Sprites-Transformation so, dass der Ursprung des Wassers in der oberen linken Ecke liegt Dadurch wird es einfacher, sich an der Kachelkarte auszurichten, und auch der Y-Wert angegeben, wenn Null die Wasseroberfläche ist Fügen Sie dann auch das unterste Sprite als Sprite-Zwei-D-Knoten hinzu. Der untere Teil kann zwar leicht gedehnt werden, um einen beliebigen Bereich auszufüllen, die Oberfläche muss dupliziert und wiederholt werden , damit der Szenenbaum übersichtlich bleibt Wir sollten einen zweiten Knoten D erstellen, zusammenklappbarer Ordner fungiert, in dem diese animierten Sprites gespeichert diese animierten Sprites Der Bereich zwei D benötigt eine Form, um zu definieren, wie seine Kollision funktionieren soll Die Wasserphysik benötigt zwei unterschiedliche Verhaltensweisen. Wenn sich etwas auf der Wasseroberfläche befindet und wenn es sich unter Wasser befindet, können wir ein Liniensegment verwenden das über die Wasseroberfläche gezogen wird, da es uns sagt, ob etwas die Oberfläche berührt oder nicht. Sie der Einfachheit halber sicher, dass der Ursprung des Wasserobjekts mit dem Surface Collider übereinstimmt Lassen Sie uns auch schnell eine unserer Staubpartikelszenen duplizieren , um eine Splash-Szene zu erstellen Löschen Sie dann die Sprite-Frames in dieser Szene und ersetzen Sie sie durch die Splash-One-Sprites aus dem Asset-Paket Damit das Wasser auf Kollisionen reagieren kann, müssen wir ein Wasserskript erstellen Dieses Skript muss auf zwei Signale reagieren, wenn ein Körper es betritt und ein Körper es verlässt Wir können diese Signale einfach mit dem Skript selbst verbinden, indem wir die Standardnamen verwenden Die Body-Parameter dieser Methoden sind vom Typ Node Two D, wie Sie der Signalliste entnehmen können. Aber um zu definieren, wie unsere Charaktere in Bezug auf das Wasser verhalten werden, müssen wir wissen, ob es sich bei diesem Knoten zwei D namens Körper um einen Charakter handelt oder ob es sich um etwas anderes handelt. Wir müssen unserem Zeichenskript einen Klassennamen geben , bevor das Wort erweitert wird. Fügen Sie in der ersten Zeile den Klassennamen und das Zeichen hinzu. Dies ist jetzt ein Wort , das andere Skripte verwenden können, um dieses Skript als allgemeinen Typ zu bezeichnen. Zurück in der Wasserschrift, wenn ein Körper ins Wasser kommt, können wir jetzt überprüfen, ob es sich bei dem Körper um eine Figur handelt Dann rufen wir eine Methode auf, die wir noch nicht definiert haben. Diese nennen wir in der Y-Position des Wassers , also der Wasseroberfläche im Körper, betreten und passieren . Methode beendet. Wir können dieselbe Prüfung durchführen, um zu sehen, ob es sich bei dem Körper um eine Figur handelt Auch hier kann eines von zwei Dingen passieren, wenn ein Charakter den Raum verlässt, , nicht mehr berührt was bedeutet, dass er das Liniensegment, das die Wasseroberfläche bedeckt zwei Dingen passieren Entweder befinden sie sich jetzt über der Wasseroberfläche oder sie befinden sich unter der Wasseroberfläche Da wir wissen, dass die Y-Position dieses Knotens die Wasseroberfläche ist, hat der Körper auch eine Y-Position. Wir können die beiden Werte vergleichen , um festzustellen, welcher Fall das ist. Aber auch das Hinzufügen von globalem PPT, geteilt durch zwei oder zwei Kacheln. Wenn die Körperposition kleiner oder gleich der Wasseroberfläche ist , bedeutet das, dass der Körper aufgehört hat , Kontakt mit der Wasseroberfläche aufzunehmen und sich vollständig über der Wasseroberfläche befindet. Da Pixel pro Kachel als Ganzzahl definiert sind, Position y jedoch als Gleitkommazahl definiert ist, warnt uns Godel davor, dass Dezimalwerte ignoriert werden Wir können hier Abhilfe schaffen, indem wir den Integer-Wert in einen Float-Wert umwandeln und der Charakter das Wasser verlässt Andernfalls befindet sich der Charakter unter der Wasseroberfläche Und wir sollten eine andere Methode nennen, die ich Dive nennen werde. zum Zeichenskript wechseln, können wir diese drei Methodendefinitionen zu unseren öffentlichen Methoden hinzufügen . Geben Sie Wasser ein. Dabei wird als Parameter ein Gleitkommawert verwendet, der die Wasseroberfläche darstellt. Tauchen Sie auch und verlassen Sie das Wasser. Der Zweck dieser öffentlichen Methoden besteht darin, den physikalischen Prozess - und Sprungmethoden mitzuteilen, wo der Charakter befindet und wie er sich verhalten soll. Wir müssen einige neue private Variablen hinzufügen. Die Höhe der Wasseroberfläche als Float und zwei Boolesche Werte, die uns sagen, ob sich der Charakter im Wasser befindet und ob er der Charakter im Wasser befindet sich unter der Jede unserer neuen Methoden kann diese Variablen jetzt entsprechend setzen Wenn Wasser eindringt, gibt die Höhe der Wasseroberfläche , dass wir uns im Wasser befinden, aber nicht unter dem Oberflächenaustritt. Das Wasser setzt ab, wenn es im Wasser abfällt. Der Tauchgang findet einfach unter der Oberfläche statt. Um der Physik gerecht zu werden, müssen wir uns überlegen, ob der Charakter schwimmt oder sinkt und wie stark der Aufenthalt im Wasser seine Bewegung einschränkt Wir können unserem Skript eine neue Kategorie exportierter Variablen namens Swim hinzufügen unserem Skript eine neue Kategorie exportierter Variablen namens Swim Der Einfachheit halber können wir den Wert, der bestimmt ob ein Zeichen schwebt oder nicht, , ob ein Zeichen schwebt oder nicht, Dichte nennen und ihm einen Standardwert von minus 0,1 geben . Dieser Wert wird mit der Dichte von Wasser verglichen Ein Wert von Null hat einen perfekten Auftrieb, weniger als Null schwebt, ein Wert von mehr als Null sinkt, um Wir können auch einen Wert für den Luftwiderstand definieren, multipliziert wird, um deren Kräften multipliziert wird, um deren Effektivität zu verringern Und verwenden Sie einen Standardwert von 0,5 Wenn ein Objekt zum ersten Mal die Wasseroberfläche erreicht, wirkt eine Aufprallkraft, die seine Geschwindigkeit reduziert. Bei der Methode „In Wasser eintauchen Wenn unsere Geschwindigkeit y größer als Null ist, können wir sie mit dem Luftwiderstand multiplizieren. Um diese Aufprallkraft zu simulieren, genau wie wir es mit dem Boden in der Luftphysik gemacht haben, können wir zuerst den physikalischen Prozess einchecken , ob sich die Figur im Wasser befindet , dann Wasserphysik anwenden sicherstellen, dass Delta passiert der nächsten Zeile auf else ändern, prüfen, ob sie auf dem Boden ist. Horizontale Bewegungen im Wasser verhalten sich fast genauso wie auf dem Boden, wobei jedoch die Verzögerung und Beschleunigung auch mit dem Luftwiderstand multipliziert werden , um ihre Effektivität zu verringern. Da ich diese Zeile von oben kopiert habe, muss ich die Verzögerung in die Beschleunigung ändern Die vertikale Bewegung hängt davon ab, ob sich der Charakter unter der Wasseroberfläche befindet oder ob seine Dichte größer als Null ist In beiden Fällen müssen wir ihre Y-Geschwindigkeit in Richtung des Auftriebs, also der Schwerkraft multipliziert mit der Dichte , bewegen und außerdem Luftwiderstand anwenden, um die Geschwindigkeit zu verlangsamen Die Änderungsrate wird anhand von Schwerkraft mal Luftwiderstand mal Delta berechnet Schwerkraft mal Luftwiderstand mal Delta Wenn der Charakter die Wasseroberfläche berührt, wollen wir, dass er auf und ab wackelt. Was mit einer weiteren if-Anweisung in zwei Situationen aufgeteilt werden kann . Wenn der Auftriebsmittelpunkt des Charakters über oder unter der Wasseroberfläche liegt , passen Sie die Y-Geschwindigkeit entsprechend an, passen Sie die Y-Geschwindigkeit um sich nach oben oder unten zu bewegen Wir können das so vereinfachen, dass die Position y des Charakters minus ein Viertel einer Kachel kleiner ist als die Oberflächenhöhe des Wassers Der Einfachheit halber können wir einfach die Formel von oben multipliziert mit minus eins kopieren die Formel von oben multipliziert mit , wenn sie sich unter der Wasseroberfläche befinden , um sich in die entgegengesetzte Richtung zu bewegen Das Letzte, was wir tun müssen, ist ändern, wie Springen im Wasser funktioniert Wenn sich der Charakter im Wasser und unter der Oberfläche befindet, sollte die Sprunggeschwindigkeit durch den Luftwiderstand beeinflusst werden. Wenn sich der Charakter nicht unter der Oberfläche befindet, sollte er über die volle Sprungkraft verfügen sodass er problemlos an Land springen kann. Wir können hier auch das Landesignal ausgeben , um die Kamera einzustellen. Auch wenn sie ins Wasser kommen auch die Stop-Jump-Methode sollte auch die Stop-Jump-Methode deaktiviert werden, während sie sich im Wasser befinden. Während wir das Charakterskript geöffnet haben, kopieren wir die Spawn-Dust-Methode und verwenden sie, um eine Splash-Methode zu erstellen Im Water-Skript benötigen wir einen Verweis auf die gepackte Szene, die den Splash enthält Unsere Variablen und Methoden entsprechend umbenennen. Da das Wasser den Spritzer erzeugt und das Wasser sich nicht bewegt, kann der Spritzer problemlos ins Wasser gespült Die Y-Position der Spritzer wird standardmäßig auf Null gesetzt, was bereits der Wasseroberfläche entspricht Und ihre globale X-Position kann auf den Wert gesetzt werden , der als Argument an die Methode übergeben wurde Dies ist die Position des Körpers , der in das Wasser eingedrungen ist , um den Spritzer zu erzeugen. Wir können die X-Position des Splash genau so einstellen, dass sie dieser Position entspricht. Das Wasser benötigt außerdem einen Audio-Stream-Player zwei D, um den Splash-Soundeffekt zu erzeugen. Befüllt mit der modifizierten Datei, die ich von FreeSound.org heruntergeladen habe , kann das Skript einen Verweis auf diesen untergeordneten Knoten abrufen während der Bereitstellungsphase einen Verweis auf diesen untergeordneten Knoten abrufen und dann den Soundeffekt anweisen, dann den Soundeffekt anweisen Wir können jedes Mal einen Spritzer erzeugen, wenn ein Körper in das Wasser eindringt und dabei die Position des Körpers Und wenn der Körper eines Charakters beschließt, das Wasser zu verlassen, das Wasser so zu positionieren, dass der Spieler darauf zugreifen kann, und daran denken, die mit Spritzwasser gefüllte Szene im Inspektor zu füllen , können wir ihn kurz testen und alle gewünschten Anpassungen am Dichtewiderstand des Charakters oder an der Berechnung des Auftriebs oder des Knallens an der Oberfläche vornehmen Dichtewiderstand des Charakters oder an der Berechnung des Auftriebs oder des Knallens an der , bis Wenn das Wasser voll funktionsfähig ist, sollten wir dafür sorgen, dass es den gesamten Vordergrund des Levels umfasst. Wenn Sie den Boden dehnen, die Oberfläche duplizieren und die Kollisionsform so bearbeiten, dass sie dem Boden entspricht , den wir in der allerersten Lektion erstellt haben , kann das auch Ihnen im Weg stehen. Jetzt haben wir das Wasser im Vordergrund unseres Levels und Charaktere können darin schwimmen In der nächsten Lektion strukturieren wir unser Level und fügen Grenzen hinzu. Wir sehen uns in der nächsten Lektion. 28. 2-7 Grenzen: Hallo Freunde. In der vorherigen Lektion haben wir Wasser in den Vordergrund unserer Szene gesetzt. In dieser Lektion richten wir die Struktur für unsere Level und unsere Grenzen ein. Erstens löst die Kachelmap gerade das Splash-Geräusch aus. Wenn wir unsere Szene ausführen, Hinzufügen einer Bedingung zu der Methode „Body kann das Hinzufügen einer Bedingung zu der Methode „Body entered“ zurückgeben, ob es sich bei dem Body um eine Kachelmap handelt, wodurch verhindert wird, dass dieser Code ausgeführt Auch in diesem Fall einige der Wasseranimationen beim Ausführen der Szene möglicherweise nicht wurden einige der Wasseranimationen beim Ausführen der Szene möglicherweise nicht synchronisiert. Dies ist nur ein vorübergehendes Problem, das dadurch verursacht wird, dass die Animationen im Editor abgespielt Wenn Sie auf den scrollenden Wolken eine Naht sehen, können Sie die Breiteneigenschaft auch um ein Pixel reduzieren Wir sollten auch die Collider der übrigen Charaktere so anpassen Collider der übrigen Charaktere so anpassen , dass sie sauber auf dem Boden stehen können Unser Szenenbaum ist jetzt voll von vielen verschiedenen Komponenten. Die Knoten Label und Floor sind nicht mehr relevant. Lassen Sie uns diese löschen. Wir sollten alle Knoten, die zum Aufbau verschiedener Ebenen verwendet werden , in einen Zweig unterteilen, sodass alle unsere Dekorationen zu untergeordneten Objekten eines Knotens zwei D werden. Diese werden einfacher zu organisieren, machen dasselbe mit unseren Feinden und machen sie alle zu Kindern eines Knotens zwei D, machen sie alle zu Kindern eines damit sie organisiert bleiben. Da dies alles Bestandteile unseres Spiellevels sind, können wir einen neuen Bereich mit zwei D erstellen sie sich befinden, und ihn Level nennen. Dann mache die Kachel zu Kartendekorationen, Feinden und Wasserkindern des Levelknotens. Der Einfachheit halber legen wir vorübergehend den Ursprung des Levels als des Spielers fest und bewegen den Spieler zum Ausgangspunkt der Szene. Passen Sie dann alle untergeordneten Knoten der Ebene so an, dass sie übereinstimmen. Speichern Sie die Ebene als eigene Szene, die in einen neuen Ordner mit dem Namen Levels gehört. Wir können diese Ebene eins, eins nennen. Die Kamera und der Hintergrund des Spielercharakters werden für jedes Level verwendet , da das Asset-Paket keine anderen Elemente für Hintergründe enthält. Je nachdem, wie Sie Ihr Spiel gestalten möchten, kann der Hintergrund auch Teil des Levels sein. Wir können jetzt das erste Level mit einer Szene öffnen. Da wir den Wurzelknoten unseres Levels zu einem Bereich mit zwei D gemacht haben, bedeutet das, dass wir ihm eine Form geben können. Definieren wir unsere Ebene als Rechteck. Und passen Sie die Größe und Position des Rechtecks an, um Grenzen zu definieren, auf die sich der Spieler und die Kamera beschränken werden. Und passen Sie die D-Bug-Farbe dieses Kollisionsbereichs so an, dass sie transparenter ist. Es hat keinen Einfluss auf unsere Sicht auf alles andere. ein neues Skript für das Level erstellen, können wir während der Bereitschaftsphase einen Verweis auf den D-Knoten der Kollisionsform erhalten . Der Zweck dieses Rechtecks besteht darin, dass der Spieler und die Kamera wissen, wo sie aufhören müssen. Wir müssen die Mindest- und Höchstwerte ermitteln die innerhalb der Grenzen dieses Rechtecks zulässig Schreiben wir zwei Methoden, get min und get max, die öffentlich sind und einen Vektor zwei zurückgeben Der Mindestwert entspricht der Position der Kollisionsformen minus der Hälfte ihrer Größe. Aber um auf die Größe zuzugreifen, müssen wir zuerst auf ihre Form, dann auf das Rechteck, dann auf die Größe und den Vorgang für den Maximalwert wiederholen. Um zu vermeiden, dass dieser Code mehrmals wiederholt wird, sollten wir ihn auch als Variable definieren und ihn halbe Größe nennen. Zurück zur Hauptszene. Der Zweck dieser Szene besteht darin Kommunikation zwischen dem Spielercharakter, der Kamera und dem aktuellen Level zu erleichtern , sodass wir das Level bei Bedarf einfach durch ein neues austauschen können. Du kannst diese Szene und ihren Stammknoten umbenennen , um diesem Zweck Rechnung zu tragen. In einem einfachen Spiel wie diesem können Sie dies die Hauptszene oder die Spielszene nennen . Wenn dein Gameplay-Loop neben Plattformspielen auch anderes Gameplay beinhaltet , solltest du der Plattform-Szene vielleicht einen Namen geben um sie von anderen Gameplay-Szenen zu unterscheiden Um die Regeln für die Funktionsweise dieser Gameplay-Szene festzulegen, sollten wir ihr ein Skript geben Der Name des Skripts ist normalerweise der Name der Szene, gefolgt vom Wort Manager. Die Aufgabe dieses Managers besteht darin , sicherzustellen, dass alle untergeordneten Notizen alle Informationen enthalten , die sie für ihre jeweiligen Aufgaben benötigen . Um zu verhindern, dass der Spielercharakter oder die Kamera die Grenzen des Levels verlassen, müssen sie wissen, was diese Grenzen sind. Da in dieser Szene jedes Level ausgeführt werden kann, muss sie die Informationen über die Grenzen des Levels aus dem Level-Skript anfordern über die Grenzen des Levels aus dem Level-Skript und diese Informationen sowohl an das Charakterskript des Spielers als auch an die Kamera weitergeben . Ganz oben im Manager-Skript. Lassen Sie uns in der Ready-Methode zunächst Verweise auf das Level, den Spieler und die Kamera abrufen . Wir können dann die Grenzen des Levels ermitteln und die Grenzen für den Spieler und die Kamera festlegen . Jetzt benötigen sowohl der Charakter als auch die Kameraskripte öffentliche Methoden, um diese Grenzen festzulegen und benötigen sowohl der Charakter als auch die Kameraskripte öffentliche Methoden, um diese Grenzen festzulegen diese Grenzen dann auch selbst durchzusetzen. Ausgehend vom Charakter können wir einfach zwei neue Variablen vom Typ Vector Two erstellen und die Minimal - und Maximalwerte speichern. Schreiben Sie eine Set-Bounds-Methode , die zwei Vektoren zwei verwendet und die Werte der privaten Variablen festlegt Am Ende des physikalischen Prozesses können wir dann mithilfe der Clamp-Methode die Position des Zeichens so einschränken, dass sie innerhalb dieser Grenzen für den aktuellen Wert ein Minimum und ein Maximum angegeben Es liegt an dir, ob du diese Einschränkungen für alle Charaktere in deinem Spiel oder nur für den Spielercharakter festlegen möchtest. Aber ich denke, dass es den Feinden freistehen sollte , die Levelgrenzen in meinem Spiel zu verlassen. Ich mache diesen letzten Schritt davon abhängig ob diese Grenzen gesetzt wurden oder nicht , indem ich auch eine boolesche Variable mit dem Namen is bound hinzufüge eine boolesche Variable Wenn die Methode set bounds den Spielercharakter aufgerufen wird, wird diese Variable ebenfalls auf true gesetzt, andere Zeichen bleiben jedoch ungebunden andere Zeichen bleiben jedoch ungebunden Die Kamera wird etwas komplizierter sein da die Kamera selbst auch eine Form hat Dieselben Variablen und die gleiche Methode werden in das Kameraskript kopiert . Wir können die Werte von min und max bearbeiten , um sie an die Größe der Kameraansicht anzupassen. Wir können diesen Wert mit Get Viewport Wrecked Size dividiert durch Zoom und Verkleinerung um die Hälfte abrufen Viewport Wrecked Size dividiert durch Zoom und Verkleinerung um Dann addieren Sie diesen Wert zum Minimum und subtrahieren Sie ihn vom Maximum Es ist fast immer besser, einen berechneten Wert in einer Variablen zu speichern berechneten Wert in , als ihn mehrmals zu berechnen Dann können wir die Position der Kamera auf die gleiche Weise festlegen, wie wir es bei den Charakteren gemacht haben. Lass es uns ausprobieren. Die Kameraansicht ist innerhalb der Levelgrenze enthalten ebenso wie der Ursprung des Charakters, und sie funktioniert von allen Seiten. Wir können Roger ganz auf dem Bildschirm behalten , indem wir dieselbe Logik anwenden und dabei die Größe des Sprites verwenden Da das Sprite jedoch nicht auf den Ursprung des Charakters ausgerichtet ist, müssen wir die X - und Y-Werte unterschiedlich berechnen Jetzt ist Roger nur noch erlaubt , wenn das gesamte Sprite auf dem Bildschirm bleibt In diesem Abschnitt haben wir viele der Funktionen entwickelt, die zur Generierung von Levels für unser Spiel verwendet werden Generierung von Levels für unser Spiel Im nächsten Abschnitt werden wir unserer Hauptszene sammelbare Schätze und eine Benutzeroberfläche hinzufügen sammelbare Schätze und unserer Hauptszene sammelbare Schätze und eine Benutzeroberfläche hinzufügen Wir sehen uns im nächsten Abschnitt. 29. 3-1-Daten: Hallo Freunde. Im vorherigen Abschnitt haben wir viele der Strukturkomponenten gebaut, die wir für den Aufbau von Levels unseres Spiels benötigen. In diesem Abschnitt werden wir sammelbare Schätze erstellen, die der Spieler sammeln und in unseren Levels verteilen kann Wenn du die Aufgabe abgeschlossen hast, solltest du zwei grundlegende Level mit unterschiedlichen Terrains, Dekorationen und Grenzen haben unterschiedlichen Terrains, Dekorationen und Grenzen Als du diese Aufgabe erledigt hast, hast du wahrscheinlich auch Anpassungen vorgenommen, damit es besser zu deinem Spiel passt oder sich besser anfühlt Ich habe zum Beispiel die Bildlaufgeschwindigkeit der Wolken auf minus 32 Pixel pro Sekunde reduziert, weil mir nicht gefiel, wie sie aussahen, wenn die Kamera tweeenete die Bildlaufgeschwindigkeit der Wolken auf minus 32 Pixel pro Sekunde reduziert, weil mir nicht gefiel, wie sie aussahen, wenn die Kamera tweeenete Als sich die Kamera umdrehte, reduzierte ich die Schwerkraft um etwa die Hälfte des vorherigen Werts und änderte die Werte für alle Charaktere, Fortbewegung Ich habe auch eine kleine Korrektur am Splash-Soundeffekt im Wasser-Skript Da die beiden D-Knoten des Audioplayers die Lautstärke je nach Nähe zur Kamera reduzieren, wird der Ton leiser weiter Sie vom Anfang des Levels entfernt sind. Um dieses Problem zu beheben, habe ich die globale Exposition des Audio-Stream-Player-Knotens auf die Exposition eingestellt des Audio-Stream-Player-Knotens auf , die an die Methode übergeben wurde, dass der Ton Lautstärke von derselben Stelle stammt bei voller Lautstärke von derselben Stelle stammt wie der Splash Tutorials sollten zwar immer das Letzte sein, was du für dein Spiel erstellst, ich möchte die Gelegenheit nutzen, um einige Leveldesign-Prinzipien für intuitives Lernen zu besprechen einige Leveldesign-Prinzipien für intuitives Beim ersten Insel-Level begann der Spieler mit einem unmittelbaren Hindernis, über das er springen muss, gefolgt von einem höheren und einem noch höheren Hindernis. Danach sollte das für den Spieler ausreichend sein, um zu verstehen, dass er die Sprungtaste gedrückt halten kann , um den oberen Teil des zweiten Hindernisses zu erreichen, aber nicht das dritte Hindernis. Ich habe den Baum als Einwegplattform in einer sicheren Umgebung eingeführt und verlangt, dass der Spieler lernt, ihn zu benutzen , bevor er den nächsten Abschnitt des Levels erreicht. Hier sind dieselben Bäume verfügbar, allerdings ist das Risiko etwas höher, dass man von Baum zu Baum springen und möglicherweise ins Wasser fällt. Wenn sie scheitern, ist das Risiko nicht real, sondern wird nur vom Spieler wahrgenommen. von diesem Teil habe ich drei verschiedene Wege entwickelt, wobei der einfachste der Weg nach vorne und die anderen beiden möglicherweise zu Belohnungen führen. Alle sind deutlich sichtbar und zeigen dem Spieler, dass er in Zukunft nach abzweigenden Pfaden wie diesem Ausschau halten sollte in Zukunft nach abzweigenden Pfaden wie diesem ich das nächste Mal auf so etwas stoße, sieht der Spieler die Belohnung zuerst, muss aber umkehren, um sie erneut zu erhalten, und zeigt dem Spieler, wonach er suchen sollte Dies ist das erste Mal, dass ich einen Baum im Hintergrund verwende. Weil ich nicht wollte, dass der Spieler denkt, er könnte auf diesen Baum springen, scheitern und fälschlicherweise lernen, dass nicht alle Bäume Plattformen sind Zu diesem Zeitpunkt hat der Spieler Erfahrung damit, Bäume im Vordergrund als Plattformen zu nutzen Dieser Baum ist so positioniert , dass er vom Baum auf der linken Seite oder vom Boden aus besprungen werden kann Baum auf der linken Seite oder vom Boden aus Dadurch wird dem Spieler beigebracht, dass nur Bäume im Hintergrund keine Plattformen sind , um fortzufahren . Er muss den Baum im Hintergrund ignorieren und von der Kante springen Falls der erste Baum nicht funktioniert hat, habe ich ihm stattdessen einen zweiten Baum nachgebaut, der den Spieler dazu verleiten sollte, darauf zu springen . Und stattdessen folgen Hier ist eine weitere geheime Höhle. Aber dieses Mal kann der Spieler es nicht sehen. Wenn sie aus den vorherigen Teilen des Levels gelernt haben , dass sie das Wasser erkunden sollten, werden sie belohnt. Alle diese Eingänge ins Wasser sind deutlich mit zwei Lichtstrahlen markiert, die dazu beitragen, die Aufmerksamkeit des zwei Lichtstrahlen markiert, die dazu beitragen, die Spielers zu erregen und das Wasser einladend aussehen zu lassen Ich habe Bäume im Vordergrund und im Hintergrund zusammengefügt, um die Fähigkeit des Spielers zu testen, zum höchsten Baum zu springen Die Bäume lassen sich außerdem anhand ihrer Färbung und ihrer Schichtung vor oder hinter dem Spieler unterscheiden ihrer Färbung und ihrer Schichtung vor oder hinter Verwendung einheitlicher Farben oder Beleuchtung, um Aufmerksamkeit des Spielers zu erregen, wird als Verwendung von Bildsprache oder Anlässen bezeichnet , um dem Spieler mitzuteilen , dass er an diesem Ort oder mit diesem Objekt etwas tun kann oder sollte Ort oder mit diesem Objekt etwas tun kann oder Viele Spiele verwenden diese Techniken um auf kletterbare Felsvorsprünge, zerbrechliche Objekte und interagierbare NBCs hinzuweisen zerbrechliche Objekte und interagierbare NBCs Oder um dir zu sagen, wann du eine bestimmte Waffe oder Fähigkeit einsetzen solltest . Das erste Level aus dem Weg räumen, es durch ein Schiffs-Level ersetzen und die Knoten umbenennen Ich kann dann stattdessen das andere Level spielen. der Spieler dieses Level erreicht hat, hat er ein gutes Verständnis der Plattformmechanik und muss nicht erst unterrichtet werden Stattdessen konzentriere ich mich darauf, das allgemeine Erscheinungsbild eines Piratenschiffs zu kreieren und das gesamte Level so zu gestalten, dass es einen Rumpf darstellt Und zusätzliche Kacheln hinzugefügt, um den Hintergrund zu verbergen , bis der Spieler den Wasserspiegel erreicht Ich habe bestimmte Räume und Sackgassen mit Fässern und Flaschen dekoriert und die Treppen thematisch angeordnet, und die Treppen thematisch angeordnet thematisch angeordnet der Spieler das Schiff nie verlassen Bevor der Spieler einen Schatz sammeln kann, müssen wir ein Skript erstellen, um zu wissen, wie viele Schätze er hat Wir können dieses Skript in den Autolodes-Ordner legen und es Data nennen Aber anstatt den Knoten zu erweitern, müssen wir diesmal Wir können die Vorlage entfernen. Der Zweck des Skripts wird darin bestehen, alle Informationen über den Fortschritt eines Spielers im Spiel zu speichern alle Informationen über den Fortschritt eines . Um zu beginnen, fügen wir einfach eine Ganzzahl hinzu, die die Anzahl der Münzen angibt, die der Spieler gesammelt hat, und eine weitere Ganzzahl, die die Anzahl der verbleibenden Leben des Spielers angibt. wir diese Variablen exportieren, können wir sie im Inspektor ansehen, während das Spiel läuft. Falls nötig, ist der Standardwert für eine Ganzzahl Null, was für die Münzen eines Spielers als Startwert in Ordnung ist, aber nicht so gut für sein Leben zu Beginn des Spiels. Wir sollten genau definieren, was diese Ressource enthalten soll , wenn sie zum ersten Mal erstellt wird. Unterstreichen Sie darin, dass wir die Anfangswerte für jede Variable festlegen und jede andere Logik ausführen können , die wir wollen Im Rahmen der Ressourceninitialisierung möchte ich, dass die Spieler mein Spiel mit null Münzen und drei Leben beginnen mit null Münzen und drei Um diese Ressource nach ihrem Typ referenzieren zu können, müssen wir ihr einen Klassennamen geben Nennen wir sie Daten mit einem großen D. Je komplizierter unser Spiel wird, desto mehr wird diese Datenressource enthalten Variablen verschiedener Typen um den Fortschritt der Spieler zu verfolgen. Jetzt haben wir einen Ort, an dem wir diese Informationen speichern können, aber wir benötigen die Skripte in unserem Spiel , um frei darauf zugreifen zu können. Wie beim globalen Autoload können wir einen weiteren Autoload erstellen, können wir einen weiteren Autoload erstellen dessen Verantwortung darin besteht, auf die Daten zuzugreifen und sie zu verwalten. Nennen wir diese Datei eine Variable namens data mit einem Kleinbuchstaben vom Typ data mit einem Großbuchstaben D enthält einem Kleinbuchstaben vom Typ data mit einem Großbuchstaben . Der Zweck des Skripts wird darin bestehen, dem Rest des Spiels Zugriff auf die aktuelle Datendatei zu gewähren, aber auch die Datendatei zu verwalten Hier müssen wir Methoden schreiben, um ein neues Spiel zu starten , zwei zu speichern und zu laden Wir sind wirklich nur daran interessiert eine neue Datenressource zu erstellen. Wir sollten den Wert von Daten auf data setzen, new data new erzeugt eine neue Datenressource und löst automatisch die Init-Methode aus, die wir gerade geschrieben haben, wodurch die Leben auf drei statt auf Null gesetzt Im Moment können wir einfach die neue Spielmethode aufrufen , wenn dieser Knoten bereit ist Öffnen Sie die Projekteinstellungen, wechseln Sie zur Registerkarte „Automatisches Laden“ fügen Sie dann das neue Dateiskript zur Liste der automatischen Ladevorgänge hinzu. Der Standardknotenname funktioniert einwandfrei, wenn wir diese Szene ausführen. Wir können zu Gott zurückkehren, während das Spiel läuft. Wechseln Sie dann auf der Registerkarte Szene von lokal zu remote. Dies zeigt uns den Szenenbaum für das Spiel, das gerade läuft. den Knoten „Datei automatisch geladen“ auswählen und in den Inspektor schauen, können wir sehen, dass er über eine Datenressource verfügt. Der Name der Datenressource ist die Objekt-ID, gefolgt von einer langen Zahl. auf die Ressource klicken, können wir ihren Inhalt anzeigen und bearbeiten. Jedes unserer Skripte kann problemlos auf diese Informationen zugreifen. Um das zu demonstrieren, öffnen wir das Game Manager-Skript. Und nachdem wir das übliche Zeug mit den Levelgrenzen gemacht haben, drucken wir einfach den Wert der abgelegten Leben aus, wenn die Szene läuft, und schon sehen wir, dass Nummer drei im Ausgabefeld gedruckt wird. Wir haben jetzt eine benutzerdefinierte Ressource eingerichtet, um die Informationen unserer Spieler zu speichern , auf die wir jederzeit zugreifen können. In der nächsten Lektion werden wir Münzen erstellen , die der Spieler sammeln kann. Wir sehen uns in der nächsten Lektion. 30. 3-2 Münzen: Hallo Freunde. In der vorherigen Lektion haben wir eine benutzerdefinierte Ressource erstellt um den Fortschritt und die Daten des Spielers zu verfolgen. In dieser Lektion werden wir Münzen zum Sammeln erstellen. Wir können sie über unsere Level verteilen , damit der Spieler sie sammeln Für diese Lektion habe ich eine Reihe von Sounds zum Klicken auf Münzen von FreeSound.org importiert , die von Val Inspire mit einer Creative Commons-Lizenz erstellt wurden mit einer Lassen Sie uns damit beginnen, unsere erste Ebene zu öffnen und einen neuen Node-2-D-Ordner für Treasure zu erstellen Münzen sind physische Objekte , die auf der Welt existieren. Wir müssen Kollisionen erkennen. Wir möchten vielleicht auch, dass sie von der Schwerkraft beeinflusst werden. Der Knoten, der diese Verhaltensweisen am besten definiert , ist ein starrer Körper mit zwei D-Knoten. Benennen wir es in Silbermünze um, damit wir unsere Münze sehen können. Lassen Sie uns zuerst ein animiertes Sprite hinzufügen. Erstellen Sie eine neue Sprite-Frames-Ressource. Suchen Sie die Sprites mit Silbermünzen im Asset-Paket und füllen Sie die Standardanimation aus Stellen Sie diese Standardanimation auf Autoplay Looping ein und legen Sie die Frames pro Sekunde fest Wir können diesem animierten Sprite auch eine zweite Animation hinzufügen , indem wir auf den Namen der Schaltfläche „ Animation hinzufügen Dieser Animationseffekt wird dann den Sprites mit Münzeffekt aus dem Asset-Paket gefüllt Sprites mit Münzeffekt aus dem Diese Animation sollte nicht wiederholt werden. Dies ist die Animation , die abgespielt werden sollte, wenn die Münze eingesammelt wurde, bevor sie verschwindet Wechselt zurück zur Standardanimation. So können wir die Größe und Form der Münze im Editor deutlich sehen . Jetzt, wo wir unsere Münze sehen können, müssen wir ihr, wie bei allen physikalischen Objekten dieser Kollisionen, wie bei allen physikalischen Objekten dieser Kollisionen, eine Kollisionsform geben , wodurch eine kreisförmige Ressource Wir können die Größe an die Größe der Münze anpassen . Möglicherweise müssen Sie die Grade-Snap-Funktion deaktivieren Kollisionen mit Münzen erzeugen in der Regel auch Soundeffekte erzeugen in der Regel auch Soundeffekte Wir sollten auch einen Audio-Stream-Player zu De Node hinzufügen und ihn mit dem Coin-Cl-Soundeffekt bestücken Speichern wir den Silbermünzzweig als eigene Szene und legen sie in einen neuen Szenenordner mit dem Namen Treasure Wie alles andere benötigen Münzen ein Skript, um zu kontrollieren, wie sie sich verhalten. Wir sollten anfangen, unsere Skripte in dafür vorgesehenen Ordnern zu organisieren . Ich werde einen Nacktordner für Schatzskripte erstellen. Wir können unser Skript starten, indem Referenzen auf die Sprite- und Audioplayer-Knoten während der Bereitschaftsphase Referenzen auf die Sprite- und Audioplayer-Knoten abrufen. Wenn der Wurzelknoten der Münze ausgewählt ist, verbinden Sie das eingegebene Signal mit Wurzelknoten der Münze ausgewählt ist, sich selbst, sodass die Münze auf Kollisionen mit anderen Körpern reagieren kann reagieren Wenn ein Körper den Coin Collider betritt, sollten wir zuerst den Soundeffekt abspielen Dann wollen wir überprüfen, ob es sich bei dem Objekt, mit dem die Münze kollidiert ist, um etwas anderes handelt als um ein Zeichen, und wenn es kein Zeichen ist, kehren wir zurück, damit es ignoriert wird Wenn das tatsächlich ein Charakter ist, können wir dem animierten Sprite sagen, dass es die Effektanimation abspielen soll Dann soll dieser Knoten aus der Szene entfernt werden. Mit einem kostenlosen Code wird dieser gesamte Code in einem einzigen Frame ausgeführt. Wir werden nicht sehen, wie sich die Animation abspielt. Wir können hier einen neuen Befehl namens Weight verwenden , um diesen Code anzuhalten, bis etwas passiert. Wir wollen warten, bis die Sprite-Animation fertig ist und der Wurzelknoten des Coins ausgewählt Wir müssen einige der Standardeinstellungen für den Starrkörperknoten ändern Standardeinstellungen für den Starrkörperknoten Standardmäßig wird das vom Körper eingegebene Signal nur dann ausgelöst, wenn sich die Collider überlappen Aber da die Physik sowohl auf den Charakter als auch auf die Münze angewendet wird, wird das nicht passieren Der Collider des Charakters drückt stattdessen den Coin Collider Wir können diese Einstellungen so ändern, dass das Signal ausgelöst wird, wenn sich die Collider berühren. Indem wir den Kontaktmonitor auf true setzen , werden maximal Kontakte gemeldet die einen Wert größer als Null haben, aber als Nächstes sollten wir eigentlich nur noch einen benötigen Erweitern Sie den Deaktivierungsbereich. Die meisten Leute würden nicht wollen, dass sich die Pixel drehen, also können wir die Rotation der Münzen sperren indem wir auf dieses Kästchen klicken Sammelmünzen lassen sich in den meisten Spielen in eine von zwei Kategorien Diejenigen, die in der Luft schweben, und solche, die herumgeworfen werden, nachdem sie eine Kiste zerbrochen oder einen Feind besiegt Wir können die erste Option wählen, indem wir die Freeze-Eigenschaft auf true setzen und den Freeze-Modus auf Kinematic ändern Jetzt wird die Münze nicht mehr von der Physik, einschließlich der Schwerkraft, beeinflusst , sondern sie wird trotzdem mit anderen Objekten kollidieren Wenn wir die Schwerkraft einschalten oder die Münze herumwerfen lassen wollen , setzen wir Freeze einfach auf False und wenden die gewünschten Kräfte darauf an Wir wollen auch sicherstellen, dass unsere Münzen nur vom Spielercharakter eingesammelt werden, nicht von den Feinden oder anderen Charakteren Der einfachste Weg, dies zu erreichen, ist die Verwendung von Kollisionsebenen. Bisher hat alles in unserem Spiel die Standard-Kollisionsebene, Ebene eins, verwendet. Mithilfe verschiedener Kollisionsebenen können wir leicht steuern , welche Objekte auf andere Objekte reagieren oder diese ignorieren. Lassen wir die Standardebene, Ebene eins, das Terrain darstellen. Da die meisten, wenn nicht sogar alle Objekte standardmäßig damit kollidieren müssen, möchten wir vielleicht in Zukunft unterschiedliche Umgebungstypen mit unterschiedlichen Kollisionstypen haben. Lassen wir die Welt einfach die ersten acht Kollisionsebenen verwenden, um Umgebungstypen mit unterschiedlichen in Zukunft unterschiedliche Umgebungstypen mit unterschiedlichen Kollisionstypen haben. Lassen wir die Welt einfach die ersten acht Kollisionsebenen verwenden, Lassen wir die Welt einfach die ersten acht Kollisionsebenen verwenden die Rogers-Szene zu öffnen Wir können seine Kollisionsebene auf Ebene neun ändern und den zweiten Block die Kollisionsebenen unserer Spieler darstellen lassen den zweiten Block die Kollisionsebenen unserer Spieler darstellen Ebenso können wir die gegnerischen Charaktere auf Ebene 17 platzieren. Und lass den dritten Block unsere feindlichen Kollisionsebenen darstellen. Schließlich können sich die Münzen auf Ebene 25 befinden, wobei der vierte Block einen Schatz darstellt. dem Maskenbereich der Mit dem Maskenbereich der Kollisionsebenen wird dieses Objekt kollidieren Das Einzige, womit die Münze kollidieren soll, ist die Umwelt Und der Spieler, den wir auf die Ebenen eins und neun Münzen gesetzt haben , ignoriert jetzt Kollisionen mit Feinden und anderen Schätzen Ich werde den Spielercharakter mit Feinden kollidieren lassen, Feinde kollidieren sowohl mit dem Spieler als auch Wir sollten auch die Projekteinstellungen öffnen und jeder dieser Kollisionsebenen Namen geben , damit wir uns leicht daran erinnern können, wofür wir sie reserviert haben Die Namen werden als Tooltip angezeigt, wenn im Inspektor mit der Maus über die Kollisionsebene Das Asset-Paket enthält einen zweiten Satz von Coin-Sprites für eine Goldmünze Lassen Sie uns unsere Silbermünzen-Szene duplizieren und sie in Goldmünze umbenennen Und ersetzen Sie die Silbermünzen-Sprites durch Goldmünzen-Sprites wenn wir möchten, dass verschiedene Münzen unterschiedliche Stückelungen haben Wir können unserem Skript auch einen exportierten Integer-Wert hinzufügen und ihm für mein Spiel den Standardwert eins geben eins Ich werde Goldmünzen im Wert von zehn Silbermünzen herstellen. zwar unwahrscheinlich, aber es ist möglich , dass der Spieler , nachdem er mit der Münze kollidiert, ein zweites Mal mit derselben Münze kollidiert, bevor sie verschwindet Um dies zu verhindern, sollten wir die Kollisionsmaske der Münze auf Null setzen und so die Möglichkeit ausschließen, dass sie nach dem Sammeln mit etwas anderem kollidiert eine von jeder Münze in unserem Level platziert, Spieler eine von jeder Münze in unserem Level platziert, kann er sie nun einsammeln. Wir können Wasser auch auf einer vom Terrain getrennten Ebene platzieren und es sowohl mit Charakteren als auch mit Schätzen kollidieren sowohl mit Charakteren als auch mit Schätzen und der Ebene in den Projekteinstellungen einen Namen Wir haben jetzt Sammelmünzen mit unterschiedlichem Wert , die der Spieler im Laufe des Spiels sammeln möchte In der nächsten Lektion werden wir eine Benutzeroberfläche mit einem Zähler erstellen, eine Benutzeroberfläche mit einem Zähler der dem Spieler zeigt, wie viele Münzen er hat Wir sehen uns in der nächsten Lektion. 31. 3-3-Benutzeroberfläche: Hallo Freunde. In der vorherigen Lektion haben wir Münzen mit unterschiedlichem Wert erstellt , die der Spieler sammeln kann. In dieser Lektion zeigen wir auf der Benutzeroberfläche an, wie viele Münzen der Spieler hat. In der Max-Szene der Hauptplattform können wir eine Benutzeroberfläche hinzufügen, auf der alle wichtigen Informationen angezeigt werden, die der Spieler benötigt. Diese Informationen sollten unabhängig von der Kamera sein und immer vor allem anderen angezeigt werden. Könnten Sie vielleicht versucht sein, dies zu einem Kind der Kamera zu machen , so wie wir es mit dem Hintergrund gemacht haben Es gibt keinen Typ, um dies einfacher zu erstellen , die so genannte Leinwandebene Jeder zweite Knoten in Arsene hat eine Zeichenreihenfolge, die auf seinem festgelegten Index und seiner Position im Szenenbaum basiert auf seinem festgelegten Index und seiner Position im Szenenbaum Aber nachdem alles von der Kamera zu einem einzigen Bild verarbeitet wurde , wird all das zur Standardebene, Ebene Null Eine Leinwandebene zeichnet standardmäßig ein ganz neues Bild auf die erste Ebene. Darüber hinaus werden die Leinwandebenen mit einem neuen Knotentyp gefüllt. In der allerersten Lektion haben wir tatsächlich einen verwendet. Diese werden Kontrollknoten genannt und sind grün markiert. Um Zahlen auf dem Bildschirm anzuzeigen, könnten wir einen Label-Node verwenden , der jeden beliebigen Text anzeigen kann, aber das würde nicht wirklich zu unserer Pixel-Art-Ästhetik passen. Und unser Asset-Paket enthält nette Zahlen-Sprites, also verwenden wir stattdessen diese Wir können der Canvas-Ebene Kontrollknoten namens Texture Rets hinzufügen , um diese Sprites für uns anzuzeigen Lassen Sie uns eine Textur für die eine Ziffer und eine weitere für die zehnte Ziffer und beide mit Nullen füllen Standardmäßig müssen Sie ein Limit für die Anzahl der Ziffern festlegen , die Sie auf dem Bildschirm anzeigen möchten Gemäß den Konventionen von Spielen wie Mario und Donkey Kong werde ich die Anzahl der Münzen auf 99 begrenzen und dem Spieler für jeweils 100 gesammelte Münzen eine zusätzliche Belohnung geben dem Spieler für jeweils 100 gesammelte Münzen eine zusätzliche Belohnung Wir sollten auch eine Icon-Textur hinzufügen , um dem Spieler mitzuteilen, was diese Zahl bedeutet, und sie mit dem Bild einer Münze füllen, um zu vermeiden, einzelne Kontrollknoten manuell neu angeordnet werden Auf der Leinwandebene gibt es auch Knoten von Godot, deren Zweck es ist, ihre untergeordneten Knoten für uns zu organisieren Fügen wir der Leinwand ein horizontales Feld hinzu, nennen wir es Münzzähler und legen unsere anderen Knoten als untergeordnete Objekte der Box Sie werden automatisch neu angeordnet, sodass sie horizontal in die Box passen Ich positioniere diesen Zähler 32 Pixel von der Ecke entfernt Und erhöht sich auf zwei Stufen, es ist viel einfacher zu erkennen und zu lesen Anschließend können wir die Einstellungen der einzelnen Steuerelemente bearbeiten , um festzulegen, wie sie im Verhältnis zu ihrem übergeordneten Container dargestellt werden im Verhältnis zu ihrem übergeordneten Container Ich möchte, dass das Symbol proportional zu seiner Breite angezeigt wird proportional zu seiner Breite Und skalieren Sie, um es an die Größe des übergeordneten Containers anzupassen. Die Ziffern würde ich gerne verdoppeln , damit sie leichter zu lesen sind. Da ich weiß, dass sie fünf Pixel breit sind, setze ich ihre benutzerdefinierte Mindestbreite auf zehn Pixel. Passen Sie sie proportional zu ihrer Körpergröße an. Und behalten Sie ihr Seitenverhältnis bei und halten Sie sie gleichzeitig in der Mitte des übergeordneten Elements Beachten Sie, wie die Steuerelemente der Leinwand hier im Wasser gezeichnet werden. Wenn wir jedoch auf Play klicken, werden sie in der oberen linken Ecke des Fensters angezeigt. Wenn Sie sich an die erste Lektion erinnern, das Bild, das standardmäßig auf dem Bildschirm gezeichnet wird , dieses blaue Rechteck. Wenn es hilft, kannst du das Level, den Charakter und die Kamera ausblenden, während du auf der Leinwand arbeitest , indem du auf die Symbole klickst. Denke daran, sie wieder einzublenden, wenn du bereit bist, dein Spiel zu testen Experimentieren Sie mit Ihres Zählers auf dem Bildschirm und überprüfen Sie, wie er während des Spiels aussieht Damit der Zähler funktioniert, müssen wir ein Skript dafür schreiben Ich lege das in einen neuen Skriptordner für UI und nenne es Counter. Da die Natur eines Münzzählers nichts mit der Organisation einer horizontalen Box zu tun hat , werde ich ihn um die allgemeinere Art der Steuerung erweitern. Stattdessen benötigen wir während der Bereitstellungsphase Verweise auf jede unserer Textureinstellungen, die wir ändern möchten jede unserer Textureinstellungen, die wir ändern Wir benötigen außerdem eine Liste von Texturen, mit denen wir sie austauschen die jede unserer Zahlen 0-9 repräsentiert. Wir können diese in einem exportierten Array von Texturen speichern diese in einem exportierten Array von , die zwei D heißen, Unterstrichziffern Ein Array ähnelt einer Liste, in diesem Fall einer Liste von zwei D-Texturen oder Bildern von Zahlen, die im Inspektor erscheinen Wir können auf dieses exportierte Array klicken , um es zu erweitern und ihm eine Größe von zehn zu geben . Die Array-Elemente sind praktischerweise Null bis Neun nummeriert. Dies sind die Indizes, die wir verwenden, um auf die einzelnen Elemente des Arrays zuzugreifen. Füllen Sie jeden Array-Index mit der passenden Ziffer aus dem Asset-Paket Dieses Skript benötigt eine Funktion, die wir aufrufen können , um die Nummer festzulegen, die angezeigt wird Ich nenne es Set Value und nehme eine Ganzzahl als Parameter. wissen, dass dieser Zähler nur die Zahl 0-99 anzeigen soll , setzen wir zunächst diese Regel Indem Sie den Wert zwischen diesen Zahlen festklemmen. Wir können die Textur, die durch die Textur k angezeigt wird, so einstellen , es sich um Ziffern an einem Index handelt. Was ist der Index? Es ist dasselbe wie die Ziffer selbst. Aber wie extrahieren wir die eine Ziffer? Wir können einen in der Programmierung gebräuchlichen Operator namens Modulus verwenden , der durch das Prozentzeichen dargestellt wird und den Rest eines Divisionswerts zurückgibt Zehn gibt die eine Ziffer zurück, die der Array-Index der Textur ist , die angezeigt werden soll Wir können dann auch die Zehnerstelle festlegen indem wir Division statt Modulus durchführen Jetzt muss der Spieler mit unseren Münzen kollidieren , um unsere Benutzeroberfläche irgendwie zu aktualisieren Aber diese existieren in verschiedenen Szenen, was Signale oder Methodenaufrufe etwas schwierig macht Um diese Lücke zu schließen, können wir diese Verantwortung an den Spielmanager delegieren , da er als Stammknoten leicht zugänglich ist als Stammknoten leicht zugänglich und Zugriff auf alle Kinder hat Das Münzskript öffnen. Wenn die Münze eingesammelt ist, können wir anhand der Dollarzeichenwurzel, gefolgt von Game, dem Namen des Stammknotens der Szene, einen Verweis auf die Wurzel der Szene abrufen Dollarzeichenwurzel, gefolgt von Game, dem Namen des Stammknotens . Rufen Sie dann eine Methode im Game Manager-Skript , die wir noch nicht geschrieben haben. Wir sammeln Münzen und geben den Wert der gesammelten Münze weiter. zum Game Manager-Skript wechseln, benötigen wir während der Bereitschaftsphase einen Verweis auf den Münzzähler. Dabei muss es sich nicht um ein horizontales Feld handeln. Da wir auf nichts zugreifen , das für diesen Knotentyp spezifisch ist, interessiert uns eigentlich nur, dass es sich um eine Art Kontrollknoten handelt. Zunächst können wir diese Methode zum Sammeln von Münzen definieren, wobei der ganzzahlige Wert der Münze als Parameter verwendet wird. Als Nächstes fügen wir den Wert der Münze zu den Dateidaten hinzu. Aktualisieren Sie dann den Zähler auf der Benutzeroberfläche und setzen Sie seinen Wert auf den neuen Münzwert der Dateidaten. Außerdem sollte diese Aktualisierung des Zählers erfolgen, wenn die Naht zum ersten Mal geladen wird. Testen wir auch den Zähler, indem wir seinen Wert auf einen zufälligen Wert wie 77 setzen. die Szene ausführen, können wir sehen, dass sie tatsächlich auf 77 gesetzt wurde. Und wenn wir mit einer Silbermünze kollidieren, steigt der Zähler um eins Das Sammeln der Goldmünze erhöht sie ebenfalls um zehn. Sie können gerne testen, ob Sie den Zähler auf eine beliebige Zufallszahl, eine negative Zahl oder etwas höher als 99 einstellen den Zähler auf eine beliebige Zufallszahl, . Denken Sie jedoch daran, diese Zeile zu löschen. Wenn du fertig bist, warnt uns Gott, dass wir durch eine ganze Zahl dividieren. auf die Warnung klicken, gelangen wir zum Münzskript, wo wir tatsächlich durch eine Ganzzahl dividieren und Dezimalwerte ignoriert werden. Da dies beabsichtigt ist, können wir hier bei der Integer-Division eine zusätzliche Zeile hinzufügen. Um diese Warnung zu ignorieren, haben wir jetzt die Benutzeroberfläche, die anzeigt wie viele Münzen der Spieler gesammelt hat. In der nächsten Lektion werden wir einen Lebensgegenstand zum Sammeln hinzufügen und diesen ebenfalls verfolgen Wir sehen uns in der nächsten Lektion. 32. 3-4 Leben: Hallo Freunde. In der vorherigen Lektion haben wir einen Münzzähler erstellt , der auf der Benutzeroberfläche angezeigt werden soll. In dieser Lektion fügen wir unserem Spiel einen Lebensgegenstand zum Sammeln Fangen wir mit unserer ersten Level-Szene an. Das Kapital, das ich repräsentieren möchte, das Leben des Spielers in meinem Spiel, ist ein goldener Schädel. Und ich glaube nicht, dass es gut aussehen würde, wenn er durch Kräfte wie die Schwerkraft beeinflusst würde. Im Gegensatz zu Münzen möchte ich, dass es bedrohlicher und mysteriöser wirkt Es wird immer etwas sein, das schwebt, bis es eingesammelt wird Wir verwenden einen D-Node im zweiten Bereich, um seine grundlegenden Eigenschaften zu definieren und ihn in Golden Skull umzubenennen Fügen Sie dann ein animiertes Sprite hinzu. Zweitens: Erstellen Sie eine Sprite-Frames-Ressource und füllen Sie sie mit den Sprite-Objekten von Golden Skull Automatische Wiedergabe in einer Schleife und Einstellung der Frames pro Sekunde. Fügen Sie dann wie die Münze eine zweite Animation mit dem Namen Effect hinzu und füllen Sie sie mit den Sprites mit Schädel-Effekt zurück zum Schädel wechseln und ihn im Editor gut betrachten , können wir ihm eine Kollisionsform hinzufügen , die ein Kreis sein wird Ich passe das Sprite ein Pixel nach links und ein bisschen nach links an, damit es besser zentriert ist Und passe den Circle-Gleiter so an, dass er passt. Fügen Sie einen Audio-Stream-Player mit zwei D-Knoten hinzu. Der Soundeffekt , den ich für den Totenkopf ausgewählt habe , ist versteckt, offen, erzeugt durch eine New-Age-Suppe offen, erzeugt durch eine New-Age-Suppe Aber ich habe ihn in einem Audio-Editor etwas gekürzt, er ist immer noch länger als die Animation, also muss ich am Ende der Animation ein oder zwei leere Frames hinzufügen, damit der Sound zu Ende Speichern Sie dann den Schädelzweig als eigene Szenenposition, den Schädel, an dem er während unseres Tests gesammelt werden kann, öffnen Sie die Schädelszene und fügen Sie dem Wurzelknoten ein Skript hinzu Viele Verhaltensweisen des Schädels werden dem Münzskript, das wir zuvor geschrieben haben, sehr ähnlich sein. Beginnen wir damit, das Münzskript zu kopieren und in das Schädelskript einzufügen Mein Totenkopf-Skript benötigt keinen Wert, da jeder Schädel für ein Leben Aber es wird immer noch einen Sprite- und Soundeffekt haben , wenn es zu einer Kollision kommt Wir können immer noch dieselbe Logik anwenden, außer dem Teil , in dem wir dem Spielmanager mitteilen , dass der Spieler eine Münze gesammelt hat Lassen Sie uns das in eine separate private Methode namens underscore collect unterteilen und die Methode von derselben Stelle aus aufrufen die Methode von derselben Stelle aus zum Coin-Skript wechseln, können wir die gleichen Änderungen am Format vornehmen Jetzt ist alles in diesen beiden Skripten fast identisch, mit Ausnahme des Inhalts dieser einen Sammelmethode und sie erweitern verschiedene Knotentypen. Wenn wir die Münze und den Schädel auswählen, können wir sehen, dass beide Eigenschaften eines Kollisionsobjekts zwei D haben Eigenschaften eines Kollisionsobjekts zwei . Wir wollen nicht genau dasselbe Skript schreiben . Jedes Mal, wenn wir einen neuen Schatztyp erstellen, um ihn zu unserem Spiel hinzuzufügen, können wir ein abstrakteres Skript namens Schatz definieren und Kollisionsobjekt zwei D erweitern. Hier können wir alle gängigen Verhaltensweisen der verschiedene Arten von Schätzen für unser Spiel, wobei der gesamte Inhalt in das neue Schatzskript kopiert wird. Das Standardverhalten der Sammelmethode kann leer sein, da Schatz ein zu abstraktes Konzept ist , um zu wissen, was wir damit machen sollen, wenn er gesammelt wird. Der Zweck dieser Methode besteht einfach darin, Godot mitzuteilen , dass alles, was ein Schatz ist, gesammelt werden kann Geben Sie diesem Skript den Klassennamen Treasure. Da sowohl Münzen als auch Schädel unterschiedliche Arten von Kollisionsobjekten sind, können wir sie dazu bringen, den Schatz zu erweitern und alle nützlichen Vorteile zu nutzen, die wir in das Schatzskript gesteckt haben das Schatzskript gesteckt Jetzt haben wir in unserem Münzskript münzenspezifische Dinge wie außer Kraft setzen Anstatt nichts zu tun, können wir das Verhalten des Sammelns und stattdessen dem Spielmanager mitteilen , dass eine Münze eingesammelt wurde. Eine Methode, die eine andere Methode überschreibt , ist mit diesem blauen Pfeil gekennzeichnet Ihr habt vielleicht bemerkt , dass dieser Pfeil erscheint, wenn wir die Bereitschaftsmethode außer Kraft gesetzt haben Wenn der Schädel eingesammelt wird, wird der Game Manager ebenfalls darüber informiert, dass ein Schädel eingesammelt wurde Unabhängig davon, welche Art von Schatz gesammelt wird, werden dieselben Verhaltensweisen automatisch bei allen eingesammelt. Aber wir müssen vorsichtig sein und sicherstellen, dass alle Schätze diese untergeordneten Knoten haben und dass das animierte Sprite eine Effektanimation haben muss Verschiedene Objekttypen so zu behandeln, dass sie alle ein ähnliches Verhalten aufweisen, wird Polymorphismus genannt Alle Münzen und Schädel können wie Schätze behandelt werden. Der einzige Unterschied wird darin bestehen, was sie tun, wenn sie Alle neuen Schätze, die wir hinzufügen, können ebenfalls diesem Muster folgen. zum Game Manager-Skript wechseln, können wir einfach eine Methode zum Sammeln von Schädeln hinzufügen, wodurch die Lebenspunkte des Spielers um eins erhöht werden. Wenn das passiert, können wir beim Duplizieren der Münzzählerreferenz der Münzzählerreferenz eine Lebenszählerreferenz hinzufügen und dann auch die Benutzeroberfläche aktualisieren, wenn ein Leben hinzugefügt wird Da die Ready-Methode zwei verschiedene Aufgaben erledigt, die nichts miteinander zu tun haben, sollten wir sie in verschiedene Methoden unterteilen, um sie zu organisieren. Lassen Sie uns private Nit-Grenzen und It-UI-Methoden schreiben , die jede dieser Aufgaben isoliert ausführen dieser Aufgaben isoliert und von der Ready-Methode aufgerufen werden Ich werde mich an die Konventionen von Mario und Donkey Kong halten und dem Spieler ein Extraleben gewähren, dem Spieler ein Extraleben wenn er 100 Münzen gesammelt hat Wenn die Anzahl der abgegebenen Münzen größer oder gleich 100 ist, subtrahiere 100 Münzen, füge ein Leben hinzu und aktualisiere auch den Lebenspunktezähler aktualisiere auch den Lebenspunktezähler Als Nächstes können wir den Münzzählerknoten auf der Leinwandebene duplizieren und ihn in Lebenspunktzähler umbenennen Um dies in der oberen rechten Ecke zu platzieren, ändere ich die Eigenschaft Layoutrichtung auf von rechts nach links. Da mein Münzzähler 32 Pixel von der linken Bildschirmseite entfernt war . Ich kann das spiegeln, indem ich 64 Pixel abziehe , um dieselbe Polsterung auf der rechten Seite hinzuzufügen Umkehrung der Layoutrichtung auch die Reihenfolge der untergeordneten Knoten umgekehrt Mir gefällt, dass sich das Symbol auf der rechten Seite befindet, aber die Eins- und Zehnerziffer sind vertauscht Ich ziehe sie an die richtige Position. Ich habe den Nulleins-Hund so bearbeitet , dass er besser in die Benutzeroberfläche passt, indem ich die Partikel über dem Schädelbild entfernt habe, um dieses Null-Null-Punkt-Png zu erstellen , das als Icon-Textur verwendet werden kann. Und schließlich möchte ich, dass die Münze in den Fällen, in denen sie nicht eingefroren ist , unbeweglich bleibt während sie eingesammelt wird. Derzeit verleiht die Kollision von Rogers mit der Münze dem starren Körper der Münze Kraft , sodass er sich bewegt, während die Effektanimation im Münzskript abgespielt Bei der Collect-Methode wollen wir auf die Eigenschaften des Einfrier- und Freeze-Modus der beiden D des starren Körpers zugreifen Eigenschaften des Einfrier- und Freeze-Modus der beiden D des starren Körpers . Aber auf diese dieses Skript nicht zugreifen da es das Kollisionsobjekt 2 D erweitert und Godot nicht möchte, dass wir die Kollisionseinstellungen ändern , während eine Kollision stattfindet Wir können diese beiden Probleme lösen, indem eine integrierte Methode namens call deferred verwenden Die Methode Call Deferred weist Godot dies auszuführen , nachdem die Kollision beendet ist Die Verarbeitung von Call deferred benötigt ein Zeichenkettenargument mit dem Namen der Methode, die In diesem Fall hat set free den Wert aktiviert, auf den wir es setzen wollen, was wahr ist Dann muss ich auch den Freeze-Modus auf einen Wert einstellen , der innerhalb des starren Körpers definiert ist. Einfriermodus mit zwei D-Klassen, statisch. Ein statischer starrer Körper bewegt sich weder durch Kräfte noch durch Kollisionen, was ich gerne hätte Dadurch wird verhindert, dass sich die Münze bewegt, nachdem sie eingesammelt wurde und der Wurzelknoten des Schädels ausgewählt Setze die Kollisionsebene auf die Schatzebene und die Kollisionsmaske auf die Spielerebene Verbinde außerdem das Signal „ Körper eingegeben mit der Methode „Schädel auf Körper eingegeben Wir haben jetzt einen Lebenspunktezähler und der Spieler kann mehr Leben gewinnen, indem er Schädel oder Münzen sammelt In der nächsten Lektion werden wir eine Schatztruhe voller Piratenbeute erstellen eine Schatztruhe voller Piratenbeute Wir sehen uns in der nächsten Lektion. 33. 3-5 Truhe: Hallo Freunde. In der vorherigen Lektion haben wir unserem Spiel einen Schädelschatz zum Sammeln hinzugefügt In dieser Lektion erstellen wir eine Truhe voller Schätze , die der Spieler öffnen kann Ich werde eine Schatztruhe als stationäres Objekt verwenden, das sich scheinbar im Hintergrund sodass der Spieler davor gehen kann. Wenn sie das tun, öffnet sich die Truhe und wirft eine Menge Münzen in die Luft. Ausgehend von der Level-Szene fügen wir dem Schatzordner einen Knoten mit zwei Bereichen hinzu. kompliziertere Verhaltensweisen als andere Gegenstände im Spiel. Ein animiertes Sprite wird nicht ausreichen. Wie bei unseren Charakteren müssen wir einen Sprite-Zwei-D-Knoten verwenden und dann einen Animations-Player verwenden, um ihn zu steuern , und einen Animationsbaum, um den Spieler zu steuern Lassen Sie uns zunächst das Standard-Sprite für den Sprite-Two-D-Knoten für den Sprite-Two-D-Knoten Ich verwende die Chest-Sprites aus dem Merchantship-Ordner, nicht den aus dem Palm Tree Ich möchte eine, bei der die Truhe nicht gesperrt ist, sondern nur innerhalb des entsperrten Ordners geschlossen Ich nehme Sprite Nummer drei. Wir können auch eine Kollisionsform hinzufügen, die ein Rechteck sein sollte und sie so ausdehnen, dass sie die gesamte Brust bedeckt Und ein Audio-Stream-Player , um einige Soundeffekte hinzuzufügen. Benennen Sie die Truhe des Zweigknotens um und speichern Sie diese als eigene Szene im Schatzordner. Für unseren Test wird ein Skript zur Steuerung benötigt, das sich ebenfalls im Ordner Treasure Scripts befinden sollte. Die Truhe wird eine exportierte Variable haben , um zu wissen, ob sie geöffnet ist oder nicht. Da der Standardwert für einen Goldbarren falsch ist, ist die Truhe nicht geöffnet Die Truhe muss auch wissen , was sich darin befindet. Fügen wir eine Integer-Variable hinzu, um den Gesamtwert aller Münzen in der Truhe anzugeben den Gesamtwert aller Münzen in , und geben ihr den Standardwert eins. Es wäre nicht sinnvoll, zuzulassen, dass diese Zahl eine negative Zahl oder eine lächerlich hohe Zahl Wir können den Wertebereich der exportierten Variablen einschränken , indem wir einen Unterstrichbereich hinzufügen und sowohl einen Mindest- als auch einen Höchstwert angeben sowohl einen Mindest- als auch einen Höchstwert Jetzt kann diese Zahl nicht mehr negativ oder viel zu hoch gesetzt werden negativ oder viel zu hoch Wir können auch eine Variable namens underscore booty als Schatzarray hinzufügen underscore booty als Schatzarray , um die tatsächlichen Münzknoten in der Schatztruhe darzustellen in der Schatztruhe Um diese Münzen herzustellen, benötigen wir vollgepackte Szenen sowohl mit der Silber - als auch mit der Goldmünze In der Ready-Methode können wir dann einen einfachen Algorithmus schreiben, um die Münzen zu instanziieren, die benötigt werden , um den Gesamtwert zu ergeben Der Gesamtwert ist zwar größer als zehn, wir können den Gesamtwert um zehn reduzieren und eine Goldmünze instanziieren Diese neu instanziierte Münze kann mit Push Back dem Beute-Array hinzugefügt werden dem Beute-Array hinzugefügt Dies wird wiederholt, bis der Gesamtwert weniger als zehn beträgt, oder es wird komplett übersprungen Wenn es bereits weniger als zehn war, wiederholen Sie den Vorgang Solange der Gesamtwert größer als Null ist, können wir ihn um eins reduzieren und eine Silbermünze instanziieren sie dann auf die Rückseite des Arrays schieben Am Ende dieses Vorgangs wird der Gesamtwert Null sein und in der Truhe befinden sich ein paar Münzen, die diesem Betrag entsprechen , zum Spawnen bereit Wenn der Spieler die Truhe öffnet, können wir mithilfe einer For-Schleife die Beute-Reihe nacheinander durchgehen mithilfe einer For-Schleife jedes Gegenstands auf dieselbe globale Position wie die Truhe setzen , aber auch ein Feld nach oben bewegen Wenn Sie die Eigenschaft „Einfrieren “ auf „falsch“ setzen, wird die Physik auf die Münze angewendet Wir können auf jede Münze ein zufälliges bisschen Kraft anwenden , damit sie beim Öffnen der Truhe in die Luft Dazu müssen wir eine Zufallszahlengenerator-Variable erstellen und sie mit einem Zufallszahlengenerator initialisieren der während der Bereitschaftsphase neu Dann füge dem Objekt einen Impuls hinzu. Die Richtung des Impulses sollte um eine Kachel höher sein , multipliziert mit einer Zufallszahl. Ich setze meinen Zufallsbereich auf 5-10. Dann füge auch Vektor zwei hinzu, rechts eine Kachel, und multipliziere mit einer Zufallszahl zwischen minus eins und positiv eins Bei negativen Zahlen geht es nach links statt nach rechts. Dadurch sollte ein zufriedenstellender Münzbrunnen entstehen. Wenn wir das Objekt zum Szenenbaum hinzufügen müssen, würde ich es vorziehen, es zu einem Geschwister der Truhe zu machen , nicht zu einem Kind Ich suche zuerst nach dem Elternteil der Truhe und füge dann die Münze als Kind hinzu Wenn das erledigt ist, können wir das Array löschen , da die Truhe jetzt leer ist. den Animations-Player auswählen, können wir damit beginnen, eine geschlossene Idle-Animation zu erstellen, die nur eine Spur für das Sprite Two D benötigt und ihre Textur an dasselbe Sprite sendet, das sie bereits hat Reduzieren Sie dann die Länge der Animation auf 0,1 Sekunden. Duplizieren Sie die geschlossene Leerlaufanimation und erstellen Sie eine offene ideale Animation. Und ändere das Sprite auf Nummer acht. Wir können dann eine geschlossene Animation erstellen, indem wir das Sprite ändern und dabei 8-4 herunterzählen, sodass die Animationslänge 0,5 Sekunden beträgt Wir können diesen Animationen auch eine Audiospur hinzufügen und die Truhe wieder schließen lassen. Sound Die Geräusche, die ich zum Öffnen und Schließen der Truhe verwende , wurden durch den Frisbee erzeugt Wenn ein Stück auf FreeSound.org die Abschlussanimation dupliziert Wir können eine offene Animation erstellen, indem wir einfach die Sprites umkehren und den Soundeffekt ändern. In der geöffneten Animation können wir der Animation aber auch einen Methodenaufruf-Track hinzufügen Wenn wir während des Frames bei geöffnetem Deckel ein Schlüsselbild hinzufügen, können wir die Plundermethode aufrufen, um die Münzen zu spawnen, den Animationsbaum zu wechseln, den Basisknoten für erweiterte Ausdrücke als Stammknoten der Truhe und die Animationsplayer-Eigenschaft für den Animations-Player festzulegen Stammknoten der Truhe und die Animationsplayer-Eigenschaft für den Animations-Player Erstellen Sie dann eine neue Zustandsmaschine für den Animationsbaum. Wir können alle vier Animationen zur Zustandsmaschine hinzufügen Animationen zur Zustandsmaschine und sie mit einem Zyklus von Übergängen verbinden. Der Übergang vom geschlossenen Leerlauf zum Offenen wird am Ende der Animation durch Is open und dann open to open inaktiv ausgelöst . ähnlicher Weise findet der Vorgang „Öffnen im Leerlauf“ zu „Schließen“ statt, wenn nichts geöffnet ist Schließen zu schließen“ am Ende der Animation Diese Struktur ermöglicht es uns, die Truhe zu Beginn der Szene entweder als offen oder geschlossen zu initialisieren , wobei der Wert von is open zugrunde Indem Sie mehr als einen Übergang vom Start aus vornehmen und deren Bedingungen festlegen, wählen Sie den Stammknoten aus und füllen die Szenen mit Münzen auf, indem sie aus dem Dateisystem in den Inspektor ziehen Außerdem müssen wir die Kollisionsebene so einrichten , dass die Truhe auf die Schatzschicht gelegt wird und dass sie nach Kollisionen auf der Spielerebene sucht Und stellen Sie den Z-Index der Truhe so ein, dass er sich hinter dem Spieler befindet. Wechseln Sie zum Node-Panel und verbinden Sie das vom Körper eingegebene Signal mit der Truhe selbst. sollten wir is open auf Wenn wir eine On-Body Entered-Methode hinzufügen und dieser Körper ein Charakter ist, true setzen, was die offene Animation auslöst, die wiederum die Plundermethode auslöst , die den Schatz hervorbringt Platziere irgendwo in deinem Level eine Schatztruhe. Versuche, auf den Schalter Ist offen zu klicken, um die Truhe zu öffnen und zu schließen und den Gesamtwert der Münzen zu ändern , die erscheinen werden Wenn sich die Truhe öffnet, spiele die Hüfte und versuche, die Truhe zu öffnen und deine hart verdienten Münzen einzusammeln Wir haben jetzt eine Schatztruhe, die eine Menge Münzen hervorbringt, die der Spieler sammeln kann der nächsten Lektion wird der Schatztruhe ein Schloss und ein Schlüssel hinzugefügt der Schatztruhe ein Schloss und ein Schlüssel dem der Spieler sie öffnen kann Wir sehen uns in der nächsten Lektion. 34. 3-6 Schloss und Schlüssel: Hallo Freunde. In der vorherigen Lektion haben wir eine Schatztruhe erstellt, sich beim Öffnen ein Springbrunnen voller Münzen bildet. In dieser Lektion werden wir die Truhe verriegeln und irgendwo in dem Level, der sie öffnet, einen Schlüssel verstecken Beginnen wir damit, die Silbermünzen-Szene zu duplizieren , um eine Schlüsselszene zu erstellen Öffne die neue Schlüsselszene, wähle das animierte Sprite aus und tausche die Sprites der Münze gegen die Schlüssel-Sprites aus Und der Schlüssel hat auch eine eigene Effektanimation. Ich ändere einfach den Soundeffekt der Tasten auf eine andere Münze. Sound Für den Schlüssel wird ein neues Skript benötigt, das von Treasure stammt , das im Ordner Treasure Scripts gespeichert Alles, was wir tun müssen, ist dem Game Manager-Skript mitzuteilen , wann der Schlüssel abgeholt wurde Das Schatzskript kümmert sich um alles andere. Um das Skript auf dem Stammknoten durch dieses neue Schlüsselskript zu ersetzen , klicken Sie einfach darauf und ziehen es auf den Knoten Da es sich immer noch um ein Schatzskript handelt, hängt das Signalverhalten immer noch mit dem Umschalten zur Spielszene zusammen Ich werde in meinem Spiel nur einen Schlüssel pro Level haben. Anstatt Schlüssel zu zählen, wie wir es mit Münzen gemacht haben, verwende ich nur eine einzige Textur, um anzuzeigen, ob der Spieler den Schlüssel hat oder nicht. Ich füge der Benutzeroberfläche eine zerstörte Textur hinzu und fülle sie mit dem Standardschlüssel Sprotte, doppelt vergrößert, besser sichtbar zu sein, und positioniere sie unter Klicken Sie dann auf das Symbol, um es auszublenden Da der Spieler im Game Manager-Skript nicht mit dem Schlüssel beginnt , können wir in der Bereitschaftsphase, wenn der Spieler den Schlüssel einsammelt, einen Verweis auf diese Textur setzen wenn der Spieler den Schlüssel einsammelt Wir können eine Variable in den Dateidaten festlegen , dass der Spieler einen Schlüssel auf true hat. Setzen Sie außerdem die Eigenschaft visible des Tastensymbols auf true. Wir sollten auch eine andere Methode für den Fall entwickeln der Spieler die Taste benutzt, um filet has key auf False zu setzen und das Symbol auf der Benutzeroberfläche auszublenden. zum Datenskript wechseln, können wir die Schlüsselvariable has hinzufügen und ihren Standardwert in der Init-Methode festlegen Platzieren Sie einen Schlüssel irgendwo in der Nähe der Ebene und versuchen Sie, ihn aufzuheben. Um die Truhe zu sperren, müssen wir eine weitere Bulling-Variable hinzufügen, damit die Truhe weiß, ob sie gerade gesperrt ist oder nicht Wir können dann die Logik im Kollisionscode ändern. Wenn die Truhe gesperrt ist und der Spieler den Schlüssel hat, ist Set gesperrt auf Falsch gesetzt und teilt dem Spielleiter , dass der Spieler den Schlüssel benutzt hat. Wenn die Truhe nicht gesperrt ist, ist Set offen auf wahr. Ich verwende ElseF hier nicht, weil ich möchte, dass die Truhe in einem Kollisionsereignis sowohl entriegelt als auch geöffnet den Animations-Player auswählen, müssen wir weitere Animationen hinzufügen Beginnen wir damit, die geschlossene Leerlaufanimation zu duplizieren die geschlossene Leerlaufanimation , um eine gesperrte Leerlaufanimation zu erstellen Und ändere das Sprite in das Leerlauf-Sprite. Duplizieren Sie dann die Schließanimation , um eine Sperranimation zu erstellen Ändern Sie das Sprite 3-2 in eins, verkürzen Sie die Länge der Animation auf 0,3 Sekunden und spielen Sie einen Diesmal verwende ich Key Twist in Lock von Karen Keegan auf FreeSound.org. Wir können diese Animation dann duplizieren, um auch eine entsperrte Animation zu erstellen, die die Reihenfolge der Sprites FreeSound.org. Wir können diese Animation dann duplizieren, um auch eine entsperrte Animation zu erstellen in Lock von Karen Keegan auf FreeSound.org. Wir können diese Animation dann duplizieren, um auch eine entsperrte Animation zu erstellen, die die Reihenfolge der Sprites umkehrt. zum Animationsbaum wechseln, können wir diese neuen Animationen zur Zustandsmaschine hinzufügen Und verbinde sie. Mit einer ähnlichen Schleife von Übergängen wie beim Öffnen und Schließen. Die Truhe wird vom geschlossenen Idol zum Schloss übergehen. When is locked ist auf true gesetzt und am Ende der Animation von Block zu gesperrt inaktiv Ebenso ändert sich die Einstellung von „Blockiertes Idol zu „Entsperren“, wenn „ gesperrt“ auf „Falsch“ gesetzt ist, und am Ende der entsperrten Animation zu „geschlossenes Idol Wir können die Truhe dann auch im gesperrten Ruhezustand starten , wenn der Wert gesperrt wahr ist, aber die Bedingungen, unter denen die Truhe als geschlossen und gesperrt gestartet wird, können beide Wir fügen die Bedingung für den geschlossenen Leerlauf hinzu, dass die Truhe in der Level-Szene weder geöffnet noch gesperrt sein darf . Wir können jetzt den gesperrten Zustand der Truhe ändern indem wir auf den Schalter Denke daran, dass eine verschlossene Truhe entriegelt werden muss, bevor sie geöffnet werden kann Eine offene Truhe muss geschlossen werden, bevor sie verschlossen werden kann. Das funktioniert, aber das gefällt mir nicht. Das Schloss verschwindet einfach. Das Asset-Paket hat ein entsperrtes Vorhängeschloss als separates Asset. Verwenden wir es also Duplizieren Sie die Schlüsselszene Um eine Szene mit einem Vorhängeschloss zu erstellen, ändern Sie den Typ des animierten Sprite-Zwei-D-Knotens in einen Sprite-2-D-Node, da das Vorhängeschloss keine Animationen enthält. Benennen Sie die Knoten entsprechend um und füllen Sie das Sprite-Objekt mit dem Ändern Sie die Kollisionsform in ein Rechteck und passen Sie die Größe an die Form des Schlosses an Beseitigen Sie die Kollision mit dem Spieler und reduzieren Sie den Z-Index des Vorhängeschlosses, sodass er der Truhe entspricht Außerdem setze ich die Standardeinstellung der Phraseneigenschaft auf False, da ich immer möchte, dass das Vorhängeschloss von der Physik beeinflusst wird Und entferne das Skript, indem du auf die Skriptschaltfläche mit einem roten X darauf Das Vorhängeschloss ist kein Schatz und sollte vom Spieler nicht eingesammelt werden das Truhen-Skript öffnen, können wir eine exportierte gepackte Szene für das Vorhängeschloss hinzufügen, genau wie wir es bei der Plundermethode getan haben Wir können eine andere Methode definieren, um das Vorhängeschloss zu öffnen. Da es sich bei der Plundermethode um ziemlich viele Münzen handeln könnte , haben wir sie während der Ready-Methode instanziiert Wenn der Spieler dann die Truhe öffnet, existieren die Münzen bereits im Speicher und werden einfach zum Szenenbaum hinzugefügt Dies ist eine verantwortungsvollere Methode, um große Mengen von Knoten zu instanziieren Da das Vorhängeschloss jedoch nur eine einzige Sache ist, müssen wir uns keine Gedanken darüber machen, es in dem Moment zu instanziieren, in dem es Innerhalb der Methode throw padlock können wir eine neue Variable für das instanziierte Vorhängeschloss definieren für Gehen Sie dann genauso vor wie bei den Münzen und positionieren Sie das Schloss neu, damit es der Position der Truhe entspricht eine Impulskraft anwende und sie zum Szenenbaum hinzufüge, entferne ich die zufällige Verteilung der Aufwärtskraft Es wird nur ein bisschen zur Seite geschmissen. zur 2-D-Ansicht wechsle, füge ich schnell das Vorhängeschlossbild zur Szene hinzu, sodass ich es an der gewünschten Stelle neu positionieren kann Wenn ich zur 2-D-Ansicht wechsle, füge ich schnell das Vorhängeschlossbild zur Szene hinzu, sodass ich es an der gewünschten Stelle neu positionieren kann. Dann schaue ich mir die transformierten Werte an, Dann schaue ich mir die transformierten Werte an um die X- und Y-Positionen zu Nachdem ich minus vier und minus sieben notiert habe, kann ich den Sprite-Knoten löschen, zur Skriptansicht zurückkehren und die Anfangsposition der Vorhängeschlösser auf die Brustposition plus Vektor zwei, negativ vier, minus sieben setzen die Brustposition plus Vektor zwei, negativ vier, negativ vier Jetzt erscheint das Vorhängeschloss genau an der Position, an der es aussieht , als ob es mit dem gesperrten Sprite übereinstimmt, und wird Denken Sie daran, die komprimierte Szene zu füllen, indem Sie das Vorhängeschloss aus dem Dateisystemfenster in den Inspektor ziehen das Vorhängeschloss aus dem Dateisystemfenster , den Animation-Player auswählen, zur entsperrten Animation wechseln und während des Frames einen Methodenaufruf-Track hinzufügen. Wenn das Vorhängeschloss verschwunden ist, können wir die Methode throw padlock wir Wenn der Spieler nun den Schlüssel einsammelt und die Schatztruhe berührt, wird das Vorhängeschloss zur Seite geworfen, die Truhe öffnet sich und der Spieler wird mit Münzen überschüttet Wir haben jetzt einen Schlüssel, mit dem wir unsere Schatztruhe öffnen können. In der nächsten Lektion fügen wir unseren Levels ein Endziel hinzu. Wir sehen uns in der nächsten Lektion. 35. 3-7 Karte: Hallo Freunde. In der vorherigen Lektion haben wir die Schatztruhe verschlossen und einen Schlüssel hinzugefügt, um sie zu öffnen. In dieser Lektion legen wir ein Endziel für unsere Stufen fest. Ich werde die kleinen Karten als Ziel für meine Level verwenden, da dies dem Spieler leicht suggeriert, dass Roger jedem Kartensegment folgt, um dem Spieler leicht suggeriert, dass Roger jedem Kartensegment folgt das nächste zu finden , um eine komplette Schatzkarte zusammenzustellen. Das Konzept ist so einfach , dass ich es nicht erklären muss. Und es bietet auch einen Rahmen für die Ebenenstruktur. Beginnen wir damit, die Schädelszene zu duplizieren , um eine kleine Karte zu erstellen In einer Szene wurde der Wurzelknoten umbenannt. Wählen Sie das animierte Sprite und tauschen Sie die Skull-Sprites aus Für die kleine Karte ein Sprite. Ich verwende die In- und Out-Sprites zusammen, um die Effektanimation zu erstellen Ändern Sie dann die Kollisionsform in ein Rechteck und passen Sie die Größe an das Sprite an Ich verwende den Papiersound von Breceps als Wie bei allen anderen Schätzen können wir ihm ein Schatzskript namens Kleine Karte geben, die vom Schatz vererbt wird. Wir müssen dem Game Manager lediglich mitteilen , dass die Karte eingesammelt wurde Schalten Sie das Skript auf dem Stammknoten für das neue kleine Kartenskript um. Dann duplizieren Sie diese Szene dreimal, um eine kleine Karte zu erstellen. Zwei, drei und vier. Tauschen Sie die Sprites in der Standardanimation gegen die passenden Sprites aus dem Asset-Paket für Small die passenden Sprites aus dem Asset-Paket für Small Ich werde jedoch die Effektanimation ändern, da der Spieler, wenn er dieses Stück sammelt, die gesamte Map fertiggestellt hat Nach der Wiedergabe des In-Effekts spiele ich die Animation zum Entfalten der großen Map gefolgt von der Animation im Leerlauf, der Faltanimation und dann dem Out-Effekt Dadurch weiß der Spieler , dass sich die kleinen Karten zu einer größeren Karte zusammengeschlossen haben zu einer größeren Karte zusammengeschlossen und dass ihr Ziel nahe ist Wenn der Spieler die kleine Karte einsammelt, ist das Level vorbei. Und ich möchte den Spieler mit einer kurzen Fanfare belohnen , gefolgt der Bildschirm schwarz wird, bevor er zu einem Levelauswahlmenü zurückkehrt Lassen Sie uns in der 2-D-Ansicht zur Spielszene wechseln. Wir können den Bildschirm mit einem Knoten namens Color Wrecked schwarz abdecken und ihm einen Namen geben, ihn im Inspektor ausblenden die Farbe auf Schwarz ändern Erweitern Sie dann den Layoutbereich und wählen Sie unter den Ankern die Option Full Wrecked aus Voreingestelltes Drop-down-Menü, um sicherzustellen , dass es immer im Vordergrund steht. Stellen Sie entweder sicher, dass es sich am unteren Rand des Benutzeroberflächenzweigs befindet, oder geben Sie ihm einen höheren Z-Indexwert als alles andere Wir möchten nicht, dass dadurch Mauseingaben auf Benutzeroberflächensteuerungen blockiert werden. Aber dahinter sollten Sie auch den Mausbereich erweitern und dem Farbwreck mitteilen , dass es Mauseingaben ignorieren soll Jetzt wird der gesamte Bildschirm schwarz sein , so sollte idealerweise jede Szene in unserem Spiel beginnen Das steht uns bei der Entwicklung dieser Szene im Weg. Lassen Sie es uns standardmäßig ausblenden , damit es einfacher in andere Szenen kopiert werden kann. Speichern wir es als eigene Szene und öffnen wir es dann, damit dieses schwarze Rechteck verblasst. Es wird ein Skript benötigt, das in den UI-Skriptordner gehört. So wie wir Tweens verwendet haben, um die Kamera zu bewegen, können wir Tweens auch verwenden, um andere Eigenschaften im Laufe der Zeit anzupassen, z. B. Definieren wir zunächst zwei Farben oben im Skript, eine für Schwarz und eine für Klar Schwarz hat Rot -, Grün - und Blauwerte von Null und einen Alphawert von Eins. Clear hat zwar den Alphawert Null, Alpha ist jedoch ein Maß für Transparenz. Wir benötigen außerdem eine private Variable für das Farb-Tween. Lassen Sie uns mit dem Ausblenden beginnen, bis es klar da das Rechteck derzeit schwarz ist Genau wie bei der Kamera ist es eine gute Idee, zuerst zu überprüfen, ob das Tween bereits existiert und läuft, und wenn ja, es zu beenden Erstellen Sie dann das Tween. Sie müssen sich hier nicht um Übergänge oder Erleichterungen kümmern, linear ist Dann verbinden Sie eine Eigenschaft auf diesem Knoten selbst, die Farbeigenschaft, mit dem Zielwert Clear über einen Zeitraum von 1 Sekunde Wir wollen wissen, wann dieses Verhalten abgeschlossen ist, damit wir von dieser Methode ein Signal zurückgeben können , das uns mitteilt, wann das Farb-Tween beendet ist Die Angabe eines Rückgabetyps für eine Methodendeklaration im Gudo-Skript erfolgt nach den mit einem Pfeil markierten Parametern Da der Übergang zu Schwarz bis auf die Änderung der Farbe identisch ist, ändern wir den Namen dieser Methode Fade und nehmen eine Farbe als Parameter verwenden diese Farbe dann als Zielwert Wir können dann Fade to Clear schreiben, um einfach Fade aufzurufen und Clear als Argument einzufügen Ebenso schreiben Sie Fade to Black. Fade aufrufen und Black als Argument übergeben. Beide Methoden können dieselben Signale zurückgeben , die von Fade zurückgegeben wurden. zum Game Manager-Skript wechseln, müssen wir einen Verweis auf das Fade während der Rotphase setzen . Das allererste, was wir tun sollten , wenn die Szene geladen ist , ist, die Eigenschaft visible des Fades auf true zu setzen, damit der Spieler nichts außer Schwarz sieht. Wenn dann alle Initialisierungen abgeschlossen und das Spiel bereit ist, damit der Spieler mit dem Spielen beginnen kann, können wir sagen, dass der Fade ausgeblendet werden soll, um sich zu löschen, und das Signal abwarten, bis der Vorgang abgeschlossen ist An diesem Punkt sollten wir dem Spieler die Möglichkeit geben , mit dem Spiel zu beginnen Lassen Sie uns während der Bereitschaftsphase einen Verweis auf den Player-Node setzen und eine Methode aufrufen, die wir noch nicht definiert haben. Setzt aktiviert und übergibt true als Argument. zum Player-Skript wechseln, können wir eine private boolesche Variable namens underscore is enabled hinzufügen namens underscore Definieren Sie auch die Methode set enabled. Dabei wird ein boolescher Parameter verwendet, ein boolescher Parameter die Überprüfen Sie dann diesen Wert, bevor alle zurückgegebenen Eingaben verarbeiten Falls der Spieler nicht wieder im Game Manager aktiviert ist wieder im Game Manager wenn der Spieler die Karte sammelt, können wir dem Spieler die Kontrolle entziehen , indem wir enabled auf false setzen. Ich würde hier auch gerne eine Siegesfanfare spielen. Also füge ich einen Audio-Stream-Player-Knoten namens Fanfare hinzu und fülle ihn mit einem kurzen Die Fanfare, die ich ausgewählt habe, ist Game Success Fanfare Short von L Boss auf FreeSound.org Nachdem der Spieler deaktiviert wurde, können wir die Game Success Fanfare Short von L Boss auf FreeSound.org. Nachdem der Spieler deaktiviert wurde, können wir die Siegesfanfare spielen. Warte, bis die Fanfare zu Ende ist. Warte, bis die Fade schwarz wird. Wechseln Sie dann zwischen den Szenen. Platziere ein Ziel am Ende deines Levels. Drücke auf Play. Die Szene wird mit einem schwarzen Bildschirm geladen und wird eingeblendet Der Spieler kann sich erst bewegen, wenn das Einblenden abgeschlossen ist. Das Sammeln des Schatzes am Ende des Levels entzieht dem Spieler die Kontrolle, löst die Fanfare aus und wird schwarz Wir haben jetzt eine Möglichkeit, unsere Level zu beenden und einen schönen, sanften Bildschirmübergang Im nächsten Abschnitt geben wir dem Spieler Gesundheit und lassen ihn Schaden erleiden. Wir sehen uns im nächsten Abschnitt. 36. 4-1 Schaden: Hallo Freunde. Im vorherigen Abschnitt haben wir eine Reihe verschiedener Schätze erstellt , die der Spieler sammeln kann. In diesem Abschnitt wird dem Spieler Gesundheit gegeben, sodass er Schaden erleiden und sterben kann. Wenn du die Aufgabe abgeschlossen hast, solltest du deine Level mit Schätzen füllen, die der Spieler sammeln kann, und sie strategisch platziert werden, um sein Verhalten zu manipulieren , wenn du die Herausforderungen gemeistert hast. Eventuell hast du in deinem Truhenskript auch eine exportierte Reihe von gepackten Szenen, Beutesammlung zusätzliche Schatzgegenstände die der Beutesammlung zusätzliche Schatzgegenstände hinzufügen und zusätzliche Schatzgegenstände hervorbringen Oder du legst einen Mindest- und Höchstwert für Münzen fest, wobei die Truhe eine zufällige Zahl dazwischen generiert Dann instanziieren Sie Münzen, die diesem zufälligen Wert entsprechen. Möglicherweise habt ihr alle die Farbdiamanten ergriffen, um neue Schätze zu erschaffen , und ihnen einen einzigartigen Zweck für euer Spiel gegeben einen einzigartigen Zweck für euer Spiel Charakteren etwas Gesundheit zu verleihen Fangen wir mit dem Charakterskript an, wo wir eine neue exportierte Variable hinzufügen können , um die maximale Gesundheit der Charaktere festzulegen. Dies sollte darauf beschränkt werden, nur eine natürliche Zahl zu sein. Etwas zwischen 1 und 100 sollte in Ordnung sein. Ich werde wahrscheinlich nur ein Steuerabkommen abschließen, einen Schaden nach dem anderen, 100 wären eine Menge, und ich setze den Standardwert auf fünf Wir können dann auch eine zweite Variable deklarieren , die ihren aktuellen Zustand repräsentiert. Um die Dinge einfach zu halten, gehe ich davon aus, dass die Charaktere, wenn sie in die Szene geladen werden , ihre volle Gesundheit haben, ihre aktuelle Gesundheit ihrer maximalen Gesundheit entspricht . Während der Bereitschaftsphase können wir dann eine öffentliche Methode schreiben, können wir dann eine öffentliche Methode schreiben die dem Charakter Schaden zufügt, wobei die Höhe des Schadens als Parameter verwendet wird. Im Moment reduzieren wir einfach die aktuelle Gesundheit um die Schadenssumme und drucken dann die aktuelle Gesundheit aus, drucken dann die aktuelle Gesundheit aus damit wir das Ergebnis sehen können. Die meisten Spiele dieser Art beinhalten eine kurze Phase der Unbesiegbarkeit, nachdem du Schaden erlitten hast. Der einfachste Weg, dies zu erreichen, wäre , Kollisionen während dieser Zeit auszuschalten Aber der Collider des Charakters erleidet nicht nur Schaden, er kollidiert auch mit der Wir können diese Zuständigkeiten trennen indem wir unseren Charakteren einen weiteren untergeordneten Knoten hinzufügen, einen Bereich zwei D, der als Rt-Box bezeichnet wird Die einzige Aufgabe der Rt-Box besteht darin, von Schadensquellen erkannt und ein- oder ausgeschaltet zu werden , ohne dass andere Aspekte des Charakters beeinträchtigt werden. Außerdem wird ein untergeordneter Knoten mit zwei Kollisionen von D benötigt , um seine Form zu bestimmen. Um es von den normalen Kollisionen des Charakters zu unterscheiden , können wir die Farbe des Rt-Felds in etwas anderes wie Grün ändern des Rt-Felds in etwas anderes wie Grün Es muss nicht unbedingt mit der Kapsel des Charakters identisch sein , aber es ist ein guter Ausgangspunkt, um mit dem ausgewählten Hip-Box-Knoten zu beginnen dem ausgewählten Hip-Box-Knoten Ändere die Kollisionsebene auf Ebene zehn und mache diese Ebene zur verletzten Ebene des Spielers. allem, was wir verletzen wollen, sollte der Spieler Ebene zehn maskieren , um nach der Schadensbox für den Spieler zu suchen. Um das zu testen, benötigen wir etwas Einfaches auf unserem Level, das den Charakter verletzen kann. Wir werden mit dem Spikes-Asset eine neue vollgepackte Szene erstellen. Dies wird ein statischer Körper mit zwei D-Knoten sein, da er sich weder bewegt noch von der Physik beeinflusst wird Fügen Sie einen Sprite-Zwei-D-Knoten und füllen Sie ihn mit einem Sprite-Objekt Fügen Sie ihm eine Kollisionsform hinzu und machen Sie daraus ein Rechteck. Dies wird eine begehbare feste Oberfläche sein, die der Collider der Charaktere so behandelt, als ob sie Teil des Geländes wäre Sie sollte sich über die gesamte Breite der Kachel erstrecken, aber nur etwa ein Viertel der Höhe der Kacheln erreichen Dadurch wird auch verhindert, dass der Spieler verletzt wenn er die Stacheln von der Seite statt von oben berührt der Seite statt von oben Dies ist ein Teil des Levels, aber nicht das Gelände oder das Wasser. Machen wir es zur dritten Ebene, einer neuen Ebene für Gefahren. Wir können dann einen weiteren Kollisionsknoten hinzufügen , um Schaden zu verursachen. Dabei handelt es sich um einen Bereich mit zwei D , den wir in Hip Box umbenennen. Je nachdem, wie präzise du mit deiner Hüftbox umgehen möchtest, möchtest du hier vielleicht eine benutzerdefinierte Form verwenden. Fügen wir nun im Inspektor ein Kollisionspolygon mit zwei D-Knoten als untergeordnetes Element der Hüftbox Wir können sehen, dass das Polygon ein gepacktes Array mit zwei Vektoren ist. Wenn Sie darauf klicken, um es zu erweitern, hat das Array eine Größe von Null und ist derzeit leer Wir können einfach auf eine beliebige Stelle im Editor klicken , um dem Polygon einen Scheitelpunkt hinzuzufügen Ich füge an jeder Speerspitze einen hinzu und einen weiteren in der Nähe des rechten Randes, um dem Ganzen etwas Volumen zu verleihen Klicken Sie dann auf den ersten Scheitelpunkt, um das Polygon zu schließen. Dies ist jetzt eine benutzerdefinierte Kollisionsform Wenn sich der Charakter berührt, wird er verletzt Beachten Sie jedoch, dass sie in zwei kleinere Formen unterteilt ist , Rot und Lila. Das liegt daran, dass die Kollisionserkennung in Videospielen komplex ist und viel Rechenleistung erfordert. Es ist viel einfacher, Kollisionen innerhalb eines konvexen Polygons zu erkennen als in einem konkaven Polygon Konkave Polygone werden von Godot in konvexe Polygone unterteilt . dass das Kollisionspolygon der Höhe dieser dritten Spitze entspricht, haben wir den Rechenaufwand verdoppelt, der erforderlich ist, um Kollisionen mit diesen Spitzen zu erkennen, da die Engine prüfen muss, ob die Figur das rote Polygon oder das Dadurch, dass das Kollisionspolygon der Höhe dieser dritten Spitze entspricht, haben wir den Rechenaufwand verdoppelt, der erforderlich ist, um Kollisionen mit diesen Spitzen zu erkennen, da die Engine prüfen muss, ob die Figur das rote Polygon oder das violette Polygon berührt. Um dies zu vereinfachen, entfernen wir den Scheitelpunkt der dritten Spitze, der in unserem Array Element Nummer zwei ist entfernen wir den Scheitelpunkt der dritten Spitze, der . Das Polygon ist jetzt konvex und vollständig rot eingefärbt. Und wir können das noch weiter vereinfachen , indem wir den letzten Scheitelpunkt entfernen Diese Hüftbox muss nach der Ebene zehn suchen, die der Spieler verletzt hat , wenn ihr wollt, dass Gegner Schaden durch Stacheln zwei erleiden, ebenfalls Ebene 18, Speichert den Zweig der Stacheln als eigene Szene Du könntest es in einem eigenen Ordner mit der Bezeichnung Fallen oder Gefahren ablegen , aber da es keine anderen Objekte gibt die in diese Kategorien fallen würden, speichere ich es einfach als Dekoration Ich werde jedoch einen neuen Skriptordner mit dem Namen Environment erstellen einen neuen Skriptordner mit dem Namen Environment dann Dinge wie Kameraebene, Parallaxe und Wasser hineinverschieben, bevor ein neues Skript mit dem Namen Hazard hinzufüge Hängen Sie dann dieses Skript an den Wurzelknoten der Spikes an. Der Zweck des Skripts besteht darin, darauf zu reagieren, dass Verletzungsbox eines Charakters mit den Spikes kollidiert Drücken Sie die Box, wählen Sie die Trefferbox aus, wechseln Sie zum Knotenfeld und verbinden Sie das eingegebene Signal mit dem Wurzelknoten des Spikes Dadurch wird der Name der Methode so geändert, dass sie im eingegebenen Hit-Box-Bereich ausgeführt wird. Das ist etwas aussagekräftiger für das, was gerade passiert Wenn wir das übergeordnete Objekt des Bereichs ermitteln, erhalten wir den Charakter Dann sollten wir diesem Charakter sagen, dass er Schaden erleiden soll Da dieses Skript für eine beliebige Anzahl von Gefahren verwendet werden kann oder Sie den Schaden spontan anpassen möchten, lassen Sie uns die Höhe des verursachten Schadens in eine exportierte Variable umwandeln und der Standardwert 1 sollte in Ordnung sein. Geben Sie ihm einen Bereich, damit er nicht auf etwas Negatives oder Null gesetzt werden kann. Öffne die Projekteinstellungen und nenne die Kollisionsebenen Gefahr“, „Spieler verletzt“ und „Feind verletzt“. Platziere Stacheln irgendwo in deinem Level und versuche, auf sie zu springen Du kannst im Ausgabefenster sehen, dass Roger jetzt bei jeder Kollision noch vier Lebenspunkte übrig hat Die Anzahl wird um eins reduziert Außerdem können der Spieler und andere Charaktere so konfiguriert werden, dass sie auf den Stacheln oder durch sie hindurchgehen, basierend auf ihrer Kollisionsmaskierung mit Ebene drei. Wir haben jetzt eine Spike-Gefahr, die dem Spieler Schaden zufügt den Stacheln oder durch sie hindurchgehen, basierend auf ihrer Kollisionsmaskierung mit Ebene drei. Wir haben jetzt eine Spike-Gefahr, die dem Spieler Schaden In der nächsten Lektion werden wir den Charakter darauf reagieren lassen, dass Charakter darauf reagieren Wir sehen uns in der nächsten Lektion. 37. 4-2 Reaktion: Oh Freunde. In der vorherigen Lektion haben wir Stacheln erzeugt, die dem Spieler Schaden zufügen In dieser Lektion wird der Charakter dazu gebracht, auf Schaden zu reagieren. Bei der Entwicklung von Charakteren ist euch wahrscheinlich aufgefallen , dass das Asset-Paket Hitanimationen enthält. Lassen Sie uns diese jetzt implementieren. in der Charakterszene, in der der Animationsspieler ausgewählt ist, eine neue Animation mit der der Animationsspieler ausgewählt ist, dem Namen hit hinzu. Füllen Sie die Trefferanimation mit den Stacheln aus dem Ordner „ Ohne Schwert Fügen Sie auch einen Soundeffekt hinzu, wenn Sie den Animationsbaum auswählen möchten den Animationsbaum auswählen Bearbeiten Sie die Zustandsmaschine ohne Schwert. Wir können die Hit-Animation hier hinzufügen und zu ihr übergehen. Wenn der Charakter getroffen wird er zurück, wenn er nicht getroffen wird. Beim Öffnen des Charakters muss das Zeichenskript eine Variable vom Typ Boolean erstellen und sie dann auf true setzen, wenn der Charakter Schaden nimmt Der Wert muss auf False zurückgesetzt werden, damit die Figur aus der Trefferanimation wieder in die Bewegung übergeht Trefferanimation wieder in die Die Animation selbst kann diese Funktion ausführen. Damit die Animation jedoch darauf zugreifen kann, muss die Variable exportiert werden. Lassen Sie uns dafür im Gesundheitswesen eine neue Kategorie namens Combat erstellen. Wir können dann der Trefferanimation eine Eigenschaftenspur hinzufügen , um den Wert von is hit am Ende der Animation wieder auf False zu setzen . Der Charakter spielt die Trefferanimation nun einmal ab, Der Charakter spielt die Trefferanimation nun wenn er Schaden erleidet. Dadurch werden alle Bewegungsanimationen unterbrochen , die während des Übergangs aus der Bewegungsebene der Zustandsmaschine Lass es uns ausprobieren. Es wäre schön, wenn der Charakter weiterhin Schaden erleidet, ohne dass er den Hitbox-Collider verlassen und erneut betreten muss Wenn sie auf den Stacheln bleiben, erleiden sie weiterhin Schaden. Außerdem sollte es nach dem erlittenen Schaden ein kurzes Zeitfenster geben, in dem der Spieler unbesiegbar ist Wir können beide Probleme mit einer Lösung lösen. Die Hurt-Box des Spielers ausschalten und wieder einschalten, dabei den Hurt-Box-Node auswählen. der Eigenschaften im oberen Bereich des Inspektorfensters mit der Bezeichnung Überwachung und Überwachbar können Sie Anhand der Eigenschaften im oberen Bereich des Inspektorfensters mit der Bezeichnung Überwachung und Überwachbar können Sie feststellen, ob Kollisionen auftreten Da es sich um eine Hurt-Box handelt, ist sie passiv und sucht nach nichts Die Überwachung kann auf „Falsch“ gesetzt werden. Ihr Zweck besteht darin, anhand von Trefferboxen gefunden zu werden. Es sollte überwachbar sein. Wenn Sie überwachbar auf falsch stellen, wird verhindert, dass Trefferboxen mit dieser verletzten Box kollidieren, und wieder auf wahr stellen, wird eine neue Kollision mit den Stacheln ausgelöst , die eine Dann können wir das Gegenteil tun. Stellen Sie es so ein, dass es die Perl-Schichten überwacht , aber nicht überwachbar ist In Godot gibt es einen einfachen Knotentyp für Timing-Zwecke, einen Timer, den wir unserem Charakter hinzufügen und ihn Unbesiegbar nennen können unserem Charakter hinzufügen und ihn Unbesiegbar nennen Die Standardzeit ist 1 Sekunde, was in Ordnung ist, und wir möchten, dass dies jeweils nur einmal zählt Markieren Sie das One-Shot-Kontrollkästchen. Während der Bereitschaftsphase können wir einen Verweis auf die Box des Charakters und den Timer setzen einen Verweis auf die Box des Charakters und den Timer , zu dem der Charakter Schaden erleidet. Wir können monitorable auf False setzen, starten, auf das Timeout-Signal warten und monitorable wieder auf true setzen Aber Godot lässt uns den Collider während einer Kollision nicht ausschalten. Wir werden set deferred verwenden, um Godot mitzuteilen, dass monitorable nach Abschluss dieser Kollision auf False gesetzt werden soll gesetzt . Wenn du andere Dinge in deinem Spiel haben möchtest, die den Charakter für eine bestimmte Zeit unbesiegbar machen, können wir dies auch zu einer öffentlichen Methode machen, die eine Float Time als Parameter können wir dies auch zu einer öffentlichen Methode machen, die eine Übergeben Sie dies dann an die Startmethode des Timers. Jetzt kann die Take-Damage-Methode die Methode become invincible aufrufen und 1 Sekunde als Parameter übergeben Aber ich möchte nicht, dass Feinde unbesiegbar werden, Ich füge eine exportierte Kampfvariable für die Zeit hinzu, in der der Charakter unbesiegbar ist nachdem er Schaden erlitten hat. Der Standardwert für die Schadensmethode Null die Ich werde dann überprüfen, ob dieser Wert nicht Null ist , bevor ich die Methode Become Invincible aufrufe Dabei verwende ich diese Zeit Wenn Feinde diesen Timer-Knoten nicht verwenden wollen, sollten sie ihn nicht in ihrem Szenenbaum haben Anstatt den Verweis auf den Timer mit ready zu setzen , verwende ich stattdessen die Ready-Methode. Überprüfen Sie den Wert von Invincible Duration. Und wenn es nicht Null ist, stellen Sie die Referenz auf den Timer ein Jetzt muss nur noch der Spielercharakter den Timer-Knoten haben und es wird ein Wert für unbesiegbare Dauer höher als Null gesetzt Aber den gegnerischen Charakteren müssen immer noch Rt-Boxen hinzugefügt werden Andernfalls versuchen ihre Skripte während der Bereitschaftsphase, Referenzen zu setzen , und verursachen einen Fehler, weil sie nicht existieren. Ihre Herdenboxen werden ebenfalls auf Ebene 18 statt auf Ebene zehn gehören. Dann gib Roger eine Unbesiegbarkeitsdauer mehr als 0 Sekunden es ausprobieren, erleidet der Charakter der auf den Stacheln steht, weiterhin jede Sekunde einen Schaden, während wir sehen, dass er auf dem Ausgabefeld herunterzählt Zu guter Letzt möchte ich, dass der Charakter von der Schadensquelle weggestoßen wird Lassen Sie uns die Take-Damage-Methode so modifizieren, dass sie auch die Richtung der Kraft als Vektor zwei akzeptiert Stellen Sie dann die Geschwindigkeit des Charakters auf diese Richtung multipliziert mit fünf Kacheln Das Gefahrenskript muss dann diese Richtung berechnen und sie an den Charakter senden, wenn er ihn verletzt Dies kann einfach die globale Position des Charakters abzüglich der globalen Position der Gefahr Damit die Gefahr ihre globale Position kennt, darf sie sich nicht über zwei D erstrecken . Aber wir wollen nicht , dass die Entfernung eine Rolle spielt, sondern nur die Richtung. das in Klammern setzen, können wir die normalisierte Methode aufrufen Normalisiert nehmen wir den Vektor und machen ihn länger oder kürzer, sodass er eine Länge von eins hat Lass es uns ausprobieren. Der Charakter der auf die Stacheln trifft, wird mit einer Rückwärtskraft getroffen, eine Trefferanimation und wird für 1 Sekunde unbesiegbar, bevor er Wir haben jetzt Charaktere, die darauf reagieren, getroffen zu werden. In der nächsten Lektion fügen wir der Benutzeroberfläche die Gesundheit des Spielers hinzu und geben ihm einen Zaubertrank , mit dem er seine Gesundheit wiedererlangen kann Wir sehen uns in der nächsten Lektion. 38. 4-3 Wiederherstellung: Hallo Freunde. In der vorherigen Lektion haben wir unseren Charakter auf Schaden reagieren lassen. In dieser Lektion fügen wir Benutzeroberfläche die Gesundheit des Spielers hinzu und kreieren Heiltränke. Lassen Sie uns zunächst einen Gesundheitsmesser erstellen. Die Elemente im Asset-Paket sind in drei separate Bilder für die Anzeige und eine flache rote Farbe für die Füllung unterteilt drei separate Bilder für die Anzeige . Die Statusanzeige selbst wird lediglich ein einfacher Kontrollknoten mit zwei untergeordneten Elementen sein , eines für den Hintergrund und das andere für die Füllung. Der Hintergrundknoten kann ein horizontales Feld sein Automatisches Sortieren der drei Hintergrundbilder für uns, denen es sich allesamt um Texturwracks Füllen Sie die Texturen mit den Elementen aus dem Asset-Paket Du kannst die anderen Zweige dort verstecken, was dir im Weg steht. Wählen Sie das horizontale Hintergrundfeld aus, erweitern Sie den Bereich „Theme Override“ im Inspektor und stellen Sie Abstand auf Null Pixel sodass die Bilder lückenlos dargestellt werden. Die Füllung ist nur ein weiteres Textukt mit dieser flachen roten Farbe, die wir manuell in der Größe ändern und an die Leiste anpassen können manuell in der Größe ändern und an die Leiste anpassen Auswahl des Stammknotens der Health Gauges. Lassen Sie uns ihn viermal vergrößern , um ihn sichtbarer zu machen. Ich denke, es würde in der unteren linken Ecke gut aussehen. Ich stelle die Anker-Voreinstellungen so ein, dass sie unten links Und stellen Sie den Pivot-Offset y so ein, dass er sich am unteren Rand der Anzeige befindet, was 40 Pixeln entspricht Stellen Sie dann die X-Position der Anzeige auf 32 Pixel ein, um die gleiche Polsterung wie bei der Münze oben hinzuzufügen , nur um das Layout und das Auschecken während des Spiels Die neue Gesundheitsanzeige vergrößern. Wählen Sie den Fülltexturect aus. Um die Füllung zu verwenden, können wir den Erweiterungsmodus so einstellen , dass er die Größe ignoriert, sodass wir die Größe manuell auf eine beliebige Größe einstellen Klicken und halten Sie auf den Wert für Größe X und bewegen Sie die Maus nach links. Wenn Sie den X-Wert reduzieren, den X-Wert reduzieren, was wir sehen können, sieht die Anzeige auch so aus, als würde sie leer werden. Wenn der X-Wert Null ist, ist die Anzeige leer, und wenn der X-Wert 75 ist, ist die Anzeige voll Wir können dies verwenden, um jede beliebige Lebenspunkte des Spielers anzuzeigen jede beliebige Lebenspunkte des Spielers indem wir sie in einen Prozentsatz von 75 Pixeln umwandeln. Ein Skript für die Gesundheitsanzeige erstellen. Wir nennen es Gauge und speichern es im UI-Skriptordner. Bereitstellungsphase können wir uns einen Verweis auf die In der Bereitstellungsphase können wir uns einen Verweis auf die Füllung holen. Wie bei den Zählern benötigt auch ein Messgerät eigentlich nur eine Methode, um den angezeigten Wert einzustellen Es wäre am besten , diesen Wert als Prozentsatz mit einem Float-Typ Um diesen Prozentsatz anzuzeigen, müssen wir lediglich die Größe der Füllung auf 75 multipliziert mit dem Prozentsatz festlegen die Größe der Füllung auf 75 multipliziert mit dem Prozentsatz Ein Prozentsatz wird in der Programmierung normalerweise als Zahl 0-1 dargestellt, im Gegensatz zu Mathematik, wo er 0-100 ist Dies vereinfacht unsere Berechnungen und ist effizienter Wenn wir dieses Skript flexibler gestalten möchten, können wir den Wert von 75 Pixeln als Variable mit dem Namen max pixels exportieren und 75 als Standardwert festlegen zum Charakterskript wechseln, können wir ein neues Signal für den Fall erzeugen Wenn wir zum Charakterskript wechseln, können wir ein neues Signal für den Fall erzeugen, dass sich der Gesundheitswert des Charakters ändert, und ihm einen Parameter geben , der dem Prozentsatz der verbleibenden Gesundheit des Charakters entspricht. Wenn der Charakter dann Schaden erleidet, können wir dieses Signal aussenden. Um den Prozentsatz der verbleibenden Gesundheit des Charakters zu berechnen , dividieren Sie einfach die aktuelle Gesundheit durch die maximale Gesundheit Beide Werte sind jedoch als ganze Zahlen definiert, was bedeutet, dass das Ergebnis immer entweder Null oder Eins ist Wenn wir einen ihrer Typen in Float ändern, das Ergebnis dann Float Two Wir können dann das Signal für die Änderung der Gesundheit des Spielercharakters mit der Gesundheitsanzeige verbinden . Aber wir wollen keine neue Methode aufrufen. Wenn Sie auf die Auswahltaste klicken, wird eine Liste der Methoden für Gesundheitsmessgeräte angezeigt, die wir als Sollwert bezeichnen möchten Um dies zu tun, sollten sowohl das Signal als auch die Methode dieselben Parameter haben In unserem Fall, float, denken Sie daran, die anderen Zweige wieder einzublenden Wenn Sie bereit sind zu testen, lassen Sie es uns ausprobieren. Die Anzeige beginnt voll, aber wenn Sie auf die Stacheln springen, wird die Anzeige jedes Mal um ein Fünftel reduziert die Anzeige jedes Mal um ein Fünftel Denken Sie daran, den Fade am unteren Rand des UI-Zweigs zu platzieren , wenn Sie möchten, dass er über alles andere gezogen wird Lasst uns dem Spieler nun mit einem Heiltrank helfen , um die verlorene Gesundheit Wie im letzten Abschnitt können wir einfach einen neuen Schatzgegenstand hinzufügen, indem wir den roten Zaubertrank verwenden und ein neues Skript dafür erstellen , dass er von einem Schatz erbt einen der anderen Schätze kopiert Benennen Sie es in Red Potion um und öffnen Sie es. Benennen Sie den Wurzelknoten entsprechend um und ersetzen Sie die Animations-Sprites den roten Potent-Sprites und die Effekt-Sprites durch den Zaubertrankeffekt Ich zentriere das Sprite und verwandle den Collider in eine Kapsel , damit es besser zum Ich verwende meine Gulp-Aufnahme von Miley Joe Moss, 1996, für den Soundeffekt des Die verschiedenen Farben der Zaubertränke werden wahrscheinlich nicht nur eine Variable anpassen, sondern stattdessen eine völlig sondern stattdessen Und wir werden ihre eigenen einzigartigen Skripte benötigen. Anstatt ein generisches Zaubertrank-Skript zu haben, nenne ich diesen roten Trank Erbe von Treasure und tausche dann das Skript aus, das an den Wurzelknoten angehängt ist Wir können eine Ganzzahlvariable für die Menge an Gesundheit , die der Trank wiederherstellt, als Ganzzahl exportieren die Menge an Gesundheit , die der Trank wiederherstellt, wiederherstellt Ich setze meins auf einen Wert von drei. Ich möchte den Spielmanager nicht damit belästigen diese Informationen vom Trank an den Charakter weiterzuleiten , da der Charakter mit dem Trank kollidiert Stattdessen nehme ich eine kleine Änderung am Schatzskript vor und speichere den Charakter, der mit diesem Schatz kollidiert ist , mit diesem Nachdem Sie überprüft haben, ob es sich bei dem Körper um einen Charakter handelt, speichern Sie den Körper als Zeichenvariable Jetzt kann das Zaubertrankskript direkt mit dem Charakter kommunizieren, wenn er eingesammelt wird Wenn der rote Trank eingesammelt wird, ruft eine Methode zur Wiederherstellung der Lebenspunkte des Charakters auf , der die wiedergewonnene Menge weitergibt zum Zeichenskript wechseln, können wir diese Methode „Gesundheit wiederherstellen“ zu den öffentlichen Methoden hinzufügen. Dabei wird die Menge der wiederherzustellenden können wir diese Methode „Gesundheit wiederherstellen“ zu den öffentlichen Methoden hinzufügen zu den öffentlichen Methoden Wenn wir zum Zeichenskript wechseln, können wir diese Methode „Gesundheit wiederherstellen“ zu den öffentlichen Methoden hinzufügen. Dabei wird die Menge der wiederherzustellenden Gesundheit als Parameter die Menge der wiederhergestellten Gesundheit zur aktuellen Gesundheit addiert wiederhergestellten Gesundheit zur aktuellen Gesundheit Außerdem sollten wir die aktuelle Gesundheit mithilfe der Min-Funktion auf die maximale Gesundheit begrenzen und dann das Signal zur Änderung des Zustands ausgeben, dann das Signal zur Änderung des Zustands ausgeben um die Gesundheitsanzeige auf dem Y zu aktualisieren. Wir können diese beiden Zeilen kombinieren und sie in einer Anweisung ausführen Platziere einen Heiltrank in deiner Stufe, versuche, Schaden durch die Stacheln zu erleiden, und sammle dann den Trank ein, um Wir haben jetzt eine Möglichkeit für den Spieler, zu erfahren, wie viel Lebenspunkte er noch hat, und einen Gegenstand, der ihm hilft, verlorene Gesundheit wiederherzustellen In der nächsten Lektion fügen wir dem Level einen Checkpoint hinzu. Wir sehen uns in der nächsten Lektion. 39. 4-4 Checkpoint: Hallo Freunde. In der vorherigen Lektion haben wir der Benutzeroberfläche eine Gesundheitsanzeige hinzugefügt und einen Teil, der dem Spieler hilft, verlorene Gesundheit wiederherzustellen. In dieser Lektion legen wir Orte fest, an denen der Spieler nach seinem Tod reagieren soll. Ich werde das andere Level aus der Spielszene löschen. Da wir nun die Struktur der Level bearbeiten werden und alle Levels diese neue Struktur benötigen , um richtig zu funktionieren, müssen auch andere Level bearbeitet werden. Bisher haben wir den Ursprung der Szene als Ort verwendet Ursprung der Szene als , an dem der Spieler anfängt, dann erwartet, dass er es bis zum Ende schafft, ohne zu sterben. Vielleicht möchtest du stattdessen, dass deine Level länger sind und den Spielern Checkpoints geben , an denen sie reagieren können , anstatt jedes Mal von vorne zu beginnen jedes Mal von vorne zu Lassen Sie uns der Hierarchie der gesehenen Ebenen einen weiteren Ordner mit dem Namen Checkpoints hinzufügen Hierarchie der gesehenen Ebenen einen weiteren Ordner mit dem Namen Checkpoints Wir können diesem Ordner dann einen einfachen leeren Zwei-D-Knoten mit dem Namen start position it hinzufügen diesem Ordner dann einen einfachen leeren Zwei-D-Knoten mit dem Namen , wo der Spieler das Level beginnen soll. Wenn du es vorziehst. Möglicherweise möchten Sie auch, dass sich der Level-Trigger in diesem Ordner befindet, und ihn in etwas wie Ende umbenennen , um einen Checkpoint zu erstellen Außerdem werden wir in diesem Ordner einen D-Node mit dem Namen Middle Geben Sie diesem Checkpoint einen animierten Sprite-Knoten. Ich werde die Flaggen-Assets für meinen Checkpoint verwenden, da der Ausgangspunkt der Checkpoints der Ort ist, an dem der Ursprung des Charakters festgelegt wird und der Ursprung des Charakters zu seinen Füßen liegt Der Ursprung der Checkpoints sollte auf dem Boden liegen, wo die Füße des Charakters positioniert werden Vor diesem Hintergrund werde ich die Flagge so positionieren, dass sich die Basis der Fahnenmasten am Ursprung befindet eine Kollisionsform hinzufüge, verwende ich einfach ein Liniensegment, das den Fahnenmast bedeckt sodass der Spieler den Fahnenmast tatsächlich berühren muss , um ihn auszulösen Ich füge außerdem einen Audiostream-Player zu De Node hinzu , der Game Reward by a Yen Ba auf FreeSound.org abspielen wird. Speichere den Checkpoint-Zweig als Ich lege meine Szenen in den Stammordner da sie in jedem Level meines Spiels enthalten sein wird Öffnen der neuen Checkpoint-Szene werde ich den Z-Index meiner Flagge so bearbeiten , dass er hinter dem Charakter gezeichnet wird und gleichzeitig dem Verhalten eines Schatzgegenstands sehr ähnlich Ich würde mir das logischerweise nicht als Schatz vorstellen und ich möchte das Schatz-Skript nicht so umgestalten , dass es hineinpasst Ich werde ein neues Skript von Grund auf neu erstellen und es im Ordner für Umgebungsskripte ablegen Schnappen Sie sich während der Bereitschaftsphase einen Verweis auf die beiden D-Knoten des Audiostream-Players während der Bereitschaftsphase einen Verweis auf die beiden D-Knoten des Audiostream-Players und verbinden Sie das eingegebene Signal, um auf die Kollision des Players mit der Flagge zu reagieren Spielen Sie den Soundeffekt ab und stellen Sie dann die Kollisionsmaske stellen Sie dann die Kollisionsmaske auf Null, um weitere Kollisionen zu verhindern Dann wollen wir eine Variable in den Dateidaten setzen , um zu wissen, dass der Spieler den Checkpoint erreicht hat Vielleicht möchtest du, dass dies ein boolescher Wert wenn du immer nur einen Checkpoint haben möchtest, wie bei einem typischen Mario-Spiel, oder eine Ganzzahl, wenn du mehrere Checkpoints haben möchtest, eher wie bei einem Donkey Kong Country-Spiel. Eine Ganzzahl ist flexibler und kann auch für das Single-Checkpoint-System verwendet werden Jeder Checkpoint benötigt dann eine eindeutige Ganzzahl, um ihn zu identifizieren, derer der Spielmanager anhand derer der Spielmanager weiß, wo er dem Spieler antworten muss. Definieren wir eine Variable als Ganzzahl, um diese Zahl zu speichern Stellen Sie dann den Wert des abgelegten Checkpoints auf diese ID-Nummer Wenn der Spieler den Checkpoint berührt, könnten wir die Variablen exportieren, um jede Variable manuell festzulegen, aber das wäre fehleranfällig und würde auf lange Sicht mehr Arbeit für uns bedeuten Stattdessen möchte ich diese Verantwortung an das Level-Skript delegieren diese Verantwortung an das Level-Skript Zuerst müssen wir sicherstellen, dass die Kollisionsmaske des Checkpoints so eingestellt ist, dass sie mit dem Spieler kollidiert Und gib diesem Skript einen Klassennamen damit es vom Level-Skript identifiziert werden kann zum Level-Skript wechseln und davon ausgehen können, Wenn wir zum Level-Skript wechseln und davon ausgehen können, dass alle Ebenen diesen Checkpoint-Ordner haben, dann können wir ihn verwenden, um eine Variable nicht auf den Checkpoint-Ordner selbst, sondern auf eine Reihe von Knoten zu setzen eine Variable nicht auf den Checkpoint-Ordner selbst, sondern auf eine Reihe von Knoten zu Wir können den Wert auf Checkpoints-Ordner setzen, was uns eine Liste aller Knoten im Dann können wir mithilfe einer Vierschleife von Null bis zur Größe dieses Arrays zählen Wenn es sich bei der Notiz um einen Checkpoint handelt, setzen Sie ihre Checkpoint-ID auf die Position in der Liste Das Level enthält jetzt eine Liste aller Checkpoints, an denen der Spielercharakter spawnen könnte , und jeder Checkpoint kennt seine Es liegt in der Verantwortung des Spielmanagers , das Level zu laden und den Spieler zum entsprechenden Checkpoint zu bringen, bevor das Spiel beginnt. Fügen wir dem Level-Skript auch eine Methode namens Get Checkpoint Position hinzu, damit der Spielmanager diese Informationen anfordern kann namens Get Checkpoint Position hinzu, damit der Spielmanager diese Informationen anfordern Wir nehmen die Checkpoint-ID als Integer-Parameter und geben einen Vektor mit zwei Positionen zurück Ich beginne mit einem ausfallsicheren Fall nur Vektor zwei Null zurückgegeben Bevor wir ein Argument verwenden, um ein Array zu indizieren, sollten wir überprüfen, ob es sich um einen gültigen Array-Index handelt , ob er sowohl größer als oder gleich Null als auch kleiner als die Größe des Arrays ist. Dann geben wir einfach den Checkpoint-Array-Index an der Checkpoint-ID zurück den Checkpoint-Array-Index an und ermitteln seine globale Position Zum Game Manager-Skript wechseln. Nachdem alle Initialisierungen abgeschlossen sind, aber bevor wir einschalten, sollten wir den Spieler spawnen Wir können jetzt die globale Position der Spielercharaktere festlegen , indem wir das Level nach der Position des Checkpoints fragen und als Argument den abgelegten Checkpoint abgelegten Checkpoint Zuletzt müssen wir der Datenressource die Checkpoint-Variable mit dem Standardwert Null hinzufügen Datenressource die Checkpoint-Variable mit dem Standardwert Null Der Spieler beginnt am obersten untergeordneten Knoten des Checkpoints-Ordners, dem leeren Startknoten Da wir den Body-Parameter, der an die Checkpoint-Kollision übergeben wurde, nicht verwenden die Checkpoint-Kollision übergeben wurde würde Godot es vorziehen, wenn er als optional gekennzeichnet wäre , indem ihm ein Unterstrich vorangestellt Platzieren Sie den Checkpoint irgendwo in der Mitte Ihres Levels und achten Sie dabei darauf, dass der Levelstart der oberste Knoten im Checkpoint-Ordner ist oberste Knoten im Wenn Sie auf Play klicken, hat sich nichts geändert, aber wir können die Startposition des Spielers jetzt einfacher verschieben Startposition des Spielers jetzt einfacher Wenn wir den Standardwert für Checkpoint im Datenskript bearbeiten, können wir den Spieler stattdessen auch den Standardwert für Checkpoint im Datenskript bearbeiten, können wir den an der Flagge spawnen Wir haben jetzt ein Checkpoint-System eingerichtet, sodass der Game Manager weiß, wo der Spieler spawnen muss In der nächsten Lektion fügen wir den Tod eines Spielers hinzu und lassen den Spieler am letzten getroffenen Checkpoint wieder erscheinen Wir sehen uns in der nächsten Lektion. 40. 4-5 Der Tod: Hallo Freunde. In der vorherigen Lektion haben wir ein Checkpoint-System erstellt, damit der Game Manager den Spieler an verschiedenen Positionen spawnen kann In dieser Lektion fügen wir den Tod eines Charakters hinzu und lassen den Spieler wieder erscheinen, wenn er stirbt Beginnend mit dem Charakterskript. So wie wir die Gesundheit auf maximale Gesundheit begrenzt haben, indem wir Min verwendet haben, wenn sich der Spieler erholt Außerdem müssen wir die aktuelle Gesundheit auf Null setzen , wenn sie Schaden erleiden, und die aktuelle Gesundheit auf das Maximum setzen, entweder die aktuelle Gesundheit abzüglich der Schadensmenge oder Wir können dann das Signal zur Änderung des Gesundheitszustands ausgeben und die Rückstoßgeschwindigkeit festlegen Der Rest dieser Methode hängt davon ab , ob sie durch diesen Schaden getötet wurden oder nicht Wir müssen überprüfen, ob der aktuelle Gesundheitszustand Null ist. Wenn es heißt, rufe eine neue Methode auf, stirb. Wenn der Charakter nicht tot ist, wird die Variable is hit auf true gesetzt und er kann unbesiegbar werden Bevor wir die Methode die schreiben, sollten wir eine boolesche Variable deklarieren, um zu wissen, ob der Charakter tot sollten wir eine boolesche Variable deklarieren ist oder Erstellen Sie außerdem ein Signal, das ausgegeben wird, wenn der Charakter stirbt, damit der Spielmanager darauf reagieren kann Bei der Methode Die können wir die neue boolesche Variable is dead auf true setzen , die wir im Animator verwenden können, wie wir es mit is hit gemacht haben , und ein Signal ausgeben, dass der Charakter Es wäre auch eine gute Idee, die Herdenbox des Charakters auszuschalten , damit er keinen Schaden mehr Aber das ist immer noch etwas, das wahrscheinlich während einer Kollision passiert. Wir müssen dies bis zum Ende des aktuellen Frames verschieben bis zum Ende des aktuellen Frames Wenn Sie die Kollisionsebene des Charakters auf Null und die Kollisionsmaske auf eins setzen des Charakters auf Null und die Kollisionsmaske , werden zukünftige Kollisionen mit etwas anderem als dem Gelände verhindert zukünftige Kollisionen mit etwas anderem als dem Gelände Ein toter Charakter sammelt keine Schätze und löst auch keinen Checkpoint schließlich die Richtung auf Null setzen, werden alle Bewegungseingaben, die zum Zeitpunkt des Todes gegeben wurden, rückgängig alle Bewegungseingaben, die zum Zeitpunkt des Todes gegeben wurden Um dem Spieler eine Antwort zu geben, benötigen wir außerdem eine öffentliche Methode um ihn vom Tod wiederzubeleben, Setting ist tot, zurück zu falscher aktueller Gesundheit zu maximaler Gesundheit. Dann müssen wir die Kollision des Charakters wiederherstellen und die Eigenschaft „ Überwachbar“ in der Rt-Box auf „true“ setzen Dies wird nicht durch eine Kollision ausgelöst, sondern eher durch die Logik des Game Managers Es ist in Ordnung, es einfach direkt einzustellen. Wir können die Werte der Kollisionsebene und der Kollisionsmaske während der Bereitschaftsphase in Variablen speichern der Kollisionsmaske während der Bereitschaftsphase in Variablen sie dann bei der Wiederbelebung des Charakters auf ihre ursprünglichen Werte zurücksetzen bei der Wiederbelebung des Charakters Da wir den Spielercharakter wiederbeleben werden nachdem wir ihn wieder am Checkpoint positioniert haben, wäre es auch eine gute Idee hier das Landing-Signal wegzulassen, wodurch die Kamera korrekt positioniert wird Wir haben das Signal des Charakters geändert, wir sollten auch das Signal „ Gesundheit geändert“ weglassen Wir wollen auch nicht , dass der Charakter irgendetwas tun kann, irgendetwas tun kann beginnen mit der Face-Left-Methode und sollten zuerst überprüfen, Wir beginnen mit der Face-Left-Methode und sollten zuerst überprüfen, ob der Charakter tot ist , und wenn ja, zurückkehren, um zu verhindern, dass das passiert Und tun Sie das für alle Methoden, die nicht ausgeführt werden sollten, solange der Charakter tot ist, einschließlich „Gesicht nach rechts“, „ Run-Jump“ und „Stop-Sprung“. Ich würde auch gerne eine Ergänzung zum Game Manager-Skript vornehmen . Beim Spawnen des Spielers legen wir seine Position wahrscheinlich auf dem Boden oder in Bodennähe an einer Stelle im Level fest Du kannst dir vorstellen, dass die Möglichkeit besteht, dass der Spielercharakter stirbt und aus großer Höhe fällt In dem Moment, in dem diese Respawn-Methode den Charakter neu positioniert, hätte der Charakter eine sehr Um zu verhindern, dass die Geschwindigkeit anhält und die Regenkollision möglicherweise unterbrochen wird, sollten wir ihre Geschwindigkeit zu diesem Zeitpunkt auf Null setzen zum Animations-Player wechseln, können wir die Animationen Dead Hit und Dead Ground hinzufügen Denken Sie daran, die Assets aus dem Ordner „Ohne Speicher“ zu verwenden. Dead Hit sollte einen Schmerzensschrei des Charakters enthalten , während Dead Ground beim Aufprall auf den Boden ein Aufprallgeräusch erzeugt. Angesichts der hohen Wahrscheinlichkeit, dass sich diese Sounds überschneiden, wäre es eine gute Idee, Gesangsgeräusche von allgemeinen Soundeffekten zu trennen . einen zweiten Audio-Stream-Player mit zwei D-Knoten hinzufügen, können wir einer Stimme und den anderen Soundeffekten einen Namen geben. Wir können dann die Stimmgeräusche darauf beschränken , dass jeweils nur ein Sound abgespielt werden kann, während gleichzeitig Soundeffekte ohne Unterbrechungen abgespielt werden Wenn die Eigenschaft „Maximale Polyphonie der Soundeffekte auf einen Wert größer als eins gesetzt wird, können auch mehrere Soundeffekte gleichzeitig wiedergegeben Dieses Format ermöglicht es uns auch, die Lautstärkeeinstellungen von Stimmen und Soundeffekten unabhängig voneinander anzupassen und Soundeffekten unabhängig voneinander den Animationsbaum auswählen Fügen Sie diese neuen Animationen der Zustandsmaschine ohne Schwert hinzu. Zuerst wird die Dead Hit-Animation abgespielt gefolgt von Dead Ground. Dead Hit wird gespielt, wenn der Charakter tot ist. Dann wird Dead Ground gespielt, nachdem Dead Hit abgeschlossen ist, und zwar nur, wenn sich der Charakter auf dem Boden befindet. Um den Spieler wiederzubeleben, müssen diese Animationen auch wieder in Bewegung versetzt werden When is dead wird in der Spielszene falsch angezeigt. Wähle den Spielercharakterknoten aus und verbinde das Did-Signal mit dem Game Manager Nennen wir diese Methode beim Spieler Did. Wenn der Spieler stirbt, eines von zwei Dingen passieren. Entweder sie reagieren an ihrem letzten Checkpoint oder ihnen sind die Leben ausgegangen und sie haben den Game over State Zunächst ist die Überprüfung, ob Dateidaten noch gültig sind, gleich Null. Dann rufen wir eine Game-Over-Methode auf, Game Over eine Definition gibt. Im Moment können wir Game Over einfach ausdrucken. Wenn die Anzahl der Leben nicht Null ist, können wir sie um eins reduzieren, die Benutzeroberfläche aktualisieren und dann eine andere Methode aufrufen. Kehren Sie zum letzten Checkpoint zurück. Um zum letzten Checkpoint zurückzukehren, sollten wir warten, verblassen und schwarz werden Spawnen Sie den Charakter am letzten erreichten Checkpoint, beleben Sie ihn wieder und warten Sie, bis er verblasst In beiden Fällen würde ich gerne einen kurzen Jingle wie bei der Siegesfanfare spielen wie Fügen wir dem Game Manager-Skript vom Typ Audiostream drei exportierte Variablen hinzu, die Victory, Death und Game Over heißen werden Death und Game Ich verwende Musik zum Ende der Szene für Tod und traurigen oder gruseligen Szenenwechsel. Musik für Game Over, beide von Dominic Trace von FreeSound.org Dann können wir dem Fanfare-Node mitteilen , dass er für jede Situation den passenden Sound abspielen soll den passenden Sound abspielen Das Thema Sieg wird gespielt, wenn der Spieler die Karte am Ende des Levels einsammelt Spielen Sie das Thema Tod, wenn sie sterben und das Game Over-Thema , wenn ihnen die Leben ausgehen. Es wäre auch ratsam, die Spielereingabe zu Beginn der Rückkehr zum letzten Checkpoint zu deaktivieren der Rückkehr zum letzten Checkpoint zu und am Ende die Spielereingabe zu aktivieren Ich habe die Startleben der Spieler auf eins und Macs Gesundheit auf eins gesetzt Startleben der Spieler auf eins und Macs Gesundheit auf Für diese Demonstration haben wir nun die Möglichkeit, wir dass der Spielercharakter am letzten Checkpoint, den er erreicht hat, sterben und reagieren In der nächsten Lektion werden wir den Feinden Angriffe geben, um den Spieler zu verletzen Wir sehen uns in der nächsten Lektion. 41. 4-6 Feinde: Hallo Freunde. In der vorherigen Lektion haben wir dem Spielercharakter eine Todesanimation gegeben und ihn nach dem Tod wieder erscheinen lassen In dieser Lektion fügen wir den gegnerischen Charakteren Angriffe hinzu , die den Spieler verletzen können Ich verwende Fierce Tooth als Beispiel für diese Lektion. aller Charaktere müssen jedoch so bearbeitet werden Knotenstrukturen aller Charaktere müssen jedoch so bearbeitet werden, dass sie übereinstimmen, bevor Tests ausgeführt werden den Animations-Player-Knoten auswählen, können wir damit beginnen, dieselben Hit-, Dead Hit- und Dead-Ground-Animationen für die Gegner hinzuzufügen , wie wir es bei Roger getan haben. Fügen Sie dann auch Vorfreude und Angriff hinzu. In der Statusmaschine der Animationsbäume können wir dieselben Hit- und Death-Animationen wie bei Roger nachstellen wie bei Roger nachstellen Strukturierung der Zustandsmaschine in Schichten. Auf diese Weise kann der Feind, der verletzt oder getötet wird, seine Angriffe unterbrechen die Angriffsebene bearbeiten, können wir dann die Antizipations - und Angriffsanimationen hinzufügen Fügen Sie hier einen Übergang von Bewegung zu Antizipation, Vorfreude zu Angriff und Angriff zu Der Übergang von der Antizipation zum Angriff wird am Ende geschehen, ebenso wie der Übergang vom Angriff Aber der Übergang von Bewegung zu Antizipation, der die Animationskette in Gang setzt, erfolgt, wenn der Charakter im Charakterskript angreifen will im Charakterskript angreifen Fügen wir den Kampfvariablen die Option will Bolin angreifen hinzu Fügen Sie dann eine öffentliche Methode namens attack hinzu, die ihren Wert auf true setzt Jedes Mal, wenn diese Methode aufgerufen wird, möchte der Feind einmal angreifen , als müsste die Variable is hit auf false zurückgesetzt werden, andernfalls würde die Animation wiederholt werden. Außerdem müssen wir die Variable will angreifen während der Animation wieder auf False setzen. Die Variable will angreifen muss exportiert werden, damit der Animationsspieler darauf zugreifen kann. Wenn wir während der Antizipationsanimation zum Animations-Player zurückkehren , können wir den Wert von will angreifen wieder auf False setzen Dies reicht aus, um die Animationssequenz auszulösen , damit dieser Feind angreifen kann Aber wie bei den Spikes muss es auch hier eine Trefferbox geben, die nach der Verletzungsbox des Spielers sucht Wählen Sie die Angriffsanimation mit dem ersten ausgewählten Frame aus Das ist es, was im Editor angezeigt wird, wenn man einen guten Überblick über den Charakter hat. Fügen wir dem D-Knoten zum Szenenbaum einen weiteren Bereich namens Hit Box hinzu und geben ihm eine Kollisionsform. Um diesen Collider vom blauen Umgebungs-Collider und der grünen Rt-Box zu unterscheiden , können wir der Hit-Box eine andere Farbe wie Rot geben Wählen Sie eine Form, die Ihrer Meinung nach am besten zu dem Bereich passt, auf den der Angriff abzielt Ich verwende eine Kapsel und passe sie dann an die Größe und Form des Zielbereichs Achten Sie darauf, dass die Hüftbox mittig auf der Figur liegt und dass die Kollisionsform nur aus der Mitte herausbewegt Es gibt auch eine Effektanimation. Fügen wir als Kind der Hip Box einen animierten Sprite-Toting Node Erstellen Sie eine Sprite-Frames-Ressource und füllen Sie sie mit den Im Gegensatz zu anderen Effektanimationen möchten wir nicht, dass diese Und außerdem die übliche Bildrate von zehn Bildern pro Sekunde, es sollte auch keine Schleife geben Fügen Sie außerdem am Ende einen leeren Frame hinzu und positionieren Sie den Sprite-Knoten neu, sodass es so aussieht , als ob der Effekt vom Angriff ausgeht Wenn Sie fertig sind, stellen Standardrahmen das letzte leere Bild ein, sodass es zunächst so in die Szene geladen wird , dass es nichts zeigt Aber wenn wir ihm dann sagen, dass er abspielen soll, spielt er die Animation einmal ab und verschwindet wieder. Wir können die Kollisionsebene der Hit-Boxen auf Ebene 19 setzen, was die Ebene für gegnerische Treffer sein wird, und sie die Ebene zehn maskieren lassen, die vom Spieler verletzte Ebene. Da es sich um eine aktive Entität handelt, sucht sie nach Schadensfeldern. Nichts sucht nach Trefferboxen. Sie sind normalerweise nicht überwachbar. Wir wollen jedoch nicht, dass dies eine Überwachung ist, bis der Feind tatsächlich Der Standardwert für Monitoring wird ebenfalls False sein. Im Zeichenskript. Es wäre eine gute Idee , sich in der Bereitschaftsphase einen Verweis auf die Hipbox zu schnappen . Wir müssen vor dem Testen jedem Zeichen einen Hit-Box-Node hinzufügen , um die Anforderungen an die Zeichenskripte zu erfüllen , um die Anforderungen an die Zeichenskripte , und die Monitoring-Eigenschaft auf false setzen. Nur für den Fall, dass wir wieder in der Angriffsanimation sind, können wir der Animation die Eigenschaft zur Überwachung der Trefferfelder hinzufügen Animation die Eigenschaft zur Überwachung der ihren Wert im ersten Frame auf true setzen, während des zweiten Frames wieder auf false. Fügen Sie dann auch eine Aufrufmethodenspur für die Effektanimation hinzu , sodass sie während des ersten Frames des Angriffs abgespielt werden soll. Die Animationen sind zwar in Antizipation und Angriff unterteilt , es gibt jedoch drei Phasen, bei denen es sich um einen Angriff, einen Kontakt und eine Erholung handelt, wenn es um Gegner In der Antizipationsphase teilt der Feind mit, dass er angreifen wird, sodass der Spieler Zeit hat, darauf zu sodass der Spieler Darauf folgt der Kontakt. Das ist genau der Moment, in dem der Collider eingeschaltet wird und der Feind dem Spieler tatsächlich Schließlich die Erholung, die dem Spieler Zeit gibt , auf einen Treffer zu reagieren oder sich zu rächen Verbinde dich mit dem eingegebenen Bereich, dem Signal der Trefferbox und dem Charakterskript Der einzige Bereich, den wir mit einer Trefferbox kollidieren lassen werden , ist eine Rt-Box Dank der Kollisionsebene müssen wir nur den Bereich der Rt-Box nach seinem übergeordneten Objekt fragen, das ein Charakter sein wird , und diesem Charakter sagen, dass er Schaden erleiden soll. Verursacht vorerst nur einen Schaden in Richtung der globalen Position des Spielers abzüglich der globalen Position dieses Feindes Dann normalisiert, sollten wir den Schadensbetrag als Kampfvariable exportieren , sodass er für jeden Charakter in der Levelszene geändert werden kann für jeden Charakter in der Levelszene Finde deinen Feind und füge ihm einen Timer-Knoten hinzu. Und stelle den Timer auf etwas Längeres ein, etwa zwei oder 3 Sekunden. Und stell es auf Autos, start. Verbinde das Timeout-Signal dieses Timers mit der Angriffsmethode des Feindes Jetzt wird dieser Feind angewiesen, jedes Mal, wenn der Timer Null erreicht, einmal anzugreifen , und das wiederholt sich Wenn du bereit bist, drücke auf Play, um zu sehen, wie der Charakter automatisch angreift, und versuche, dich von ihm treffen zu lassen Das funktioniert, solange sich der gegnerische Charakter nicht umdreht. Lassen Sie uns die Eigenschaft Flip H der Sprite-Knoten auf true setzen, um zu simulieren, dass der Feind nach rechts schaut Jetzt zeigt die Angriffsanimation nach rechts, aber die Hüftbox und die Effektanimation zeigen immer noch nach links Wählen Sie die Hüftbox im Transformationsbereich aus und klicken Sie auf das Kettensymbol, um die Verknüpfung der X- und Y-Werte aufzuheben, sodass sie separat bearbeitet werden können Klicken und ziehen Sie dann von der Eigenschaft Scale X bewegen Sie die Maus dabei nach links Wenn sich der Wert Null nähert, ist der Hüftbereich so dünn, dass er verschwindet. er jedoch negativ wird, wird er an der Y-Achse gespiegelt Wir können das im Charakterskript verwenden, um die Hip Box umzudrehen Gleichzeitig drehen wir den Sprite mit der Face-Links-Methode Stellen Sie die Hip-Box-Skala auf eins ein, wenn das Sprite von Natur aus nach links zeigt, l negativ auf eins und umgekehrt Bei der Methode „Gesicht nach rechts“ können wir mit der exportierten Variablen die ursprüngliche Blickrichtung unseres Feindes umkehren . Um das zu testen, greifen jetzt unsere feindlichen Charaktere den Spieler an. In der nächsten Lektion werden wir einen Spiel-Overscreen hinzufügen. Wir sehen uns in der nächsten Lektion. 42. 4-7 Game Over: Hallo Freunde. In der vorherigen Lektion haben wir die Angriffe des Feindes ausgeführt , um den Spieler zu verletzen. In dieser Lektion fügen wir ein Spiel über den Bildschirm hinzu. Dabei handelt es sich um eine Kontrollnotiz über der Benutzeroberfläche, die wahrscheinlich über alles andere gezeichnet wird, aber immer noch unter der Blende liegt. heißt Game Over Menu. Ich verwende ein vertikales Feld, um alles einfach zu sortieren beginne mit einer Bezeichnung, auf der Game Over steht , damit der Spieler schnell versteht, was passiert, wenn dem Spieler die Leben ausgehen. Ich zeige ihnen einfach drei Optionen an, versuche es erneut mit dem Levelanfang, gehe zurück zum Levelauswahlmenü oder verlasse das Spiel Ich füge für jede meiner drei Optionen drei Schaltflächen hinzu: Auswählen und Beenden Ich vergrößere das Ganze viermal und positioniere es neu, sodass es sich in der Mitte des Bildschirms befindet. Wählen Sie mithilfe von Ankern die einzelnen Tasten verbinden Sie das gedrückte Signal mit dem Game Manager-Skript. Dadurch entstehen drei neue Methoden, die aufgerufen werden , wenn der Spieler die Tasten drückt Zunächst benötigen wir einen Verweis auf das Game Over-Menü , das während der Bereitschaftsphase eingestellt Und setze seine sichtbare Eigenschaft auf Stürze, um es zu verstecken. Wenn dann der Status Game Over erreicht ist, können wir seine Eigenschaft visible auf true setzen. Wenn Sie dann eine dieser Tasten drücken, sollte das Gameover-Bildschirmmenü ausgeblendet werden, indem die Eigenschaft visible wieder auf false gesetzt Wenn der Spieler am Anfang des Levels von vorne beginnen möchte , müssen wir eine Reihe von Variablen zurücksetzen, auf alle Feinde, Schätze und Checkpoints usw. reagieren und Checkpoints usw. Wir können das vereinfachen, indem wir einfach dasselbe Level entladen und neu laden Entladen ist einfach, da wir einen Verweis auf den Level-Knoten haben Wir können Underscore Level Free einfach aufrufen. Um das Level neu zu laden. Wir müssen jedoch wissen, welches Level geladen wurde. das Datenskript öffnen, können wir zwei neue Variablen hinzufügen, eine für die Welt und die andere für Level, beide mit einem Anfangswert von eins. Wenn Sie Ihre Ebenen nicht in Welten organisieren möchten, können Sie diese Variable ignorieren, solange wir hier sind. Wir müssen auch diese anderen Werte zurücksetzen , wenn der Spieler vom Anfang des Levels von vorne anfängt vom Anfang des Levels von vorne , indem wir eine öffentliche Wiederholungsmethode hinzufügen Wir können Münzen auf Null setzen, Leben auf drei, Checkpoint auf Null und den Schlüssel auf Falsch Zurück im Game Manager-Skript können wir Dateidaten aufrufen, um den Fortschritt des Spielers zurückzusetzen Dann können wir den Wert von level auf load setzen, was ein Zeichenkettenargument benötigt das den Dateipfad zu der Ressource darstellt , die wir laden möchten. Suchen Sie im Dateisystem-Tab nach Ihrem Level, klicken Sie mit der rechten Maustaste und wählen Sie Pfad kopieren aus. Fügen Sie dann diesen Pfad in die Anführungszeichen ein. Und folgen Sie dem Load-Aufruf , der eine Ressource mit instantiate zurückgibt , um diese Ressource in einen Knoten umzuwandeln Fügen Sie dann diesen Knoten mit add child zum Szenenbaum hinzu, aber dadurch wird immer nur Ebene eins geladen Wir können die Variablen im Dateinamen durch die Variablen aus unseren Dateidaten ersetzen , aber die Variablen sind ganze Zahlen Und das ist eine Zeichenfolge die die ganzen Zahlen mit STR-Klammern in Zeichenketten umwandelt. Solange sich jede Ebene im Levels-Ordner befindet und im gleichen Format benannt ist, wird sie geladen, indem einfach die Variablen world und level in den Dateidaten Wir können dann den Spieler spawnen, die Spielersteuerung ausschalten und ihn wiederbeleben Aber wir wollen nicht, dass der Spieler mitbekommt , dass irgendwas davon passiert Wir sollten damit beginnen, zu Schwarz zu verblassen. Sie dann am Ende, bis das Ausblenden gelöscht und schalten Sie die Spielersteuerung wieder Der Spieler befindet sich am Anfang des Levels, der komplett neu geladen wurde , und versucht es erneut mit Vorerst können wir, wenn der Spieler zum Level-Auswahlmenü zurückkehren möchte , einfach zu Schwarz wechseln und seine Dateidaten zurücksetzen, da wir die Szene noch nicht erstellt Hinterlassen Sie hier jedoch einen Kommentar oder eine Erklärung zum Ausdruck , damit wir diese Funktion in Zukunft implementieren können Wenn sie die Ex-It-Taste drücken, können wir warten und es wird schwarz Rufen Sie dann Get Tree Quit auf, um das Spiel zu beenden. Alternativ möchtest du vielleicht, dies zum Titelbildschirm des Spiels zurückkehrt, wenn wir einen haben. Zu Testzwecken lasse ich einfach den Overscreen des Spiels sichtbar machen Standardmäßig funktioniert die Quit-Taste. Die Levelauswahltaste macht noch nicht viel, aber das ist beabsichtigt Die Wiederholungstaste funktioniert auch. Aber dieses Menü sieht schlecht aus und passt nicht zur Ästhetik des Spiels Lassen Sie uns das Asset Pack verwenden, um es besser zu machen. Ich ändere zunächst die Bezeichnung einen einfachen Kontrollknoten namens Banner und fülle ihn mit Texturwracks, fülle sie mit den Buchstabenbildern, um Game over zu buchstabieren , und sortiere sie anhand von zwei horizontalen Kästchen Ich setze die Größe zurück und ändere den Abstand zwischen den einzelnen Buchstaben auf zwei Pixel Ich füge fünf weitere Textur-Ts und verwende die kleinen Bannerbilder, um ein Banner zusammenzustellen. Dabei ordne ich sie so an, dass sie mittig um den Startpunkt des Banners passen und die Wörter auf dem Banner stehen . Dann weise ich das Banner an, sich innerhalb des übergeordneten vertikalen Felds zu zentrieren sich innerhalb des übergeordneten vertikalen Felds das Spiel über dem Menüknoten aus Erweitere den Themenbereich und wähle Neues Thema aus der Drop-down-Liste aus. Klicken Sie dann auf die Themenressource , um sie im unteren Bereich zu öffnen. Diese Anzeige zeigt uns verschiedene UI-Elemente und wie sie mit dieser Themenressource aussehen werden, die wir bearbeiten können. Lassen Sie uns dem Thema eine Schaltfläche hinzufügen. der Registerkarte „Stilfeld“ gibt es fünf Optionen für verschiedene Schaltflächenstatus. Sie werden alle zum Thema hinzugefügt. Wir können dann ändern, wie die Schaltfläche in jedem Status aussieht. Beginnen Sie mit „Normal“, fügen Sie eine neue Style-Box-Textur hinzu, klicken Sie auf das Style-Feld, um es zu öffnen, füllen Sie es dann mit der grünen Schaltfläche Ein Bild. Die Buttons in der Vorschau sind jetzt grün, genau wie die Buttons in unserem Spiel. Aber sie sind gestreckt und hässlich. Erweitern Sie dann den Bereich mit den Texturrändern fügen Sie einige Pixel Randabstand hinzu. Das Bild sieht jetzt besser aus. Die Bilder in diesem Asset-Paket haben einen größeren unteren Rand als die anderen Seiten. Da das Game Over-Menü diese Themenressource verwendet. allen untergeordneten Elementen wird außerdem dasselbe Thema angewendet, wenn Sie den Mauszeiger über eine Schaltfläche bewegen oder sich darauf konzentrieren Ich tausche die Textur gegen den gelben Button aus. Wir können sehen, wie sich das verhält, wenn wir den Mauszeiger bewegen und auf die Schaltflächen in der Vorschau klicken Wenn diese Option deaktiviert ist, verwende ich dieselbe grüne Button-Textur, moduliere aber die Farbe, indem ich die RGB - und Alpha-Werte alle mit der Hälfte multipliziere RGB - und Alpha-Werte alle mit der Hälfte multipliziere, sodass sie grauer und verblasster wird Wenn diese Taste gedrückt wird, verwende ich dieselbe gelbe Tastentextur, mache aber dasselbe, moduliere mit Lassen Sie Alpha jedoch bei voller Deckkraft und entfernen Sie den Text von den Schaltflächen Ich werde sie stattdessen durch Symbole ersetzen. Unterordnen Sie dann jede Schaltfläche einem horizontalen Feld, das mit einem anderen horizontalen Feld gepaart mit einem anderen horizontalen Feld ist , das als Bezeichnung für die Schaltfläche dient. Jedes horizontale Feld für die Beschriftung hat für jeden Buchstaben des Wortes, das ich buchstabieren möchte, mehrere Textur-Zeilen. Dadurch wird für jeden Buchstaben des Wortes, das ich buchstabieren möchte, mehrere Textur-Zeilen das horizontale Feld angewiesen, sich das horizontale Feld angewiesen zu verkleinern und vertikal zu zentrieren Für die Ebenenauswahl verwende ich einfach einen leeren Text direkt als Ich hätte gerne mehr Platz zwischen den Schaltflächen und ihren Beschriftungen. Also wähle ich die horizontalen Felder in Gruppen aus und bearbeite ihre Abstandswerte so, dass sie 14 Pixel betragen. Dann füge ich alle drei Schaltflächen in ein weiteres vertikales Feld ein und platziere es in einem Panel-Container-Knoten mit dem Namen Wood. Und füge dem Panel-Container auch einen Panel-Knoten mit dem Namen Paper hinzu, Reopening the Theme Im unteren Bereich können wir weitere Änderungen an Panels und Panel-Containern vornehmen weitere Änderungen an Panels und Panel-Containern den Panel-Container zum Thema hinzufügen, können wir ihm auch eine Style-Box geben, wobei Prefabs Three als Bild Ich möchte breitere Ränder in diesem Bereich damit die Schaltflächen an den Rändern nicht so überfüllt aussehen Container-Knoten wird automatisch Größe von Container-Knoten wird automatisch an ihren Inhalt angepasst Lassen Sie uns auch das Panel zum Thema hinzufügen. Bedienfelder ähneln einer zerstörten Textur, haben aber wie die Schaltflächen auch Texturränder Und ich werde Prefab Nine als Textur verwenden. Das hat ziemlich breite Ränder bei 20 Pixeln. Und im Gegensatz zu den Schaltflächenbildern bei denen die Innenseite nur flach war, weisen Papier und Holz eine Textur auf , die gedehnt wird. den Bereich „Achse dehnen“ erweitern, können wir die Texturen so einstellen, dass sie nebeneinander statt gestreckt werden, um mehr Abstand Ich gebe der Holzplatte eine Mindestbreite von 160 Pixeln und dem Papier eine benutzerdefinierte Größe von 120 mal 100 Pixeln. Positionieren Sie das Papier auf der rechten Seite des Holzes und die Knöpfe vertikal zentriert. Die Wörter sehen aus, als wären sie auf dem Papier geschrieben. Und entfernen Sie die benutzerdefinierte Mindesthöhe des Banners. Jetzt haben wir ein thematisches Spiel auf dem Bildschirm. Im nächsten Abschnitt geben wir dem Spieler ein Schwert, damit er sich wehren kann. Wir sehen uns im nächsten Abschnitt. 43. 5-1 Schwert: Hallo Freunde. Im vorherigen Abschnitt haben wir dem Spielercharakter erlaubt, Schaden zu nehmen und zu sterben. In diesem Abschnitt geben wir dem Spieler ein Schwert und eigene Angriffe damit er sich wehren kann, wenn du die Aufgabe abgeschlossen hast. Alle deine Level haben jetzt den Checkpoint-Ordner. Und all deine Feinde werden Todesattacken und Angriffsanimationen haben Todesattacken und Angriffsanimationen Alle deine Feinde können angreifen. Der Spieler erleidet Schaden und stirbt, Der Spieler erleidet Schaden und wenn du die Herausforderungen gemeistert hast. Es kann auch sein, dass die Benutzeroberfläche und das Game-Over-Menü aus dem Off eingeblendet Sowie grüne und blaue Zaubertränke , die sich auf einzigartige Weise auf den Charakter auswirken Fangen wir mit ein bisschen Hauswirtschaft an. Ich möchte die Charaktere- und Spielerskripte in einen neuen Skriptordner mit dem Namen Characters sortieren . Diese Hauptspielszene wird für jedes Level verwendet, nicht nur für das erste Level. So können wir den Level-Knoten im Game Manager-Skript löschen . Wir werden den Wert von level nicht mit at on ready festlegen . In der Ready-Methode. Nachdem wir den Fade so eingestellt haben, dass er sichtbar ist, sollten wir dann den aktuellen Level laden. Eine neue private Methode schreiben. Beim Laden des Levels können wir denselben Code verwenden, den wir in der Methode mit der Wiederholungstaste geschrieben haben , um den Level zu laden und ihn durch einen Methodenaufruf zu ersetzen Dann verschieben Sie auch die Grenzen und die Benutzeroberfläche auf die Ladeebene. Sie werden aktualisiert, um den neuen Werten zu entsprechen. Fügen Sie außerdem eine Zeile zur Benutzeroberfläche hinzu, um die sichtbare Eigenschaft des Tastensymbols darauf festzulegen die sichtbare Eigenschaft des , ob der Spieler den Schlüssel besitzt oder nicht. Unabhängig davon, für welche Welt ein Level in den Dateidaten festgelegt ist , wird dieses Level geladen, wenn das Spiel gestartet wird. Wenn das Level neu geladen oder geändert wird, werden die Grenzen und die Benutzeroberfläche entsprechend aktualisiert Bisher war alles, was wir in unserem Charakterskript gemacht haben , anwendbar oder zumindest flexibel genug, um auf jeden Charakter angewendet zu werden Das Asset-Paket enthält jedoch nur den Menschen, der das Schwert trägt. Um diese Verhaltensweisen vom Charakterskript zu trennen, können wir ein neues Skript erstellen, das vom Charakter erbt. Es wird Verhaltensweisen enthalten, die immer nur auf den Helden unseres Spiels angewendet werden können, der im neuen Ordner für Charakterskripte gespeichert wurde, ersetzt und das Charakterskript in der Grundnote von Roger Dieses Skript benötigt eine exportierte boolesche Variable um uns mitzuteilen, ob der Held gerade ein Schwert in der Hand hält oder nicht gerade ein Schwert in der Hand hält Wir können diesem Skript auch einen Klassennamen geben, damit andere Skripte leicht überprüfen können, ob um einen Charakter oder einen Helden handelt Ich werde auch einen privaten Hinweis auf das Schwert haben , das damit ausgestattet ist. Dann füge eine neue öffentliche Methode hinzu, andere Skripte Roger anweisen können, ein Schwert auszurüsten. Das Schwert als Parameter nehmen, die lokale private Variable setzen und sein Schwert auf eine andere öffentliche Methode setzen , um unserem Helden zu sagen, dass er das Schwert fallen lassen soll. Wenn sie kein Schwert zum Abwerfen haben, können wir es ignorieren und zurückkehren. Andernfalls wird das Schwert beim Setzen herunterfallen, was bedeutet , dass das Schwert fallen gelassen werden soll. Wenn das Schwert die globale Position des Helden als Argument vorgibt, weiß es, wo es sein sollte. Da der Held kein Schwert mehr hat, die Schwert-Variable Null, was leer bedeutet. Wenn der Held stirbt, überschreiben wir das Würfelverhalten des Charakters um zu überprüfen, ob der Held ein Schwert hat, und wenn ja, lassen wir es fallen, dann wollen wir trotzdem, dass der Rest des Würfelcodes auch ausgeführt wird. Anstatt zu kopieren und einzufügen, können wir Super Die verwenden, um die ererbte Definition von sterben aufzurufen Nach dem gleichen Verfahren haben wir all unsere sammelbaren Schätze erstellt Lass uns ein zweideutiges Schwert für den Spielercharakter herstellen. Ich möchte, dass bei meinem Schwert Physik angewendet wird. Manchmal mache ich es zu einem starren Körper, zwei D, wie Münzen, aber mein Schwert wird komplexer sein als typische Schatzgegenstände mit mehreren Zuständen und mehr Dingen geändert werden müssen als nur der Sprite, eher wie die Schatztruhe Ich gebe ihm einen Sprite-2-D-Knoten. Ich setze das Standard-Sprite auf Sword, Idle, Zero One. einen Animations-Player und den Animationsbaum hinzufüge, kann ich die Idle-Animation so erstellen , dass sich das Schwert dreht. Fügen Sie dann dem Ast eine Kollisionsform hinzu und geben Sie ihm eine kapselförmige Größe, die zum Sprite des Schwertes passt Ich lege es auf Ebene 26, um es von anderen Gegenständen zu trennen und es nur mit dem Zug oder dem Spieler kollidieren zu lassen , wie es bei den Münzen der Fall Ich lasse es standardmäßig nicht rotieren, eingefroren, sein Freeze-Modus ist auf Kinematisch eingestellt, sodass es sich nicht bewegt, aber trotzdem Kollisionen haben kann Und melde Kollisionen bei Kontakt mit bis zu zwei Personen gleichzeitig, indem du den Animationsbonus auswählst Ich setze die Anim-Player-Eigenschaft auf diesen Animation-Player und erstelle vorerst eine neue Zustandsmaschine Dadurch wird standardmäßig nur die Animation im Leerlauf abgespielt Außerdem füge ich dem Node einen Audio-Stream-Player hinzu, ich mit dem unverhüllten Soundeffekt bestücke diesen Zweig als eigene Vielleicht möchtest du das in einen Waffen- oder Ausrüstungsordner legen , aber da es keine anderen Objekte dieser Art gibt, behalte ich es einfach im Ich habe das Schwert vom Ursprung der Szene entfernt, also setze ich seine Übertragung und Eigenschaft zurück, um es erneut einzugeben Jetzt müssen wir ein Skript für das Schwert erstellen. Das verhält sich zwar ähnlich wie Treasure, ist aber so unterschiedlich, dass ich den Code lieber nicht umgestalten und stattdessen einfach Rigid Body Two D erben und das vom Körper eingegebene Signal mit dem Skript verbinden Dank der Kollisionsebenen man mit ziemlicher Sicherheit davon ausgehen, dass das einzige Wesen, das mit dem Schwert sterben kann, Aber ich werde nachschauen, nur um sicherzugehen ob der Körper ein Held ist und das Schwert ausrüsten kann. Wir müssen diese Methode definieren und sie einen booleschen Wert zurückgeben Dann können wir dem Helden sagen, er soll dieses Schwert ausrüsten , sich selbst als Argument ausgeben und unsichtbar werden, sodass der Spieler das Schwert nicht mehr sehen kann Denn der Charakter wird zeichnen, um die Physik beim Abwerfen des Schwertes einfacher zu machen Ich werde auch den Firstkörper wieder auftauen, wenn das Set zurückgestellt ist. Ich hole mir einen Verweis auf den Audio-Stream-Player zwei während der Bereitschaftsphase tun Wir können den Soundeffekt auch abspielen. Wenn das im Heldenskript passiert, müssen wir die Methode „Equipped Sword“ schreiben, die einen booleschen Wert zurückgibt Wir müssen nur sagen, ob der Held kein Schwert hat und nicht tot ist Unter diesen Bedingungen sollte der Held in der Lage sein, das Schwert auszurüsten. Wenn der Held dann das Schwert fallen lässt, ruft er eine Methode auf. diese Definition schreiben, können wir die Position, von der das Schwert fallen gelassen wurde, als Parameter vom Typ Vektor zwei annehmen der das Schwert fallen gelassen wurde, als Parameter vom . Ich benötige einen Zufallszahlengenerator, der während der Bereitschaftsphase gestartet wird , um einen zufälligen Wert zwischen minus eins und positiv zu berechnen. Ich setze die globale Position des Schwertes auf diese Position plus ein halbes Plättchen nach oben. Wende eine Impulskraft von acht Feldern plus rechts multipliziert mit einer zufälligen Zahl , die der Wirkung der Münzen ähnelt Und setze schließlich visible auf true, damit der Spieler es sehen kann Wir können jetzt unsere Animationen duplizieren, um neue zu erstellen, in denen der Held das Schwert in der Hand hält, angefangen beim Idol, dann rennen, springen, zu Boden fallen und zuschlagen Jetzt können wir unsere Helden ohne Schwert-Zustandsmaschine mit der Breiten-Schwertzustandsmaschine verbinden ohne Schwert-Zustandsmaschine , basierend auf dem Wert von hat Schwert, das die Breite der gespeicherten Zustandsmaschine öffnet Diese oberste Ebene enthält die Attack-Zustandsmaschine der Hit-Schwertanimation verbunden ist, denn wenn der Spieler stirbt, wirft er das Schwert in die Attack-Zustandsmaschine. Fügen Sie vorerst einfach die Bewegungszustandsmaschine und verbinden Sie sie von Anfang an die Sprung -, Fall- und Bodenanimationen sowie die Fortbewegungszustandsmaschine hinzu -, Fall- und Bodenanimationen sowie die Fortbewegungszustandsmaschine verbinden Sie sie auf die gleiche Weise wie alles andere miteinander die gleiche Weise wie alles andere Und schließlich musst du die zweite Fortbewegungszustandsmaschine abschließen und das Schwert irgendwo in deinem Level platzieren Der Held kann es jetzt aufheben und alle Animationen funktionieren immer noch genauso, nur wenn das Schwert ausgerüstet ist Und wenn sie sterben, wird das Schwert fallen gelassen. Wir haben jetzt einen Schwert-Gegenstand, den der Spieler aufheben und ausrüsten kann. In der nächsten Lektion werden wir Schwertangriffe hinzufügen. Wir sehen uns in der nächsten Lektion. 44. 5-2 Angriff: Hallo Freunde. In der vorherigen Lektion haben wir ein Schwert hinzugefügt, das der Spieler ausrüsten und fallen lassen kann. In dieser Lektion fügen wir einen Angriffsknopf und die Angriffsanimationen für den Spieler hinzu. Öffnen wir zunächst die Projekteinstellungen, den Tab „Eingabemap“ und fügen eine Angriffsschaltfläche hinzu. Ich verwende die linke Maustaste auf die J-Taste auf der Tastatur und die linke Gesichtstaste für das Gamepad Bietet Platz für eine Vielzahl von Spielstilen in zwei Namen für Physik-Ebenen Ich werde auch die Namen der Ebenen „Treffer“, „ Gegner getroffen“ und „ Schwert“ hinzufügen Namen der Ebenen „Treffer“, „ Gegner getroffen“ und „ Schwert dann im Spielerskript während des Eingabeereignisses Wenn dann im Spielerskript während des Eingabeereignisses die Angriffstaste gedrückt wird, sollten wir dem Spielercharakter sagen, dass er angreifen soll. Das Charakterskript wurde bereits so eingerichtet dass es diese Eingabeeinstellung „Attacke“ auf „true“ verarbeitet, aber Spieler können und werden Buttons auch dann drücken , wenn die gewünschte Aktion nicht möglich ist Die Einstellung „Will angreifen“ auf „True“ löst einen Angriff , sobald dies dank des Animationsbaums möglich wird Dies geschieht jedoch auch dann, wenn der Taste eine beträchtliche Zeit vergangen ist Drücken der Taste eine beträchtliche Zeit vergangen ist. Wir sollten ein Zeitlimit dafür setzen, wie lange die Angriffseingabe als gültig betrachtet wird , bevor wir sie ignorieren, falls der Charakter den Angriff während dieser Zeit nicht ausführen kann Fügen wir der Trefferbox einen Timer-Knoten mit dem Namen Input Buffer hinzu und setzen die Zeit auf eine halbe Sekunde und einen Schuss auf wahr Dann können wir im Hero-Skript während der Bereitschaftsphase einen Verweis auf diesen Knoten abrufen während der Bereitschaftsphase einen Verweis auf diesen Knoten Indem wir die Definition von Attack außer Kraft setzen, können wir will angreifen auf true setzen, den Eingangspuffer-Timer starten auf sein Timeout-Signal warten Dann will set wieder angreifen und wieder auf False setzen. Wenn innerhalb einer halben Sekunde nach dem Drücken der Taste kein Angriff ausgelöst wurde , wird das Drücken der Taste ignoriert. Die Dauer kann einfach in den Eigenschaften des Timer-Knotens angepasst werden . Während eines Angriffs möchte ich verhindern, dass Charaktere andere Aktionen im Charakterskript ausführen. Ich benötige eine weitere Bullion-Variable, um zu wissen, ob der Charakter gerade angreift oder nicht werde ich während der Animationen einstellen und ihren Wert auf False setzen, wenn die Szene zum ersten Mal geladen wird, nur für den Fall, wie wir es bei der Hitbox-Überwachung gemacht haben die gleiche Weise, wie ich überprüfe, ob der Charakter tot ist, bevor ich andere Aktionen ausführe, füge ich auch die Bedingung , dass er nicht angreifen darf. Ich ändere „Lauf“ jedoch so, dass ich den Wert von direction auf Null setze, wenn er tot ist oder angreift , anstatt einfach zurückzukehren . Ansonsten verhalte dich normal. Charaktere müssen ihre Angriffe beenden, bevor sie weitere Aktionen ausführen können. Ich werde der Kollision mit der Trefferbox auch die Bedingung hinzufügen, dass dieser Charakter nicht tot sein darf und angreifen muss, um Schaden anrichten zu können In der Ansicht von Rogers Two D habe ich dem Hip-Box-Knoten von Rogers noch keine Form gegeben, noch das Signal verbunden oder die Kollisionsebene und Maske festgelegt Wir können das Knotensignal des eingegebenen Bereichs einfach mit der Methode verbinden , die wir bereits im Zeichenskript definiert Dann stelle diese Hüftbox so ein, dass sie standardmäßig ausgeschaltet ist, wenn der Spieler die Kollisionsebene 11 trifft und die gegnerische T-Ebene 18 maskiert Rogers Animation Player auswählen, können wir eine Attack-One-Animation hinzufügen die mit den entsprechenden Sprites gefüllt ist und ihre Längeneinstellung will angreifen im ersten Frame auf False setzen. Wir müssen den Wert von is attack auf true setzen, Wir müssen den Wert von is attack auf true setzen während die Animation abgespielt wird. Dann zurück zu Falsch. Danach weiß der Charakter, dass er sich weder bewegen noch springen soll. Setzen Sie dann die Überwachungseigenschaft der Hüftbox im zweiten Bild auf „Wahr “ und im dritten auf „Falsch“. Erkennung der Kollision , bei der Feinde verletzt werden. Verwenden Sie das zweite Bild der Animation als visuelle Anleitung erstellen Sie eine neue Form für die Kollision. Ich verwende eine Kapsel und setze ihre Farbe auf Rot, damit sie zu meinen anderen Hüfttaschen passt. Stellen Sie dann Form, Position und Drehung so ein, dass sie zum betroffenen Angriffsbereich passen. Hinzufügen von Spuren zur Animation für die Kollision. Formknoten, Form, Position und Drehung. Frames der Animation können wir für jedes einzelne Keyframes hinzufügen Während des ersten Frames der Animation können wir für jedes einzelne Keyframes hinzufügen. Fügen Sie der Hip-Box ein animiertes SO hinzu, um die Effektanimationen zu erstellen. Und erstellen Sie für jeden der drei Angriffseffekte eine Animation der drei Angriffseffekte mit einem leeren Frame am Ende als Standardwert. So wie wir es bei den feindlichen Angriffen gemacht haben. Positionieren Sie den Knoten vor dem Charakter, sodass die Sprite-Animation so aussieht, als ob sie mit dem Angriff in der ersten Attack-Animation übereinstimmt. Wir können einen Track hinzufügen, der die Effektanimation abspielt, wobei Attack One als erstes Argument in der Play-Methode übergeben erstes Argument in der Play-Methode Rufen Sie den Inspektor an. Und auch ein Audio-Playback zum Abspielen eines Swipe-Soundeffekts, der die Attack-Animation dupliziert Wir können den Angriff zwei und den Angriff drei Animationen erstellen, die Sprite-Texturen austauschen, die Argumentübergabe an das animierte Sprite ändern und die Audiowiedergabe mit einem neuen Soundeffekt füllen Audiowiedergabe Dann erstellen Sie eine neue Kollisionsform für die Sie die Position, Drehung und Passen Sie die Position, Drehung und Form an den betroffenen Bereich des Angriffs an Je nachdem, welche Version von Godot Sie verwenden. Der Editor zeigt den Collider möglicherweise nicht korrekt an, während Sie dies tun, aber Sie können trotzdem Werte manuell in den Inspektor eingeben und den gesamten Vorgang wiederholen, um Angriff drei zu starten Stellen Sie sicher, dass Sie für jede Animation eine neue kollisionsförmige Ressource erstellen für jede Animation eine neue kollisionsförmige Ressource Oh, den Animationsbaum auswählen. tauchen in die Breite der Schwertebene und Wir tauchen in die Breite der Schwertebene und der Angriffsebene ein und wollen unsere drei Angriffsanimationen hinzufügen. Ich möchte diese drei Angriffsanimationen der Reihe nach durchgehen , solange der Spieler die Angriffstaste gedrückt hält, aber von einer der Animationen solange der Spieler die Angriffstaste gedrückt hält, zur Bewegung zurückkehren , wenn er aufhört, die Angriffstaste zu drücken. der Charakter angreifen will und sich auf dem Boden befindet, muss er zuerst aus der Bewegung übergehen Wenn der Charakter angreifen will und sich auf dem Boden befindet, muss er zuerst aus der Bewegung übergehen, um eine anzugreifen Folgt dann bei den anderen beiden Angriffen den gleichen Bedingungen den anderen beiden Angriffen wechselt erst am Ende der vorherigen Animation Angriffe zwei und drei kehren am Ende der Animation zur Bewegung zurück. Der Übergang von Angriff zwei zu Angriff drei wird jedoch Vorrang haben. Wenn die Bedingungen erfüllt sind, geht Angriff eins wieder zur Bewegung über, wenn der Charakter entweder nicht angreifen will oder wenn er sich nicht mehr auf dem Boden befindet. Vor dem Testen wäre es hilfreich, wenn der Collider im Debug-Menü animiert wird Wählen Sie Sichtbare Kollisionsformen, um Kollisionsformen zu rendern , während das Spiel läuft Wenn wir das Schwert nun in unserem Spiel in die Hand nehmen, kann der Spieler damit Komboangriffe mit jeweils unterschiedlichen Animationen, Kollisionsformen und Soundeffekten ausführen mit jeweils unterschiedlichen Animationen, . Und die Angriffe werden auch Feinde verletzen und töten. Wir haben den Spielercharakter jetzt in der Lage, einen Kombiangriff mit drei Treffern mit einem Schwert auszuführen einen Kombiangriff mit drei Treffern mit , um sich gegen seine Feinde zu wehren. In der nächsten Lektion werden wir zwei Luftangriffe hinzufügen. In der nächsten Lektion sehen wir uns. 45. 5-3 Luftangriff: Hallo Freunde. In der vorherigen Lektion haben wir Angriffsanimationen für den Spieler hinzugefügt. In dieser Lektion werden wir weitere Angriffe hinzufügen , die der Spieler beim Springen einsetzen kann. Beginnen Sie in der Rogers-Szene und wählen Sie Rogers Animations-Player-Knoten Wir können die Animation des ersten Angriffs duplizieren, um einen Luftangriff zu erstellen , und die Sprites gegen diese Animation austauschen Den Swipe-Soundeffekt gegen einen anderen austauschen. Wir müssen auch eine neue Kollisionsform für diese Animation erstellen Kollisionsform für diese Anpassung von Form, Position und Drehung an den betroffenen Bereich. Wenn Sie diese Kollisionsformen mit einer Animation anpassen, ist es hilfreich, einen neuen kollisionsförmigen Knoten zu erstellen und diesen stattdessen anzupassen. Kopieren Sie dann die Werte in die Animations-Keyframes und löschen Sie den neuen Knoten. Wenn Sie fertig sind, benennen wir den animierten Sprite-Two-Node in Attack-Effekte um Dann duplizieren Sie es, um Luftangriffseffekte zu erzeugen. Stellen Sie sicher, dass Sie eine neue Sprite-Frames-Ressource für diesen neuen Knoten erstellen und die beiden Animationen mit Luftangriffseffekten Die Luftangriffseffekte sind nicht die gleiche Weise positioniert wie die Bodenangriffseffekte Also müssen wir den Knoten neu positionieren und die Spur für den Angriffseffekt löschen Wir können stattdessen eine neue Spur für die Luftangriffseffekte hinzufügen und diese Animation dann duplizieren Um Air Attack Two zu erzeugen, können wir den Vorgang wiederholen, die Sprites austauschen, Argument hinter der Effektanimation ändern und den Soundeffekt umschalten Passen Sie dann die Kollisionsform an den Angriff an. diese beiden neuen Animationen zum Animationsbaum hinzufügen, Sie diese beiden neuen Animationen zum Animationsbaum hinzufügen, verhalten sie sich fast genauso wie die Bodenangriffe, nur mit der Bedingung, dass der Charakter nicht auf dem Boden befinden darf übergeht am Ende der Animation unter den gleichen Bedingungen von Luftangriff eins zu Luftangriff zwei unter den gleichen Bedingungen Und zurück zur Bewegung am Ende des zweiten Angriffs, Übergang vom ersten Luftangriff zurück zur Wenn der Spieler nicht mehr angreifen will oder auf dem Boden liegt, möchte ich das Gefühl vermitteln, in der Luft zu schweben , während der Spieler diese Luftangriffe möchte ich das Gefühl vermitteln, in der Luft zu schweben, während der Spieler diese Luftangriffe ausführt Wir werden die Definition von Luftphysik im Heldenskript außer Kraft setzen Luftphysik im Heldenskript Wenn der Held angreift und seine Y-Geschwindigkeit größer als Null ist, was bedeutet, dass er fällt, setze ich seine Y-Geschwindigkeit auf Null ihn stattdessen für die Dauer seines Angriffs in der Luft. Andernfalls können wir Super Air Physics Delta verwenden , um die ererbten Verhaltensweisen aus dem Charakterskript auszuführen . Aber da der Spieler sich dafür entscheiden kann , unendlich weiter anzugreifen, kann er sich auch dafür entscheiden, für immer in der Luft zu bleiben Wir können dies mit einer anderen Spielmechanik korrigieren, einem Cool-Down-Timer Hinzufügen eines weiteren Timer-Knotens zur Hip-Box namens Cool Down. Ich belasse die Zeiteinstellung auf die Standardeinstellung 1 Sekunde, setze aber One Shot auf True. Ich suche während der Bereitschaftsphase im Hero-Skript einen Verweis auf diesen Knoten , damit wir ihn im Animationsbaum referenzieren können ihn im Animationsbaum referenzieren Später in den Angriffsanimationen können wir jedem Start des Cooldown-Timers am Ende jeder Animation einen Methodenaufruf-Track hinzufügen jedem Start des Cooldown-Timers am Ende jeder Animation einen Methodenaufruf-Track Start beim Cooldown-Timer aufrufen. Auch hier wird bei jedem Angriff einfach der Zeitwert auf 1 Sekunde zurückgesetzt Zeitwert auf 1 Sekunde zurückgesetzt und der Countdown wird erneut gestartet. Im Animationsbaum lassen wir den Übergang zum ersten Angriff der Sequenz erst zu, wenn der Cooldown-Timer gestoppt wird. Auf diese Weise wird der Spieler gezwungen sein , seinen Angriff nach maximal drei Angriffen am Boden oder zwei Angriffen in der Luft einzustellen maximal drei Angriffen . Die Dauer der Abkühlung kann einfach in den Eigenschaften des Timer-Knotens angepasst werden. Ich würde auch gerne einen Feind von oben angreifen , um den Spieler abzuprallen zu Hinzufügen einer Überschreibung zum Heldenskript der eingegebenen Methode im Hit-Box-Bereich Ich muss zuerst überprüfen, ob dieser Held entweder tot ist oder nicht angreift, und dann zurückkehren, wenn er nicht auf dem Boden ist. Und die globale Y-Position des vom Angriff getroffenen Bereichs ist größer als die globale Y-Position des Helden, der getroffene Feind befindet sich also darunter. Dann stelle ich ihre Y-Geschwindigkeit so ein, dass die Sprungkraft durch zwei geteilt wird, wodurch ein Sprung entsteht, der kleiner ist als ein voller Sprung Und schließlich rufe ich die ererbte Definition auf, Schaden anzurichten Nun, bei der Erstellung der Angriffsanimationen der Spieler habe ich die neue Variable für Angriffe hinzugefügt, aber diese Variable war nicht in den gegnerischen Angriffsanimationen enthalten . Fügen wir das also hinzu. Während der Animationsbaum im Zustand der Maschine hilft, die Dinge zu organisieren Außerdem besteht die Möglichkeit Animationen unterbrochen werden, sodass Variablen so gesetzt werden, wie sie es eigentlich nicht sein sollten Wenn Roger zum Beispiel seine angreifende Variable angreift, sind sowohl die Hip-Box-Überwachung als auch die Hip-Box-Überwachung auf „true“ gesetzt. Aber dann wird er getroffen, bevor die Animation abgeschlossen ist, und diese Variablen werden nicht auf False zurückgesetzt. Roger kann sich jetzt nicht mehr bewegen und alle Feinde , die sich ihm nähern, werden durch Phantom-Hip-Boxen beschädigt Wir können diese Variablen zurücksetzen , wenn der Charakter Schaden erleidet oder stirbt Um dies zu verhindern, erstellen wir eine Methode zur Unterbrechung von Angriffen Wir setzen den Wert für Angriff und Hip-Box-Überwachung wieder auf False zurück und rufen diese Methode auf, wenn der Charakter Schaden erleidet Der Spielercharakter ist jetzt in der Lage, Angriffe in der Luft auszuführen, wobei die Schwerkraft aufgehoben wird und beim Aufprall eine Sprungkraft erzeugt In der nächsten Lektion werden wir KI-Skripte hinzufügen, damit der Feind im Gebiet patrouillieren Wir sehen uns in der nächsten Lektion. 46. 5-4 Patrol: Hallo Freunde. In der vorherigen Lektion haben wir Luftangriffe für den Spieler hinzugefügt. In dieser Lektion schreiben wir ein KI-Skript, Feinde in einem Gebiet patrouillieren können. Ich habe die anderen Gegner bewegt und einen starken Zahn zwischen zwei Hindernissen in meinem Level positioniert starken Zahn zwischen zwei Hindernissen in meinem Level Und der Timer für automatische Angriffe wurde für das grundlegendste Verhalten von Feinden deaktiviert für automatische Angriffe wurde für das grundlegendste Verhalten von Feinden Ich möchte, dass sie einfach vorwärts gehen , bis sie gegen eine Wand stoßen, und sich dann umdrehen. Ähnlich wie wir den Spielerknoten geschaffen haben , um den Spielercharakter zu kontrollieren, können wir einen untergeordneten Knoten einrichten über den Feinde ihr Verhalten kontrollieren können. Bei KI benötigt dieser Knoten zwei D-Positionierungen. Also mache ich daraus einen Node zwei D und nenne ihn Patrol. Ich gebe diesem Knoten einen Skriptnamen zum Patrouillieren. Ich lege ihn in den Ordner mit den Zeichenskripten und verwende die Standardvorlage für einen Knoten mit zwei D. Während der Bereitstellungsphase ich mir einen Verweis auf den übergeordneten Knoten , also den Charakter, der gesteuert wird. Deklarieren wir auch eine Variable, damit wir wissen , in welche Richtung wir uns bewegen wollen, als Float-Typ. In der Ready-Methode können wir den Richtungswert basierend darauf initialisieren , ob das übergeordnete Zeichen nach links zeigt oder nicht Aber die Variable ist nach links gerichtet wurde als privat markiert. Wir sollten eine öffentliche Methode hinzufügen, die ihren Wert an das Zeichenskript zurückgibt, damit wir falsch darauf zugreifen können Dann können wir den Wert der Unterstrichrichtung auf der Grundlage Rückgabewerts der übergeordneten Methode Public is facing left ermöglicht es uns, den Wert von is facing left zu lesen , ihn aber nicht zu ändern Bei der Prozessmethode benötigen wir kein Delta. Wir sollten einen Unterstrich davor setzen , damit die Engine ihn ignorieren kann Das Standardverhalten besteht einfach darin, dem Charakter zu sagen , dass er in die gewünschte Richtung laufen soll Aber bevor wir das tun, sollten wir überprüfen, ob der Charakter gegen eine Wand gestoßen ist, was für uns praktischerweise im Hauptteil des Charakters enthalten ist. Befindet sich der Charakter an einer Wand, sollten wir den Richtungswert ändern. Wir können den Normalenvektor der Wände Dabei handelt es sich um einen Vektor , der senkrecht ist und von der Wandoberfläche weg zeigt. Wir sind nur an dem X-Teil dieses Vektors interessiert , um zu wissen, ob die Wand nach links oder rechts zeigt. Wir können das auch signieren. Die Rendite wird entweder negativ oder positiv sein. Das wird in meinem Spiel keine Rolle spielen, da jede Wand perfekt flach ist. Ihre normalen Vektoren werden sowieso genau links oder rechts sein. Aber dieser Code funktioniert mit abgewinkelten Wänden. Nun zwei, lass es uns ausprobieren. Fierce Tooth läuft jetzt zwischen den beiden Hindernissen hin und her Sie erkennen den Spieler sogar als Hindernis. Zweitens: Alles, womit der Körper des Charakters zum D-Knoten kollidiert und das horizontale Bewegungen verhindert, wird mit das horizontale Bewegungen verhindert, der Is-on-Wall-Methode erkannt Was ist, wenn wir Fierce Tooth oben auf der Plattform positionieren? Sie werden einfach von der Seite weglaufen und das gleiche Verhalten wie zuvor wiederholen Ich möchte dieses Verhalten zwar manchmal, ich möchte wahrscheinlich nicht, dass es ständig passiert , und ich möchte vielleicht , dass Feinde sich umdrehen, wenn sie es als vermeintlich ansehen. Das ist etwas komplizierter, da die Erkennung von Leisten für uns nicht vorgesehen Hinzufügen eines untergeordneten Knotens zum Patrol-Knoten. Wir können einen Raycast-Two-D-Knoten verwenden, um zu erkennen vorhanden ist oder vor einem Charakter Terrain vorhanden ist oder nicht. Ich positioniere den Strahl so, dass er sich im leeren Bereich vor dem Charakter befindet und nach unten auf den Boden zeigt. Wir wollen, dass sich das Verhalten dieses Feindes ändert, je nachdem, ob der Pfeil auf den Boden trifft oder nicht. Wenn sie sich umdrehen, positionieren den Pfeil auf die andere Seite Zurück im Patrouillenskript können wir uns einen Verweis auf die Besetzung während der Bereitschaftsphase holen und sie Floor Re nennen Dann setzen wir ihre Position so , dass sie in der Bereitschaftsmethode eine halbe Kachel vor dem Charakter Alternativ könntest du eine Variable exportieren, falls deine Gegner unterschiedliche Größen haben und den Strahl unterschiedlich positionieren müssen. Das ist eine Ganzzahldivision, aber ich mache das mit Absicht, also ignoriere ich die Warnung. In der Prozessmethode. Immer wenn der Charakter auf dem Boden liegt und der Strahl mit nichts kollidiert, würde das bedeuten, dass der Charakter vor einem Felsvorsprung steht Wir können also eine Methode „Ledge Detected“ aufrufen. Wenn eine Leiste erkannt wird, können wir den Richtungswert leicht zwischen minus eins und positiv austauschen minus eins und positiv indem wir ihn mit minus multiplizieren Setze dann die Position des Strahls zurück, sodass er vor der neuen Richtung des Charakters liegt Anstatt den Code zu duplizieren, können wir den Code aus der Ready-Methode in eine neue Methode umwandeln und sie jederzeit aufrufen , wenn wir möchten, dass sie die Richtung ändern Jetzt bewegt sich Fierce Tooth hin und her, ohne die Kanten der Plattform Wenn wir im Debug-Menü die Option „Sichtbare Kollisionsformen im Debug-Menü die , können wir dabei auch den Bodenstrahl bei der Arbeit beobachten dabei auch den Bodenstrahl bei der Arbeit Aber was ist, wenn ich eine Ausnahme machen und einige Gegner von Felsvorsprüngen laufen lassen Wir können unserem Skript einen neuen Variablentyp hinzufügen, eine Aufzählung, die oft mit Enum abgekürzt wird, was nur eine nummerierte Liste ist Nennen Sie es Ledge Behavior und füllen Sie diese Liste dann mit all unseren Optionen auf, die Ich füge einfach zwei Optionen hinzu. Der Standardwert ganz oben auf der Liste lautet „Umdrehen“, aber ich möchte auch die Möglichkeit haben, über die Leisten zwei zu gehen Vielleicht möchtest du auch Dinge wie anhalten oder abspringen usw. Die Konvention für Aufzählungen besteht darin, große Unterstriche zu verwenden. Sie erinnern sich vielleicht daran, dass Sie bei der Einstellung der Eigenschaft Standmodus bereits eine Aufzählung verwendet haben, die bereits im D-Knoten des starren Körpers definiert war bei der Einstellung die Aufzählung definiert ist, können wir eine Variable exportieren die Aufzählung als Typ verwenden Wenn dann ein Vorsprung erkannt wird, können wir den Wert dieser Variablen zuordnen und für jede Variable einen Codeblock bereitstellen , der ausgeführt werden soll Wenn das angebliche Verhalten sich umkehren soll, sollten wir den gleichen Code wie zuvor ausführen Aber wenn es so eingestellt ist, dass es weggeht, dann können wir einfach weitermachen oder zurückkehren. Anhand dieser Methode können Sie sich vorstellen, wie dieses Format verwendet werden kann, um eine beliebige Anzahl alternativer Verhaltensweisen bereitzustellen. Auswahl des Patrouillenknotens. Der Inspektor enthält jetzt ein Drop-down-Menü mit der Bezeichnung „Verhalten in der Leiste“, aus dem wir das Verhalten auswählen können , das wir so beschreiben möchten , dass es für jeden leicht verständlich Ich werde auch die Startposition der Spieler verschieben , um eine bessere Sicht Sagen wir Fierce Tooth, sie sollen von den Felsvorsprüngen heruntergehen und sehen, was passiert Speichert den Patrouillenknoten als eigene Szene im Ordner des Charakters Wir können jetzt dasselbe Verhaltensskript auf jeden Basisfeind in unserem Spiel anwenden . können wir anpassen, wie sie auf unterschiedliche Geländehindernisse reagieren Mithilfe von Würfen und Aufzählungen In der nächsten Lektion werden wir der Spielererkennung des Feindes ein aggressives Verhalten geben Spielererkennung des Feindes ein aggressives Wir sehen uns in der nächsten Lektion. 47. 5-5 Aggression: Hallo Freunde. In der vorherigen Lektion haben wir ein KI-Skript erstellt , mit dem jeder Feind in unserem Spiel in einem Gebiet patrouillieren und sogar sein Verhalten ändern kann jeder Feind in unserem Spiel in einem Gebiet patrouillieren . In dieser Lektion werden wir ein weiteres Skript schreiben, das es den Feinden ermöglicht, den Spieler wahrzunehmen und zu versuchen, ihn anzugreifen. Fangen wir mit einer Szene mit heftigen Zähnen an. Der erste Schritt besteht darin , zu wissen, ob ein Feind den Spieler sehen kann oder nicht Dies wird nur für die Charaktere, die wir als Feinde haben wollen, ein einzigartiges Verhalten sein. Wir sollten ein neues Skript für Feinde erstellen , die vom Charakter erben Wir können dann das Charakterskript durch das feindliche Skript auf dem Stammknoten von Fierce Tooth ersetzen feindliche Skript auf dem Stammknoten von Fierce Tooth Fügen wir eine boolesche Variable hinzu, um zu wissen, ob der Feind den Spieler sehen kann Aber woher wissen wir, ob der Feind den Spieler sehen kann? Ähnlich wie beim Angriff können wir dem Knoten einen weiteren Bereich hinzufügen, der die Sicht des Feindes repräsentiert. Und gib ihm eine Kollisionsform. Und verwenden Sie eine neutrale Farbe, wie Weiß für das Sehen. Und mach es zu einer großen kreisförmigen Fläche, die mehrere Kacheln vor ihnen und leicht um sie herum auf allen Seiten bedeckt. Dies entspricht ihrem gesamten Sichtfeld. Wir müssen wissen, ob der Spielercharakter diesen Bereich betritt. Passen wir die Kollisionsebene an. legen das auf Ebene 20, eine neue Ebene für feindliche Sicht, und maskieren Ebene neun, sodass sie nur den Spieler sehen können Dieser Bereich wird überwacht, aber nicht überwachbar sein. Und standardmäßig immer aktiviert. Möglicherweise stehen ihnen jedoch Hindernisse im Weg, die ihre Sicht blockieren. Wir können auch einen geworfenen Knoten verwenden , um ihre Sichtlinie zu überprüfen. Es spielt keine Rolle, wo sich das Ziel gerade befindet, ich lege es einfach in die Mitte. Aber der Ausgangspunkt des Raycast sollte in den Augen des Feindes liegen Wir können diese beiden Knoten unterscheiden indem wir sie aus Gründen der Klarheit umbenennen. Field Division wird nur nach dem Spieler suchen. Die Sichtlinie wird durch das Gelände und den Spieler sowie durch alles andere, was Sie ihm die Sicht versperren möchten, maskiert den Spieler sowie durch alles . Als Nächstes können wir die Signale des eingetretenen und ausgehenden Körpers des D-Nodes der Zone 2 mit dem feindlichen Skript verbinden Signale des eingetretenen und ausgehenden Körpers des D-Nodes der Zone 2 Diese sind hübsch benannt, damit wir sehen können, ob der Körper ein- und ausgetreten Speichern wir den Helden in einer Variablen wenn er das Sichtfeld des Feindes betritt und verlässt Dank Kollisionsebenen sollte nur der Held diese Methode auslösen Aber es ist immer sicherer, zuerst zu überprüfen, indem man einen Verweis auf den Helden speichert, einen Verweis auf den Helden speichert wenn er das Sichtfeld betritt , und diesen Verweis auf Null setzt, wenn er das Sichtfeld verlässt Um die Sichtlinie zu überprüfen, benötigen wir einen Verweis auf die Sichtlinienknoten , die während der Bereitschaftsphase gesetzt wurden. Während der Prozessmethode benötigen wir dann kein Delta. Befindet sich der Held in unserem Sichtfeld, rechnen wir ein bisschen, aber wenn er nicht in unserer Felddivision ist, können wir nicht sehen , dass der Spieler ihn auf „Falsch“ setzt Wir können die Zielposition der Sichtlinie so festlegen , dass sie der Differenz zwischen der Position des Helden und der Position des Feindes entspricht und die Sichtlinie direkt auf den Spielercharakter zeigt die Sichtlinie direkt auf den Spielercharakter Wenn die Sichtlinie auf etwas trifft und dieses Etwas der Held ist, dann können wir den Spieler sehen. Andernfalls muss es auf nichts oder etwas anderes treffen, wie Gelände oder ein Hindernis. Wir können nicht sehen, dass der Spieler sichtbare Kollisionsformen im Debug-Menü aktiviert und auf Play klickt dann zum Editor zurückkehren, können wir zum Remote-Szenenbaum wechseln und Fierce Tooth auswählen , um ihre Variablen im Inspektor in Echtzeit zu beobachten ihre Variablen im Inspektor in Echtzeit Jetzt können wir sehen, dass, der Spieler das Sichtfeld betritt, die Sichtlinie beginnt, seine Position zu verfolgen Die Spielervariable can C wird nur dann auf true gesetzt, wenn sie sich innerhalb des Sichtfeldes befinden und nicht durch Gelände von der Sichtlinie behindert werden Außerdem muss sich das Sichtfeld wie alles andere umdrehen , wenn der Feind nach links oder rechts schaut Wir greifen während der Bereitschaftsphase auf den Sichtknoten zurück und setzen die Definitionen von Gesicht links und Gesicht rechts außer Kraft Wir können damit beginnen, ihre Supermethoden aufzurufen. Fügen Sie dann hinzu, dass Sie die X-Skala der Sicht auf eins einstellen , wenn Sie nach links schauen, oder negativ auf eins, wenn Sie nach rechts schauen. Da die Feinde standardmäßig alle nach links schauen. Da Würfe die Skalierungseigenschaft nicht verwenden, müssen wir bei der Berechnung der Zielposition eine zusätzliche Bedingung hinzufügen . Wenn der gegnerische Charakter nicht nach links schaut, multipliziere das X der Zielposition mit minus Eins, um es zu spiegeln. Sobald der Feind den Spieler gesehen hat, wollen wir sein Patrouillenverhalten unterbrechen und ihn stattdessen den Spieler verfolgen lassen Im Patrouillenskript können wir eine private boolesche Variable hinzufügen, um zu kontrollieren, ob dieser Charakter patrouilliert oder nicht Und setzen Sie ihren Wert standardmäßig auf true. Stellen Sie dann öffentliche Methoden bereit, um dieses Verhalten anzuhalten und wieder aufzunehmen. Das Setzen des Werts von patrollt in jedem Fall, wenn es angehalten ist . Rufen Sie auch character run zero auf, um zu erzwingen, dass die Ausführung in der Prozessmethode beendet run zero auf, um zu erzwingen, dass die Ausführung in der Prozessmethode beendet wird. Wenn dieses Zeichen nicht patrouilliert, sollten wir zurückkehren und diesen Code nicht ausführen Im Enemy-Skript können wir während der Bereitschaftsphase einen Verweis auf den Patrouillenknoten abrufen , auch wenn er möglicherweise existiert oder nicht, indem wir eine Methode namens get node oder null verwenden , indem wir den Namen des Knotens, nach dem wir suchen, als Argument übergeben Ersetze dann jede dieser drei Zeilen durch einen Methodenaufruf, der dem Feind mitteilt, ob er sehen kann, wie der Held diesen neuen privaten Methodenhelden schreibt oder nicht der Held diesen neuen privaten Methodenhelden schreibt . Es wird ein boolescher Parameter benötigt, der angibt , ob sie den Helden jetzt sehen können oder nicht , wenn der Feind den Helden nicht sehen kann, was bedeutet, dass der Wert bis zu diesem Moment falsch war, aber jetzt können sie den Helden sehen Das ist genau der Moment, in dem der Spieler sowohl sein Sichtfeld als auch seine Sichtlinie betreten Dann sollten wir Can See Hero auf True setzen. Wenn der Patrouillenbrief existiert, dann sag ihm, dass er sein Verhalten unterbrechen soll. Umgekehrt, wenn der Feind den Helden sehen konnte, jetzt aber nicht, dann können wir sagen, dass das Patrouillenverhalten wieder aufgenommen werden soll, falls der Held hinter dem Feind steht Wir können den Feind auch zwingen, sich in diesem Moment der Richtung des Spielers indem wir seine globalen Positionen und die Vorgehensweise des Feindes vergleichen und die Vorgehensweise des Feindes Wenn wir den Helden sehen können, sollten wir auf ihn zurennen und dabei den Unterschied zwischen der globalen Exposition des Helden und der globalen Exposition des Feindes nutzen des Helden und der globalen Exposition , um die Richtung zu ermitteln und sie mit einem Zeichen zu kennzeichnen Es ist also immer nur negativ eins oder positiv eins oder Null, wenn sie direkt darüber oder darunter sind Zurück in der Ansicht können wir dem Knoten einen weiteren Bereich hinzufügen , um Zeit zu sparen. Machen wir es zu einem Kind des Hip-Box-Knotens und nennen wir dieses eine Ziel. Ich mache es gelb, um Gefahr anzuzeigen , und mache diese Form , wie Sie es für sinnvoll halten, aber wahrscheinlich ähnlich oder nur ein bisschen größer als die rote Trefferbox. Platziere es auf einer weiteren neuen Kollisionsebene, Ebene 21, der Zielebene und Maske des Feindes. Dann für die Rt-Box-Ebene des Spielers. Dies wird überwachend und nicht überwachbar sein. Wir können uns mit dem eingegebenen Gebiet verbinden und das Signal an das feindliche Skript senden Wir brauchen den Bereich zwei D nicht, also können wir ihn mit einem Unterstrich kennzeichnen Wenn dann das T-Feld des Spielers das Zielgebiet des Feindes betritt , greift der Feind an Lass es uns ausprobieren. Wenn Fierce Tooth Roger sieht, verfolgen sie ihn Und wenn sie Roger nicht sehen können, kehren sie zu ihrem normalen Patrouillenverhalten zurück Wenn sie Roger erwischen, werden sie angreifen. Unsere Feinde können den Spieler jetzt sehen und ihn aggressiv verfolgen und angreifen In der nächsten Lektion werden wir einen Feind erschaffen, der Projektile abfeuern kann Wir sehen uns in der nächsten Lektion. 48. 5-6 Projektil: Hallo Freunde. In der vorherigen Lektion haben wir unseren Feinden erlaubt, den Spielercharakter wahrzunehmen und ihn anzugreifen. In dieser Lektion werden wir mit Fernangriffen einen neuen Feind erschaffen . Ich habe bereits damit begonnen, für diese Lektion einen neuen Feind zu erschaffen , die Muschel. Bisher ist die Struktur des Knotenbaums dieselbe. Die Wurzel ist ein Charakterkörper, zwei D auf der gegnerischen Kollisionsebene, maskiert die Geländeebene mit dem Sprite Two D, dem Animation-Player und dem Animationsbaum Ein kollisionsförmiger Knoten mit einer kapselförmigen Ressource, einer passenden Rt-Box, Hüftbox, einer Zielbox und einer passenden Vision Vergewissern Sie sich, dass jeder Ebene die entsprechende Kollisionsebene zugewiesen ist, die richtigen Ebenen maskiert sind und dass sie überwachbar oder überwachbar sind Ich beginne damit, einen Knoten zwei D mit dem Namen Projektilursprung hinzuzufügen , der den genauen Ort markiert, von dem aus Projektile abgefeuert werden abgefeuert Und ein Timer-Knoten, der diesem Feind sagt, er soll schießen. Ein Projektil, das automatisch startet und alle 3 Sekunden abgefeuert wird Die Animationen wurden alle mit den entsprechenden Sprites gefüllt Im Leerlauf, getroffen, abgefeuert und zerstört. Zerstört ist nur ein Frame. Dann setzt der zweite Frame die Eigenschaft „Sichtbarkeit“ des Sprites auf „fällt“, um es zu verbergen Die Animationsbaumstatusmaschine hat die Animationen „Treffer“ und „ Zerstört“ auf der obersten Ebene, wobei der Übergang auf der Grundlage des Treffers und der Variablen des Charakterskripts innerhalb der Attack-Zustandsmaschine erfolgt innerhalb der Attack-Zustandsmaschine Die Muschel ist standardmäßig im Leerlauf und geht dann in den Feuermodus über, wenn sie am Ende der Animation wieder in den Leerlauf zurückkehren und nicht feuern möchten feuern am Ende der Animation wieder in den Leerlauf zurückkehren und nicht Lassen Sie uns einen neuen Ordner mit Charakterskripten für Feinde erstellen und Feind- und Patrouillenskripte darin ablegen So wie wir das Feind-Skript erstellt haben indem wir es vom Charakter übernommen haben, können wir dem feindlichen Skript einen Klassennamen Feind geben dann ein neues Skript mit dem Namen So Inheriting Enemy erstellen Nun, dieses Skript hat alle Verhaltensweisen und Eigenschaften eines Charakters, eines Feindes und was auch immer wir in das Shooter-Skript eingegeben um ein Projektil zu spawnen, genau wie wir es beim Spawnen von Münzen getan haben Wir können eine gepackte Szenenvariable exportieren und dann auch Variablen exportieren, exportieren und dann auch Variablen exportieren um das Verhalten der Projektile zu beschreiben, wie ihre Geschwindigkeit, die ich beschreiben möchte in Kacheln pro Sekunde. Ich setze es standardmäßig auf zehn. Außerdem der Schaden, den das Projektil anrichtet, wenn es den Spieler trifft, eine Ganzzahl zwischen 1 und 100 , die Standardeinstellung ist eins der maximalen Dauer lasse ich das Projektil existieren, bevor es sich als Float selbst zerstört Bei der maximalen Dauer lasse ich das Projektil existieren, bevor es sich als Float selbst zerstört. Die Standardeinstellung ist 10 Sekunden. Solange es fertig ist Nachdem ich alle geerbten Ready-Methoden ausgeführt habe, multipliziere ich meine in Kacheln pro Sekunde gemessene Geschwindigkeit mit Cobolpt, um sie in Pixel pro Sekunde umzuwandeln Besorgen Sie sich auch einen Verweis auf den Ausgangsknoten des Projektils. Mit at on ready können wir eine Methode zum Spawnen des Projektils schreiben , das von der Feueranimation des gegnerischen Schützen genau in dem Frame aufgerufen wird Feueranimation des gegnerischen Schützen genau in dem , in dem das Projektil erscheinen Erstellen einer temporären Variablen, die das neu instanziierte Projektil aufnehmen soll neu instanziierte Projektil aufnehmen Wir können es an seinem Ausgangspunkt positionieren und es dem Szenenbaum als Geschwister des Feindes hinzufügen Wenn sich der Feind bewegen kann, wird das Projektil nicht von der Bewegung des Elternteils beeinflusst Es wird als unabhängige Einheit der Welt existieren. Wir können dem Projektil dann sagen, dass es abfeuern soll, und ihm die Informationen geben, die es für seine Arbeit benötigt — Richtung, Geschwindigkeit, Schaden und Dauer Dieser Feind feuert Projektile nur nach links oder rechts ab, je nachdem, in welche Richtung er blickt, um die Feueranimation auszulösen Genau wie bei den Angriffsanimationen werden wir eine boolesche Variable haben, die abgefeuert werden soll . Diese wird durch eine öffentliche Methode „ Feuer“ im Animations-Player mit Meeresmuscheln auf „true“ gesetzt eine öffentliche Methode „ Feuer“ im Animations-Player mit Meeresmuscheln Während der Feueranimation, die wir einstellen können, zurückfeuern will, um das Projektil auf „false“ zu starten wird das Projektil während des Frames erzeugt, wenn es am korrektesten aussieht Dazu erstelle ich in der Muschelszene auch Projektil, bei dem es sich um einen D-Node im zweiten Bereich handelt Ich möchte nicht, dass Physik auf meine Projektile angewendet wird, und ich würde ihr Verhalten lieber mathematisch berechnen Wenn Sie möchten, dass Ihre Projektile Physik verwenden, sollten sie einen starren Körper mit zwei D als Wurzelknoten verwenden Das Projektil, das vom Feind mit der Muschel abgefeuert wird , ist eine Perle. Diese wird auf die gegnerische Trefferschicht gelegt, wodurch das Terrain und die T-Ebene des Spielers maskiert Da dies die einzigen Dinge sind die das Projektil treffen soll. Und zum Zeichnen wird ein Sprite benötigt. Und eine Kollisionsform, das ist der Kreis. Ich färbe rot. Ich positioniere das Projektil dort, wo es seinen Ursprung in der Muschel haben sollte Möglicherweise möchten Sie den Ausgangsknoten des Projektils neu positionieren , je nachdem, wie er im Verhältnis zum gegnerischen Schützen aussehen sollte Ich werde auch einen Timer-Knoten hinzufügen, in erster Linie dazu verwendet wird, die Dauer zu begrenzen , während der dieses Projektil existieren Ich werde es auf einen Schlag wahr machen, wenn die Perle auf etwas trifft, das ich zerbrechen wollte Ich werde einen Knoten zwei D mit dem Namen Trümmer hinzufügen. Ich verstecke das Muschel-Sprite in Kollisionsform für eine bessere Sicht, während ich die Perlenreste mit Trümmern als Ordner herstelle . Dann kann ich für jedes Stück zerbrochener Perle untergeordnete Knoten als starren Körper hinzufügen , zwei D-Knoten Seitdem möchte ich Physik anwenden. Die Trümmerteile werden ihre eigenen Sprites und Kollisionsformen haben ihre eigenen Sprites und Kollisionsformen Ich positioniere die obere Hälfte der Perle dort, wo sie zum ursprünglichen Perlensprite passt zum ursprünglichen Perlensprite und gebe ihr eine passende Kollisionsform Lege sie auf eine neue Ebene, Schicht vier für Trümmer und maskiere nur das Gelände, es sich nicht drehen kann und eingefroren ist, wenn der Gefriermodus auf Kinematisch eingestellt Duplizieren Sie es dann, um die Unterseite zu erstellen, indem Sie das Sprite austauschen und es so neu positionieren, dass es mit dem Boden der ungebrochenen Perle übereinstimmt Sowohl der obere als auch der untere Trümmer werden standardmäßig ausgeblendet. Wenn die Knotenstruktur abgeschlossen ist, können wir den Projektilzweig als eigene Szene in einem neuen Projektilordner speichern und ihn zur Bearbeitung öffnen Wir können jetzt die Perle aus der Muschelszene löschen und ihre Position so ändern , dass sie um den Ursprung zentriert ist Als Nächstes fügst du dem Wurzelknoten der Perle ein Skript mit dem Namen Projectile hinzu, das im Ordner Enemy Scripts gespeichert ist hinzu, das im Ordner Enemy Scripts gespeichert Während der Bereitschaftsphase suche ich nach Verweisen auf die untergeordneten Knoten Ich weiß, dass ich Zugriff auf Sprite, Trümmer und Timer haben muss Sprite, Trümmer und Timer Nachdem wir den Methodenaufruf Feuer bereits in das Shooter-Skript geschrieben haben, können wir ihm eine Definition geben Wir akzeptieren eine Richtung als Vektor, zwei Geschwindigkeiten als Float, Schaden als Ganzzahl und Dauer als Float. Wir müssen all diese Werte mit Ausnahme der Dauer in privaten lokalen Variablen speichern . Die Dauer können wir einfach verwenden, um den Timer einzustellen. Wenn die angegebene Dauer mehr als Null wäre, Wert von weniger als oder gleich würde ein Wert von weniger als oder gleich Null als unbegrenzte Dauer betrachtet. Ich benötige auch eine private lokale Variable, um zu wissen, ob dieses Projektil zerstört wurde oder nicht. Wenn dieses Projektil nicht zerstört wurde, addieren Sie bei der Prozessmethode Wenn dieses Projektil nicht zerstört wurde zu seiner Position die Richtung mal Geschwindigkeit mal Delta Dadurch bewegt sich das Projektil in einer geraden Linie mit konstanter Geschwindigkeit Welches ist das erwartete Verhalten von Projektilen in den meisten Videospielen Verbinden des in den Körper eingegebenen Bereichs eingegebene Signale mit dem Skript Der einzige Körper, mit dem dieses Projektil kollidieren sollte, ist Gelände In diesem Fall teilt es dem Projektil mit, dass es zerbrechen soll, wenn es in einen Bereich eindringt , der die Verletzungsbox des Spielers sein sollte Ich versuche zuerst, das übergeordnete Objekt des Bereichs zu finden, das sollte der Spielercharakter sein Nachdem ich überprüft habe, ob es sich um den Helden handelt, werde ich ihnen sagen, dass sie Schaden einstecken sollen, indem sie die Schadenssumme und Richtung als Argumente normalisieren und dann das Projektil zerbrechen sollen füge die Break-Methode hinzu und Ich füge die Break-Methode hinzu und verbinde sie mit dem Timeout-Signal des Timers Es wird automatisch 10 Sekunden nach dem Abfeuern des Projektils aufgerufen 10 Sekunden nach dem Abfeuern des Projektils Wenn es nichts getroffen hat, wenn das Projektil zerbricht, würde ich mir wünschen, dass im Laufe der Zeit ein paar verschiedene Dinge passieren, was mit einem Animationsplayer gemacht werden könnte, aber ich würde es lieber mit relativ einfachem Code machen Zuerst füge ich eine exportierte Variable für die Textur zwei D hinzu, die zeigt, wie das Projektil zerstört wird Und tausche die Sprake gegen die Variable D is destroyed gegen Das Projektil bewegt sich nicht mehr und seine Kollisionsmaske ist auf Null gestellt, sodass es keine weiteren Kollisionen auslöst Dann möchte ich den Timer-Knoten wiederverwenden, der gerade verwendet wird, um die Break-Methode für das Timeout-Signal auszulösen Break-Methode für das Timeout-Signal Da es sich um die Break-Methode handelt, hat das Projektil etwas getroffen und dieses Verhalten ist nicht mehr erforderlich Ich erhalte das Timeout-Signal des Timers und trenne ihn von der Break-Methode Dann starte den Timer mit einer neuen Zeit, 0,1 Sekunden, neu. Das ist die Framerate, die ich für alle meine Animationen verwendet habe 0,1 Sekunden später auf das Timeout-Signal warte, setze ich die Eigenschaft „ Sichtbar“ der Sprites auf „Falsch“ und weise die Trümmer dann an, sich zu die Trümmer dann Warten Sie dann weitere zehn Sekunden, bevor Sie der Engine mitteilen, dass dieses Projektil nicht mehr relevant ist und aus dem Szenenbaum entfernt werden kann Jetzt können wir ein neues Skript erstellen, um die Trümmer zu zerstreuen , indem wir es mit dem Trümmerknoten verbinden Ich werde es in den Umgebungsordner legen Dieses Skript benötigt nur eine Variable, ein Array von Knoten, die seine untergeordneten Elemente sind Wenn wir aufgefordert werden, zu streuen, können wir dieses Array mit einer For-Schleife durchlaufen , die dem Format folgt wie es andere Sprachen schreiben würden Für jede Schleife können wir jedes Mitglied des Pieces-Arrays als Teil bezeichnen . Dann weisen wir es an, dass es sichtbar wird, auftaut und eine Impulskraft auf Da die Trümmerteile bereits an ihren ursprünglichen Positionen relativ zum durchbrochenen Loch verteilt sind , können wir ihre Position einfach als Richtung der Impulskraft verwenden und sie dann mit einer Kachel multiplizieren Natürlich können Sie mit unterschiedlich starker Kraft experimentieren, um die Trümmer zu zerstreuen Möglicherweise wird die Richtung normalisiert, sodass ihre Entfernung vom Ursprung keine Rolle spielt Wenn die Muschel zerstört ist, können wir dasselbe tun wie mit der Perle, aus der die Trümmer entstanden Knoten zwei D, diesmal mit vier Kindern. Für jedes der vier kaputten Shell-Sprites , die die Knoten kopieren und einfügen, haben sie bereits die richtigen Einstellungen Positionieren Sie jedes Sprite exakt an der Stelle, an der es mit dem Sprite der unversehrten Shell übereinstimmt Sprite der unversehrten Shell und passen Sie auch ihre Kollisionsformen an Hängen Sie dann das Trümmerskript an den Trümmerknoten an. Schließen Sie abschließend das Timeout-Signal des Timers an, um der Muschel mitzuteilen, dass sie alle 3 Sekunden feuern soll den Wurzelknoten der Meeresmuscheln auswählen, müssen wir die komprimierte Szene mit dem Projektil füllen und das Sprite nach links und nach links richten, damit es wahr ist. Ja. Fügen Sie dann der zerstörten Animation einen Methodenaufruf-Track damit die Trümmer verstreut werden können. im selben Moment , in dem der Muschelgeist unsichtbar wird Lassen Sie uns im selben Moment , in dem der Muschelgeist unsichtbar wird, ihn ausprobieren Die Muschel schießt alle 3 Sekunden Perlen ab, die mit dem Gelände kollidieren und zerbrechen, wodurch Trümmer entstehen, die automatisch entfernt werden Nach 10 Sekunden können diese Perlen den Spieler treffen und ihm Schaden zufügen Und der Spieler kann die Muschel auch zerstören , indem er sie mit dem Schwert angreift. Wir haben jetzt einen Feind, der Projektile auf den Spieler schießen kann Projektile auf den Spieler schießen In der nächsten Lektion werden wir unserem Spiel einen Boss-Feind hinzufügen. Wir sehen uns in der nächsten Lektion. 49. 5-7 Boss: Hallo Freunde. In der vorherigen Lektion haben wir einen neuen Feindtyp hinzugefügt , der Projektile abschießen kann In dieser Lektion werden wir unserem Spiel eine Begegnung mit Bossen und Feinden hinzufügen unserem Spiel eine Begegnung mit Bossen und Feinden Ich habe ein neues Level für die Bossbegegnung erstellt ein neues Level für die Bossbegegnung handelt es sich um eine Grube, in die der Spieler, wenn er einmal eingesprungen ist, das Level nicht mehr verlassen kann Checkpoint ist direkt vor dem Boss und das Schwert ist da, also werden sie es schon getan haben Der Totempfahl besteht aus drei Shooter-Gegnern, bei denen es sich fast genau um Eimer Muscheln aus der Abgesehen davon, dass sie die gegnerische Kollisionsebene zum Stapeln maskieren zum Stapeln Das blaue Totem hat ein benutzerdefiniertes Kollisionspolygon das es dem Spieler erschwert, darauf zu stehen, aber trotzdem darüber springen kann In ihrem Projektil befindet sich eine hölzerne Spitze, bei der es sich um ein Duplikat der Perle handelt, bei der nur die Sprites Im Gegensatz zu den Perlenspriten ist der hölzerne Dorn in der Projektilschrift nicht symmetrisch Fügen wir eine neue exportierte Variable hinzu und drehen sie mit der Richtung um. dann beim Abfeuern des Projektils Wenn dann beim Abfeuern des Projektils „Mit Richtung und Richtung x drehen “ größer als Null ist, sollten wir die Skala x zwei negativ auf eins setzen, um den Sprite, die Kollisionsform und die Trümmer umzudrehen, und den Wert für die Holzspitzen dieser Variablen auf true setzen, sodass die Leider sind diese Totem-Sprites nicht zentriert. Damit die einzelnen Totems nach links oder rechts zeigen können und dabei innerhalb des Totempfahls zentriert bleiben , benötigen sie einen Dann überschreibe ich die Definitionen von Gesicht nach links und Gesicht nach rechts von Gesicht nach links und Gesicht nach rechts und setze den Offset der Sprites auf diese Zahl multipliziert mit eins, wenn es Sprites Gesicht nach links gibt, andernfalls negativ eins, und umgekehrt für Gesicht nach rechts negativ eins Ich setze dann den Wert dieser Variablen auf „Ready“ und dann auf „Super Ready Da Super Ready dem Charakter sagt, dass er nach links oder rechts schauen soll, habe ich ein Problem beim Einstellen der Position der Projektile entdeckt der Position der Projektile bevor sie zum Szenenbaum hinzugefügt Also können wir das beheben, indem wir es zuerst zum Baum hinzufügen. Außerdem möchte ich nicht, dass diesem Feind eine Rückstoßgeschwindigkeit verliehen wird, wenn er Schaden erleidet. Im Charakterskript können wir eine weitere Kampfvariable namens Stagger als Float mit einem Standardwert von fünf hinzufügen Stagger als Float mit einem Standardwert Die anderen Feinde werden immer noch das gleiche Verhalten wie zuvor haben Wenn dann ein Charakter Schaden erleidet, können wir die Rückstoßgeschwindigkeit mit dieser neuen Variablen multiplizieren Rückstoßgeschwindigkeit mit dieser neuen Variablen und ihren Wert für den Boss auf Null setzen , wodurch der Effekt aufgehoben wird Wie erzeugen wir eine Begegnung mit einem Boss? Beginnen wir damit, diesem Level einen Gebietsknotenpunkt hinzuzufügen Wenn der Spieler ihn betritt, starten wir die Bossbegegnung und stellen ihn dann so ein, dass er für die Spielerebene überwacht wird Ich gebe ihm eine rechteckige Form und lasse es die gesamte Arena füllen Ich möchte, dass die Kamera während des Bosskampfes still und mittig bleibt . Also füge ich einen neuen Knoten vom Typ A hinzu, markiere zwei D-Knoten und nenne ihn Kamera A Markierung zwei D-Knoten entspricht fast exakt einem Knoten zwei D, außer dass er im Editor ein Fadenkreuz-Gizmo zeichnet, sodass wir leicht erkennen können, wo es Editor ein Fadenkreuz-Gizmo zeichnet, sodass wir leicht erkennen können, wo Wenn wir möchten, dass die Kamera während des Bosphte an Ort und Stelle bleibt , müssen wir in der Lage sein, ihr Standardverhalten bei einer booleschen Variablen, die dem Subjekt folgt, mit dem Standardwert true in der Prozessmethode zu überschreiben ihr Standardverhalten bei einer booleschen Variablen, die dem Subjekt folgt , mit dem Standardwert true in der . Wenn die Kamera dem Motiv nicht folgt, können wir zurückkehren, um zu verhindern, dass die Kameraposition verändert wird Lassen Sie uns eine neue Pan-Variable erstellen, um dieses Schwenkverhalten mithilfe eines Tweens auszuführen Dann eine neue öffentliche Methode, pan to marker, die eine Markierung mit zwei D als Parameter und auch die Dauer des Pans mit einem Standardwert von 1 Wenn der Pan existiert und läuft, sollten wir ihn beenden. Erstellen Sie dann eine neue und weisen Sie sie an, die Position der Kamera auf die globale Position der Markierung zu schwenken . Wenn wir diese Methode aufrufen, möchten wir das standardmäßige Following-Verhalten außer Kraft setzen , indem wir is following auf False setzen . Dann können wir eine weitere Methode hinzufügen, um fortzufahren wenn die Betreff-Einstellung folgt auf true. Aber wenn wir es dabei belassen, schneidet die Kamera genau auf die Position des Motivs zu. Zunächst sollten wir überprüfen, ob die Kamera gerade schwenkt, und dieses Verhalten beenden Wenn dies der Fall ist, können wir die Berechnungen der Kameraposition aus der Prozessmethode rückgängig machen die Berechnungen der Kameraposition aus und stattdessen berechnen, wie hoch die Werte für die Entfernung nach vorne und die Bodenhöhe an der aktuellen Position der Kamera wären Senden Sie dann sowohl die geänderte Richtung als auch die Landungssignale aus, wodurch die Kamera sanft zurück zum Motiv bewegt wird Zurück in der Level-Szene können wir auch eine Leinwandebene hinzufügen Im Gegensatz zur Leinwandebene in der Spielszene, die über alle Ebenen gezeichnet wird, wird diese Leinwandebene nur in Leveln gezeichnet, bei der Boss die Gesundheitsanzeige des Spielers kopiert. Wir können sie in die Leinwand „ Boss-Begegnungen“ einfügen und sie dann neu positionieren, sodass sie sich oben in der Mitte des Displays Und ersetze das Herz durch den Schädel, sodass es versteckt ist. Standardmäßig stelle ich sicher, dass es nur während des Kampfes angezeigt wird. Wenn der Kampf vorbei ist, möchte ich, der Schatz am Ende des Levels von selbst enthüllt. Ich werde den Schatz in einem Bereich positionieren , der unmöglich zu erreichen ist und im Schatzskript unsichtbar ist. Ich werde eine einfache öffentliche Methode namens To Reveal hinzufügen, die als Vektor-Zwei-Parameter eine neue Position einnimmt. Diese Methode verschiebt den Schatz an die gewünschte Position und macht ihn sichtbar. Spielen Sie die Effektanimation rückwärts ab. Warten Sie, bis die Animation abgeschlossen ist. Spielen Sie dann die Standardanimation ab und wählen Sie den Boss-Encounter-Knoten aus. Lassen Sie uns das Boss-Encounter-Skript erstellen es im Skriptordner des Feindes speichern. Dieses Skript benötigt einen Verweis auf die Knoten Kameramarkierung und Gesundheitsanzeige die während der Bereitschaftsphase gesetzt wurden. Aber auch ein Verweis auf die Kamera selbst, die wir erreichen können, indem wir unseren Pfad vom Wurzelknoten aus starten . Ich hole mir auch einen Verweis auf das Level Treasure, indem ich zuerst auf das übergeordnete Element dieses Knotens zugreife , also das Level. Dann hol dir Knoten-Checkpoints. Alternativ können Sie dies als Variable exportieren , die das vom Text eingegebene Signal mit dem Skript verbindet eingegebene Signal mit dem Skript Dies wird ausgelöst, wenn der Spieler den Bereich der Boss-Arena betritt. Zu diesem Zeitpunkt sollten wir mit der Boss-Begegnung beginnen. Lassen Sie uns auch einen Verweis auf den Helden in einer lokalen Variablen speichern . Wenn das passiert, um die Position und das Verhalten leichter verfolgen zu können. Um die Begegnung zu starten, schwenke ich zuerst die Kamera auf die Kameramarkierung und zeige dann die Statusanzeige auf der Benutzeroberfläche an. Umgekehrt sollten wir, um die Begegnung zu beenden, die Kamera anweisen, dem Spieler weiter zu folgen und die Gesundheitsanzeige auszublenden . Die Begegnung könnte beendet werden, wenn der Spieler stirbt oder wenn der Boss besiegt wird Wenn der Boss besiegt ist, sollte die Begegnung enden, aber auch die Belohnung wird angezeigt Der Kameramarker wird als Ort der Belohnung wiederverwendet. Wir können die Methode der Endbegegnung automatisch auslösen , indem wir das vom Körper ausgehende Signal mit der Methode verbinden Da der Spieler außerhalb der Arena reagiert, muss dieses Skript wissen, wer der Endgegner ist In diesem Beispiel, das ich verwende, die Boss-Begegnung eigentlich aus drei Feinden. Ich exportiere eine Reihe von Feinden. Ich möchte nur eine Gesundheitsanzeige haben die die kombinierte Gesundheit aller drei Feinde anzeigt. Ich lasse das Boss-Encounter-Skript die zusätzliche Logik übernehmen zwei neue Variablen für die aktuelle und maximale Gesundheit erstellen. Dann kann ich in der Bereitschaftsmethode meine Reihe von Bossgegnern iterieren und ihre maximale Gesundheit addieren, um eine Gesamtsumme zu erhalten Dann stelle ich den Strom so ein, dass er dem Maximum entspricht. Ich werde hier auch eine neue Methode schreiben , die den Health Gauge aktualisiert. Starten Sie den aktuellen Zustand bei Null und iterieren Sie durch das Array Die aktuelle Gesundheit aller Bossgegner zusammenzählen. Um eine Gesamtsumme zu erhalten, können wir dann den Prozentsatz der gesamten Lebenspunkte berechnen , die noch auf einen Float geworfen werden, und ihn durch das Maximum dividieren. Dann legen Sie den Wert für die Gesundheitsanzeigen anhand dieses kombinierten Prozentsatzes Wenn die Summe der Lebenspunkte Null ist, ist der Boss besiegt Wir können das vom Zeichenskript ausgegebene Signal zur Änderung des Zustands verwenden , um diese Methode aufzurufen. Aber das Signal zur Änderung des Zustands übergibt ein Float-Argument fügt dieses als Parameter zu unserer Methode hinzu. Wir können es ignorieren, indem wir ihm einen Unterstrich voranstellen und die Signale während der Bereitschaftsmethode verbinden , wenn wir die maximale Integrität berechnen Eine übliche Mechanik in Spielen besteht darin, dass sich das Verhalten des Bosses bei einem bestimmten Prozentsatz seiner Lebenspunkte ändert bei einem bestimmten Prozentsatz Wenn der Boss noch nicht tot ist, rufen wir eine Phase-Check-Methode auf, der der Prozentsatz als Argument übergeben Da dieses Verhalten von Boss zu Boss unterschiedlich sein wird, lassen Sie den Text leer und verwenden Sie eine weitere leere Methode. Entscheide dich für den nächsten Angriff. Wir haben jetzt alle generischen Strukturen für die Begegnung mit Bossen eingerichtet. Geben wir diesem Skript einen Klassennamen, damit es vererbt werden kann , um begegnungsspezifische Verhaltensweisen bereitzustellen. Das Boss-Encounter-Skript wird vom Knoten entfernt. Wir können es stattdessen durch ein geerbtes Skript ersetzen, speziell das Verhalten des Totempfahls beschreibt In diesem Skript können wir definieren, wie es über seine nächsten Angriffe entscheidet und wie und wann es zwischen den Kampfphasen wechselt Ich werde die Dinge einfach halten, indem ich der Bossbegegnung einfach eine Timer-Notiz beifüge, auf die ich mich bei Bedarf beziehen werde. Fangen Sie an, wenn die Boss-Begegnung beginnt, und hören Sie auf, wenn die Boss-Begegnung endet. Verbinde dann das Timeout-Signal, um über den nächsten Angriff zu entscheiden. Der Totempfahl entscheidet alle 1 Sekunde, was zu tun ist. Hinzufügen eines Zufallszahlengenerators und einer Ganzzahl zum Speichern einer zufälligen Ganzzahl Ich iteriere zuerst durch jeden Boss im Array des Bosses und generiere dann eine Zufallszahl von 0 bis 2, generiere dann eine Zufallszahl die ich mit den Ergebnissen abgleichen kann Ich ignoriere Null, was bedeutet, dass der Feind nichts tun wird. Wenn es eine Eins ist, werden sie nach links schauen und schießen. Oder wenn es eine Zwei ist, schauen sie nach rechts und schießen. Um den Schwierigkeitsgrad zu erhöhen. die Gesundheit des Chefs langsamer wird, überprüfe ich, wann der Prozentsatz weniger als ein Drittel und weniger als zwei Drittel erreicht weniger als ein Drittel und weniger als zwei Drittel wenn diese Schwellenwerte überschritten werden Ich stelle die Wartezeit der Timer etwas kürzer ein, damit die Totems häufiger angreifen Aber ich werde dafür sorgen, dass die Zeit länger bleibt als die Animation, sodass ihr zwischen jedem Angriff den Vorgang beenden und in den Leerlauf zurückkehren zwischen jedem Angriff den Vorgang beenden und in den Leerlauf zurückkehren Ich werde nicht vergessen, das Feld des Bosses mit den Boss-Feinden zu füllen . Lass es uns ausprobieren. Die Boss-Begegnung wird ausgelöst , wenn der Spieler die Arena betritt. Die Kamera schwenkt und rastet ein, und die Gesundheitsanzeige des Bosses wird angezeigt, die die gesamte Gesundheit aller drei Gegner aufzeichnet Wenn der Spieler stirbt, reagiert er am Checkpoint und die Begegnung mit dem Boss wird unterbrochen bis der Spieler die Arena wieder betritt. Wenn alle Feinde tot sind, verschwindet die Gesundheitsanzeige, die Kamera folgt dem Spieler weiter und die Belohnung wird aufgedeckt und die Wir haben jetzt einen Boss-Feind, der angemessen wäre , um eine ganze Welt von Levels in unserem Spiel Im nächsten Abschnitt werden wir uns auf Menüs und Spielfortschritte konzentrieren . Wir sehen uns im nächsten Abschnitt. 50. 6-1 Pause: Hallo Freunde. Im vorherigen Abschnitt haben wir unserem Spiel den Kampf hinzugefügt. In diesem Abschnitt werden wir Menüs und Fortschritte hinzufügen . Wenn du die Aufgabe abgeschlossen hast, werden alle deine Feinde nun ein einzigartiges Verhalten haben. Erlaube ihnen, in einem Bereich deines Levels zu patrouillieren, nach dem Spieler zu suchen, ihn dann zu verfolgen und anzugreifen Du solltest auch eine Kanone haben, die eine Kanonenkugel abfeuern kann , die beim Aufprall explodiert Wenn du die Herausforderungen gemeistert hast, können deine Feinde auch Schätze fallen lassen, wenn sie besiegt werden Die Kanone kann entweder vom Spieler oder von einem Feind bedient werden , und die Muschel hat auch einen Beißangriff In dieser Lektion kann der Spieler das Spiel pausieren und ein Pausenmenü öffnen Öffnen wir zunächst die Projekteinstellungen und fügen der Eingabekarte eine Pause-Taste hinzu. Ich benutze die Escape-Taste, die Starttaste auf meinem Gamepad. Unsere gesamte Eingabeverarbeitung wird derzeit vom Spielerskript verarbeitet. Aber das Spiel zu pausieren hat nicht wirklich etwas mit der Steuerung eines Charakters zu tun Jeder Knoten in unserem Szenenbaum kann die Eingabemethode überschreiben. Das Unterbrechen des Spiels sollte in der Verantwortung des Spielmanagers Im Game Manager-Skript können wir eine Eingabemethode hinzufügen , die ein Eingabeereignis als Parameter verwendet Wenn die Pause-Taste gedrückt wurde, sollten wir das Spiel pausieren. Die Pause-Methode kann einen Bulling-Parameter annehmen, ich nenne ihn, sollte auf diese Weise pausiert werden Sie kann verwendet werden, um entweder eine Pause einzulegen, wenn das Argument wahr ist, oder die Pause aufzuheben, wenn das Pausieren ist in Godot sehr einfach, nur dass der Wert von get tree paused, oder in diesem Fall two, pausiert werden oder in diesem Fall Wenn dann die Pause-Taste gedrückt wird, können wir den Wert von get tree pause mit einem Knotenoperator übergeben , um seinen Wert als Argument können wir den Wert von get tree pause mit einem Knotenoperator übergeben, um seinen Wert als Argument zu ändern. Wenn wir jedoch den gesamten Szenenbaum pausieren, einschließlich des Game Managers, dann wird der Game Manager nicht mehr in der Lage sein, Eingaben entgegenzunehmen und das Spiel zu Eingaben entgegenzunehmen unterbrechen Auswahl des Stammknotens der Szene. Ich schaue in den Inspektor. Unter Knoten können wir den Prozessbereich erweitern und seinen Prozessmodus auf „Immer“ setzen, auch wenn das Spiel angehalten ist, läuft der Spielmanager weiterhin Alles, was du in deinem Spiel pausieren möchtest, wähle den Knoten aus und setze seine Prozessmodus-Eigenschaft auf Der Standardwert von inherit weist alle untergeordneten Knoten an, den Prozessmodus ihrer übergeordneten Knoten zu übernehmen. Wenn der Rogers-Knoten pausiert, wird auch der Player-Knoten wird auch Levelknoten pausiert werden, werden all ihre feindlichen Schätze und alles, was sich in ihnen befindet, pausiert alles, was sich in ihnen befindet Bedienelemente auf der Benutzeroberfläche, wie Schaltflächen, funktionieren auch dann, wenn das Spiel pausiert ist Wenn du jedoch Tweens verwendest, um sie ein- oder auszublenden, müssen sie so eingestellt sein, dass sie immer zwei verarbeiten müssen sie so eingestellt sein, dass sie immer zwei verarbeiten. Lass es uns ausprobieren. Wenn die Pause-Taste gedrückt wird, pausiert das Spiel. Wenn die Pause-Taste erneut gedrückt wird, wird die Pause aufgehoben. Das funktioniert, aber ich möchte dem Spieler ein Pausenmenü aber ich möchte dem Spieler und Wir können damit beginnen, das Spiel über das Menü zu duplizieren und es in Pause-Menü umzubenennen, wobei wir uns einen Verweis auf das Pausenmenü einen Verweis auf Während der Bereitschaftsphase können wir festlegen, welche Eigenschaft sichtbar ist wenn das Spiel pausiert oder beendet wird Ich werde schnell das Banner oben im Pausenmenü so bearbeiten , dass es Pause statt Spiel vorbei sagt Ändere dann die Schaltfläche „Erneut versuchen“, um fortzufahren. Ich möchte nicht mehr, dass die Resume-Taste die Methode bei wiederholtem Versuch aufruft Ich bearbeite die Signalverbindung. Wir können das sogar direkt die Pause-Methode aufrufen lassen. Die Pause-Methode benötigt jedoch einen Parameterklick auf das erweiterte Ziel, um zusätzliche Aufrufargumente hinzuzufügen. Das Argument, das wir an die Pause-Methode übergeben müssen, ist ein boolescher Wir können es der Liste hinzufügen und sein Standardwert ist falsch, was genau das ist, was wir wollen Wenn du auf die Schaltfläche „Fortfahren“ wird das Spiel nun angewiesen, die Pause zu beenden Die Schaltflächen zur Levelauswahl und zum Verlassen des Levels können genauso bleiben wie im Spiel-Over-Menü Aber ich möchte eine weitere Option hinzufügen, um dieses Level von Anfang an neu zu starten und die Schaltfläche „Fortfahren zu duplizieren. Ich ändere diese Option in Neu starten und bearbeite die Schaltflächenbeschriftung, damit sie besser auf den Bildschirm passt Mit einer zusätzlichen Schaltfläche bearbeite ich Feld für den Panel-Stil im Theme-Editor. Dieses Papierbild ist 128 Pixel groß, hat aber einen leeren Rand von etwa 12 Pixeln auf allen Seiten. Ich kann Godot anweisen, nur die Unterregion dieses Bildes zu verwenden und dabei die X- und Y-Startkoordinaten sowie die Breite und Höhe der zu verwendenden Unterregion festzulegen die Breite und Höhe der zu verwendenden Unterregion Dann muss ich die einzelnen Menüs anpassen , damit die Wörter auf dem Papier erscheinen Die Wiederholungstaste aus dem Game Over-Menü und diese Neustart-Schaltfläche verhalten sich sehr ähnlich Versuchen wir, sie zu einer Methode zu kombinieren. Die einzige wirkliche Änderung, die ich hier vornehmen möchte, besteht darin Leben und Münzen des Spielers nicht zurückzusetzen Wir können diese Methode beim erneuten Versuch so umbenennen , dass sie neu gestartet wird, und sie einen booleschen Parameter annehmen lassen, der angibt, ob das Spiel vorbei ist oder nicht , mit dem Standardwert False Übergeben Sie dies dann an die Methode zur Wiederholung von Dateidaten, die ich in Reset umbenennen werde Das Level wird entladen, neu geladen und der Spieler kehrt zum Anfang des Levels zurück Auf die gleiche Weise wie zuvor. Wenn der Spieler jedoch im Pausenmenü die Neustarttaste gedrückt hat , müssen wir auch die Pause des Spiels aufheben Das können wir tun, wenn wir das Level im Datenskript laden. Wir können die Wiederholungsmethode bearbeiten, sie umbenennen, zurücksetzen und das Spiel über den booleschen Parameter übernehmen Jetzt sollten die Leben und Münzen nur dann zurückgesetzt werden, wenn sie von einem Game Over-Status aus aufgerufen wird sollten die Leben und Münzen nur dann zurückgesetzt werden, wenn sie von einem Game Over-Status Im Pausenmenü kann die Restart-Taste mit der Neustart-Methode verbunden werden. Da der Parameter den Standardwert false hat, müssen wir hier kein Argument angeben. Aber im Game Over-Menü kann die Wiederholungstaste mit derselben Neustartmethode verbunden werden derselben Neustartmethode verbunden Diesmal wird true als Argument angegeben. Jetzt werden diese beiden Buttons dieselben Verhaltensweisen verwenden, mit dem einzigen Unterschied, dass die Leben und Münzen der Spieler zurückgesetzt werden , wenn ihnen die Leben ausgehen. Lass es uns ausprobieren Jetzt. Wenn das Spiel angehalten ist, wird das Pausenmenü angezeigt und durch Drücken von Fortfahren wird das Pausenmenü ausgeblendet, das das Spiel pausiert Mit der Neustart-Taste kehrt der Spieler zum Anfang des Levels zurück und setzt alle Levelkomponenten auf ihren ursprünglichen Zustand der Spieler zum Anfang des Levels zurück und setzt alle Levelkomponenten auf ihren ursprünglichen Zustand zurück. Die Levelauswahltaste macht noch nichts, da wir noch kein Levelauswahlmenü haben und die Exit-Taste das Spiel beendet Wir können jetzt unser Spiel pausieren und dem Spieler ein Optionsmenü geben , während das Spiel pausiert ist In der nächsten Lektion fügen wir einen Titelbildschirm hinzu, um unser Spiel zu starten Wir sehen uns in der nächsten Lektion. 51. 6-2 Titel: Hallo Freunde. In der vorherigen Lektion haben wir unserem Spiel eine Pause-Taste und ein Pausenmenü hinzugefügt. In dieser Lektion fügen wir eine Titelszene und ein Hauptmenü hinzu. Beginnen wir mit der Erstellung einer neuen Zwei-D-Szene mit dem Namen title, die im Ordner Szenen gespeichert ist. Wir können viele Komponenten aus anderen Szenen kopieren , um sie in die Titelszene einzufügen. Wie beim Hintergrund setze ich die Skalierungseigenschaft des Stammknotens der Titelszenen auf drei, was dem Zoom der Spielszenen entspricht. Kamera positioniert dann den Hintergrund neu, füllt den Bildschirm und schnappt sich die animierten Sprites der Wasseroberfläche aus meiner Levelszene Hinzufügen eines Knotens zwei D, um sie als eine Gruppe zusammenzufassen. Ich werde auch einen neuen animierten Sprite-2-D-Node hinzufügen der das Handelsschiff enthält Füllen Sie jeden mit den Sprites aus dem Asset-Paket. Wir können ihre Animationen so einstellen, gewünschten Bildrate automatisch abgespielt Ich setze das Schiff hinter das Wasser, indem ich ihre Knoten neu ordne , einen für das Segel und einen für Roger Um dann auch noch einen Sprite-Zwei-D-Knoten für den Anker hinzuzufügen Wenn wir einen Canvas-Layer-Knoten hinzufügen, können wir der Titelszene Steuernotizen hinzufügen Ich verwende ein vertikales Feld für den Titel und ein anderes für die Tasten. Das Titelfeld wird zwei horizontale Felder enthalten , eines für jedes Wort, Jolly und Roger, und jedes Feld wird mit fünf Textzeilen gefüllt Ich verwende die großen Buchstaben aus dem Asset-Paket für den Titel, der Jolly Roger buchstabiert Ich möchte, dass die Buchstaben immer ihr Seitenverhältnis beibehalten. Ich vergrößere den Titel um das Achtfache, damit er die Szene dominiert Dann duplizieren und wiederholen , bis das andere Wort entsteht. Ich verschiebe den Drehpunkt so, dass er sich in der Mitte des Titels befindet. Verwenden Sie dann benutzerdefinierte Anker, um es horizontal auf dem Bildschirm zentriert und zu einem Drittel vom oberen Bildschirmrand entfernt zu platzieren Vorerst werde ich auf meinem Titelbildschirm nur zwei Schaltflächen haben Neues Spiel und Weiter Ich möchte, dass diese Schaltflächen genauso aussehen wie die in meiner anderen Szene. Ich verwende dasselbe Theme, aber das Theme, das wir erstellt haben, ist lokal in der Spielszene. Wechseln Sie zur Spielszene wählen Sie einen beliebigen Knoten aus, auf den das Thema angewendet wurde. Wie das Game Over-Menü. das Drop-down-Menü erweitern, können wir das Theme als Ressourcendatei speichern, sodass es für das gesamte Projekt verfügbar ist. Ich speichere es im Stammordner, nenne es in der Titelszene Wood and Paper und wähle den Kontrollknoten der Schaltflächen aus. Das Holzpapierdesign ist jetzt im Schnelllademenü verfügbar , und die untergeordneten Elemente übernehmen das Design Ich vergrößere die Schaltflächen um das Vierfache und positioniere sie in der unteren linken Ecke neu Dann fülle ich jede Schaltfläche mit horizontalen Feldern voller Texturrekorde aus, um ihre Beschriftungen zu buchstabieren halte ich das Seitenverhältnis der Buchstaben in einem Abstand von der Buchstaben Abstand zwei Pixeln Und geben Sie den Schaltflächen eine Mindestgröße , die zu ihrem Inhalt passt die Größe des Etiketts zurücksetze, verankere ich es in der Mitte der Schaltfläche und dupliziere es dann, um das fortlaufende zurücksetze, verankere ich es in der Mitte der Schaltfläche und dupliziere es dann, um Etikett zu erstellen Der Anker wird zurückgesetzt. Ich mache die Knöpfe nur ein bisschen größer und positioniere sie neu Ich werde die Taste „Weiter“ standardmäßig deaktivieren , da es keinen Sinn machen würde , dem Spieler zu erlauben, sie zu drücken Falls es noch keine Datei gibt, können wir das Fade auch per Drag-and-Drop einfügen, da wir das als Zonenszene gespeichert haben. Mal sehen, wie es im Dateiskript gut aussieht. Fügen wir eine neue Methode hinzu, um zu überprüfen, ob die sichere Datei existiert. Einen Bullen zurückbringen. Im Moment kann es einfach falsch zurückgeben. Genau wie der Root-Node der Spielszenen hat er ein Game Manager-Skript. Für diese Titelszene wird auch ein Titelmanager-Skript benötigt. Dieses Skript beginnt damit, den Fade sichtbar zu machen. Ich hole mir mit On Ready einen Verweis auf die Schaltfläche Weiter. Bitten Sie dann die Datei automatisch zu laden, ob eine Datei zum Laden vorhanden ist. Wenn eine Say-Datei existiert, sollten wir die deaktivierte Eigenschaft der Continue-Taste auf False setzen , damit der Spieler sie drücken kann. Sagen Sie dann, dass der Fade zu Beginn des Spiels ausgeblendet werden soll. Sie die gedrückte Taste verbinden , werden Signale an den Titelmanager gesendet. Wir können Methoden hinzufügen, um beide Tasten zu handhaben. Wenn der Spieler die Taste „Neues Spiel“ drückt , weise ich die Datei automatisch zu laden an, eine neue Datenressource zu erstellen. Nachdem ich auf Fade, Fade to Black gewartet habe, lade ich die Spielszene, die das erste Level meines Spiels mit Get Tree Change Scene to File lädt. Dabei wird ein String-Argument verwendet, das den Dateipfad zu der Szene angibt, die wir laden möchten das Dateisystem erkunden, können wir die Spielszene mit der rechten Maustaste finden und ihren Pfad kopieren Fügen Sie es dann in die Anführungszeichen ein. Wenn sie die Schaltfläche Weiter drücken, werde ich die Datei zum Laden auffordern. Um die Datenressource zu laden. Ich möchte dann wie bei der neuen Spieltaste zu Schwarz übergehen und die Szenen wechseln , aber stattdessen die Levelauswahl-Szene laden. Lassen Sie uns das Ändern von Szenen zu einer separaten Methode machen. Ändern Sie die Szene, indem Sie einen Zeichenkettenparameter des Szenendateipfads verwenden. Dann können Sie durch Drücken der Taste „Neues Spiel“ und „Weiter “ die Option „Szene wechseln“ aufrufen, aber zu anderen Szenen wechseln. Inzwischen haben Sie wahrscheinlich versehentlich mindestens einmal die Schaltfläche „Projekt ausführen“ anstelle der Schaltfläche „Aktuelle Szene ausführen“ gedrückt versehentlich mindestens einmal die Schaltfläche „Projekt ausführen“ anstelle der Schaltfläche „Aktuelle Szene und wurden aufgefordert, eine Standardszene für Ihr Projekt festzulegen . Wenn Sie noch keine Hauptszene festgelegt haben, können Sie auf Aktuell auswählen klicken, um diese Titelszene als Hauptszene festzulegen. Alternativ können Sie die Projekteinstellungen öffnen und im Anwendungsbereich nachschauen und die Hauptszene hier mit dem Dateibrowser festlegen. Wenn wir unter Renderumgebung nachsehen, können wir die Standardfarbe ändern, die angezeigt wird, wenn Cade nichts anderes zu rendern hat. Sie können sie auf Schwarz setzen, um alle Lücken zwischen Ausblenden und Einblenden Wenn wir jetzt auf die Schaltfläche „Projekt ausführen“ klicken, wird die Titelszene von Schwarz eingeblendet Da keine Datei existiert, bleibt die Schaltfläche „Weiter“ deaktiviert, aber wir können auf die Schaltfläche „Neues Spiel“ klicken Dies wird schwarz und das erste Level wird geladen, sodass der Spieler mit dem Spielen eines neuen Spiels beginnen Unser Spiel hat jetzt eine Titelszene, die auf die Standardszene für unser Projekt In der nächsten Lektion werden wir die Levelauswahl-Szene hinzufügen . Wir sehen uns in der nächsten Lektion. 52. 6-3 Level-Auswahl: Hallo Freunde. In der vorherigen Lektion haben wir unserem Spiel einen Titelbildschirm und ein Hauptmenü hinzugefügt. In dieser Lektion fügen wir eine Szene zur Levelauswahl hinzu. Ich habe eine einfache Szene erstellt, ähnlich der Titelszene, nur mit animierten Sprites von Roger und dem Schiffshelm im Hintergrund , einer Leinwandebene und der Überblendung Wie bei der Theme-Ressource können wir jede Ebene öffnen, den Kachel-Map-Knoten auswählen und das Kachelset als Ressource speichern, und das Kachelset als Ressource speichern sodass es vom gesamten Projekt gemeinsam genutzt werden kann In der Level-Select-Szene füge ich einen Kachel-Map-Knoten und lade ihn mit der Kachelset-Ressource. Zeichne dann mithilfe der Kachelkarte das Achterdeck eines Schiffes mit Roger am Ruder. Das bedeutet für den Spieler , dass Roger zwischen den einzelnen Levels sein Schiff zwischen den Inseln hin- und hersegelt Mal sehen, wie das bisher aussieht. Schön, die Levels anzuzeigen. Ich füge der Leinwand einen Panel-Container hinzu. Skalieren Sie ihn so, dass er zu allem anderen passt, und legen Sie als Thema Holz und Papier fest. Dieser Container wird ein vertikales Feld enthalten, das ein horizontales Feld für den Titel enthalten wird. Ich füge vier Textur-Ts in das horizontale Feld ein, um die Wortkarten zu buchstabieren. Dabei achte ich darauf, dass sie ihr Seitenverhältnis beibehalten und zentriert bleiben. Außerdem werde ich den Titel als Ganzes zentrieren und den Abstand zwischen den Buchstaben verringern. Unter dem Titel füge ich einen Rastercontainer hinzu. Dies funktioniert ähnlich wie ein vertikales oder horizontales Feld, organisiert seinen Inhalt jedoch in einem einfachen Raster Da die Karten jeweils aus einem Viertel bestehen, mache ich sie zu einem Raster von zwei mal zwei und setze die Spalten auf zwei Jede Rasterzelle wird ein weiteres vertikales Feld enthalten ein weiteres vertikales Feld enthalten , das eine Schaltfläche und ein Bedienfeld enthält. Das Design wurde so eingestellt, dass es wie Papier aussieht. Ich setze die Mindestgröße auf 36 mal 32 Pixel, sodass sie groß genug ist, um den Namen der Ebene aufzunehmen. verwende ein weiteres horizontales Feld, um einen Bindestrich zu schreiben, Ich verwende ein weiteres horizontales Feld, um einen Bindestrich zu schreiben, und stelle sicher, dass das Etikett Mitte des Papiers verankert ist Fühlen Sie sich frei, Ihren Levels einen beliebigen Namen für die Schaltflächen zu geben. Ich möchte den grünen Knopf nicht benutzen. Ich kann es entfernen, indem ich auf den flachen Schalter klicke. Anstatt diese grünen und gelben Schaltflächen zu verwenden, ich die Eigenschaft des Schaltflächensymbols so ein, dass es sich um eine kleine Map, eine Textur Ich werde dafür sorgen, dass die Schaltfläche in der Mitte ihrer Rasterzelle bleibt. Unter „Thema“ wird die Erweiterung des Bereichs „Stil“ außer Kraft gesetzt. Ich werde den Fokusstil auch so einstellen, dass er ein leeres Stilfeld ist, sodass die Schaltfläche unsichtbar bleibt Ich werde die Ebene 113 Mal duplizieren , um die anderen Schaltflächen im Raster zu erstellen. Dabei ändere ich die Namensbeschriftungen der einzelnen Schaltflächen, sodass sie den Ebenen entsprechen. Du kannst diese Oberfläche so gestalten, wie du willst, und sie berücksichtigt, wie viele Welten die Level haben sollen, die du in deinem Spiel haben möchtest Dies reicht jedoch aus, um Drehpunkt der Panel-Container so einzustellen, dass er sich in der Mitte befindet Ich werde es so verankern, dass es zwei Drittel von der linken Seite des Bildschirms und eins, zwei von oben entfernt ist. Und ändere die Schaltflächensymbole , dass sie zu den verschiedenen Kartensegmenten passen. Um diese Schaltflächensymbole animieren zu lassen, können wir eine neue animierte Textur aus dem Drop-down-Menü auswählen Da die kleine Kartenanimation acht Bilder enthält, füge ich dieser animierten Textur acht Frames hinzu stelle dann jedes Bild entsprechend Die Standardwerte weisen diese Animation an, ein Bild pro Sekunde abzuspielen. Wir können entweder die einzelnen Framelängen auf 0,1 Sekunden ändern oder die Gesamtgeschwindigkeitsskala der gesamten Textur auf zehn setzen . Die Schaltfläche wird nicht gerendert, daher ändere ich eine Eigenschaft , um eine Aktualisierung zu erzwingen. Ich wiederhole diesen Vorgang und stelle jedes der vier Kartensegmente als animierte Texturen für die jeweiligen Schaltflächensymbole ein. Ich entferne den überschüssigen Platz am unteren Rand des Panel-Containers, indem ich seine Größe zurücksetze und dem Titel mehr Platz mit einer benutzerdefinierten Mindestgröße gebe dem Titel mehr Platz mit einer benutzerdefinierten Mindestgröße Ein neues Skript für den Levelauswahl-Manager erstellen. Ich werde mir zuerst einen Verweis auf das Fade holen, indem ich at on verwende. Bereit. Wenn ich bereit bin, stelle ich die Überblendung so ein, dass sie sichtbar ist, weise sie dann an, bis sie gelöscht wird. Ich werde eine benutzerdefinierte Methode schreiben, um die Schaltflächen mit On level selected zu verbinden . Dabei werden die Welt und die Ebene als Parameter verwendet, beide durch Ganzzahlen dargestellt Verbinde das Signal, das die Taste gedrückt hat, von der ersten Taste mit dem Levelauswahl-Manager und wähle diese neue Methode wir dann die Option Erweitert erweitern, können wir der Signalverbindung zwei Integer-Argumente hinzufügen der Signalverbindung zwei Integer-Argumente die Welt und die Ebene, beide mit dem Wert Eins. Die Werte von file dot data, dot world und level werden auf ihre neuen Werte gesetzt . Wir können dann warten, zu Schwarz übergehen und die Spielszene laden. Die Spielszene übernimmt automatisch das Laden des richtigen Levels auf der Grundlage der Dateidaten. Denken Sie daran, dass ein Level, damit es mit dieser Methode geladen werden kann, sich im Level-Szenen-Ordner befinden und im richtigen Format benannt sein muss , damit es erkannt wird. Wir können dann die restlichen Schaltflächen mit derselben Methode verbinden und die Werte der Argumente so ändern, dass sie der Welt und der Ebene entsprechen, die geladen werden, der Welt und der Ebene entsprechen, die geladen werden, sodass das Schicksal über alles andere gezogen wird. Indem ich es am Ende der Knotenliste positioniere, verringere ich den Abstand zwischen den vertikalen Feldern, damit sie weniger Platz beanspruchen. Setze dann die Größe und Position des Menüs zum letzten Mal zurück. Probieren wir es aus, indem wir die aktuelle Szene ausführen. die Szene eingeblendet ist, durch Klicken auf die erste Ebene eine Taste wieder ausgeblendet und die erste Ebene geladen Wenn wir es noch einmal machen, wird durch Klicken auf eine andere Schaltfläche eine andere Ebene geladen Unser Spiel hat jetzt eine Levelauswahl-Szene, die es dem Spieler ermöglicht, jedes Level in unserem Spiel zu laden. In der nächsten Lektion ermöglichen wir dem Spiel, Spielerdaten zu speichern und zu laden. Wir sehen uns in der nächsten Lektion. 53. 6-4 Sparen: Hallo Freunde. In der vorherigen Lektion haben wir eine Levelauswahl-Szene hinzugefügt , mit der jedes Level in unserem Spiel geladen werden kann. In dieser Lektion werden die Fortschrittsdaten der Spieler im Dateiskript gespeichert und geladen. Wir haben bereits viele der Methoden eingerichtet, Wir haben bereits viele der Methoden eingerichtet die wir für diese Lektion ausführen müssen. In anderen Engines und beim Speichern von Konsolen ist das Laden schwer zu erlernen. Aber für die Zwecke unseres Spiels bietet die Godot Engine einfache Möglichkeiten, bietet die Godot Engine genau das zu erreichen, was wir brauchen Zunächst müssen wir wissen, wo die Datei gespeichert werden soll. Lassen Sie uns eine Variable mit dem Namen path vom Typ string deklarieren. den Pfad mit dem Benutzerdoppelpunkt Godot beginnen wird automatisch der entsprechende Ort zum Speichern unserer, sagen wir, Datei gefunden entsprechende Ort zum Speichern unserer, sagen wir, Datei Auf den meisten Plattformen können wir der Datei einen Namen geben. Nennen wir es Auto Save. Die Erweiterung für unsere Textressource ist RS. Da dies ein Wert ist, der niemals geändert werden sollte, deklariere ich die Konstante anstelle einer Variablen. Dies ist eine effizientere Methode zum Speichern von Werten, von denen Sie wissen, dass sie sich nicht ändern werden. Im Gegensatz zu Variablen, die so konzipiert sind, dass sie sich ändern, besteht der Hauptzweck darin, denselben Wert an mehreren Stellen in Ihrem Skript wiederzuverwenden an mehreren Stellen in Ihrem Skript ohne ihn jedes Mal neu schreiben Das T steht für Text, was bedeutet, dass die erstellte Datei in jedem Texteditor geöffnet, gelesen und sogar bearbeitet werden kann in jedem Texteditor geöffnet, gelesen und sogar bearbeitet , der nicht sehr sicher Verschlüsselung ist jedoch sehr ineffektiv und im Allgemeinen den zusätzlichen Aufwand nicht wert , egal wie viele Maßnahmen Sie ergreifen. Wenn jemand betrügen will, wird er es tun. Ich würde nur empfehlen, sich bei Online-Multiplayer-Spielen um die Sicherheit zu kümmern Um zu überprüfen, ob diese Datei existiert, müssen wir lediglich die Methode exists des Resource Loaders aufrufen und das Argument der Pfadzeichenfolge übergeben Um das Spiel zu speichern, müssen wir nur die Speichermethode des Ressourcensparers aufrufen und die zu speichernden Daten und den Pfad zum Speicherort übergeben zu speichernden Daten und den Pfad zum Speicherort Jedes Mal, wenn wir save aufrufen , werden die vorhandenen Speicherdaten überschrieben Ebenso muss beim Laden nur der Wert der Daten auf Resource Loader Load gesetzt werden, wodurch der gleiche Pfad zur Datei zugewiesen wird Dies ist eine einfache Implementierung des automatischen Speicherns einer einzelnen Datei Sie könnten die Befehle zum Speichern und Laden einfach mit Menüschaltflächen verknüpfen Befehle zum Speichern und Laden einfach mit Menüschaltflächen Und mit demselben Verfahren können Sie sogar mehrere Say-Dateien erstellen . Der Titelmanager ist bereits so eingerichtet, dass er die Spielerdaten lädt , wenn die Continue-Taste gedrückt wird. Die Frage ist, wann sollten wir es speichern? Wir können damit beginnen, die Daten gleichzeitig mit ihrer Erstellung zu speichern . Denken Sie daran, dass dieses Autosave-System beispielsweise nur eine Datei speichert ein neues Spiel starten , werden alle vorhandenen sicheren Dateien überschrieben alle vorhandenen sicheren Wenn also die Schaltfläche „Neues Spiel“ gedrückt wird keine sichere Datei vorhanden ist, können wir eine neue Methode aufrufen, um ein neues Spiel zu starten, die neue Speicherdatei zu erstellen, sie zu speichern und zur Spielszene überzugehen Wenn eine Say-Datei existiert, sollten wir den Spieler um Zustimmung bitten bevor wir seine bestehende Say-Datei überschreiben. Ich werde schnell einen einfachen Container mit den Fragen Überschreiben, Datei speichern und zwei Buttons für Ja und Nein zusammenstellen mit den Fragen Überschreiben, Datei speichern und zwei Buttons für Ja und Nein Und legt standardmäßig die sichtbaren Eigenschaftsstandards einen Verweis auf die Bestätigung mit dem Add-On mit Ich mache es sichtbar, wenn der Spieler die neue Spieltaste drückt, aber eine sichere Datei ist bereits vorhanden Verbinde dann die Tasten „Ja“ und „Nein“ mit dem Skript. Alles, was N tun muss, ist diese Bestätigung zu verstecken und ja, wir starten ein neues Spiel. Aufgrund des Formats meines Spiels ist es mir egal, was einem bestimmten Level passiert. Um den Fortschritt der Spieler in meinem Spiel verfolgen zu können, muss ich nur wissen, wann sie ein Level abgeschlossen oder verlassen haben. Einfachheit halber kann ich das Spiel jedes Mal automatisch speichern, wenn der Spieler die Levelauswahl-Szene betritt. Im Game Manager-Skript haben wir einige Schaltflächen im Pausenmenü , die immer noch nicht funktionieren. Fügen wir die Übergänge vom Pausenmenü des Spiels zur Levelauswahlszene hinzu. Wenn sie auf Exit drücken, kehren sie zur Titelszene zurück. Auf diese Methoden kann über das Pausenmenü zugegriffen werden. Der Szenenbaum wird angehalten, wenn diese Übergänge stattfinden Wenn eine neue Szene geladen wird, bleibt der Baum Wir müssen die Pause des Szenenbaums aufheben, wenn die anderen Szenen mit den Ready-Methoden des jeweiligen Managers geladen werden mit den Ready-Methoden des jeweiligen Da das Pausenmenü jetzt nur noch zur Titelszene zurückkehrt, sollte die Titelszene eine Exit-Taste haben , um das Spiel zu schließen Ich lege das in die obere rechte Ecke. Verbinden Sie das gedrückte Signal mit dem Manager-Skript und lassen es warten, bis es schwarz wird, bevor Sie Get aufrufen . Kopieren Sie den Exit-Button-Node Wir können es in die Levelauswahl-Szene einfügen und das Signal bearbeiten, um es mit dem Levelauswahl-Manager-Skript zu verbinden . Und lassen Sie es warten, bis es schwarz bevor es zur Titelszene wechselt. Lass es uns ausprobieren. Nachdem ich eine Münze gesammelt habe, kann ich das Level verlassen kehre zur Levelauswahl-Szene zurück, in der der Fortschritt automatisch gespeichert wurde Schließe das Spiel und führe es erneut aus. Die Schaltfläche „Weiter“ ist aktiviert , da die Speicherdatei bereits geladen werden kann. Weiter klicken, gelangen wir zur Levelauswahl-Szene, in der ein beliebiges Level geladen wird. Wir können sehen, dass der Münzzähler zwischen den Sessions gespeichert und geladen wurde, wodurch das Spiel geschlossen und erneut ausgeführt wurde. Wir können versuchen, die Speicherdatei zu überschreiben und eine Bestätigung erhalten, bevor wir ein neues Spiel mit Null Münzen starten ein neues Spiel mit Null Münzen Unser Spiel speichert und lädt jetzt Spielerdaten jedes Mal, wenn der Spieler ein Level verlässt oder abschließt In der nächsten Lektion sperren wir den Zugang zu Levels und schalten sie frei, wenn der Spieler ein Level abgeschlossen hat Wir sehen uns in der nächsten Lektion. 54. 6-5 Unlock: Hallo Freunde. In der vorherigen Lektion haben wir den Fortschritt des Spielers gespeichert und geladen. In dieser Lektion werden Zugriff auf Level sperren, bis der Spieler das vorherige Level abgeschlossen hat, um es in unserer Datenressource Wir werden Informationen zu jedem Level in unserem Spiel verfolgen wollen , die in Welten organisiert sind. Wir können eine Variable mit dem Namen Progress als ein Array von Welten deklarieren , das eine Reihe von Ebenen enthält, ein zweidimensionales Array, ein Rasiermesser leer Standardmäßig müssen wir sie so initialisieren, dass sie die richtige Größe für unsere Bedürfnisse und sie mit Startwerten auffüllen Wir benötigen ein Array für jede Welt und einen Wert für jedes Level in jeder Wenn ich zwei Welten hätte, würde das Array so aussehen, aber ich habe nur eine. Ich werde das zweite Subarray entfernen. Wir wollen, dass das erste Level des Spiels freigeschaltet wird. Standardmäßig ändere ich den Wert 0-1, je nachdem, wie viele verschiedene Fortschrittsmarkierungen du pro Level verfolgen möchtest Es kann problematisch sein, sich ihre numerischen Codes zu merken. Wir können eine Aufzählung definieren, um die verschiedenen Fortschrittsmarker zu beschreiben, angefangen damit, dass das Level gesperrt, dann freigeschaltet und dann abgeschlossen Initialisieren Sie dann die erste Ebene, um den Fortschritt zu entsperren. Hinzufügen einer öffentlichen Methode zum Setzen einer Fortschrittsmarkierung. Wir können die Fortschrittsmarkierung zusammen mit einer Welt-ID und einer Level-ID als Parameter verwenden. Stellen Sie dann den Wert des Fortschritts auf Welt minus eins, Stufe minus eins indexiert Da Arrays bei Null beginnen, unsere Welt- und Ebenenzahlen jedoch bei Eins beginnen , verwenden Sie den Gleichheitsoperator R mit der Fortschrittsmarkierung, wodurch diesen Werten ein Wir gehen davon aus, dass die meisten Fortschrittsmarkierungen für das Level gesetzt werden , das der Spieler gerade spielt erlaubt uns aber trotzdem, Marker für andere Level zu setzen , wenn wir wollen. Da diese Zahlen zur Indexierung von Arrays verwendet werden, sollten wir sie validieren, um Abstürze zu vermeiden. Damit diese Zahlen als gültige Array-Indizes betrachtet werden können, sollten sie größer als Null und kleiner als der Größe des Arrays sein. Da wir eins von diesen Zahlen subtrahieren. Wenn die Array-Indizes nicht gültig sind, sollten wir zurückkehren. Wir können aber auch eine Meldung ausgeben, um uns oder einen anderen Entwickler über diesen Fehler zu informieren, mit einer Warnung, dass der Fortschrittsmarker-Index ungültig war und die Welt der verwendeten Level-IDs anzeigen. Dies ist eine Bitoperation, was bedeutet, dass diese Zahl nicht wie eine Ganzzahl behandelt wird , sondern als eine Reihe von Bits, Einsen und Nullen Wenn wir jedes Bit als eine Fortschrittsmarkierung betrachten, dann sperrt die erste Fortschrittsmarkierung, das erste Bit, die Ebene, wenn sie Null ist, und entsperrt die Ebene, wenn sie eins ist Das nächste Bit sagt uns, ob das Level abgeschlossen wurde. Es beginnt bei Null, was bedeutet, dass es noch nicht abgeschlossen ist, wechselt dann aber zu eins, um abgeschlossen zu werden Beginnt das Level mit einem Wert von 0000, wird das Entsperren zu 0001. Wenn das Level dann als abgeschlossen markiert wird, erhält es 0011 Da es sowohl entsperrt als auch abgeschlossen ist, können wir einzelne Bits mithilfe von Bitoperatoren ändern, sodass wir eine große Menge an Informationen in einer einzigen Variablen kodieren eine große Menge an Informationen in einer einzigen Variablen Dieser Operator oder setzt den Wert des durch die Fortschrittsmarkierung markierten Bits auf eins Wir können das Bit auch auf Null setzen, indem Fortschrittsmarkierung invertieren und das wenn der Operator der Methodendefinition einen zusätzlichen Parameter hinzufügt der Methodendefinition einen zusätzlichen Parameter hinzufügt Wir können die Fortschrittsmarkierung ein- oder ausschalten. Ich werde standardmäßig das Bit auf eins oder ein setzen, da ich nicht vorhabe , jemals etwas zu sperren , das vom Spieler in meinem Spiel freigeschaltet wurde. Da eine einzelne Variable 32 Bit enthält, können wir bis zu 32 verschiedene Informationsbits pro Ebene verfolgen . Auf diese Weise werden Fortschrittsmarkierungen zur Aufzählung hinzugefügt. Eine Aufzählung ist nur eine nummerierte Liste. Der Eintrag oben in der Liste hat den Standardwert Null Der nächste, dann 234 usw. Wir können diese numerischen Zuweisungen ändern, wenn wir wollen, indem wir einen Wert von Null gesperrt, eins entsperrt und zwei abgeschlossen haben Ich möchte aber auch nachverfolgen, ob der Spieler in meinen Levels eine Schatztruhe öffnet. Der nächste Fortschrittsmarker wird statt drei vier sein. Wir könnten bis zu 32 verschiedene Werte in dieser Aufzählung haben verschiedene Werte in dieser Aufzählung jedes Mal den Wert auf acht, 16 usw. verdoppeln. Wenn einer im Binärformat 0012 ist, ist 0104, ist 100 Jede Fortschrittsmarkierung besteht ausschließlich aus Nullen, wobei nur ein Bit den Wert Eins hat. Dabei handelt es sich um das Bit, das mit der Methode set progress marker gesetzt oder aufgehoben wird aufgehoben Wir sollten entfernen, dass gesperrt gleich Null ist, da der richtige Weg, ein Level zu sperren Fortschrittsmarkierung für entsperrt auf Aus zu setzen Außerdem müssen wir die Werte unserer Fortschrittsmarkierungen überprüfen und die Fortschrittsmarkierung sowie die Welt- und Level-ID-Nummern akzeptieren Welt- und Level-ID-Nummern Wie bei der Set-Methode, aber mit der Rückgabe eines booleschen Werts, können wir den von der Welt indizierten Fortschrittswert in Level-ID-Zahlen minus eins zurückgeben Welt indizierten Fortschrittswert in Level-ID-Zahlen Wenden Sie dann den Bit-End-Operator mit der Fortschrittsmarkierung an. Wir sollten auch überprüfen, ob die Array-Indizes gültig sind, bevor wir sie verwenden, genau wie oben, und die Warnmeldung klarstellen, damit sie hilfreicher ist. Dies gibt true zurück, wenn die Fortschrittsmarkierung aktiviert ist, oder falsch, wenn sie ausgeschaltet ist, oder wenn die Indizes in der Levelauswahl-Szene nicht gültig waren . Wir können leicht kontrollieren , auf welches Level der Spieler Zugriff hat , indem wir die Sichtbarkeit der Level-Tasten ein- und ausschalten die Sichtbarkeit der Level-Tasten Der Grid-Container sortiert die sichtbaren Inhalte automatisch sortiert die sichtbaren Inhalte Im Level Select Manager-Skript können wir mithilfe von add on ready ein Array der untergeordneten Elemente des Grid-Containers abrufen mithilfe von add on ready ein Array der untergeordneten Elemente des Grid-Containers eine neue Integer-Variable als Index für das Array der Level-Schaltflächen deklarieren als Index für das Array der Level-Schaltflächen Dann iterieren wir durch die Welten im Fortschrittsarray. Nochmals, durch die Levels in jeder Welt. Wir können die Eigenschaft „Sichtbar“ jeder Schaltfläche im Rastercontainer so einstellen, ob die jeweilige Ebene freigeschaltet wurde oder nicht. Wir müssen der Welt und dem Level eine hinzufügen, um die richtigen ID-Nummern aus ihren Array-Indizes zu erhalten und den Button-Index jedes Mal zu erhöhen Im Level-Skript können wir Variablen exportieren, um zu erfahren, welches Level freigeschaltet wird , wenn wir dieses Level abschließen und ihre Standardwerte auf eins setzen Das Standardverhalten wird darin bestehen, das erste Level zu entsperren und damit im Grunde nichts zu erreichen, aber keine Fehler zu verursachen die Karte dann im Game Manager-Skript Wenn die Karte dann im Game Manager-Skript gesammelt ist, können wir die Fortschrittsmarkierung des aktuellen Levels als abgeschlossen festlegen des aktuellen Levels als abgeschlossen Und setze auch die freigeschaltete Fortschrittsmarkierung des Levels, das durch das Abschließen dieses Levels freigeschaltet werden soll . Gehen Sie dann zur Level-Auswahlszene im ersten Level über. Ich stelle die exportierten Werte so ein , dass die zweite Ebene freigeschaltet wird. Zurück im Level-Skript können wir nachverfolgen, ob der Spieler die Truhe geöffnet hat, erhalten einen Verweis auf den Schlüssel und die Truhe, falls sie existieren. Mit at on ready get node oder null. Wenn das Level dann zum ersten Mal geladen wird wenn sie existieren und der Spieler die Truhe für dieses Level geöffnet hat, können wir den Schlüssel entfernen und der Truhe mitteilen, dass sie bereits im Truhen-Skript geöffnet wurde . Fügen wir eine öffentliche Methode hinzu, die bereits geöffnet ist, wodurch das Beute-Array Dann wird die Einstellung auf Falsch gesetzt und bei Plünderung der Truhe auf True geöffnet . Setze die Fortschrittsmarkierung für das Level, Setze die Fortschrittsmarkierung für das dass die Truhe Lass es uns ausprobieren. Wenn ich ein neues Spiel starte, kann ich das erste Level verlassen und zur Levelauswahl-Szene wechseln, und nur das erste Level ist freigeschaltet. zum ersten Level zurückkehre, kann ich es beenden und werde zur Levelauswahl-Szene zurückgebracht, in der das zweite Level freigeschaltet wurde. Ich kehre wieder zum ersten Level zurück. Diesmal öffne ich die Truhe und kehre zur Levelauswahl-Szene zurück. ein letztes Mal in die erste Ebene, um zu sehen, dass der Schlüssel nicht da ist und die Truhe bereits geöffnet ist. Fortschritt der Spieler im Spiel wird jetzt beispielsweise anhand der Datei verfolgt, wodurch der Zugriff auf neue Level freigeschaltet wird, während sie gehen In der nächsten Lektion werden wir unserem Spiel Hintergrundmusik hinzufügen Wir sehen uns in der nächsten Lektion. 55. 6-6 Musik: Hallo Freunde. In der vorherigen Lektion haben wir den Zugang zu den Levels gesperrt, bis der Spieler das vorherige Level abgeschlossen hat. In dieser Lektion fügen wir Hintergrundmusik hinzu. Beginnen wir mit der Titelszene und fügen Szene einen Audio-Stream-Player-Knoten hinzu. Wir könnten hier eine Audiospur einstellen, ihr sagen, dass sie automatisch abgespielt werden soll, und die Lautstärke einstellen Dann mach das für jede Szene im Level. Aber die Szenenübergänge würden unsere Musiktitel hart schneiden und dadurch ziemlich erschütternd klingen, ähnlich wie bei uns, wenn der Bildschirm schwarz wird. Übergehende Musik sollte auch ausgeblendet werden, um ein besseres Gesamterlebnis zu bieten Ich lasse die automatische Wiedergabe vorerst eingeschaltet und die Lautstärke auf die niedrigste Stufe stellen. Im Grunde genommen stummgeschaltet Die meisten Spieleentwickler , die nicht gleichzeitig Soundingenieure sind, neigen dazu , sich Lautstärke als Float vorzustellen, 0-1, wobei Null stummgeschaltet und Eins volle Tatsächlich wird die Lautstärke jedoch in Dezibel gemessen, was nicht Eine Verdoppelung der Dezibel führt nicht zu einer Verdoppelung der Lautstärke. Die Lautstärkeskala reicht hier von negativen 80 bis Zum Glück müssen wir nicht wissen, wie das funktioniert, um es effektiv nutzen zu können Lassen Sie uns ein neues Skript an diesen Musikknoten anhängen. Wenn das Spiel zum ersten Mal gestartet wird, wird der Titel automatisch abgespielt, wobei die Lautstärke stummgeschaltet Wir können damit beginnen, die Lautstärke vorsichtig von Null auf den gewünschten Pegel zu verringern und eine Variable zum Speichern der gewünschten Lautstärke zu deklarieren Einfacher ausgedrückt, die leichter zu verstehen sind, ein Float 0-1 mit linearer Skalierung Lautstärkeeigenschaft des Audio-Stream-Player-Knotens heißt Volume DB Wir können also eine weitere neue Variable, Volume L, für linear deklarieren , um die aktuelle Lautstärke auf einer linearen Skala darzustellen , und ihr den Standardwert Null oder stummgeschaltet geben Standardwert Null Bei der Ready-Methode können wir sicherstellen, dass die Lautstärke stummgeschaltet bleibt indem wir die Dezibel-Lautstärke so einstellen, dass sie der linearen Lautstärke entspricht Es wird mit einer praktischen Umrechnungsformel von Gade linear in Dezibel umgerechnet, wobei die lineare Lautstärke als Argument angegeben wird Definition einer privaten Methode zum Ausblenden der Lautstärke. Wir können das lineare Zielvolumen als Parameter verwenden. Zusammen mit der Dauer des Schicksalseffekts mit dem Standardwert von 1 Sekunde. Das lineare Volumen entspricht zwar nicht dem linearen Zielvolumen, wir sollten das lineare Volumen um einen kleinen Betrag in Richtung des linearen Zielvolumens bewegen . Dazu können wir die Deltazeit des Prozesses ermitteln und diese durch die Dauer dividieren. Stellen Sie dann die Lautstärke in Dezibel so ein, dass sie der linearen Lautstärke entsprechen , und warten Sie, bis der nächste Prozessrahmen dies erneut ausführt Wenn das alles erledigt ist, können wir das Signal aussenden, damit jeder , der darauf hört, weiß, dass das Lautstärke-Schicksal beendet ist dass das Lautstärke-Schicksal So wie dieser Code geschrieben ist, ist es offensichtlich, dass der Wert der Dauer eine positive Zahl sein soll. Um mögliche Fehler oder Endlosschleifen zu vermeiden, sollten wir prüfen, ob der Wert von duration kleiner oder gleich Null ist. In diesem Fall können wir die Lautstärke einstellen, das Signal sofort weglassen und zurückkehren Da Musik wahrscheinlich in jeder Szene des Spiels enthalten sein wird , wäre es einfacher, daraus ein automatisches Ladeskript zu machen Das Skript in den Ordner für automatisches Laden verschieben. Öffnen der Registerkarte „Automatisches Laden“ der Projekteinstellungen. Wir können dies zur Liste der automatisch geladenen Knoten hinzufügen. Löschen Sie dann den Audio-Stream-Player-Knoten aus unserer Titelszene. Damit jeder Szenenmanager die Hintergrundmusik mit einer einzigen Codezeile steuern kann , müssen wir lediglich zwei öffentliche Methoden definieren, eine zum Starten eines Tracks und eine zum Stoppen. Beginnend mit dem Stop-Track nehmen wir eine Überblendzeit als Parameter, einen Float, mit einem Standardwert von 1 Sekunde. Das kann einfach Fade aufrufen. Die lineare Ziellautstärke ist Null, stummgeschaltet. Das Überschreiten der Überblendzeit ist das Argument für die Dauer Warten Sie dann das Signal Volume Fade finished ab, bevor Sie den Audiostream beenden Player-Node zum Abspielen eines Titels . Wir können den betreffenden Titel zusammen mit der Überblendzeit als Parameter verwenden. Stellen Sie den Stream, der gerade abgespielt wird, auf diesen neuen Titel ein, weisen Sie ihn an, dass er abgespielt werden soll, und reduzieren Sie dann die Lautstärke für die Dauer der Fadezeit auf die gewünschte Lautstärke . Was aber, wenn ein Titel bereits abgespielt wird? Wir können ein paar zusätzliche Schecks hinzufügen. Überprüfen Sie zunächst, ob bereits Musik abgespielt wird, überprüfen Sie dann auch, ob der Titel, der gerade abgespielt wird, mit dem Titel übereinstimmt, den wir abspielen möchten. Wenn dies der Fall ist, müssen wir überhaupt nichts tun und können zurückkehren. Wir können diese Gelegenheit auch nutzen , um Null-Tracks zu ignorieren. Andernfalls spielt der Musik-Node gerade einen anderen Titel ab. Wir sollten diesen Titel ausblenden, bevor wir den neuen einblenden Fade mit einer linearen Ziellautstärke von Null aufrufen und warten, bis das Signal „Volume Fade Finished“ angezeigt wird, kann der Rest der Methode das gleiche Fading in der neuen Spur durchführen, wodurch harte Einschnitte in den einzelnen Scene Manager-Skripten vermieden in den einzelnen Scene Manager-Skripten Wir können eine Variable exportieren, die den Hintergrundmusiktitel für diese Dann können wir in der Bereitschaftsmethode vor dem Ausblenden bis zum Löschen die Musik anweisen, den Musiktitel abzuspielen Ich fülle diese Variable mit einem Musiktitel aus ausgewählten Szene auf der Ebene meiner importierten Assets Ich exportiere auch eine Variable für die Hintergrundmusik und spiele den Titel während der Schreibmethode ab Ich verwende dieselbe Hintergrundmusik wie in der Titelszene für die Levelauswahl-Szene im Game Manager-Skript. Wenn ich ein Level lade, fordere ich den Musiktitel des Levels an. Auf diese Weise kann jedes Level seine eigene Hintergrundmusik im Level-Skript festlegen , eine Musikvariable exportieren und einen anderen Titel als die anderen Szenen einstellen. Und ich werde auch Musiktitel zu meinen anderen Levels hinzufügen. Schließlich füge ich dem Boss-Encounter-Skript auch Musik hinzu, deklariere aber auch eine zweite Variable den Titel zu speichern , der von dem Level aus abgespielt wurde, als die Bossbegegnung beginnt. Ich kann die normale Hintergrundmusik des Levels in der zweiten Variablen speichern und dann den Boss abspielen. Musik Wenn die Begegnung mit dem Boss beendet ist, spiele ich wieder das normale Level Bossbegegnung wurde von Musik die intensiver war als das normale Level Musik Beim Beenden des Spiels können wir auch die Hintergrundmusik ausblenden Wenn du Hintergrundmusik importierst, ist es wichtig, dass sie so konzipiert ist, dass sie sich wiederholt, je nachdem, wo du deine Musik herbekommst Looping ist möglicherweise in den Dateien selbst kodiert und kann für diese Dateien bereits als Loop ausgeführt werden Ich muss die Importeinstellungen öffnen und ihren Loop-Modus auf Forward einstellen Klicken Sie dann auf Erneut importieren, damit sie wiederholt werden. Lass es uns ausprobieren. Der Titelbildschirm wird mit Musik zum Thema Piraten eingeblendet. Drücken Sie und fahren Sie fort Die Musik wird während des Szenenübergangs weiter abgespielt da der Musiktitel für beide Szenen derselbe ist Beim Betreten des Boss-Levels wird die Musik ausgeblendet und wieder eingeblendet ein neuer Titel die Boss-Arena betritt Die Standard-Hintergrundmusik des Levels wird durch einen intensiveren Musiktitel ersetzt Wenn der Boss besiegt ist, kehrt die Musik zur Normalität zurück. Wenn Sie zur Levelauswahl-Szene zurückkehren, wird die Musik erneut geändert und beim Beenden des Spiels die Musik ausgeblendet, bevor das Fenster geschlossen wird Unser Spiel spielt jetzt Hintergrundmusik jede Szene und jedes Level einzigartig ist, für jede Szene und jedes Level einzigartig ist, sodass Titel sogar vorübergehend geändert werden In der nächsten Lektion werden wir das Spiel exportieren, um es zu spielen und zu testen. Wir sehen uns in der nächsten Lektion. 56. 6-7 Export: Hallo Freunde. In der vorherigen Lektion haben wir unserem Spiel Hintergrundmusik hinzugefügt. In dieser Lektion exportieren wir das Spiel, um es zu vertreiben und zu testen. Bevor wir Godot exportieren können, müssen wir Exportvorlagen aus dem Editor-Menü herunterladen Exportvorlagen aus dem Editor-Menü Wählen Sie Exportvorlagen verwalten. Wählen Sie einen Mirror aus der Drop-down-Liste klicken Sie dann auf Herunterladen und installieren. Mit diesen Vorlagen kann Ihr Godot-Projekt zur Verteilung in eine Vielzahl von Formaten exportiert Sobald der Vorgang abgeschlossen ist, können Sie den Exportvorlagenmanager schließen In den Projekteinstellungen haben wir unserem Projekt bereits einen Namen gegeben. Möglicherweise möchten Sie auch eine Beschreibung, eine Versionsnummer und ein Symbol hinzufügen , um optimale Ergebnisse zu erzielen. Versuchen Sie, ein Bild zu verwenden, das 256 mal 256 Pixel groß ist oder zumindest quadratische Abmessungen hat. Wir haben bereits festgelegt, dass die erste Szene läuft. Wenn du für ein Studio oder einen Verlag arbeitest, kannst du hier auch ein Bild hinzufügen. Möglicherweise möchten Sie die Anzeigeeinstellungen anpassen, um sie besser an das exportierte Projekt anzupassen, z. B. die Standardeinstellung Vollbild statt Fenster Wenn du irgendwelche Anzeigeeinstellungen änderst, teste das Spiel, um sicherzustellen, dass dein verkauftes Spiel korrekt angezeigt wird, bevor du dein verkauftes Spiel korrekt angezeigt wird Um das Spielsymbol beim Export für Windows zu ändern , musst du eine ausführbare RC-Edit-Datei von Github herunterladen . Ich empfehle, diese Datei im Ordner Gio Projects abzulegen, da Sie sie wahrscheinlich in den meisten, wenn nicht sogar in allen Ihrer Projekte verwenden müssen . Öffnen Sie im Editor-Menü die Editor-Einstellungen unter Windows exportieren Es gibt eine Option zum Hinzufügen des Pfads zur ausführbaren RC-Edit-Einstellung, sodass Cado nun Symbole für exportierte Windows-Projekte bearbeiten kann , sofern Sie über ein Paketsignaturzertifikat verfügen. Dies ist auch der Ort, an dem diese Informationen bereitstellen alle Einstellungen konfiguriert sind, können wir jetzt zum Projektmenü gehen und auf Exportieren klicken Klicken Sie auf die Schaltfläche Anzeigen und wählen Sie die Plattform aus , auf die Sie Ihr Projekt exportieren möchten. Zweitens wähle ich Web First. Wir müssen nicht viel tun, um die Einstellungen hier anzupassen. Erkundung des Exportpfads. Wir sollten einen neuen Ordner mit dem Namen Export oder Builds erstellen , wenn Sie das bevorzugen. Sie dann in diesem Ordner Erstellen Sie dann in diesem Ordner einen neuen Ordner für jede Plattform. In diesem Fall Web. Das Wichtigste beim Exportieren ins Web ist, dass das Projekt den Namen Index-HTML haben muss. Dies ist der Dateiname , nach dem Webplattformen beim Einbetten Ihres Spiels suchen Wenn es nicht da ist, wird es nicht funktionieren. Wenn Sie auf Projekt exportieren klicken, deaktivieren Sie das Kontrollkästchen Export mit Debug, um beispielsweise Warnmeldungen zu entfernen Klicken Sie dann auf Speichern. Wenn es fertig ist, können wir das Fenster schließen. Sobald das Projekt exportiert wurde, finden Sie es in Ihrem Dateibrowser. Wählen Sie alle Dateien aus, die von Godot erstellt wurden, und komprimieren Sie sie in eine Zip-Datei mit dem Namen index zip Dies ist die Datei, die du hochladen wirst, um dein Spiel in Webhosting-Plattformen wie Itch einzubetten. In den Einbettungsoptionen dieser Plattformen ist möglicherweise die Unterstützung von Shared Array Buffer erforderlich, Unterstützung von Shared Array Buffer damit das Spiel ausgeführt werden kann Dies ist eine der einfachsten Möglichkeiten, frühe Versionen Ihrer Spiele zu verteilen Auf solchen Plattformen können Sie auch Ihre Spiele verkaufen. Aber was ist, wenn dein Spiel wirklich gut ist und du es professionell auf Plattformen wie Steam verkaufen möchtest? Zurück im Projektexportfenster können wir eine weitere Plattform hinzufügen, diesmal Windows. Hier möchtest du vielleicht einige Einstellungen anpassen, z. B. festlegen, wie die Größe des Spielsymbols in einem Pixel-Art-Spiel geändert wird. Bei der Skalierung mit Nächsten Nachbarn wird die Pixelisierung beibehalten Möglicherweise möchten Sie auch den Namen Ihres Unternehmens hinzufügen, wenn Sie einen Namen und eine Beschreibung haben Urheberrecht, Marken usw. Wir werden das in einen vom Web-Export getrennten Ordner exportieren, einen neuen Ordner für Windows erstellen und die ausführbare Datei so umbenennen, dass sie dem Namen des Spiels entspricht Wenn Sie dies intern für Alpha-Tests verteilen, möchten Sie vielleicht einen Debug-Build für Betatests, Early-Access- oder Release-Builds exportieren Early-Access- oder Release-Builds Sie sollten das Debuggen auch in den Debug-Einstellungen deaktivieren und den Konsolen-Wrapper entfernen Exportieren Sie dann das Projekt und speichern Sie es. Sobald der Exportvorgang abgeschlossen ist, können Sie die von Godot und Ihrem Datei-Explorer erstellten exportierten Dateien finden , die Dateien auswählen, eine Zip-Datei komprimieren und die komprimierte Zip-Datei zum Herunterladen auf Vertriebsplattformen hochladen zum Herunterladen auf Vertriebsplattformen Derselbe Prozess kann auch für die Entwicklung auf Mac-, Linux-, IOS- und Android-Plattformen verwendet Linux-, IOS- und Android-Plattformen Exportvorlagen für andere Plattformen wie Nintendo oder Playstation werden standardmäßig nicht bereitgestellt. Sie müssen von der Plattform genehmigt werden, bevor Sie ihr SDK zum Erstellen von Spielen verwenden können. Unser Spiel wird jetzt exportiert und auf Vertriebsseiten wie It oder Steam hochgeladen Vertriebsseiten wie It , damit es von jedem gespielt werden kann. Sie verfügen jetzt über alle erforderlichen Fähigkeiten, um eine komplette Pixel-Plattform und ein vollständiges Spiel zu erstellen. Sie können mehr Level erstellen, Dinge nach Ihren Wünschen optimieren und anpassen und mehr Ressourcen aus diesem Asset-Paket implementieren Sie können auch andere Asset-Pakete herunterladen oder Ihre eigenen Assets erstellen, um ständig neue Inhalte hinzuzufügen Alles in diesem Projekt ist so strukturiert , dass es isoliert bearbeitet werden kann. Sie können ihre einzelnen Szenen und Drehbücher ändern , wenn Sie möchten. Jede Implementierung ist nur eine grundlegende Vorlage , auf der Sie aufbauen oder Ihre eigene Vorlage von Grund auf neu erstellen und in das Spiel integrieren Alles zu ändern, vom Verhalten der Kamera bis hin zur Verwaltung der Speicherdateien, sollte einfach zu ändern sein Dank der Struktur, die wir aufgebaut haben, weitermachen und dein Spiel so gestalten es dir zu eigen machen möchtest Dann teile es mit der Klasse, indem du entweder das Projekt hochlädst oder einen Link zu deiner Ch-Seite teilst Schau dir die eingereichten Projekte deiner Kollegen an und hinterlasse konstruktives Feedback zu ihrer Arbeit Vielen Dank, dass Sie den Kurs abgeschlossen haben. Schauen Sie sich auch meine anderen Kurse an, um weiter zu lernen.