Crear un arma cuerpo a cuerpo en Box2D (libGDX)

10

Estoy luchando sobre cómo implementar un arma cuerpo a cuerpo que pueda balancearse cuando se presiona una tecla.

Estoy imaginando dos ataques diferentes (puñalada y swing)

He intentado crear dos accesorios (personaje + arma), dos cuerpos diferentes, dos cuerpos diferentes + junta giratoria, pero no puedo codificarlo para que se comporte de la manera que imagino. mi imaginación

PUÑALADA:

Entonces, con solo presionar un botón, un cuerpo / dispositivo (sensor) saldría por ~ 1 segundo y luego desaparecería (alternativamente, el cuerpo / dispositivo siempre podría estar en el héroe y simplemente rotar 90 grados alrededor de los vértices cuando se presiona, y luego gire de nuevo a la normalidad)

COLUMPIO:

Lo mismo, pero ahora el arma comenzará desde arriba y se balanceará hacia abajo. El arma también será un sensor.

Lo que he intentado:

Creé dos cuerpos dinámicos.

El arma tiene que seguir al héroe, así que usé una articulación revolutiva para mantenerlos unidos. Cuando se presiona una tecla, configuro la velocidad angular del arma en un número. Sin embargo, el arma continuará girando después de soltar la llave. Intenté implementar una verificación if (si el ángulo es mayor que ___, establezca la velocidad angular en cero). Sin embargo, eso solo significa que el arma dejará de girar cuando presione la tecla por segunda vez.

quid pro quo
fuente
Como ya ha realizado los cuerpos / accesorios en forma de rectángulo, solo tendría que girar el cuerpo de la espada 90 grados hacia la derecha para la animación del swing. También debe desactivar las colisiones del cuerpo de la espada, cuando no se produce la animación, y no dibujarla en la pantalla. La animación de puñalada es solo una versión más simple de swing, donde la espada tiene un ángulo de inicio diferente. ¿No es así? Me parece bastante simple. ¿Dónde te quedaste?
dimitris93
¿Es el problema la superposición de la espada y el héroe? Tal vez un pequeño cuerpo cuadrado podría ser la punta de la espada para que nunca se superponga. tal vez edite para obtener más información
drumbumLOLcatz
@ Shiro incluí mis intentos en la parte inferior. En este momento estoy atascado porque no sé cómo iniciar y detener la rotación con solo presionar una tecla.
quidproquo
Sí, parece que su pregunta real es cómo rotar un objeto al presionar una tecla
dimitris93

Respuestas:

1

Por cierto, he hecho exactamente lo que estás tratando de hacer. El único inconveniente es que estaba usando Jbox2d, por lo que el código está en Java, pero aún así debería poder resolverlo si está usando C ++

Básicamente, necesitas usar articulaciones / motores y todas esas cosas divertidas si quieres hacer una acción de balanceo. Aquí hay un fragmento de cómo se ve mi código basado en la entrada clave:

    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;

    }

Y luego, en cuanto a la construcción de los brazos y demás, el fragmento se ve así.

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

Me doy cuenta de que están sucediendo muchas cosas aquí, pero probablemente sea más fácil si me preguntas sobre qué necesitas claridad y te lo explico. Sin embargo, si nunca ha usado alguna de estas cosas, probablemente tendrá que leer bastante.

EDITAR >>

Tenga en cuenta que Box2d tiene toda la detección de colisiones y la física integrada en sus bibliotecas. Tómelo con fe cuando digo que es más fácil descubrir su sistema que tratar de hacer las cosas desde cero. Si desea colisión, utiliza accesorios bodydefs, si desea que giren o se muevan, use juntas. Puede parecer un poco más complicado al principio, pero al final le ahorra infinitamente más tiempo para usar sus métodos.

De hecho, sugeriría que probablemente nunca terminarás si intentas hacer cosas desde cero, suponiendo que estés creando un juego de física. Porque calcular cosas como la fricción, la flotabilidad y, por no mencionar, la detección eficiente / de colisión, te llevará toda la vida.

bigcodeszzer
fuente
0

He encontrado algún tipo de solución, pero no estoy seguro de si es una buena forma de codificar.

Cuando se presiona una tecla, configuro la velocidad angular en 10 y luego en cada actualización, le pido que verifique

    if(weapon.getAngle() >= Math.PI / 2) {
        weapon.setAngularVelocity(-10);
    }
    if(weapon.getAngle() <= 0) {
        weapon.setAngularVelocity(0);
    }
quid pro quo
fuente
En el interior if(weapon.getAngle() <= 0), también debe colocarlo manualmente en el ángulo específico que desee, de lo contrario no será preciso y necesita una if-elsedeclaración en lugar de if-if. Todo se reduce a la codificación básica de Java que no tiene mucho que ver con un problema específico del juego.
dimitris93
0

Por lo que está diciendo, parece que también podría tener que simplemente mover el código que restablece la velocidad angular después de alcanzar un cierto ángulo. Sospecho que este código solo se usa cuando se presiona el botón, ya que usted dice que presionar el botón por segunda vez hace que el movimiento se detenga (y así hace que el código de prueba funcione).

Si este es el caso, puede moverlo a una instrucción 'else' después del código que prueba si se presiona la tecla.

libélula
fuente
0

Una cosa que puede hacer es en el comando, ejecute un método que cree un cuerpo relativo a la posición del cuerpo principal usando body.getPosition.set (); configura los bits del filtro para que no choquen, luego configura la velocidad lineal o aplica la fuerza, lo que quieras mover hacia adelante después de iniciar un temporizador para destruir después de x cantidad de bucles de juego

O podría hacer lo mismo, pero en lugar de crear una junta de distancia combinada con una junta prismática solo a lo largo del eje x para hacer un movimiento de empuje repentino con colisión conectada como falsa para que no colisione con el cuerpo principal, esta opción probablemente funcione mejor

para un ataque de swing, cree un cuerpo similar que gire la mitad de pi con solo la punta de la espada conectada al cuerpo principal con colisión conectada a igual falso, por supuesto, entonces puede aplicar fuerza motora en la articulación un impulso angular sobre el cuerpo de la espada destruyéndolo después de que se logra una rotación establecida del cuerpo o ha ocurrido un cierto tiempo,

Si necesita asistencia adicional, solo comente a continuación

Youseflapod
fuente