Schneller Tipp Trigonometrie für Flash-Spieleentwickler

In Bereitstellen eines Tanks in einer isometrischen Kriegszone haben Sie gelernt, wie ein Objekt gedreht wird, um auf den Zeiger zu zeigen und sich beim Klicken auf eine Position zu bewegen. In diesem Quick Tip werfen wir einen allgemeinen Blick auf die dahinterliegende Mathematik: Trigonometrie.


Endergebnisvorschau

Dies ist das Endergebnis meines vorherigen Tutorials. Es verwendet die Trigonometrie-Prinzipien, die wir in diesem Quick Tip behandeln werden:

Bewegen Sie die Maus, um den Turm darauf zu richten, und klicken Sie irgendwo, um den Panzer dazu zu bringen, dorthin zu fahren.

Jeder Programmierer, insbesondere jeder Spielprogrammierer, sieht sich früher oder später gezwungen, Objekte auf dem Bildschirm zu verschieben. Dies ist eine einfache Aufgabe, wenn Sie ein Objekt in eine Richtung bewegen müssen, beispielsweise entlang der X- oder Y-Achse. Angenommen, Sie möchten, dass ein Objekt Ihrem Mauszeiger folgt, wohin Sie ihn bewegen, oder Sie erstellen ein Rennspiel, in dem Sie die Beschleunigung eines Autos durch Drücken der Pfeiltaste nach oben steuern und mit den linken und rechten Pfeilen steuern.

Angenommen, Sie drücken die rechte Pfeiltaste einmal und fügt der Rotationseigenschaft Ihres Autos 10 Grad hinzu. Sie möchten jedoch trotzdem, dass sich das Auto vorwärtsbewegt (dh beschleunigt), wenn Sie eine Aufwärtspfeiltaste drücken, auch wenn ein Auto zum Boden hin gedreht wird der Bildschirm oder eine linke oder rechte Seite usw. und Sie möchten nicht, dass er so aussieht, als würde er seitwärts gleiten. Also, wie würdest du das machen? Da hilft eine kleine Trigonometrie!

Für diejenigen, die Mathe beherrschen, ist das kein Problem, aber es gibt viele Leute, die es überhaupt nicht verstehen oder sogar Angst davor haben. Ich werde versuchen, es in diesem Quick Tip so klar wie möglich aufzuschlüsseln.

Schritt 1: Das Flash-Koordinatensystem

Erinnern wir uns anfangs an das kartesische Koordinatensystem. Ton kompliziert? Wenn ja, schauen Sie sich das Bild unten an und ich bin mir sicher, dass es Ihnen bekannt ist:

Es hat X- und Y-Achsen. Sie können deutlich sehen, wo X und Y positiv und negativ sind. Bei den Koordinaten in Flash ist die Situation etwas anders. Flash hat auch ein Koordinatensystem, aber es sieht aus wie das kartesische System auf dem Kopf stehend:

Es hat auch X- und Y-Achsen und den Ursprungspunkt, der einzige Unterschied besteht darin, dass die Y-Achse positiv ist unten die X-Achse.

Jedes in Flash erstellte Symbol verfügt über ein eigenes Koordinatensystem. Wenn Sie ein neues Symbol erstellen, sei es ein Movieclip oder eine Schaltfläche, wird im Dialogfeld zur Symbolerstellung möglicherweise die Eigenschaft "Registrierungspunkt" angezeigt. Was ist es? Der Registrierungspunkt ist der Ursprungspunkt eines Symbols. Der Punkt, um den sich das Objekt dreht, wenn Sie seine Rotationseigenschaft ändern.

Hinweis: Der Ursprungspunkt der Bühneninstanz befindet sich in der linken oberen Ecke. Dies bedeutet, dass alle Punkte auf der Bühne positive X- und Y-Koordinaten haben.

In diesem Schnelltipp werden die drei am häufigsten verwendeten trigonometrischen Funktionen in Flash beschrieben. Sinus, Cosinus und Atan2. Einige Leute fragen sich vielleicht, wie wir diese Funktionen in Flash nutzen können. Nun, schauen wir uns einige praktische Beispiele an und verstehen, warum wir sie brauchen und wie sie unser Leben ein bisschen leichter machen können.

Schritt 2: Winkel berechnen

Lassen Sie uns den Winkel zwischen zwei Punkten berechnen. Erstellen Sie eine neue Flash-Datei (ActionScript 3.0). Wählen Sie den ersten Frame der Zeitleiste aus und drücken Sie F9, um ein Aktionsfenster zu öffnen.

An dieser Stelle wollen wir etwas einfaches machen. Geben Sie dies einfach in das Aktionsfeld ein:

 stage.addEventListener (MouseEvent.CLICK, berechneAngle) Funktion berechneAngle (e: MouseEvent): void trace ("stage X" + e.stageX); trace ("stage Y" + e.stageY)

Dadurch erhalten Sie bei jedem Klick auf die Bühne die Position des Mauszeigers. Nicht gerade faszinierend ist es?

Angenommen, Sie möchten einem Objekt die Koordinaten des Mauszeigers relativ zu diesem Objekt "mitteilen" und ihm dann die Richtung zeigen, in die er fahren soll, um die Position des Zeigers zu erreichen.

Schließen Sie den Aktionsbereich und wechseln Sie zu Einfügen> Neues Symbol oder drücken Sie einfach Strg + F8.

Vergeben Sie einen beliebigen Namen (oder belassen Sie einen Standardnamen) und drücken Sie OK. Das kleine Fadenkreuz in der Mitte des Bildschirms ist der Registrierungspunkt des Symbols oder sein Ursprungspunkt. Dies sind die X- und Y-Positionen des Objekts. Schnappen Sie sich nun das Oval-Werkzeug (O-Taste) und zeichnen Sie einen Kreis (bei gedrückter Umschalttaste) an einer beliebigen Stelle auf dem Bildschirm.

Klicken Sie auf den Kreis, um ihn auszuwählen, und wechseln Sie in das Eigenschaftenfenster> Position und Größe. Für W (Breite) geben Sie 20 ein, das gleiche für H (Höhe) und für X- und Y-Position (-10). Dadurch wird der Kreis 20x20 px und wird genau auf den Registrierungspunkt zentriert. Beenden Sie nun den Symbolbearbeitungsmodus (klicken Sie oben auf Szene 1), greifen Sie dieses Symbol in Ihre Bibliothek und ziehen Sie es einfach auf die Bühne (irgendwo, wir erhalten seine Position später dynamisch). Wenn sich Ihr Objekt auf der Bühne befindet, geben Sie ihm einen Instanznamen mCircle.

Nun wollen wir die Richtung von der Y- und X-Position unseres Kreises bis zur Y- und X-Position des Mauszeigers berechnen. Die rote Linie im Bild unten ist die Richtung, die wir kennen müssen. Es kann unter Verwendung eines Standards gefunden werden Math.atan2 () Funktion.

Lass es uns jetzt machen. Löschen Sie die "trace" -Anweisungen aus dem Code und erstellen Sie stattdessen eine neue Variable. Verfolgen Sie dann diese Variable, um zu sehen, was Sie erhalten:

 stage.addEventListener (MouseEvent.CLICK, berechneAngle); var myAtan2: Anzahl; Funktion berechneAngle (e: MouseEvent): void myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x); Spur (myAtan2); 

Beachten Sie, dass e.stageY - mCircle.y ist der Vertikale Entfernung von der Maus zum Kreis und e.stageX - mCircle.x ist der horizontaler Abstand.

Im Ausgabefenster werden folgende Nummern angezeigt:

 -2.419017353128333 3.0118660246925346 2.5704959452340326 1.6726588917423932 1.0238847495551058 0.21368467849101092

Dies sind die relativen Winkel (zwischen der X-Achsenlinie und der roten Linie) im Bogenmaß. Warum nicht grad? Nun, Flash verwendet Radiant, um Sinus und Cosinus zu berechnen. Wenn Sie jedoch wissen möchten, welche Winkel in Grad angegeben werden, können Sie "myAtan2" immer mit 180 multiplizieren und durch dividieren Math.PI. So was:

 trace (myAtan2 * 180 / Math.PI) // gibt den Winkel in Grad an;

Editor: Als zusätzliche Ressource finden Sie hier eine Reihe von Funktionen für die Konvertierung in Grad / Radiant. Es wird als Snippet auf snipplr.com gespeichert, dem neuesten Mitglied von Envatos Netzwerk!

