Erstellen einer Nahkampfwaffe in Box2D (libGDX)

10

Ich habe Probleme damit, eine Nahkampfwaffe einzusetzen, die schwingen kann, wenn eine Taste gedrückt wird.

Ich stelle mir zwei verschiedene Angriffe vor (Stich und Schwung)

Ich habe versucht, zwei Vorrichtungen (Charakter + Waffe), zwei verschiedene Körper, zwei verschiedene Körper + Drehgelenk zu erstellen, aber ich kann es nicht so codieren, dass es sich so verhält, wie ich es mir vorstelle. meine Vorstellung

STECHEN:

Auf Knopfdruck würde ein Körper / eine Vorrichtung (Sensor) für ~ 1 Sekunde herauskommen und dann verschwinden (alternativ könnte sich der Körper / die Vorrichtung immer auf dem Helden befinden und sich beim Drücken einfach um 90 Grad um die Eckpunkte drehen, und dann wieder normal drehen)

SCHWINGEN:

Das Gleiche, aber jetzt startet die Waffe von oben und schwingt nach unten. Die Waffe wird auch ein Sensor sein.

Was ich versucht habe:

Ich habe zwei dynamische Körper geschaffen.

Die Waffe muss dem Helden folgen, also habe ich sie mit einem Drehgelenk zusammengehalten. Wenn eine Taste gedrückt wird, setze ich die Winkelgeschwindigkeit der Waffe auf eine Zahl. Die Waffe dreht sich jedoch weiter, nachdem ich den Schlüssel losgelassen habe. Ich habe versucht, eine if-Prüfung durchzuführen (wenn der Winkel größer als ___ ist, setzen Sie die Winkelgeschwindigkeit auf Null). Dies bedeutet jedoch nur, dass sich die Waffe nicht mehr dreht, wenn ich die Taste ein zweites Mal drücke.

quidproquo
quelle
Da Sie die rechteckigen Körper / Vorrichtungen bereits hergestellt haben, müssen Sie den Schwertkörper für die Swing-Animation nur um 90 Grad nach rechts drehen. Außerdem müssen Sie die Kollisionen des Schwertkörpers ausschalten, wenn die Animation nicht auftritt, und sie nicht auf dem Bildschirm zeichnen. Die Stichanimation ist nur eine einfachere Version des Schwungs, bei der das Schwert einen anderen Startwinkel hat. Ist das nicht richtig? Scheint mir ziemlich einfach. Wo bist du geblieben?
dimitris93
Ist das Problem das überlappende Schwert und der Held? Vielleicht könnte ein kleiner quadratischer Körper die Schwertspitze sein, damit er sich nie überlappt. Vielleicht bearbeiten für weitere Informationen
drumbumLOLcatz
@Shiro Ich habe meine Versuche unten eingefügt. Im Moment stecke ich fest, weil ich nicht weiß, wie ich die Drehung mit einem Tastendruck starten und stoppen soll.
quidproquo
Ja, es fühlt sich so an, als ob Ihre eigentliche Frage ist, wie man ein Objekt beim Tastendruck dreht
dimitris93

Antworten:

1

Ich habe übrigens genau das getan, was Sie versuchen. Der einzige Haken ist, dass ich Jbox2d verwendet habe, also ist der Code in Java, aber Sie sollten es trotzdem herausfinden können, wenn Sie C ++ verwenden

Grundsätzlich müssen Sie Gelenke / Motoren und all das lustige Zeug verwenden, wenn Sie schwingende Aktionen ausführen möchten. Hier ist ein Ausschnitt davon, wie mein Code basierend auf der Tasteneingabe aussieht:

    if (myinput.mouse0) {

        agents.get(0).rightForeJoint.enableMotor(true);
        agents.get(0).rightArmJoint.enableMotor(false);    

        if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
            agents.get(0).rightForeJoint.enableMotor(false);
        }

        mouseY = Mouse.getY();
        mouseX = Mouse.getX();
        float temp = mouseY - prevPos[1];

        float temp2 = -mouseX + prevPos[0];

        temp2 *= modifier; temp2 *= 0.000026;
        temp  *= modifier; temp  *= 0.000030;

        agents.get(0).armR.applyAngularImpulse(-temp);
        agents.get(0).foreR.applyAngularImpulse(temp2); 

        prevPos[1] = mouseY;
        prevPos[0] = mouseX;

        if(temp2 < 0){
            temp2 *=-1;
        }
        if(temp < 0){
            temp *=-1;
        }
        fatigueDrain += temp2;
        fatigueDrain += temp;

    }

