Libgdx Box2D如何将图片设置为物体的一部分

7
我有一个关于将图片设置为动态/静态主体的问题。
我找到了一个与此相关的Flash代码。
public void setImage()
{
    sprite = new B2Sprite();
    var bitmap:Bitmap = new Image();
    sprite.addChild();
    bitmap.x -= bitmap.width / 2;
    bitmap.y -= bitmap.height / 2;
    body.SetUserData(sprite);
    sprite.body = body;
}

但是要将它转换为Java :( 请问有人能帮我或者提供关于在Java上使用box2D的教程链接吗?

你是否在使用一些框架,比如AndEngine或其他的? - Pavel
看起来他正在使用LibGDX。 - jellyfication
3个回答

9

您有一个非常有用的链接,关于box2D和libgdx教授逻辑和渲染的概念。这里

然后您可以按照以下方式将逻辑部分与渲染部分分开:

逻辑部分:

private void createBottleBody() {
    // 0. Create a loader for the file saved from the editor.
    BodyEditorLoader loader = new BodyEditorLoader(sourceFile);

    // 1. Create a BodyDef, as usual.
    BodyDef bd = new BodyDef();
    bd.position.set(0, 0);
    bd.type = BodyType.DynamicBody;

    // 2. Create a FixtureDef, as usual.
    FixtureDef fd = new FixtureDef();
    fd.density = 1;
    fd.friction = 0.5f;
    fd.restitution = 0.3f;

    // 3. Create a Body, as usual.
    bottleModel = world.createBody(bd);

    // 4. Create the body fixture automatically by using the loader.
    loader.attachFixture(bottleModel, "test01", fd, BOTTLE_WIDTH);
}

渲染部分:

public void render() {
    Vector2 bottlePos = bottleModel.getPosition().sub(bottleModelOrigin);

    bottleSprite.setPosition(bottlePos.x, bottlePos.y);
    bottleSprite.setOrigin(bottleModelOrigin.x, bottleModelOrigin.y);
    bottleSprite.setRotation(bottleModel.getAngle() * MathUtils.radiansToDegrees);

    ...
}

加载器:在链接中可以找到一个加载器。
public void attachFixture(Body body, String name, FixtureDef fd, float scale) {

    //Load the rigidModel by key
    RigidBodyModel rbModel = (RigidBodyModel) this.model.rigidBodies.get(name);

    if (rbModel == null)
        throw new RuntimeException("Name '" + name + "' was not found.");

    //Loading polygons
    Vector2 origin = this.vec.set(rbModel.origin).mul(scale);
    Vector2[] vertexes;
    PolygonModel polygon;

    for (int i = rbModel.polygons.size()-1; 0 <= i; i--) {
        polygon = (PolygonModel) rbModel.polygons.get(i);
        vertexes = polygon.vectorBuffer;

        //Loading vertexes (scaled) from polygon
        for (int ii = vertexes.length-1; 0 <= ii; ii--) {
            vertexes[ii] = new Vector2().set((Vector2) polygon.vertices.get(ii)).mul(scale);
            vertexes[ii].sub(origin);
        }

        //sets vertexs to polygon
        this.polygonShape.set(vertexes);
        fd.shape = this.polygonShape;
        body.createFixture(fd);

    }


    //Loading circles
    CircleModel circle;
    Vector2 center;
    float radius;

    for (int i = rbModel.circles.size()-1; 0 <= i; i--) {
        circle = (CircleModel) rbModel.circles.get(i);
        center = new Vector2().set(circle.center).mul(scale);
        radius = circle.radius * scale;

        this.circleShape.setPosition(center);
        this.circleShape.setRadius(radius);
        fd.shape = this.circleShape;
        body.createFixture(fd);

    }
}

最后...模型
public static class CircleModel {
    public final Vector2 center = new Vector2();
    public float radius;
}

public static class PolygonModel {
    public final List<Vector2> vertices = new ArrayList<Vector2>();
    private Vector2[] vectorBuffer;
}

public static class RigidBodyModel {
    public String name;
    public String imagePath;
    public final Vector2 origin = new Vector2();
    public final List<PolygonModel> polygons = new ArrayList<PolygonModel>();
    public final List<CircleModel> circles = new ArrayList<CircleModel>();
}

public static class Model {
    public final Map<String, RigidBodyModel> rigidBodies = new HashMap<String, RigidBodyModel>();
}

希望这能有所帮助!

链接已失效。 - Zoe stands with Ukraine

5

鉴于您的问题标记为LibGDX,使用Sprites将更方便。

public void setImage(Sprite sprite){
    body.setUserData(sprite);
}

然后在 render() 中,可能会有这样的内容。
private SpriteBatch batch = new SpriteBatch();
public void render() {
    batch.begin();
    Iterator<Body> iter = world.getBodies();
    Body body;
    Sprite sprite;
    while (iter.hasNext()) {
        body = iter.next();
        sprite = (Sprite) body.getUserData();
        // I did not take a look at implementation but you get the idea
        sprite.x = body.x;
        sprite.y = body.y;
        sprite.draw(batch);
    }
    batch.end();  
}

在it技术方面,编写一个包装类来封装body,并添加方法getImage(),返回一个具有适当位置、旋转等属性的sprite不失为一种好的想法。

请注意,我没有测试我的代码,可能会存在错误。


xball = PIXELS_PER_METER*(theBall.getWorldCenter().x)-sprite.getWidth()/2; yball = PIXELS_PER_METER*(theBall.getPosition().y)-sprite.getHeight()/2;batch_sprite.begin(); sprite.draw(batch_sprite); sprite.setX(xball); sprite.setY(yball); batch_sprite.end(); - Methnani Bilel

4
public void create()
{texture = new Texture(Gdx.files.internal("data/ball.png"));
sprite = new Sprite(texture,0,0,32,32);
batch_sprite = new SpriteBatch();
.....
}
public void render()
{
....
xball=PIXELS_PER_METER*(theBall.getWorldCenter().x)-sprite.getWidth()/2;
yball=PIXELS_PER_METER*(theBall.getPosition().y)-sprite.getHeight()/2;

batch_sprite.begin();
sprite.draw(batch_sprite);
sprite.setX(xball);
sprite.setY(yball);
batch_sprite.end();
....}

由于重力和加速度的影响,精灵延迟,但使用重力 = Vector2(0.0f, -1.1f) 的情况下可以正常工作,这正是我想要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接