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.