VorwortIch wollte vor kurzem CocosCreator lernen, also habe ich den Editor heruntergeladen und gestartet. Wie wir alle wissen, lernt man am schnellsten, indem man schreibt. Sie müssen eine Demo schreiben, um zu üben. Was sollten Sie also schreiben? Ich habe gehört, dass „Ink Shrimp Exploring Tadpoles“ derzeit sehr beliebt ist. Lasst es uns also (In „Ink Shrimp Exploring Tadpole“ ist die Position der Fische festgelegt. Wenn eine bestimmte Anzahl von Fischen erreicht ist, wird der Spieler ein Upgrade durchführen und es wird keinen großen Fischschwarm geben. Dieses Projekt unterscheidet sich tatsächlich davon. Es gibt kein Upgrade oder keine Evolution, aber es wird einen großen Fischschwarm geben. Jeder Fisch hat keine feste Position, sondern hat seine eigene Bewegungslogik. Eigentlich ist es eher wie ein anderes Spiel, aber ich weiß nicht, wie es heißt …) Effektanzeige: TextErstellen Sie zunächst einen Player: Die verwendeten Bildressourcen sind Bilder aus der offiziellen Demo von CocosCreator. Ich habe aus der offiziellen Demo gelernt. Ich war zu faul, Bilder von Fischen zu suchen, also habe ich die Bilder einfach direkt verwendet. Dieses Projekt verwendet derzeit nur zwei Bilder. Sobald Sie einen Spieler haben, müssen Sie ein Skript zur Spielersteuerung schreiben. Klicken Sie in eine Richtung und der Spieler bewegt sich weiter in diese Richtung. Dann müssen wir zunächst die Position ermitteln, auf die der Spieler klickt, und dann die Richtung berechnen, in die sich der Spieler bewegt. Dies schreiben wir in den GameManager, erstellen also ein neues Skript GameManager und hängen dieses Skript an den Canvas. Definieren Sie zunächst zwei Variablen, den Spielerknoten und den Richtungsvektor: @Eigenschaft(cc.Node) Spieler: cc.Node = null; ir: cc.Vec2 = cc.Vec2.ZERO; So erhalten Sie die Wegbeschreibung: getClickDir(Ereignis) { let pos: cc.Vec2 = event.getLocation(); //In lokale Koordinaten konvertieren let localPos = this.node.convertToNodeSpaceAR(pos); lass playerPos: cc.Vec2 = neuer cc.Vec2( diese.Spielerposition.x, diese.Spielerposition.y ); let len = localPos.sub(playerPos).mag(); this.dir.x = localPos.sub(playerPos).x / Länge; this.dir.y = localPos.sub(playerPos).y / länge; } Diese Methode wird bei onMouseDown und onMouseMove aufgerufen: beiMausDrücken(Ereignis) { wenn (event.getButton() == cc.Event.EventMouse.BUTTON_LEFT) { this.getClickDir(Ereignis); } } beiMausbewegung(Ereignis) { wenn (event.getButton() == cc.Event.EventMouse.BUTTON_LEFT) { this.getClickDir(Ereignis); } } beim Laden() { cc.director.getCollisionManager().enabled = true; cc.director.getPhysicsManager().enabled = true; dies.node.on(cc.Node.EventType.MOUSE_DOWN, dies.onMouseDown, dies); dies.node.on(cc.Node.EventType.MOUSE_MOVE, dies.onMouseMove, dies); } beimZerstören() { dies.node.off(cc.Node.EventType.MOUSE_DOWN, dies.onMouseDown, dies); dies.node.off(cc.Node.EventType.MOUSE_MOVE, dies.onMouseMove, dies); } Mit dem Richtungsvektor können Sie den Player bewegen. Erstellen Sie ein neues FishPlayer-Skript. Um das Herumrennen des Spielers zu verhindern, bauen wir zuerst die Mauer: Einen physikalischen Kollisionskörper zur Wand hinzufügen: Dann können Sie mit dem Schreiben des FishPlayer-Skripts beginnen. Definieren Sie zunächst die Variablen, die Sie verwenden möchten: @Eigenschaft(cc.Node) Kamera: cc.Node = null; @Eigenschaft(cc.Node) SpielManager: cc.Node = null; Spiel: GameManager; Geschwindigkeit: Zahl = 170; Geschwindigkeit: cc.Vec3 = cc.Vec3.ZERO; Weisen Sie dem Spiel in onLoad() einen Wert zu: beim Laden() { dieses.spiel = dieses.gameManager.getComponent("GameManager"); } Die Methode zum Erkennen der Grenze durch Strahlen, um zu bestimmen, ob sich der Spieler bewegen kann: kannBewegen() { Var-Flag: Boolean = true; //Vor uns ist ein Hindernis var pos = this.node.convertToWorldSpaceAR(cc.Vec3.ZERO); var endPos = pos.add(this.node.up.mul(40)); var Treffer: cc.PhysicsRayCastResult[] = cc.director .getPhysicsManager() .rayCast( neuer cc.Vec2(pos.x, pos.y), neuer cc.Vec2(endPos.x, endPos.y), cc.RayCastType.Alle ); if (Trefferlänge > 0) { Flagge = falsch; } Flagge zurückgeben; } Steuern Sie die Spielerbewegung im Update: update(dt) { wenn (this.game.dir.mag() < 0.5) { diese.Geschwindigkeit = cc.Vec3.ZERO; zurückkehren; } lass vx: Zahl = dieses.Spiel.Dir.x * diese.Geschwindigkeit; lass vy: Zahl = dieses.Spiel.Dir.y * diese.Geschwindigkeit; diese.Geschwindigkeit = neuer cc.Vec3(vx, vy); //Verschiebenwenn (this.canMove()) { dieser.Knoten.x += vx * dt; dieser.Knoten.y += vy * dt; } //Kamera folgt this.camera.setPosition(this.node.position); //In Bewegungsrichtung drehen let hudu = Math.atan2(this.game.dir.y, this.game.dir.x); sei Winkel = hudu * (180 / Math.PI); Winkel = 360 - Winkel + 90; dieser.Knoten.Winkel = -Winkel; } Nachdem die Bewegungslogik des Spielers geschrieben ist, schreiben wir nun den Fischschwarm. Erstellen Sie ein neues FishGroupManager-Skript und ein FishGroup-Skript, hängen Sie FishGroupManager an Canvas und hängen Sie FishGroup an den Player. Zur Verwaltung aller Gruppen wird im FishGroupManager eine statische FishGroups-Variable definiert (da es in der Szene mehrere Spieler und mehrere Fischschwärme geben kann und es derzeit nur einen Spieler gibt, was für zukünftige Erweiterungen praktisch ist): statische Fischgruppen: FishGroup[]; //alle Gruppen Hier ist eine statische Methode zum Hinzufügen einer Gruppe zu Gruppen: statische AddGroup(Gruppe: FishGroup) { wenn (this.fishGroups == null) this.fishGroups = neues Array(); wenn (this.fishGroups.indexOf(Gruppe) == -1) this.fishGroups.push(Gruppe); } Hier ist eine weitere statische Methode zum Abrufen der Gruppe (Abruf nach Index): statisch GetFishGroup(index: zahl) { für (var i = 0; i < this.fishGroups.length; i++) wenn (this.fishGroups[i].groupID == index) returniere this.fishGroups[i]; } FishGroupManager ist nun geschrieben. Schreiben Sie als Nächstes FishGroup, um die oben verwendete groupID und das Fish-Group-Array zu definieren: groupID: Zahl = 0; //Gruppen-ID fishArr: cc.Component[] = neues Array<cc.Component>(); Fügt sich selbst in onLoad zu fishGroups hinzu: beim Laden() { FishGroupManager.AddGroup(diese); } Jetzt haben wir einen Fischschwarm, aber es sind keine Fische darin, also brauchen wir eine Möglichkeit, Fische zu fangen: fangFisch(Fisch) { dies.fishArr.push(Fisch); } Definieren Sie einige weitere zu verwendende Parameter, und FishGroup ist fertig: keepMinDistance: Zahl = 80; keepMaxDistance: Zahl = 100; keepWeight: Zahl = 1; //Mitglieder halten Abstand und Gewicht für Abstand halten moveWeight: Zahl = 0,8; //und Mitgliedsbewegungsgewicht Jetzt kommt der Clou – die Bewegungslogik anderer Kleinfische im Schwarm. Kopieren Sie einfach den Player, entfernen Sie die gemounteten FishPlayer- und FishGroup-Skripte und nennen Sie ihn „Fish“. Das ist unser kleiner Fisch. Machen Sie ihn zu einem Prefab. Erstellen Sie dann ein neues FishBehaviour-Skript, das an den Spieler und den gewöhnlichen Fisch angehängt wird. Implementieren Sie zunächst die Funktion „Fischfang“. Wenn sich der Spieler einem kleinen Fisch nähert, wird der kleine Fisch gefangen und wird Mitglied des Fischschwarms des Spielers. Definieren Sie die relevanten Variablen: @Eigenschaft(cc.Node) SpielManager: cc.Node = null; Spiel: GameManager; isPicked: boolean = false; pickRadius: Zahl = 50; //Greifdistanz groupId: Zahl = -1; //Gruppen-ID meineGruppe: FishGroup; Auf ähnliche Weise weisen Sie game in onLoad() einen Wert zu: beim Laden() { dieses.spiel = dieses.gameManager.getComponent(GameManager); } Methode zur Ermittlung der Distanz zum Spieler: getPlayerDistance() { let dist = this.node.position.sub(this.game.player.position).mag(); Rückwegverteiler; } So schließen Sie sich einem Fischschwarm an: beiAusgewählt() { //Gruppe festlegen diese.groupId = dieses.spiel.spieler.getComponent(FishGroup).groupID; dies.meineGruppe = FishGroupManager.GetFishGroup(diese.groupId); wenn (diese.meineGruppe != null) { dies.meineGruppe.catchFish(dies); dies.isPicked = wahr; } } Update zum Anruf: update(dt) { wenn (dies.istAusgewählt) { //Bewege dich mit dem Fischschwarm} anders { wenn (diese.getPlayerDistance() < diese.pickRadius) { dies.onPicked(); } } } OK, jetzt ist der kleine Fisch im Fischschwarm. Wie kann er sich mit dem Fischschwarm bewegen? Hier gibt es zwei Hauptpunkte: 1. Der Fisch bewegt sich mit den umliegenden „Nachbarfischen“ 2. Halten Sie Abstand zwischen kleinen Fischen und vermeiden Sie es, sie zu bedrängen Wir müssen also den Durchschnittswert des Fischbewegungsvektors innerhalb eines bestimmten Bereichs um den kleinen Fisch herum berechnen. Das reicht nicht aus. Wir müssen auch feststellen, ob es „dicht“ ist. Wenn es „dicht“ ist, fügen wir eine Tendenz hinzu, sich zu entfernen. Wenn es zu weit ist, fügen wir eine Tendenz hinzu, sich zu nähern. Dann multiplizieren wir sie jeweils mit den Gewichten und addieren sie, um den gewünschten Vektor zu erhalten. Der Code lautet wie folgt: Variablen definieren: Bewegungsgeschwindigkeit: Zahl = 170; rotateSpeed: Zahl = 40; //Bewegungsrotationsgeschwindigkeit neighborRadius: Zahl = 500; //Eine Entfernung von weniger als 500 wird als Nachbargeschwindigkeit betrachtet: Zahl = 0; aktuelleGeschwindigkeit: Zahl = 0; meineBewegung: cc.Vec3 = cc.Vec3.ZERO; Finden Sie den Mittelwertvektor: GetGroupMovement() { var v1: cc.Vec3 = cc.Vec3.ZERO; var v2: cc.Vec3 = cc.Vec3.ZERO; für (var i = 0; i < this.myGroup.fishArr.length; i++) { var otherFish: FishBehaviour = this.myGroup.fishArr[i].getComponent( FischVerhalten ); var dis = this.node.position.sub(otherFish.node.position); //Entfernung//Kein Nachbar if (dis.mag() > this.neighborRadius) { weitermachen; } var v: cc.Vec3 = cc.Vec3.ZERO; //Größer als die maximale Distanz, schließen if (dis.mag() > this.myGroup.keepMaxDistance) { v = dis.normalize().mul(1 - dis.mag() / this.myGroup.keepMaxDistance); } //Kleiner als die Mindestdistanz, weit weg else if (dis.mag() < this.myGroup.keepMinDistance) { v = dis.normalize().mul(1 - dis.mag() / this.myGroup.keepMinDistance); } anders { weitermachen; } v1 = v1.add(v); //Entfernung zu umliegenden Einheiten v2 = v2.add(otherFish.myMovement); //Bewegungsrichtung umliegender Einheiten} //Gewichtsfaktor hinzufügen v1 = v1.normalize().mul(this.myGroup.keepWeight); v2 = v2.normalize().mul(this.myGroup.moveWeight); var ret = v1.add(v2); Rückkehr ret; } Jetzt können wir das Update abschließen: update(dt) { //Bewege dich mit dem Fischschwarm if (this.isPicked) { var Richtung = cc.Vec3.ZERO; wenn (this.node.name != "Spieler") { Richtung = Richtung.Hinzufügen(this.GetGroupMovement()); } diese.Geschwindigkeit = cc.misc.lerp(diese.Geschwindigkeit, diese.Bewegungsgeschwindigkeit, 2 * dt); this.Drive(direction, this.speed, dt); //Bewegen} //Erfassen sonst { wenn (diese.getPlayerDistance() < diese.pickRadius) { dies.onPicked(); } } } Drive()-Methode: Antrieb(Richtung: cc.Vec3, spd: Zahl, dt) { var finialDirection: cc.Vec3 = Richtung.normalisieren(); var finialSpeed: Zahl = Geschwindigkeit; var finialRotate: Zahl = 0; var rotateDir: Zahl = cc.Vec3.dot(finialDirection, this.node.right); var forwardDir: Zahl = cc.Vec3.dot(finialDirection, this.node.up); wenn (Vorwärtsrichtung < 0) { rotateDir = Math.sign(rotateDir); } //Anti-Shake wenn (forwardDir < 0,98) { finialRotate = cc.misc.clampf( Drehrichtung * 180, -this.rotateSpeed, diese.rotateSpeed ); } finialSpeed *= cc.misc.clamp01(direction.mag()); finialSpeed *= cc.misc.clamp01(1 - Math.abs(rotateDir) * 0,8); wenn (Math.abs(finialSpeed) < 0.01) { finialSpeed = 0; } //Verschiebenwenn (this.canMove()) { this.node.x += this.node.up.x*finialSpeed*dt; this.node.y += this.node.up.y*finialSpeed*dt; } //Rotation var angle1 = finialRotate * 8 * dt; var Winkel2 = dieser.Knoten.Winkel - Winkel1; this.node.angle = Winkel2 % 360; this.currentSpeed = endgültigeGeschwindigkeit; dies.meineBewegung = direction.mul(finialSpeed); } kannBewegen() { Var-Flag: Boolean = true; //Vor uns ist ein Hindernis var pos = this.node.convertToWorldSpaceAR(cc.Vec3.ZERO); var endPos = pos.add(this.node.up.mul(40)); var Treffer: cc.PhysicsRayCastResult[] = cc.director .getPhysicsManager() .rayCast( neuer cc.Vec2(pos.x, pos.y), neuer cc.Vec2(endPos.x, endPos.y), cc.RayCastType.Alle ); if (Trefferlänge > 0) { Flagge = falsch; } Flagge zurückgeben; } Oben finden Sie eine ausführliche Erklärung des Fischschwarmalgorithmus des CocosCreator-Spiels. Weitere Informationen zum CocosCreator-Fischschwarmalgorithmus finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Linux verwendet join -a1, um zwei Dateien zusammenzuführen
>>: Meine persönliche Zusammenfassung der Installationsschritte für die MySQL 5.7-Datenbank
So ändern Sie das MySQL-Tabellenpartitionierungsp...
In den vorherigen Kapiteln haben wir gelernt, wie...
In diesem Artikelbeispiel wird der spezifische Co...
Hinweis: Sie müssen dem übergeordneten Container ...
Dieser Artikel verwendet Javascript + CSS, um den...
Zum Einfügen von Videos in HTML werden am häufigst...
In diesem Artikelbeispiel wird der spezifische JS...
Ich bin während der Entwicklung auf ein solches P...
Syntax: <marquee> …</marquee> Mithilfe...
Inhaltsverzeichnis 1. Schnittstellendefinition 2....
1. Was ist mycat Ein vollständig Open Source-Groß...
Überblick: Oracle Scott-Benutzer haben vier Tabel...
In diesem Artikel finden Sie das Installations-Tu...
In diesem Artikelbeispiel wird der spezifische Co...
Tutorial-Reihe MySQL-Reihe: Grundlegende Konzepte...