极限变焦与游戏摄像头-Libgdx



嗨,伙计们,我对libgdx很陌生,我试着让相机跟随玩家。为了做到这一点,我在网上读到,我不得不添加这行代码

game.getBatch().setProjectionMatrix(gamecam.combined);

通过这样做,我注意到我的游戏真的被放大了,我试图取消它,但我没能让它发挥作用。你们有什么建议吗?这是我渲染玩家的GameScreen

`公共类GameScreen实现Screen{

private Logang game;
//basic playscreen variables
private OrthographicCamera gamecam;
private Viewport gamePort;
//Box2d variables
private World world;
private Box2DDebugRenderer b2dr;
boolean drawn = true;
private Player p;
private int pX = 100, pY = 300;
public GameScreen(Logang game) {
this.game = game;
//create cam used to follow mario through cam world
gamecam = new OrthographicCamera(Logang.GWIDTH, Logang.GHEIGHT);
gamecam.update();
//create our Box2D world, setting no gravity in X, -10 gravity in Y, and allow bodies to sleep
world = new World(new Vector2(0, Logang.GRAVITY), true);
//allows for debug lines of our box2d world.
b2dr = new Box2DDebugRenderer();

//create a FitViewport to maintain virtual aspect ratio despite screen size
gamePort = new ScalingViewport(Scaling.fill, Logang.GWIDTH / Logang.PPM, Logang.GHEIGHT / Logang.PPM, gamecam);
p = new Player(new Sprite(new Texture("badlogic.jpg")), world, pX, pY, 1);
//initially set our gamcam to be centered correctly at the start of of map
//gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2, 0);
line();
}

@Override
public void show() {
}
public void update(float dt) {
//handle user input first
p.update(dt);
//update our gamecam with correct coordinates after changes
/*gamecam.position.set(p.getSprite().getX(),0,0);
gamecam.update();*/
}

@Override
public void render(float delta) {
//separate our update logic from render
update(delta);
//Clear the game screen with Black
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1f / 60f, 6, 2);
gamecam.position.set(p.getSprite().getX(), p.getSprite().getY(), 0); // x and y could be changed by Keyboard input for example
//gamecam.position.set(p.getSprite().getX(), p.getSprite().getY(), 0);
gamecam.update();
game.getBatch().setProjectionMatrix(gamecam.combined);
//renderer our Box2DDebugLines
b2dr.render(world, gamecam.combined);
System.out.println("Player x: " + p.getSprite().getX() + " Camera X: " + gamecam.position.x + " Body X: " + p.getBody().getPosition().x);
//System.out.println("Player y: " + p.getSprite().getY() + " Camera Y: " + gamecam.position.y + " Body Y: " + p.getBody().getPosition().y);

game.getBatch().begin();

if (p.getBody() != null)
p.render(game.getBatch());
EntityManager.renderTerra(game.getBatch(), delta);

game.getBatch().end();
}
public void line() {
Texture tmp = new Texture("dirt.png");
tmp.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
for (int i = 0; i < 10; i++) {
EntityManager.add(new Ground(new Sprite(tmp), world, i * Logang.TILE, 0, 2));
}
//EntityManager.changeSize(Logang.TILE * 5,Logang.TILE);
}
@Override
public void resize(int width, int height) {
//updated our game viewport
gamePort.update(width, height);
}
public World getWorld() {
return world;
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
world.dispose();
b2dr.dispose();
}`

这是我的实体类,它是由我现在清空的播放器扩展的`公共抽象类实体{

private World world;
private Sprite sprite;
private Body body;
private int tipo;
public Entity(Sprite sprite, World world, int x, int y, int tipo){
this.sprite = sprite;
this.world = world;
getSprite().setPosition(x, y);
getSprite().setSize(Logang.TILE, Logang.TILE);
define(tipo);
this.tipo = tipo;
}
public abstract void update(float dt);
public void define(int tipo){
BodyDef bdef = new BodyDef();
bdef.position.set((getSprite().getX() + getSprite().getWidth() / 2) / Logang.PPM, (getSprite().getY() + getSprite().getHeight() / 2) / Logang.PPM);
switch(tipo){
case 1: {
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
case 2:{
bdef.type = BodyDef.BodyType.StaticBody;
break;
}
case 3:{
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
}
body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(getSprite().getWidth() / Logang.PPM / 2, getSprite().getHeight() / Logang.PPM / 2);

fdef.shape = shape;
body.createFixture(fdef);
body.setUserData(this);
shape.dispose();
}
public void render(SpriteBatch batch){
if(tipo != 2) {
float posX = getBody().getPosition().x * Logang.PPM;
float posY = getBody().getPosition().y * Logang.PPM;
getSprite().setPosition(posX - getSprite().getWidth() / 2, posY - getSprite().getHeight() / 2);
}
getSprite().draw(batch);
}
public Sprite getSprite() {
return sprite;
}
public void setSprite(Sprite sprite) {
this.sprite = sprite;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}`

如果我一开始就去掉那条线,游戏尺寸就很好,但我的相机不会跟着我的玩家

谢谢你的回答,如果问题问得不好,很抱歉。

1)如果您的视口尺寸除以Logang.PPM,则所有纹理大小也应除以Logang.PPM。

Logang.TILE应为float并除以Logang.PPM

Player sprite也应调整大小**。

2)要跟随玩家,请尝试将gamecam分辨率除以Logang.PPM

初始化如下:

gamecam = new OrthographicCamera(Logang.GWIDTH / Logang.PPM, Logang.GHEIGHT / Logang.PPM);

UPD:我发现了问题,它在播放器渲染方法中:

float posX = getBody().getPosition().x; // delete  * Logang.PPM
float posY = getBody().getPosition().y; // delete  * Logang.PPM

相机接收两个变量:世界的宽度和高度。这是一个重要的关键字,因为它定义了世界的渲染大小。如果相机的宽度和高度是300x300,这意味着即使屏幕是1920x1080,屏幕上也有300x300个单位可见。

当你这样做:

gamecam = new OrthographicCamera(Logang.GWIDTH, Logang.GHEIGHT);

将摄影机的宽度和高度设置为给定值。

第二次应用:

game.getBatch().setProjectionMatrix(gamecam.combined);

用于渲染的批处理使用相机的投影矩阵,这意味着它会根据同时可见的东西的宽度和高度将屏幕坐标转换为世界坐标。对于一个300x300的实例。

如果你认为世界太小(意味着你渲染的东西显示得太大),你当然可以通过添加比例因子来缩小,但你也可以增加相机的宽度和高度。我不知道你把宽度和高度设置为什么,但如果你增加宽度和高度,它可能会起作用。

正如我已经提到的,世界坐标可以与屏幕坐标不同。

最新更新