Schritt 3: Sinus und Cosinus verstehen

Da wir den Winkel zwischen zwei Punkten kennen, können wir nun berechnen, um wie viele Pixel wir die X- und Y-Eigenschaften jedes Kreises hinzufügen müssen, bis der Klickpunkt erreicht ist. Lassen Sie uns untersuchen, was wir hier wissen müssen:

Die blaue Linie ist der Cosinus des Winkels und die Orange ist der Sinus des Winkels. Mit anderen Worten,

  • Sinus (Winkel) == e.stageY - mCircle.y
  • Cosinus (Winkel) == e.stageX - mCircle.x

Anstatt zu erklären Wie Sinus- und Cosinus-Arbeit zeige ich anhand einiger praktischer Beispiele, wie man sie benutzt. Das Sinus und Cosinus sind die Beziehungen zwischen Y und X in unserem Winkel.

Stellen Sie sich vor, der Winkel zwischen zwei Objekten beträgt 45 Grad. In diesem Fall ist die Beziehung zwischen Sinus und Cosinus 1: 1 (siehe Abbildung unten), was bedeutet, dass wir die X- und Y-Eigenschaften unseres Kreises mit jedem Frame um den gleichen Betrag erhöhen müssen, um das Ziel zu erreichen. Zum Beispiel müssen Sie jedem Pixel 5 Pixel zu X und 5 Pixel zu Y hinzufügen.

In diesem Diagramm hat sich der Winkel geändert und auch das Verhältnis zwischen Sinus und Cosinus hat sich geändert. Es geht jetzt um 1: 2.

In diesem Fall müssen wir der X-Eigenschaft unseres Kreises doppelt so viele Pixel hinzufügen wie Y. X + = 10, Y + = 5;

Schritt 4: Praktische Beispiele

Sie werden wahrscheinlich fragen, warum wir Sinus und Cosinus benötigen, wenn wir die Koordinaten des Klickpunkts bereits kennen - wir können unsere Koordinaten verschieben mCircle Ihnen sofort? Nun, Sie hätten es auf diese Weise tun können, wenn Sie möchten, dass Ihr Kreis (oder ein anderes Objekt) an den Koordinaten eines Klickpunkts "teleportiert" wird, sobald ein Klick erfolgt. Aber was ist, wenn Sie möchten, dass es schrittweise in die Richtung des Klickens bewegt wird? Dazu müssen Sie den X- und Y-Eigenschaften eine bestimmte Pixelmenge hinzufügen, beispielsweise jeden Frame oder jede Sekunde.

Lassen Sie uns nun berechnen, wie viele Pixel wir seinen X- und Y-Eigenschaften hinzufügen sollten, basierend auf Sinus und Cosinus des Winkels zwischen unserem Objekt und einem Klickpunkt. Denken Sie daran, dass Flash den Winkel zwischen ihnen anhand dieser Operation kennt:

 myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x);

Zu diesem Zweck sollten wir unseren Code ein wenig aktualisieren.

 stage.addEventListener (MouseEvent.CLICK, berechneAngle); // 2 ist die maximale Anzahl von Pixeln, die den X- und Y-Eigenschaften jedes Objekts hinzugefügt werden können // Sie können eine beliebige Anzahl verwenden, die Sie mögen. Var moveAmount: Number = 2; var myAtan2: Anzahl; var mouseClickX: Number; var mouseClickY: Anzahl; Funktion compareAngle (e: MouseEvent): void mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x); addEventListener (Event.ENTER_FRAME, moveTheCircle);  Funktion moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount; 

Beachten Sie, was ich hier gemacht habe: Ich habe alle meine Variablen außerhalb von Funktionen befördert, da ich jetzt mehr als eine Funktion habe und diese Variablen von jeder Funktion aus zugänglich sein sollen.

 var moveAmount: Number = 2; var myAtan2: Anzahl; var mouseClickX: Number; var mouseClickY: Anzahl;

Die Bühne verfügt über einen Ereignis-Listener für Mausklicks, also die Methode, wenn der Klick erfolgt berechneAngle () wird aufgerufen und die nächsten Variablen werden instanziiert:

 mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x);

