简体   繁体   中英

Processing / box2d - using setTransform() to set position of object not working as expected

I'm making a 2d game using processing and box2d. In my game I have an object targetBox that is an instance of Box . On game start targetBox appears and rests on a see-saw. The goal of the game is to use a sling shot to fire other boxes at the see-saw and launch the targetBox onto a ledge. If the player misses the ledge the box will land on an area, that 99% of the time, won't be the see-saw.

I'm trying to implement functionality that will allow the player to reset the box to its original place (on the see-saw) by pressing 'r' or 'R'.

targetBox is initially added to the box2d world in the draw() funciton: targetBox.display(true);

If 'r' or 'R' is pressed...

if(key == 'R' || key == 'r')
{
    targetBox.reset();
}

...call reset function of Box class:

public void reset()
{
    body.setTransform(new Vec2(width/2+75, height-70), body.getAngle());
    // width and height are same as values given to targetBox when it's created
}

In game, when 'r' or 'R' is pressed, targetBox just disappears and does not get set to its original position. I'm not too familiar with processing or box2d. Does anyone know why this happening? Help appreciated.

EDIT - added more code:

public class Main extends PApplet 
{

public static void main(String[] args) 
{
    PApplet.main(new String[] { "Main" });
}

PBox2D box2d;
Box targetBox;

public void setup() 
{
    size(800, 600);
    smooth();
    // initialize box2d and world
    box2d = new PBox2D(this);
    box2d.createWorld();
    // targetBox to get on ledges
    targetBox = new Box(width/2+75, height-70); 
}

public void draw() 
{
    background(255);
    // always step through time
    box2d.step();
    // draw the targetBox
    targetBox.display(true);
}

public void keyPressed()
{
    if(key == 'R' || key == 'r')
    {
        targetBox.reset();
    }
}

// a class that represents a box
class Box 
{
    // We need to keep track of a Body and a width and height
    Body body;
    FixtureDef fd;
    float w;
    float h;

    // Constructor
    Box(float X, float Y) 
    {
        float x = X;
        float y = Y;
        w = 24;
        h = 24;
        // Add the box to the box2d world
        makeBody(new Vec2(x,y),w,h);
    }

    // This function removes the particle from the box2d world
    public void killBody() 
    {
        box2d.destroyBody(body);
    }

    boolean contains(float x, float y) 
    {
        Vec2 worldPoint = box2d.coordPixelsToWorld(x, y);
        Fixture f = body.getFixtureList();
        boolean inside = f.testPoint(worldPoint);
        return inside;
    }

    // Drawing the box
    public void display(boolean isFirst)
    {
        // We look at each body and get its screen position
        Vec2 pos = box2d.getBodyPixelCoord(body);
        // Get its angle of rotation
        float a = body.getAngle();

        if(isFirst == true)
        {
            rectMode(PConstants.CENTER);
            pushMatrix();
            translate(pos.x,pos.y);
            rotate(a);
            fill(255,0,0);
            stroke(0);
            rect(0,0,w,h);
            popMatrix();
        }
        else
        {
            rectMode(PConstants.CENTER);
            pushMatrix();
            translate(pos.x,pos.y);
            rotate(a);
            fill(175);
            stroke(0);
            rect(0,0,w,h);
            popMatrix();
        }
    }

    // This function adds the rectangle to the box2d world
    public void makeBody(Vec2 center, float w_, float h_) 
    {
        // Define and create the body
        BodyDef bd = new BodyDef();
        bd.type = BodyType.DYNAMIC;
        bd.position.set(box2d.coordPixelsToWorld(center));
        body = box2d.createBody(bd);

        // Define a polygon (this is what we use for a rectangle)
        PolygonShape sd = new PolygonShape();
        float box2dW = box2d.scalarPixelsToWorld(w_/2);
        float box2dH = box2d.scalarPixelsToWorld(h_/2);
        sd.setAsBox(box2dW, box2dH);

        // Define a fixture
        fd = new FixtureDef();
        fd.shape = sd;
        // Parameters that affect physics
        fd.density = 2.5f;
        fd.friction = 2f;
        fd.restitution = 0.2f;

        body.createFixture(fd);
        //body.setMassFromShapes();

        // Give it some initial random velocity
        body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5)));
        body.setAngularVelocity(random(-5, 5));
    }

    // reset box to initial position
    public void reset()
    {
        body.setTransform(new Vec2(width/2+75, height-70), body.getAngle());
    }
}
}

I researched this function and it takes coordinates in world space form . This means that if you use screen form coordinates, you won't get an error, but it will teleport it wherever the coordinates are in the box2d world. You have to convert it your desired coordinates in screen form into the space coordinates like this:

    body.setTransform(box2d.coordPixelsToWorld(x,y),0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM