Circular Bullet Spread ist nicht gleichmäßig

7

Ich erstelle einen Bullet Shooter im Stil von Touhou. Im Moment möchte ich einen sehr einfachen kreisförmigen Schuss vom Feind haben.

Der Abstand ist jedoch sehr ungleichmäßig, was nicht sehr gut ist, wenn Sie überleben wollen.

Der Code, den ich verwende, lautet:

private function shoot() : void
{
    const BULLETS_PER_WAVE : int = 72;
    var interval : Number = BULLETS_PER_WAVE / 360;

    for (var i : int = 0; i < BULLETS_PER_WAVE; ++i)
    {
        var xSpeed : Number = GameConstants.BULLET_NORMAL_SPEED_X * Math.sin(i * interval);
        var ySpeed : Number = GameConstants.BULLET_NORMAL_SPEED_Y * Math.cos(i * interval);

        BulletFactory.createNormalBullet(bulletColor_, alice_.center, xSpeed, ySpeed);
    }

    canShoot_ = false;
    cooldownTimer_.start();
}

Ich stelle mir vor, mein Fehler liegt in den sin& cos-Funktionen, bin mir aber nicht ganz sicher, was los ist.

IAE
quelle
Wie kam es zu einem Tippfehler in Ihrem Code-Snippet? Haben Sie das Einfügen nicht aus Ihrem Editor kopiert, nachdem Sie bestätigt haben, dass der Code kompiliert wurde?
aaaaaaaaaaaa
2
Dies ist keine mathematische Antwort, aber BulletML hilft Ihnen dabei, die Flut von Aufzählungszeichen in XML zu definieren und zu speichern: asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html
BrandFeelsGood
@eBusiness: Welcher Tippfehler? Der Code wird einwandfrei kompiliert.
IAE
@SoulBeaver Ohne die Endklammer in Zeile 6 ist dies nicht der Fall. Natürlich ist es in Ihrem Code enthalten, aber warum hat es die Frage nicht geschafft?
aaaaaaaaaaa
@eBusiness: Ich habe absolut keine Ahnung, was dort passiert ist. Ich habe möglicherweise einen Fehler gemacht, als ich den Code eingerückt und formatiert habe, damit er auf GameDev richtig aussieht, aber ich habe keine andere Erklärung. XD Jetzt behoben, danke.
IAE

Antworten:

13

Goldene Regel beim Arbeiten mit einem beliebigen Winkel: Stellen Sie sicher, dass Sie das richtige Gerät verwenden. In diesem Fall sollten Sie Bogenmaß verwenden, nicht Grad.

Math.sin(i * interval * Math.PI / 180);
Math.cos(i * interval * Math.PI / 180);

Wenn Sie Kugeln direkt zwischen Boss und Spieler abfeuern möchten, verwenden Sie atan2FYI.

Ingenieur
quelle
Warum sind Bogenmaß besser als Grad?
Asche999
Weil Sie durch 360 teilen. Sie drehen sich im Wesentlichen hunderte Male um den Kreis, deshalb ist es nicht einmal.
UltimateBrent
1
Radiant sind für Triggerfunktionsaufrufe in AS3 erforderlich. Aber warum sie mathematisch besser sind (und daher viele Sprachen sich für sie entscheiden), liegt daran, dass das Bogenmaß den Wert von pi, einer universellen mathematischen Konstante, direkt in Beziehung setzt. Während Grad sind ein von Menschen gemachtes Konstrukt, so eine zusätzliche Dereferenzierungsebene bei der Verarbeitung beteiligt ist (was die sind *oder / Math.PI/180Sie im Freien sehen da draußen - wenn es nicht in der Basis trigonometrischen Funktionen enthalten, haben Sie es selbst zu tun , um in und von Grad umrechnen).
Ingenieur
1
Sinus und Cosinus werden als Reihen von Brüchen berechnet. In ihrer einfachsten Form nehmen diese Reihen Bogenmaß als Eingabe. Nur durch Einführung einer Konstante basierend auf π können diese Reihen mit Grad verwendet werden. Ich würde raten, dass Sie Grad für die interne Darstellung insgesamt überspringen. Das Bogenmaß ist vielleicht etwas gewöhnungsbedürftig, aber auf lange Sicht ist es einfacher, nicht die ganze Zeit konvertieren zu müssen.
aaaaaaaaaaa
Wissenswertes im Bogenmaß: Wenn Sie einen Kreis mit einem Radius von einem Meter haben und entlang eines Bogens von n Bogenmaß dieses Kreises gehen, hätten Sie eine Strecke von genau n Metern zurückgelegt, und der durch diesen Weg definierte Sektor des Kreises hat einen Fläche von genau ** n ** / 2 Quadratmetern. Radiant sind fantastisch.
Trevor Powell
7