Diese Funktion fügt der Bühne außerdem einen Ereignis-Listener für den Eintrittsrahmen hinzu moveTheCircle () Methode jeden Frame.

 addEventListener (Event.ENTER_FRAME, moveTheCircle);

Schritt 5: Pixel berechnen

Nun, lass uns unsere brechen moveTheCircle () Methode selbst. Im Moment macht es nur zwei Dinge:

 mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;

Wie Sie sehen, berechnet die erste Zeile, wie viele Pixel sie der X-Eigenschaft hinzufügen soll, und die zweite befasst sich mit Y. Lassen Sie mich das erklären. Math.cos findet den Cosinus (x-Eigenschaft) des Winkels "myAtan2", Math.sin macht dasselbe mit seinem Sinus (y-Eigenschaft). Wenn unser myAtan2-Winkel ungefähr 0,785 Radiant (45 Grad) entspricht, sind Cosinus und Sinus beide gleich 0.707… Sie können dies mit einem Taschenrechner überprüfen.

Eine einfache Berechnung zeigt, wie viele Pixel der obige Code zu den X- und Y-Eigenschaften unseres Objekts hinzufügt, wenn der Winkel 45 Grad beträgt.

 Cosinus (45 Grad) = 0,707 × 2 = 1,414; Sinus (45 Grad) = 0,707 × 2 = 1,414; So wird der Code diese Ergebnisse berechnen: mCircle.x + = 1,414 Pixel; mCircle.y + = 1,414 Pixel;

Wenn der Winkel z. 60 Grad wären dann die Ergebnisse so:

 Cosinus (60 Grad) = 0,5 * 2 = 1; Sinus (60 Grad) = 0,866 * 2 = 1,732; Und der Code würde folgendermaßen aussehen: mCircle.x + = 1 Pixel; mCircle.y + = 1,732 Pixel;

Schritt 6: Beheben eines Problems mit dem Code

Nun, wir sind fast fertig. Es gibt jedoch immer noch ein kleines Problem mit unserem Code. Sie haben vielleicht bemerkt, dass unser Objekt niemals anhält, selbst wenn es den Klickpunkt erreicht, in dem es sich noch bewegt. Wir können dieses Problem sehr leicht beheben. Wenn sich unser Objekt in Richtung des Klickpunkts bewegt, verkürzt sich der Abstand zwischen ihnen absolut Der Wert der Entfernung verringert sich ebenfalls. Wir können das so verfolgen:

 trace (Math.abs (mCircle.x - mouseClickX)); trace (Math.abs (mCircle.y - mouseClickY));

(Math.abs () verwandelt negative Zahlen in positive, indem sie einfach mit -1 multipliziert werden. Zahlen, die bereits positiv sind, machen nichts.)

Sie müssen diese Trace-Anweisung nicht zu Ihrem Code hinzufügen. Ich habe sie hier eingefügt, um Ihnen die Art und Weise zu zeigen, wie Sie den absoluten Wert sehen können. In diesem Fall sind beide absoluten Werte kleiner als 3, wenn das Objekt den Klickpunkt erreicht. Also müssen wir jetzt eins hinzufügen ob Aussage in unserem moveTheCircle () Funktion.

 Funktion moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount; // Prüfen Sie, ob die horizontalen und vertikalen Abstände vom Kreis zum Mauspunkt sehr nahe liegen, wenn (Math.abs (mCircle.x - mouseClickX) < 3 && Math.abs(mCircle.y - mouseClickY) < 3)  removeEventListener(Event.ENTER_FRAME, moveTheCircle);  

Wenn der absolute Wert unter 3 fällt, wird der Eingabebildlistener entfernt. Wir müssen die absoluten Werte von X und Y überprüfen, da einer von ihnen sogar 3 erreichen kann, wenn der zweite nicht vorhanden ist. Dies bedeutet, dass die Objekte möglicherweise so aufhören:

Das Bild oben zeigt die Version, in der nur der absolute Wert von X geprüft wird. Der absolute Abstand des X-Abstandes ist bereits kleiner als 3, so dass der Y-Wert nicht mehr beachtet wurde.


Fazit

Das war's. Ich hoffe, dieser Quick Tip hilft Ihnen, einige Trigonometrien zu verstehen, die in der Flash-Entwicklung verwendet werden :)