0
votes

I have a revolute joint which connects a rotator body with an arrow body, but I am stuck on how to make the arrow have the same position every time. Need the arrow body to be set at the same angle at which it was fired previously.

Here is my code:

I use a button to fire my arrow

FIREBUTTON.addListener(new InputListener()
    {
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
        {
            world.destroyBody(rotatorBody);
            arrowBody.applyLinearImpulse(300 * MathUtils.cos(joint.getJointAngle()), 300 * MathUtils.sin(joint.getJointAngle()), arrowBody.getWorldCenter().x, arrowBody.getWorldCenter().y, true);
                return true;
        }

        public void touchUp(InputEvent event, float x, float y, int pointer, int button)
        {
            reload();
        }
    });

and this is my reload()

public void reload()
{
    arrowSprite = new Sprite(new Texture(Gdx.files.internal("sprites/arrow3.png")));
    arrowSprite.setSize(4f, 2f);                                //setting the size of the sprite
    arrowSprite.setOrigin(arrowSprite.getWidth()/2,arrowSprite.getHeight()/2); //setting the centre of the sprite to the centre of the body

    /***ARROW BODY***/

    //DEFINE the definition of the arrow body
    arrowBodyDef = new BodyDef();
    arrowBodyDef.type = BodyType.DynamicBody;


    arrowBodyShape = new PolygonShape();
    arrowbodyPolygon = new Polygon(new float[]
                                    {
                                        -0.125f*3, -0.25f*3,
                                        0.125f*3, -0.25f*3,
                                        0.25f*3, 0.25f*3,
                                        0*3, 0.5f*3,
                                        -0.25f*3, 0.25f*3
                                    });     
    //arrowbodyPolygon.setOrigin(0*3, 0.5f*3);
    arrowbodyPolygon.rotate(-90);
    arrowBodyShape.set(arrowbodyPolygon.getTransformedVertices());
    arrowBody = world.createBody(arrowBodyDef);
    arrowBody.createFixture(arrowBodyShape, 2.0f);
    arrowBody.setUserData(arrowSprite);

    /***ROTATOR CIRCLE BODY***/

    rotatorBodyDef = new BodyDef();
    rotatorBodyDef.type = BodyType.KinematicBody;
    rotatorBodyDef.position.set(-90,-15);

    rotatorCircleShape = new CircleShape();
    rotatorCircleShape.setRadius(0.5f);
    rotatorBody = world.createBody(rotatorBodyDef);
    rotatorBody.createFixture(rotatorCircleShape, 1.0f);


    /*** REVOLUTE JOINT THAT JOINS THE ROTATOR BODY TO THE ARROWBODY ***/
    revoluteJointDef = new RevoluteJointDef();
    revoluteJointDef.bodyA = rotatorBody;
    revoluteJointDef.bodyB = arrowBody;
    revoluteJointDef.localAnchorA.set(Vector2.Zero);
    revoluteJointDef.localAnchorB.set(Vector2.Zero);
    revoluteJointDef.maxMotorTorque = 250;
    revoluteJointDef.enableMotor = true;

    joint = (RevoluteJoint) world.createJoint(revoluteJointDef);
}

I am really stuck on how to make the arrow reload at the same position as before, any ideas ?

I have added an image so basically the first picture shows what happens when the joints and bodies are created it starts with the arrow pointing to the right, if i rotate the arrow 45 degrees to the left as shown in picture 2 then when i fire the arrow it reloads the arrow but this time the arrow is pointing upwards. I want the arrow to be created and pointing in the same angle where it was left off last time. Is it making more sense now ? enter image description here

1
This kinda needs a diagram I think...iforce2d
I added two diagrams to show what i meant hopefully this will helpuser3197976

1 Answers

0
votes

You need to store the angle of the RevoluteJoint after firing the arrow. The problem is that there is no setJoingAngle() for RevoluteJoint, but you can set it for the creation of the body so the body itself will be rotated itself instead of the joint.

private float arrowAngle;

// in your listener
arrowAngle = joint.getJoingAngle(); // store it here
world.destroyBody(rotatorBody);
arrowBody.applyLinearImpulse(300 * MathUtils.cos(joint.getJointAngle()), 300 * MathUtils.sin(joint.getJointAngle()), arrowBody.getWorldCenter().x, arrowBody.getWorldCenter().y, true);
            return true;

// in your reload() method
arrowBodyDef = new BodyDef();
arrowBodyDef.type = BodyType.DynamicBody;
arrowBodyDef.angle = arrowAngle; // set it on your body