Reflexionswinkel

11

Ich habe dieses Spiel im "Breakeout-Stil".

Ich habe eine Kanone in der Mitte, Blöcke um die Kanone und Pads um die Blöcke. So sieht das Spiel aus:

Ein kreisförmiges Breakout-Spiel

Ich habe es geschafft, die Kollision pro Pixel zu erhalten, und mein Ball " reflektiert " den Kontakt mit den Blöcken mit der folgenden Mathematik:

Ball.Direction = 2 * (Block.Direction - Ball.Direction) + 180;

Bild, das eine Reflexionswinkelberechnung darstellt

Dabei ist die blaue Linie die Kugelrichtung und die schwarze Linie (Basislinie) die Blockoberfläche.

Die Richtung ist ein Winkel im Bogenmaß (der natürlich in Grad umgerechnet werden kann).
Der Ball wird bewegt von:

// Event.ENTER_FRAME
x += Math.sin(Direction) * Velocity;
y -= Math.cos(Direction) * Velocity;

So weit, ist es gut.

Mein Problem kommt jetzt mit den Pads (die 3 dunklen und großen Blöcke um die kleinen farbigen Blöcke).

Während sie sich drehen, ändert sich der Oberflächenwinkel.
Darüber hinaus sollte der Ball auch die Seiten treffen. Wie kann ich also die Schlagrichtung und die neue Bewegungsrichtung des Balls messen?

ps : Bei Bedarf kann ich Code und einen spielbaren SWF bereitstellen.


Bearbeiten

Ok, das Problem mit den Winkeln wurde mit Vektoren gelöst , aber ich habe immer noch das Problem mit Seiten- und Rückenkollisionen.

Ich werde dafür eine andere Frage öffnen und sie hier verlinken.

NemoStein
quelle
3
Wenn Sie Ihre Konten neu zuordnen, sollten Sie den Reputationsbonus von +100 erhalten. Dies sollte eine Option auf der Registerkarte "Konten" Ihres Profils sein. In der Zwischenzeit werde ich diese Bilder jedoch für Sie veröffentlichen.
Grace Note
Ich nehme an, Ihre Richtung ist ein Winkel zwischen 0 und 360 und um den Ball zu bewegen, verwenden Sie Trigonometrie?
Jonathan Connell
@Grace, vielen Dank für die Bilder ... @ 3nixios, ich habe weitere Informationen über den Winkel und die Bewegung hinzugefügt.
NemoStein
Wenn Sie nur eine "Richtung" pro Block speichern, stellen Sie sich möglicherweise jeden schwarzen Block als Gruppe von vier einzelnen Blöcken neu vor, wobei die "Richtung" immer nach außen zeigt. Es würde wahrscheinlich Randfälle an den vier Ecken geben.
Horatio

Antworten:

8

Ich bin mir nicht sicher, ob ich Ihr Problem richtig verstanden habe, aber ich ging davon aus, dass Sie nach einer Kollision die resultierende Richtung Ihres Balls finden möchten.

Hier ist eine kurze Zeichnung auf meiner weißen Tafel, die eine mögliche Lösung dafür zeigt:

Geben Sie hier die Bildbeschreibung ein

Die grünen Pfeile repräsentieren die Geschwindigkeit des Balls (als Vektor), die blauen Blöcke repräsentieren Ihre großen schwarzen Blöcke und der rote Pfeil ist der resultierende Vektor.

Im ersten Fall hat der blaue Block eine Neigung von 30 Grad. Eine Möglichkeit, das Kollisionsproblem zu beheben, besteht darin, alles wieder auf die horizontale Achse zu bringen. Was Sie tun müssen, ist alles um 30 Grad zu drehen (die Neigung des Blocks) (Sie können dafür Matrizen verwenden).

Dann überprüfen Sie , woher die Kollision kam . Wenn die Kollision horizontal war, kehren Sie die x-Komponente der Geschwindigkeit um. Wenn es vertikal war (wie in diesem Fall), die y-Komponente ( ball.Velocity.Y = -ball.Velocity.Y). Dadurch wirkt der Ball auch korrekt, wenn er auf Ecken trifft (beide Komponenten werden umgekehrt). Danach müssen Sie nur noch zu drehen zurück in die reale Situation (die nicht auf der Zeichnung).

Im zweiten Fall ist es dasselbe, außer dass die Geschwindigkeit des Balls nicht senkrecht zum Block ist. Sie drehen sich um 70 Grad, prüfen, woher die Kollision stammt, und kehren die entsprechenden Komponenten um. Danach kehren Sie zu Ihrer realen Situation zurück.

Hinweis: Mir ist aufgefallen, dass Sie anstelle eines Vektors einen Winkel verwenden, um die Richtung darzustellen. Sie können einfach einen Vektor für diese Berechnungen erstellen oder dieselbe allgemeine Idee beibehalten, aber mit Winkeln arbeiten.

Dies ist sicherlich nicht der beste Weg und ich bin sicher, dass Sie es einfach auf irgendeine Weise berechnen können, aber ich denke, es ist eine mögliche Lösung für Ihr Problem.

Jesse Emond
quelle
Danke ... Liebte dein Board. Ich werde es gleich versuchen ... Ahn, und denkst du, dass Vektoren besser zu pflegen / zu bearbeiten sind?
NemoStein
Haha, entschuldigen Sie meine schlechten Zeichenfähigkeiten.
Jesse Emond
Hoppla, ich habe beim Zeichnen tatsächlich einen wichtigen Schritt vergessen. Sie müssen sich zurückdrehen -block inclination angle, um eine angemessene Kollisionsreaktion zu erhalten. Blöd mich.
Jesse Emond
Ich denke, es geht um persönliche Vorlieben, aber ich bevorzuge Vektoren sehr. Sie müssen die meiste Zeit nicht über die Mathematik nachdenken, die dahinter steckt, und das macht den Code normalerweise sauberer. Sie können also a Direction(als Vektor) beibehalten und die Position des Balls folgendermaßen aktualisieren : ball.Position += ball.Direction * ball.Speed;.
Jesse Emond
@ Jesse, das konnte ich bis jetzt nicht. Ich habe Ihre Methode perfekt verstanden, konnte sie aber nicht implementieren. Dazu muss ich den gesamten Teil neu schreiben, der Bogenwinkel verwendet, um Vektoren zu verwenden (das ist eigentlich nicht viel). Im Moment werde ich andere Alternativen ausprobieren, und wenn Sie eine andere haben, werde ich es gerne versuchen. Vielen Dank.
NemoStein