Herumspielen mit elastischen Kollisionen

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.

Erneut veröffentlichtes Tutorial

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.


Endergebnisvorschau

Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:


Schritt 1: Starten Sie los

Erstellen Sie eine neue Flash-Datei (ActionScript 3.0)

Stellen Sie die Abmessungen der Bühne auf 500x500px und FPS auf 32 ein.


Schritt 2: Die Ballklasse

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.


Schritt 3: Bereitstellen von Getters und Setters

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

Schritt 4: Aktualisierungsfunktion

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

Schritt 5: Die abgeschlossene Klasse

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 

Schritt 6: Zeigen Sie Objekte für unsere Ballklasse an

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.)


Schritt 7: Verknüpfen unserer Bibliotheksobjekte

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.


Schritt 8: Die Anwendungsklasse (Dokumentenklasse)

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!.


Schritt 9: Die init () - Funktion

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.


Schritt 10: Funktion setBackground ()

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)

Schritt 11: updatePlayerBall () - Funktion

Diese Funktion aktualisiert die Position von Ballspieler entsprechend der Position Ihrer Maus.

 private Funktion updatePlayerBall (e: MouseEvent): void ballPlayer.x = mouseX ballPlayer.y = mouseY

Schritt 12: updateTime () - Funktion

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 (); 

Schritt 13: startGame () - Funktion

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)]

Schritt 14: addBall () - Funktion

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))

Schritt 15: gameLoop () - Funktion

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).


Schritt 16: Kollisionsfunktion ()

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 

Schritt 17: doCollision () - Funktion

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.


Schritt 18: endOfGame () - Funktion

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.


Schritt 19: checkBounds () - Funktion

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  

Schritt 20: Die vollständige Antragsklasse

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;    

Fazit

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!