Processing / box2d - 使用setTransform()设置对象的位置不按预期工作

时间:2013-03-15 15:58:25

标签: java box2d processing jbox2d

我正在使用处理和box2d进行2D游戏。在我的游戏中,我有一个对象targetBox,它是Box的一个实例。在游戏开始targetBox出现并依赖于跷跷板。游戏的目标是使用吊索射击在跷跷板上发射其他箱子并将targetBox发射到壁架上。如果玩家错过了壁架,那么该箱子将落在一个区域上,99%的时间都不会是跷跷板。

我正在尝试实现允许玩家通过按“r”或“R”将盒子重置到其原始位置(在跷跷板上)的功能。

targetBox最初添加到draw()功能区的box2d世界中:targetBox.display(true);

如果按下'r'或'R'......

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

...调用Box类的重置功能:

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
}

在游戏中,当按下“r”或“R”时,targetBox会消失,并且不会设置为原始位置。我对处理或box2d不太熟悉。有谁知道为什么会这样?帮助赞赏。

编辑 - 添加了更多代码:

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());
    }
}
}

1 个答案:

答案 0 :(得分:2)

我研究了这个功能,它采用世界空间形式的坐标。这意味着如果您使用屏幕格式坐标,您将不会收到错误,但它会在box2d世界中的坐标处传送它。您必须将屏幕形式中所需的坐标转换为空格坐标,如下所示:

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