【发布时间】:2016-03-13 17:41:58
【问题描述】:
最近我读到,只要涉及 Box2d,您就可以使用 2 个摄像头,它只能以米为单位。
在我的 Renderer 类中,我接收游戏中的所有实体,然后绘制它们。
我使用 ashley 库,所以我的所有实体都是由组件组成的。
现在,在我的渲染器方法中,我检查当前实体是否有BodyComponent。如果为真,那么它会在 physicsCam 中绘制 Sprite,它的视口为米。否则,它只会在具有像素视口的 sceneCam 中绘制 Sprite。
我的问题是我尝试根据身体的位置(以米为单位)绘制 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);
}
这是我在模拟过程中截取的屏幕截图:
【问题讨论】:
-
我阅读了这篇文章,但我仍然不明白我的代码有什么问题。我为 GUI 使用一台相机,为物理世界使用一台相机。为什么还是不行?
-
只需使用一台相机。该屏幕截图中没有任何内容可以使用香蕉单位。不要让事情变得更难。
标签: java android libgdx sprite box2d