Creazione di un'arma da mischia in Box2D (libGDX)


10

Sto lottando con come implementare un'arma da mischia che può oscillare quando viene premuto un tasto.

Sto immaginando due diversi attacchi (stab e swing)

Ho provato a creare due dispositivi (personaggio + arma), due corpi diversi, due corpi diversi + giunto rotante, ma non riesco a codificarlo per comportarsi come immagino che assomigli. la mia immaginazione

STAB:

Quindi con la pressione di un pulsante, un corpo / apparecchio (sensore) verrebbe fuori per ~ 1 secondo e poi scomparire (in alternativa, il corpo / apparecchio potrebbe sempre essere sull'eroe e ruotare di 90 gradi attorno ai vertici quando premuto, e quindi tornare alla normalità)

SWING:

Stessa cosa, ma ora l'arma inizierà dall'alto e oscillerà verso il basso. L'arma sarà anche un sensore.

Cosa ho provato:

Ho creato due corpi dinamici.

L'arma deve seguire l'eroe, quindi ho usato un giunto rotante per tenerli insieme. Quando viene premuto un tasto, imposto la velocità angolare dell'arma su un numero. Tuttavia, l'arma continuerà a girare dopo che ho lasciato andare la chiave. Ho provato a implementare un controllo if (se l'angolo è maggiore di ___, impostare la velocità angolare su zero). Tuttavia, ciò significa che l'arma smetterà di girare quando premo il tasto una seconda volta.


Dato che hai già realizzato i corpi / dispositivi a forma di rettangolo, per l'animazione dell'oscillazione dovresti solo ruotare il corpo della spada di 90 gradi a destra. Inoltre, è necessario disattivare le collisioni del corpo della spada quando l'animazione non si verifica e non disegnarla sullo schermo. L'animazione della pugnalata è solo una versione più semplice dell'oscillazione, in cui la spada ha un diverso angolo iniziale. Non è vero? Mi sembra abbastanza semplice. Dove ti sei bloccato?
dimitris93,

Il problema è la spada e l'eroe sovrapposti? forse un piccolo corpo quadrato potrebbe essere la punta della spada in modo che non si sovrapponga mai. forse modificarlo per qualche informazione in più
drumbumLOLcatz

@Shiro ho incluso i miei tentativi in ​​fondo. In questo momento sono bloccato perché non so come avviare e arrestare la rotazione premendo un tasto.
quidproquo,

Sì, sembra che la tua vera domanda sia come ruotare un oggetto alla pressione dei tasti
dimitris93,

Risposte:


1

Per inciso, ho fatto esattamente quello che stai cercando di fare. L'unico problema è che stavo usando Jbox2d, quindi il codice è in Java, ma dovresti essere ancora in grado di capirlo se stai usando C ++

Fondamentalmente devi usare giunti / motori e tutte quelle cose divertenti se vuoi fare un'azione oscillante. Ecco uno snippet di come appare il mio codice basato sull'input chiave:

    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;

    }

E poi per quanto riguarda effettivamente la costruzione delle armi e quant'altro, lo snippet si presenta così.

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

Mi rendo conto che qui sta succedendo molto, ma probabilmente è più facile se mi chiedi su cosa hai bisogno di chiarezza e te lo spiego. Se non hai mai usato nessuna di queste cose, probabilmente avrai bisogno di leggere un bel po '.

EDIT >>

Realizza, Box2d ha tutto il rilevamento delle collisioni e la fisica integrata nelle sue librerie. Dagli fede quando dico che è più facile capire il loro sistema che provare a fare le cose da zero. Se si desidera una collisione, si utilizzano infissi bodydefs, se si desidera che ruotino o si muovano, si utilizzano giunti. All'inizio può sembrare un po 'più complicato, ma alla fine ti fa risparmiare infinitamente più tempo per usare i loro metodi.

In effetti, suggerirei che probabilmente non finirai mai se provi a fare le cose da zero, supponendo che tu stia creando un gioco di fisica. Perché calcolare cose come attrito, galleggiamento e, per non parlare, / rilevamento efficiente / di collisione, ti richiederà una vita.


0

Ho trovato una sorta di soluzione alternativa, ma non sono sicuro che questo sia un buon modo per codificare.

Quando viene premuto un tasto, imposto la velocità angolare su 10 e quindi ad ogni aggiornamento, chiedo di controllarlo

    if(weapon.getAngle() >= Math.PI / 2) {
        weapon.setAngularVelocity(-10);
    }
    if(weapon.getAngle() <= 0) {
        weapon.setAngularVelocity(0);
    }

Al suo interno if(weapon.getAngle() <= 0)dovresti anche metterlo manualmente nell'angolazione specifica che desideri, altrimenti non sarà preciso e avrai bisogno di una if-elsedichiarazione invece di if-if. Dipende dalla codifica Java di base non molto da fare con il problema specifico del gioco.
dimitris93,

0

Da quello che stai dicendo, sembra che potresti dover semplicemente spostare il codice che reimposta la velocità angolare dopo aver raggiunto un determinato angolo. Sospetto che questo codice venga utilizzato solo quando si preme il pulsante, poiché si dice che premendo il pulsante una seconda volta si interrompe il movimento (e quindi si attiva il codice di test).

In tal caso, è possibile spostarlo in un'istruzione 'else' dopo il codice che verifica se viene premuto il tasto.


0

Una cosa che potresti fare è a comando, eseguire un metodo che crei un corpo relativo alla posizione del corpo principale usando body.getPosition.set (); imposta i bit del filtro in modo che non si scontrino, quindi imposta la velocità lineare o applica la forza, qualunque cosa tu voglia spostare in avanti dopo aver avviato un timer per distruggere dopo x quantità di loop di gioco

Oppure potresti fare la stessa cosa, ma invece creare un giunto a distanza combinato con un giunto prismatico solo lungo l'asse x per rendere improvvisa una spinta improvvisa con collisione collegata in modo che non si scontri con il corpo principale questa opzione probabilmente funziona meglio,

per un attacco di oscillazione creare un corpo simile ruotato della metà di pi con solo la punta della spada collegata al corpo principale con una collisione collegata allo stesso falso naturalmente, quindi è possibile applicare una forza motoria sull'articolazione un impulso angolare sul corpo della spada distruggendolo dopo che è stata raggiunta una rotazione prestabilita del corpo o si è verificato un certo tempo,

se è necessaria ulteriore assistenza, basta commentare di seguito

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.