Und was das Bauen der Arme und so weiter betrifft, sieht das Snippet so aus.

    // RIGHTARM //
    this.rightArmDef = new RevoluteJointDef();
        this.rightArmDef.bodyA = this.torso ; this.rightArmDef.bodyB = this.armR;
        this.rightArmDef.collideConnected = false;

        torso_armL_pin = new Vec2(0.50f, +0.05f);
        local_armL_pin = new Vec2(0.14f, 0.14f);

        this.rightArmDef.localAnchorA.set(this.torso.getLocalCenter().add(torso_armL_pin));
        this.rightArmDef.localAnchorB.set(this.armR.getLocalCenter().add(local_armL_pin));

        this.rightArmDef.enableMotor = true;
        this.rightArmDef.motorSpeed = 0f;
        this.rightArmDef.maxMotorTorque =10f;

        this.rightArmDef.enableLimit = true;
        this.rightArmDef.lowerAngle = 1.2f;// * DEGTORAD;
        this.rightArmDef.upperAngle = 5;
    this.rightArmJoint = (RevoluteJoint)world.createJoint(this.rightArmDef);

Mir ist klar, dass hier viel los ist, aber es ist wahrscheinlich einfacher, wenn Sie mich nur fragen, worüber Sie Klarheit brauchen, und ich erkläre es. Wenn Sie noch nie eines dieser Dinge benutzt haben, müssen Sie wahrscheinlich ein bisschen lesen.

BEARBEITEN >>

In Box2d ist die gesamte Kollisionserkennung und -physik sauber in seine Bibliotheken integriert. Nehmen Sie es auf Glauben, wenn ich sage, es ist einfacher, ihr System herauszufinden, als zu versuchen, Dinge von Grund auf neu zu tun. Wenn Sie eine Kollision wünschen, verwenden Sie Vorrichtungen bodydefs. Wenn Sie möchten, dass sie sich drehen oder bewegen, verwenden Sie Gelenke. Es mag auf den ersten Blick etwas komplizierter erscheinen, aber am Ende sparen Sie unendlich mehr Zeit, um ihre Methoden anzuwenden.

In der Tat würde ich vorschlagen, dass Sie wahrscheinlich nie fertig werden, wenn Sie versuchen, Dinge von Grund auf neu zu machen, vorausgesetzt, Sie erstellen ein Physikspiel. Weil das Berechnen von Dingen wie Reibung, Auftrieb und nicht zu vergessen / effizienter / Kollisionserkennung ein Leben lang dauern wird.

bigcodeszzer
quelle
0

Ich habe eine Art Problemumgehung gefunden, bin mir aber nicht sicher, ob dies eine gute Möglichkeit zum Codieren ist.

Wenn eine Taste gedrückt wird, setze ich die Winkelgeschwindigkeit auf 10 und fordere sie bei jedem Update auf, dies zu überprüfen

    if(weapon.getAngle() >= Math.PI / 2) {
        weapon.setAngularVelocity(-10);
    }
    if(weapon.getAngle() <= 0) {
        weapon.setAngularVelocity(0);
    }
quidproquo
quelle
Im Inneren if(weapon.getAngle() <= 0)sollten Sie es auch manuell in den gewünschten Winkel bringen, da es sonst nicht präzise wird und Sie if-elsestattdessen eine Aussage benötigen if-if. Es kommt auf die grundlegende Java-Codierung an, die nicht wirklich viel mit spielspezifischen Problemen zu tun hat.
dimitris93
0

Nach dem, was Sie sagen, müssen Sie möglicherweise auch einfach den Code verschieben, der die Winkelgeschwindigkeit zurücksetzt, nachdem ein bestimmter Winkel erreicht wurde. Ich vermute, dass dieser Code nur verwendet wird, wenn die Taste gedrückt wird, da Sie sagen, dass ein zweites Drücken der Taste die Bewegung stoppt (und somit den Testcode funktioniert).

Wenn dies der Fall ist, können Sie es nach dem Code, der prüft, ob die Taste gedrückt wird, in eine 'else'-Anweisung verschieben.

Libelle
quelle
0

Sie können auf Befehl eine Methode ausführen, mit der mithilfe von body.getPosition.set () ein Body relativ zur Position des Hauptkörpers erstellt wird. Stellen Sie die Filterbits so ein, dass sie nicht kollidieren, und stellen Sie dann die Lineargeschwindigkeit ein oder wenden Sie Kraft an, unabhängig davon, was Sie nach dem Starten eines Timers vorwärts bewegen möchten, um nach x Anzahl von Spielschleifen zu zerstören

Oder Sie können das Gleiche tun, aber stattdessen ein Distanzgelenk in Kombination mit einem prismatischen Gelenk nur entlang der x-Achse erstellen, um eine plötzliche Verschiebungsbewegung mit einer falsch verbundenen Kollision auszuführen, damit diese Option nicht mit dem Hauptkörper kollidiert wahrscheinlich besser arbeiten,

Für einen Schwungangriff wird ein ähnlicher Körper gedreht, der die Hälfte von pi dreht, wobei nur die Spitze des Schwertes mit dem Hauptkörper verbunden ist, wobei die Kollision natürlich gleich falsch ist. Dann können Sie eine Motorkraft auf das Gelenk ausüben und einen Winkelimpuls auf den Schwertkörper ausüben es zu zerstören, nachdem eine festgelegte Rotation des Körpers erreicht wurde oder eine bestimmte Zeit aufgetreten ist,

Wenn zusätzliche Unterstützung benötigt wird, kommentieren Sie einfach unten

Youseflapod
quelle