Libgdx + Box2d使用2个摄像头

时间:2016-03-13 17:41:58

标签: java android libgdx sprite box2d

最近我读到,只要你涉及Box2d,你就可以使用2台摄像机,它只能在米里工作。

在我的Renderer类中,我收到游戏中的所有实体,然后绘制它们。 我使用ashley库,所以我的所有实体都是由组件构成的。

现在,在我的渲染器方法中,我检查当前实体是否有BodyComponent。如果为true,则它会在physicsCam中绘制一个Sprite,其视口为米。否则,它只会在sceneCam中绘制Sprite,它具有像素视口。

我的问题是我尝试根据Body的位置以米为单位绘制Sprite,但它不是精确绘制在身体的位置。

注意:我还有PhysicsDebugSystem,它基本上只调用DebugRenderer.render()方法。

这是我的RenderSystem类:

package engine.systems;

import com.badlogic.ashley.core.Component;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.Array;

import engine.Values;
import engine.components.BodyComponent;
import engine.components.SpriteComponent;
import engine.components.TransformComponent;

public class RenderSystem extends IteratingSystem{

    private SpriteBatch batch;
    private Array<Entity> renderQueue;
    private OrthographicCamera sceneCam;
    private OrthographicCamera physicsCam;
    private ComponentMapper<SpriteComponent> txt;
    private ComponentMapper<TransformComponent> trs;

    @SuppressWarnings("unchecked")
    public RenderSystem(SpriteBatch batch) {
        super(Family.all(TransformComponent.class, SpriteComponent.class).get());
        txt = ComponentMapper.getFor(SpriteComponent.class);
        trs = ComponentMapper.getFor(TransformComponent.class);
        sceneCam = new OrthographicCamera(Values.WIDTH, Values.HEIGHT);
        sceneCam.setToOrtho(false);
        physicsCam = new OrthographicCamera(Values.WIDTH, Values.HEIGHT);
        physicsCam.setToOrtho(false);
        renderQueue = new Array<Entity>();
        this.batch = batch;
    }

    @Override
    public void update(float deltaTime) {
        super.update(deltaTime);
        Gdx.gl.glClearColor(230/255f, 242/255f, 242/255f, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        sceneCam.update();
        physicsCam.update();
        batch.enableBlending();
        batch.begin();
        for (Entity entity : renderQueue) {
            Component comp = entity.getComponent(BodyComponent.class);
            if(comp == null) {
                batch.setProjectionMatrix(sceneCam.combined);
            } else {
                batch.setProjectionMatrix(physicsCam.combined);
            }
            SpriteComponent texture = txt.get(entity);
            TransformComponent transform = trs.get(entity);
            if (texture.region == null || transform.isHidden) {
                continue;
            }
            texture.region.setPosition(transform.position.x, transform.position.y);
            texture.region.setRotation(transform.rotation);
            texture.region.setScale(transform.scale.x, transform.scale.y);
            texture.region.draw(batch);
        }
        batch.end();
        renderQueue.clear();
    }

    @Override
    protected void processEntity(Entity entity, float deltaTime) {
        renderQueue.add(entity);
    }

    public OrthographicCamera getCamera() {
        return sceneCam;
    }

}

在我的GameWorld课程中,我用这种方法构建球:

public void initBall() {
        Entity entity = new Entity();
        float x = Values.WIDTH/2*Values.PPM;
        float y = Values.HEIGHT*Values.PPM;
        SpriteComponent txt = new SpriteComponent();
        txt.region = skin.getSprite("soccerball");
        txt.region.setSize(Values.BALL_WIDTH, Values.BALL_HEIGHT);
        entity.add(txt);
        TransformComponent trs = new TransformComponent();
        trs.isHidden = false;
        trs.position.x = x;
        trs.position.y = y;
        entity.add(trs);
        BodyComponent bc = new BodyComponent();
        BodyDef bodyDef = new BodyDef();
        // Set our body to dynamic
        bodyDef.type = BodyDef.BodyType.DynamicBody;

        // Set our body's starting position in the world
        bodyDef.position.set(x, y+Values.BALL_HEIGHT/2);
        bc.body = world.createBody(bodyDef);
        bc.body.applyAngularImpulse(50f, true);

        CircleShape circle = new CircleShape();
        circle.setRadius(Values.BALL_WIDTH/2f);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circle;
        fixtureDef.density = 20f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f;
        bc.body.createFixture(fixtureDef);
        circle.dispose();
        entity.add(bc);
        engine.addEntity(entity);
    }

这是我在模拟过程中拍摄的截图: https://i.imgsafe.org/053cfa2.png

1 个答案:

答案 0 :(得分:0)

你的球精灵似乎是从你的box2d身体偏移的原因是因为你的纹理的锚是它的左下角,这意味着当你设置你的纹理位置时基本上设置了它左下角的位置。为了正确定位你的球,你需要从它的位置减去它的半宽和半高:

+++++++++++++++++++++++++++++++++++++++++++++++++
NAME | PRODUCTS_BOUGHT | PPL_BUYING_SAME_PRODUCTS
Bob  | 3               | 2
Amy  | 2               | 1
Chris| 1               | 1
+++++++++++++++++++++++++++++++++++++++++++++++++

我还会催促你read this box2d blog post,因为从你发布的代码中,你似乎没有扩展你的box2d entites,这意味着你拥有的那个球是final float halfWidth = texture.region.getRegionWidth() * 0.5f; final float halfHeight = texture.region.getRegionHeight() * 0.5f; texture.region.setPosition(transform.position.x - halfWidth, transform.position.y - halfHeight); METERS宽。从截图来看,它看起来像是半径2.5米。那是一个巨大的球!