【问题标题】:Processing / box2d - using setTransform() to set position of object not working as expectedProcessing / box2d - 使用 setTransform() 设置对象的位置未按预期工作
【发布时间】:2013-03-15 15:58:25
【问题描述】:

我正在使用处理和 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类的reset函数:

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

【问题讨论】:

  • 需要更多代码。如果可能的话,在代码中或作为 jsfiddle 的简化最小示例,以便我们可以查看您是否正确使用 box2d 会有很大帮助。没有它,就不可能知道你是否真的在更新东西,或者只是设置属性而不让 box2d 提交它们。
  • 请参阅编辑 - 很抱歉延迟回复您。

标签: java box2d processing jbox2d


【解决方案1】:

我研究了这个函数,它采用世界空间形式的坐标。这意味着,如果您使用 screen form 坐标,您不会收到错误,但它会传送到 box2d 世界中坐标所在的任何位置。您必须将其以屏幕形式转换为所需的坐标,如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-03
    • 2013-10-12
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多