Sie machen die Division falsch herum und verwenden eher Grad als Bogenmaß, wie es die mathematischen Funktionen tun. Durch Zufall ergibt sich ein Muster, das dem gewünschten etwas ähnelt. Korrigieren Sie einfach Ihre Berechnung der Intervallvariablen.

var interval : Number = 2 * Math.PI / BULLETS_PER_WAVE;

Bearbeiten: Für diejenigen, die mit dem Konzept nicht vertraut sind, erzeugt dieser Code den gewünschten Winkel zwischen Aufzählungszeichen im Bogenmaß, wodurch die Berechnung von xSpeedund ySpeedohne weitere angewendete Konstanten verlassen werden kann.

aaaaaaaaaaaa
quelle
+1 Richtig. Er sollte period = 2 * pivon sin / cos Funktionen berechnen und dann interval = period / BULLETS_PER_WAVE.
user712092
5

Ich denke, Sie sollten stattdessen 360 / BULLETS_PER_WAVE ausführen, was in Ihrem Fall 360/72 = 5 Grad zwischen den einzelnen Aufzählungszeichen ergibt. Sind Sie sich auch sicher, dass die Funktionen Math.sin und Math.cos ihre Eingabe in Grad und nicht im Bogenmaß wünschen?

Durza007
quelle
4

Während Sie beantwortet wurden, ist hier eine lustigere Antwort: Lernen Sie von der Natur.

Verwenden Sie stattdessen den goldenen Schnitt.

const GOLDEN_RATIO : Number = 1.618033989;
var interval : Number = 2 * Math.PI * GOLDEN_RATIO;

Siehe: http://www.mathsisfun.com/numbers/nature-golden-ratio-fibonacci.html

Klems
quelle
Wenn Sie zwischen den einzelnen Aufnahmen eine kleine Verzögerung einlegen, wird dies ein wirklich schönes Muster.
aaaaaaaaaaa
@ Klems: Super! Ich benutze dies total für mein nächstes Muster: 3
IAE
3

Abgesehen von möglichen Grad- / Bogenmaßproblemen besteht das Hauptproblem meiner Meinung nach darin, dass Sie für die Berechnungen ganzzahlige Werte verwenden. Sie haben GameConstants.BULLET_NORMAL_SPEED_Xdas Y-Gegenstück nicht angezeigt , stellen jedoch sicher, dass es als Gleitkommazahlen und nicht als Ganzzahlen dargestellt wird. Alternativ können Sie sie während der Multiplikation für die Geschwindigkeitsberechnung in Gleitkommawerte umwandeln.

Kylotan
quelle
Die Werte sind Autocast. Ich bin mit Actionscript nicht vertraut genug, um jeden einzelnen Fall aufzurufen, aber in diesem Fall bin ich mir ziemlich sicher, dass dies nicht das Problem ist.
aaaaaaaaaaaa
Ich glaube nicht, dass sie richtig besetzt werden. Schauen Sie sich die 2 Kreise an, die dem Zeichen am nächsten sind, oben und rechts davon. Diese 2 und jeder einzelne Kreis in diesen beiden Strahlen haben identische Y-Werte wie der in dem anderen Strahl, was nicht zu erwarten ist, wenn die Y-Inkremente ein Gleitkommawert wären.
Kylotan
Sie haben Recht, es gibt ein Problem mit gerundeten Werten, aber ich glaube nicht, dass es im geposteten Code-Snippet sichtbar ist. Alles, was dort schlecht werden könnte, würde zu einer 0 führen und somit nichts erzeugen, das aus der Ferne wie ein Kreis aussieht. Es muss ein Problem weiter unten in der Kette sein, wahrscheinlich numberwird stattdessen eine Variable deklariert , die hätte sein sollen int.
aaaaaaaaaaaa
+1: Ich habe vergessen, den Typ von BULLET_X anzugeben, daher hat AS ihn standardmäßig auf int gesetzt. Hoppla.
IAE