In diesem Lernprogramm erstellen wir ein Spiel, bei dem verhindert werden soll, dass andere Objekte mit dem Cursor kollidieren. Wir werden keine eingebauten Flashs verwenden hitTestObject ()
Methoden; Stattdessen schreiben wir unsere eigenen Kollisionserkennungsroutinen.
Alle paar Wochen besuchen wir einige der Lieblingsbeiträge unserer Leser aus der gesamten Geschichte der Website. Dieses Tutorial wurde erstmals im Februar 2011 veröffentlicht.
Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:
Erstellen Sie eine neue Flash-Datei (ActionScript 3.0)
Stellen Sie die Abmessungen der Bühne auf 500x500px und FPS auf 32 ein.
Diese Klasse enthält alle Daten, die sich auf einen Ball beziehen. Ein Ball hat eine _Masse
, ein _Radius
, ein _xSpeed
und ein _ySpeed
. Also machen wir für jeden eine Immobilie. Im Konstruktor übergeben wir die Masse, den Winkel und die Geschwindigkeit des Balls. Da die Klasse mit einem Anzeigeobjekt verknüpft wird, können Sie den Radius unseres Balls abrufen, indem Sie die Breite des Anzeigeobjekts durch 2 teilen _xSpeed
und _ySpeed
kann mit einfachen Sinus- und Cosinusfunktionen berechnet werden.
package import flash.display.Stage import flash.display.Sprite import flash.events.Event öffentliche Klasse Ball erweitert Sprite private var _radius: Number = 0 private var _mass: Number = 0 private var _xSpeed: Number = 0 private var _ySpeed : Number = 0 public function Ball (Masse: Number = 10.0, Winkel: Number = Math.PI, Geschwindigkeit: Number = 10.0): void this.mass = Masse this._radius = this.width / 2 this.xSpeed = Geschwindigkeit * Math.sin (Winkel) this.ySpeed = Geschwindigkeit * Math.cos (Winkel)
Weitere Informationen zu diesen trigonometrischen Funktionen von Math.sin () und Math.cos () finden Sie in diesem Quick Tip.
In unserer Ballklasse stellen wir Getter und Setter für unsere Eigenschaften zur Verfügung.
public function get radius (): Number return this._radius public function set Masse (Masse: Anzahl): void this._mass = Masse öffentliche Funktion get mass (): Number return this._mass öffentliche Funktion set xSpeed (xSpeed: Number): void this._xSpeed = xSpeed öffentliche Funktion get xSpeed (): Number return this._xSpeed öffentliche Funktion gesetzt ySpeed (ySpeed: Number): void this._ySpeed = ySpeed öffentliche Funktion get ySpeed (): Number return this._ySpeed
Diese Funktion aktualisiert die x- und y-Eigenschaften unseres Balls gemäß _xSpeed
und _ySpeed
. Wir implementieren diese Funktion in unserem Ball
Klasse.
public function update (): void this.x + = _xSpeed this.y + = _ySpeed
Wir beenden unsere Ball
Klasse in diesem Schritt.
package import flash.display.Stage import flash.display.Sprite import flash.events.Event öffentliche Klasse Ball erweitert Sprite private var _radius: Number = 0 private var _mass: Number = 0 private var _xSpeed: Number = 0 private var _ySpeed : Number = 0 public function Ball (Masse: Number = 10.0, Winkel: Number = Math.PI, Geschwindigkeit: Number = 10.0): void this.mass = Masse this._radius = this.width / 2 this.xSpeed = Geschwindigkeit * Math.sin (Winkel) this.ySpeed = Geschwindigkeit * Math.cos (Winkel) öffentliche Funktion get radius (): Number return this._radius öffentliche Funktion, gewählte Masse (Masse: Number): void this._mass = masse public function get masse (): number return this._mass öffentliche Funktion gesetzt xSpeed (xSpeed: Number): void this._xSpeed = xSpeed öffentliche Funktion get xSpeed (): Number return this._xSpeed öffentliche Funktion setze ySpeed (ySpeed: Number): void this._ySpeed = ySpeed öffentliche Funktion get ySpeed (): Number return this._ySpeed öffentliche Funktion update (): void this.x + = _xSpeed this.y + = _ySpeed
In den Quelldateien habe ich eine Start-FLA eingefügt, die alle Bibliothekselemente enthält, die Sie benötigen. Sie können sie natürlich selbst zeichnen, wenn Sie möchten. Stellen Sie sicher, dass Ihr FLA die folgenden Anzeigeobjekte hat:
(Anmerkung der Redaktion: Das ist ein Tippfehler: "ennemyball" sollte "feindball" sagen.)
Das Ball
Klasse, die wir gerade erstellt haben, muss mit der Feindball
Sprite in der Bibliothek.
Das Spielerball
Sprite muss haben Ball
als Basisklasse und Spielerball
als Klasse.
Das Ergebnis
Movieclip muss ein Ergebnis
Klasse.
Das Anwendung
Die Klasse enthält die gesamte Logik des Spiels. Wir importieren alle Klassen, die wir brauchen. Wie Sie sehen, verwenden wir TweenMax.
Als Nächstes definieren wir unsere Feldvariablen. Die erste Feldvariable ist die Ballspieler
.
Weil die Basisklasse unserer Spielerball
Sprite ist Ball
Wir können diese Klasse im speichern Ballspieler
Variable. Dies macht es später einfacher, auf Kollisionen zwischen den Geräten zu prüfen Ballspieler
und die feindlichen Bälle.
Die zweite Feldvariable ist ein Array, das alle unsere Feindbälle enthält. Die dritte Variable ist der Timer, der zur Durchführung der Hauptspielschleife verwendet wird. Das vierte und letzte Feld ist ein Beispiel von unserem Ergebnis
Bibliotheksobjekt, das zur Anzeige der abgelaufenen Spielzeit verwendet wird. Im Konstruktor nennen wir das drin()
Funktion, die ich im nächsten Schritt erklären werde.
Paket import flash.display.Sprite import flash.display.Graphics import flash.events.Event import flash.events.TimerEvent import flash.events.MouseEvent import flash.geom.Matrix import flash.utils.Timer import flash.ui.Mouse import com.greensock.TweenMax import com.greensock.easing. * public class Anwendung erweitert Sprite private var ballPlayer: Ball private Variebälle: Array private var tmr: Timer private var score: öffentliche Funktion Application (): void init ( )
Vergessen Sie nicht, die Dokumentenklasse zu verknüpfen!.
Schauen Sie sich diesen Code an:
private Funktion init (): void ballPlayer = neuer PlayerBall () eballs = neues Array () tmr = neuer Timer (10) score = neuer Score () stage.align = "TL" stage.scaleMode = "noScale" Mouse.hide () setBackground () score.x = stage.stageWidth / 2 score.y = stage.stageHeight / 2 stage.addChild (score) stage.addEventListener (MouseEvent.MOUSE_MOVE, updatePlayerBall) stage.addChild (ballPlayer) tmr.addEventListener (TimerEvent) .TIMER, updateTime) stage.addEventListener (MouseEvent.CLICK, startGame)
In den ersten vier Zeilen initialisieren wir unsere Feldvariablen.
Als Nächstes stellen wir sicher, dass unsere Bühne an der oberen linken Ecke ausgerichtet ist und nicht skaliert wird.
Wir verstecken den Mauszeiger. Unser Cursor wird durch das ersetzt Spielerball
Sprite Als nächstes rufen wir die Hintergrund einstellen
Funktion (im nächsten Schritt erklärt).
Wir zentrieren unser Ergebnis
auf dem Bildschirm und fügen Sie es der Anzeigeliste hinzu. Um die Position von zu aktualisieren Ballspieler
wir hängen ein MouseEvent.MOUSE_MOVE -Ereignis an die Bühne.
Das updatePlayerBall
Funktion (erläutert in Schritt 11) behandelt dieses MouseEvent. Als nächstes fügen wir die Ballspieler
zur Anzeigeliste.
Der Timer wird zur Anzeige der Spielzeit verwendet. Wir fügen einen TimerEvent.TIMER-Listener an unseren Timer an, der das auslöst Updatezeit()
Funktion (erklärt in Schritt 12) alle 10 Millisekunden.
Schließlich fügen wir unserer Bühne ein MouseEvent.CLICK hinzu. Das Spiel beginnen
Funktion (erklärt in Schritt 13) startet dann unser Spiel.
Diese Funktion fügt der Anzeigeliste einen radialen Hintergrund mit Farbverlauf hinzu. Um einen Farbverlauf auf einem Sprite zu zeichnen, müssen Sie die Art des Farbverlaufs, die Farben, die Sie verwenden möchten, die Alpha-Werte der Farben, die Verhältnisse (diese definieren die Verteilung der Farben) und die Ausbreitungsmethode definieren.
Weitere Informationen finden Sie in diesem Quick Tip zu Farbverläufen.
private Funktion setBackground (): void var type: String = "radial" var Farben: Array = [0xffffff, 0xcccccc] var alphas: Array = [1, 1] var Verhältnisse: Array = [0, 255] var matr: Matrix = new Matrix () matr.createGradientBox (stage.stageWidth, stage.stageHeight, Math.PI / 2, 0, 0) // SpreadMethod legt fest, wie der Farbverlauf verteilt wird. Hinweis!!! Flash verwendet CONSTANTS zur Darstellung von String-Litern var sprMethod: String = "pad" // Starten Sie den Gradietn und übergeben Sie unsere Variablen an das var-Sprite: Sprite = new Sprite () // Speichern Sie die Eingabe und erhöhen Sie die Leistung durch lokale Referenz auf ein Graphics-Objekt var g: Graphics = Sprite.graphics g.beginGradientFill (Typ, Farben, Alphas, Verhältnisse, Matr, SprMethod) g.drawRect (0,0, stage.stageWidth, stage.stageHeight) stage.addChild (Sprite)
Diese Funktion aktualisiert die Position von Ballspieler
entsprechend der Position Ihrer Maus.
private Funktion updatePlayerBall (e: MouseEvent): void ballPlayer.x = mouseX ballPlayer.y = mouseY
Wir berechnen die Zeit in Sekunden und legen sie in das Textfeld unserer Ergebnis
Sprite Alle 5000ms (fünf Sekunden) fügen wir dem Spiel einen neuen Ball hinzu.
private Funktion updateTime (e: TimerEvent): void score.txtScore.text = String (((tmr.currentCount * tmr.delay) / 1000) .toFixed (2)); if ((tmr.currentCount * tmr.delay)% 5000 == 0) addBall ();
Das Spiel wird durch Anklicken der Bühne gestartet. Zuerst entfernen wir den Listener für den Bühnenklick, so dass wir das Spiel nicht mehrmals starten können. Wir fügen dem Spiel drei Bälle hinzu, indem wir die addBall ()
Funktion (erklärt im nächsten Schritt) dreimal. Wir starten unseren Timer, der unsere Spielzeit aktualisiert.
Schließlich fügen wir unserer Bühne ein Ereignis ENTER_FRAME hinzu. Das gameLoop ()
Funktion (erklärt in Schritt 15) aktualisiert die Position unserer gegnerischen Bälle.
private Funktion startGame (e: MouseEvent): void stage.removeEventListener (MouseEvent.CLICK, startGame) addBall () addBall () addBall () tmr.start () stage.addEventListener (Event.ENTER_FRAME, gameLoop)]
Zuerst machen wir eine neue Instanz von unserem Ball
Klasse. Wir positionieren die Ball
zufällig auf der Bühne mit einem Alpha von 0 und fügen Sie es der Anzeigeliste hinzu.
Als nächstes tippen wir das Alpha auf 1 zurück. (Ich verwende TweenMax, es ist in den Quelldateien enthalten. Sie können auch die integrierte Flash-Tween-Engine verwenden.) Das zweite Tween ist eigentlich kein Tween. Es wartet nur eine Sekunde und die onComplete
Funktion drückt die Ball
in unser Kugeln
Array. Auf diese Weise die gameLoop ()
Funktion (im nächsten Schritt erklärt) kann den Rest erledigen.
private Funktion addBall (): void var ball: Ball = neuer Ball (10, Math.random () * Math.PI * 2, 5) ball.x = Math.random () * stage.stageWidth ball.y = Math .random () * stage.stageHöhe Ball.alpha = 0 stage.addChild (Ball) TweenMax.to (Ball, 0,5, Alpha: 1) TweenMax.to (Ball, 0, delay: 1, onComplete: function ( ): void eballs.push (ball))
Jeder Frame wird diese Funktion durchlaufen.
private Funktion gameLoop (e: Event): void for (var i: uint = 0; i < eballs.length; i++) for (var j:uint = i + 1; j < eballs.length; j++) if (collision(eballs[i], eballs[j])) doCollision(eballs[i], eballs[j]) if(collision(eballs[i], ballPlayer)) endOfGame() break eballs[i].update() checkBounds(eballs[i])
Wir beginnen mit dem Durchlaufen aller Feindbälle.
Die zweite for-loop prüft auf Kollisionen zwischen den gegnerischen Bällen. Die Schleife beginnt bei 'i + 1'. Auf diese Weise überprüfen wir die Kollisionen nicht noch einmal.
Als nächstes prüfen wir, ob die Ballspieler
trifft den feindlichen Ball. Wenn ja, ist das Spiel beendet. Dann aktualisieren wir die Position unseres gegnerischen Balls.
Wir sorgen dafür, dass die Bälle im Spiel bleiben, indem Sie die Funktion aufrufen checkBounds ()
(später erklärt).
Diese Funktion prüft, ob ein bestimmtes Kugelpaar kollidiert.
Zuerst berechnen wir den x-Abstand und den y-Abstand zwischen den beiden Kugeln. Mit dem Satz von Pythagoras (siehe folgendes Diagramm) berechnen wir den absoluten Abstand zwischen ihnen. Wenn der Abstand kleiner oder gleich der Summe der Radien der Kugeln ist, kommt es zu einer Kollision.
private Funktionskollision (Ball1: Ball, Ball2: Ball): Boolean var xDist: Number = Ball1.x - Ball2.x var yDist: Number = Ball1.y - Ball2.y var Dist: Number = Math.sqrt (xDist *) xDist + yDist * yDist) return Dist <= ball1.radius + ball2.radius
Diese Funktion berechnet die neuen X- und Y-Geschwindigkeiten der Kugeln entsprechend der Geschwindigkeit und dem Winkel der Kollision. Achtung: Mathe;)
Zuerst berechnen wir den horizontalen Abstand zwischen den beiden Kugeln und dann den vertikalen Abstand zwischen den Kugeln. Mit diesen Abständen (und etwas mehr Trigonometrie) können wir den Winkel zwischen den Kugeln berechnen (siehe Diagramm)..
Als nächstes berechnen wir, was ich das nenne Größe von jedem Ball. (Wir haben einen xspeed-Vektor und einen yspeed-Vektor; die Größe ist die Vektorsumme davon.) Dann berechnen wir den Winkel jeder Kugel (ähnlich wie bei der vorherigen Winkelberechnung)..
Als nächstes drehen wir die neuen X- und Y-Geschwindigkeiten jeder Kugel. Was wir eigentlich tun, ist das Koordinatensystem zu drehen. Durch Drehen unserer Achsen kommt es zu einer 1D-Kollision. (Siehe folgendes Diagramm).
Newton sagt, dass die Gesamtmenge an kinetischer Energie in einem geschlossenen System konstant ist. Jetzt verwenden wir diese Formeln:
v1 = (u1 * (m1-m2) + 2 * m2 * u2) / (m1 + m2)
v2 = (u2 * (m2 - m1) + 2 * m1 * u1) / (m1 + m2)
woher:
v1 = final xSpeedBall 1
v2 = final xSpeedBall 2
m1 = Massekugel 1
m2 = Massekugel 2
u1 = Anfangsgeschwindigkeitskugel 1
u2 = Anfangsgeschwindigkeitsball 2
Die y-Geschwindigkeiten ändern sich nicht, da es sich um eine 1D-Kollision handelt.
Mit diesen Formeln können wir das berechnen xSpeed
und ySpeed
von jedem Ball.
Jetzt haben wir die neuen X- und Y-Geschwindigkeiten in unserem rotierten Koordinatensystem. Der letzte Schritt besteht darin, alles wieder in ein normales Koordinatensystem umzuwandeln. Wir gebrauchen Math.PI / 2
weil der Winkel zwischen xSpeed
und ySpeed
muss immer 90 Grad betragen (pi / 2 Bogenmaß).
private Funktion doCollision (Ball1: Ball, Ball2: Ball): void var xDist: Nummer = Ball1.x - Ball2.x var yDist: Nummer = Ball1.y - Ball2.y var collisionAngle: Nummer = Math.atan2 (yDist, xDist) var magBall1: Number = Math.sqrt (ball1.xSpeed * ball1.xSpeed + ball1.ySpeed * ball1.ySpeed) var magBall2: Number = Math.sqrt (ball2.xSpeed * ball2.xSpeed + ball2.ySpeed * ball2). ySpeed) var angleBall1: Number = Math.atan2 (ball1.ySpeed, ball1.xSpeed) var angleBall2: Number = Math.atan2 (ball2.ySpeed, ball2.xSpeed) var xSpeedBall1: Number = magBall1 * Math.cos (angleBall1-collisionAngle) ) var ySpeedBall1: Number = magBall1 * Math.sin (angleBall1-collisionAngle) var xSpeedBall2: Number = magBall2 * Math.cos (angleBall2-collisionAngle) var ySpeedBall2: Number = magBall2 * Math.sin (angleBall2-collisionAngle) var finalxSpeedBall2 = ((ball1.mass-ball2.mass) * xSpeedBall1 + (ball2.mass + ball2.mass) * xSpeedBall2) / (ball1.mass + ball2.mass) var finalxSpeedBall2: Anzahl = ((ball1.mass + ball1.mass) * xSpeedBall1 + (ball2.mass-ball1.mass) * xSpeedBall 2) / (ball1.mass + ball2.mass) var finalySpeedBall1: Number = ySpeedBall1 var finalySpeedBall2: Number = ySpeedBall2 ball1.xSpeed = Math.cos (collisionAngle) * finalxSpeedBall1 + Math.cos (collisionAngle + Math.PI / 2) * finalySpeedBall1 ball1.ySpeed = Math.sin (collisionAngle) * finalxSpeedBall1 + Math.sin (collisionAngle + Math.PI / 2) * finalySpeedBall1 ball2.xSpeed = Math.cos (collisionAngle) * finalxSpeedBall2 + Math.cos (collisionAngle + Math.PI) / 2) * finalySpeedBall2 ball2.ySpeed = Math.sin (collisionAngle) * finalxSpeedBall2 + Math.sin (collisionAngle + Math.PI / 2) * finalySpeedBall2
Weitere Informationen zu elastischen Kollisionen finden Sie auf hoomanr.com.
Dies wird ausgeführt, wenn das Spiel endet.
private Funktion endOfGame (): void tmr.stop () Mouse.show () stage.removeEventListener (MouseEvent.MOUSE_MOVE, updatePlayerBall) stage.removeEventListener (Event.ENTER_FRAME, gameLoop), während (eballs.length>) TweenMax.. (eballs [0], 0.5, scaleX: 0, scaleY: 0, leicht: Bounce.easeOut) eballs.splice (0,1) TweenMax.to (ballPlayer, 0.5, scaleX: 0, scaleY: 0) Leichtigkeit: Bounce.easeOut)
Zunächst einmal stoppen wir den Timer. Wir zeigen die Maus wieder. Als nächstes entfernen wir die Listener MOUSE_MOVE und ENTER_FRAME. Schließlich machen wir alle Bälle auf der Bühne unsichtbar.
Diese Funktion stellt sicher, dass die Bälle im Spielbildschirm bleiben. Wenn also der Ball die obere oder untere Seite trifft, kehren wir den Ball um ySpeed
. Wenn der Ball die linke oder rechte Seite des Bildschirms trifft, kehren wir den Ball um xSpeed
. Es verwendet eine ähnliche Logik wie die Kollisionserkennungsfunktion, um zu prüfen, ob die Kanten der Kugel eine Kante des Bildschirms treffen.
private function checkBounds (Ball: Ball): ungültig if ((ball.x + ball.radius)> stage.stageWidth) ball.x = stage.stageWidth - ball.radius ball.xSpeed * = -1 if (( ball.x - ball.radius) < 0) ball.x = 0 + ball.radius ball.xSpeed *= -1 if((ball.y + ball.radius) > stage.stageHeight) ball.y = stage.stageHeight - ball.radius ball.ySpeed * = - 1 if ((ball.y - ball.radius) < 0) ball.y = 0 + ball.radius ball.ySpeed *= - 1
Wir haben unsere Bewerbungsklasse abgeschlossen. Wir haben jetzt ein funktionierendes Spiel!!!
package import flash.display.Sprite; import flash.display.Graphics; import flash.events.Event; import flash.events.TimerEvent; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.utils.Timer; import flash.ui.Mouse; import com.greensock.TweenMax; import com.greensock.easing. *; öffentliche Klasse Anwendung erweitert Sprite private var ballPlayer: Ball; private var eballs: Array; private var tmr: Timer; private var Bewertung: Score; öffentliche Funktion Application (): void init (); private Funktion init (): void ballPlayer = new PlayerBall (); eballs = neues Array (); tmr = neuer Timer (10); Score = neuer Score (); stage.align = "TL"; stage.scaleMode = "noScale"; Mouse.hide (); Hintergrund einstellen(); score.x = stage.stageWidth / 2; score.y = stage.stageHeight / 2; stage.addChild (score); stage.addEventListener (MouseEvent.MOUSE_MOVE, updatePlayerBall); stage.addChild (ballPlayer); tmr.addEventListener (TimerEvent.TIMER, updateTime); stage.addEventListener (MouseEvent.CLICK, startGame); private Funktion setBackground (): void var type: String = "radial"; var colors: Array = [0xffffff, 0xcccccc]; var alphas: Array = [1,1]; Var Verhältnisse: Array = [0,255]; var matr: Matrix = neue Matrix (); matr.createGradientBox (stage.stageWidth, stage.stageHeight, Math.PI / 2, 0, 0); // SpreadMethod legt fest, wie der Farbverlauf verteilt wird. Hinweis!!! Flash verwendet CONSTANTS zur Darstellung von String-Literalen. Var sprMethod: String = "pad"; // Starten Sie den Gradietn und übergeben Sie unsere Variablen an ihn. Var Sprite: Sprite = new Sprite (); // Speichern Sie die Eingabe und erhöhen Sie die Leistung durch lokale Referenz auf ein Graphics-Objekt. Var g: Graphics = sprite.graphics; g.beginGradientFill (Typ, Farben, Alphas, Verhältnisse, Matr, SprMethod); g.drawRect (0,0, stage.stageWidth, stage.stageHeight); stage.addChild (Sprite); private Funktion updatePlayerBall (e: MouseEvent): void ballPlayer.x = mouseX; ballPlayer.y = mouseY; private Funktion updateTime (e: TimerEvent): void score.txtScore.text = String (((tmr.currentCount * tmr.delay) / 1000). if ((tmr.currentCount * tmr.delay)% 5000 == 0) addBall (); private Funktion startGame (e: MouseEvent): void stage.removeEventListener (MouseEvent.CLICK, startGame); addBall (); addBall (); addBall (); tmr.start (); stage.addEventListener (Event.ENTER_FRAME, gameLoop); private Funktion addBall (): void var ball: Ball = neuer Ball (10, Math.random () * Math.PI * 2,5); ball.x = Math.random () * stage.stageWidth; ball.y = Math.random () * stage.stageHeight; Ball α = 0; stage.addChild (Ball); TweenMax.to (Ball 0,5, alpha: 1); TweenMax.to (Ball, 0, delay: 1, onComplete: function (): void eballs.push (ball)); private Funktion gameLoop (e: Event): void for (var i: uint = 0; i < eballs.length; i++) for (var j:uint = i + 1; j < eballs.length; j++) if (collision(eballs[i],eballs[j])) doCollision(eballs[i], eballs[j]); if (collision(eballs[i],ballPlayer)) endOfGame(); break; eballs[i].update(); checkBounds(eballs[i]); private function collision(ball1:Ball, ball2:Ball):Boolean var xDist:Number = ball1.x - ball2.x; var yDist:Number = ball1.y - ball2.y; var Dist:Number = Math.sqrt(xDist * xDist + yDist * yDist); if (Dist <= ball1.radius + ball2.radius) if (ball1.x < ball2.x) ball1.x -= 2; ball2.x += 2; else ball1.x += 2; ball2.x -= 2; if (ball1.y < ball2.y) ball1.y -= 2; ball2.y += 2; else ball1.y += 2; ball2.y -= 2; return Dist <= ball1.radius + ball2.radius; private function doCollision(ball1:Ball, ball2:Ball):void var xDist:Number = ball1.x - ball2.x; var yDist:Number = ball1.y - ball2.y; var collisionAngle:Number = Math.atan2(yDist,xDist); var magBall1:Number = Math.sqrt(ball1.xSpeed * ball1.xSpeed + ball1.ySpeed * ball1.ySpeed); var magBall2:Number = Math.sqrt(ball2.xSpeed * ball2.xSpeed + ball2.ySpeed * ball2.ySpeed); var angleBall1:Number = Math.atan2(ball1.ySpeed,ball1.xSpeed); var angleBall2:Number = Math.atan2(ball2.ySpeed,ball2.xSpeed); var xSpeedBall1:Number = magBall1 * Math.cos(angleBall1 - collisionAngle); var ySpeedBall1:Number = magBall1 * Math.sin(angleBall1 - collisionAngle); var xSpeedBall2:Number = magBall2 * Math.cos(angleBall2 - collisionAngle); var ySpeedBall2:Number = magBall2 * Math.sin(angleBall2 - collisionAngle); var finalxSpeedBall1:Number = ((ball1.mass-ball2.mass)*xSpeedBall1+(ball2.mass+ball2.mass)*xSpeedBall2)/(ball1.mass+ball2.mass); var finalxSpeedBall2:Number = ((ball1.mass+ball1.mass)*xSpeedBall1+(ball2.mass-ball1.mass)*xSpeedBall2)/(ball1.mass+ball2.mass); var finalySpeedBall1:Number = ySpeedBall1; var finalySpeedBall2:Number = ySpeedBall2; ball1.xSpeed = Math.cos(collisionAngle) * finalxSpeedBall1 + Math.cos(collisionAngle + Math.PI / 2) * finalySpeedBall1; ball1.ySpeed = Math.sin(collisionAngle) * finalxSpeedBall1 + Math.sin(collisionAngle + Math.PI / 2) * finalySpeedBall1; ball2.xSpeed = Math.cos(collisionAngle) * finalxSpeedBall2 + Math.cos(collisionAngle + Math.PI / 2) * finalySpeedBall2; ball2.ySpeed = Math.sin(collisionAngle) * finalxSpeedBall2 + Math.sin(collisionAngle + Math.PI / 2) * finalySpeedBall2; private function endOfGame():void tmr.stop(); Mouse.show(); stage.removeEventListener(MouseEvent.MOUSE_MOVE, updatePlayerBall); stage.removeEventListener(Event.ENTER_FRAME, gameLoop); while (eballs.length > 0) TweenMax.to (eballs [0], 0.5, scaleX: 0, scaleY: 0, Leichtigkeit: Bounce.easeOut); eballs.splice (0,1); TweenMax.to (ballPlayer, 0.5, scaleX: 0, scaleY: 0, Leichtigkeit: Bounce.easeOut); private Funktion checkBounds (Ball: Ball): void if ((ball.x + ball.radius)> stage.stageWidth) ball.x = stage.stageWidth - ball.radius; Kugel x Geschwindigkeit * = -1; if ((ball.x - ball.radius) < 0) ball.x = 0 + ball.radius; ball.xSpeed *= -1; if ((ball.y + ball.radius) > stage.stageHeight) ball.y = stage.stageHeight - ball.radius; ball.ySpeed * = -1; if ((ball.y - ball.radius) < 0) ball.y = 0 + ball.radius; ball.ySpeed *= -1;
Das war es für dieses Tutorial. Natürlich können Sie die Möglichkeit hinzufügen, das Spiel neu zu starten, aber das sollte nicht zu schwer sein. Dieses grundlegende Beispiel für elastische Kollisionen kann für größere Spiele wie ein Billardspiel oder ähnliches verwendet werden.
Ich hoffe, Ihnen hat dieses Tutorial gefallen, danke fürs Lesen!