【问题标题】:How to make .tmx map fill the whole screen如何使 .tmx 地图填满整个屏幕
【发布时间】:2017-04-09 04:32:57
【问题描述】:

我正在使用 Libgdx 加载 .tmx 地图,但地图没有填满整个屏幕。我无法弄清楚这个问题,所以作为最后的手段,我在这里问一个问题。我正在关注 YouTube 上的教程,但他没有解决这个问题,因此我无法继续。我已经尝试了很多事情但没有成功。地图宽度:240 块,高度:13 块,块为 16 x 16

, .

这是代码。我认为问题与

有关
renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM),
gameCam.position.set(gamePort.getWorldWidth()/2, 
gamePort.getWorldHeight()/2, 0);,
gameCam = new OrthographicCamera(); 
gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);

    public class PlayScreen implements Screen {
    private  DBZ game;
    private OrthographicCamera gameCam;
    private Viewport gamePort;
    private Hud hud;
    private TmxMapLoader maploader;
    private TiledMap map;
    private OrthogonalTiledMapRenderer renderer;

    private World world;
    private Box2DDebugRenderer b2dr;

    private Goku player;
    private TextureAtlas atlas;


    public PlayScreen(DBZ game){
        atlas = new TextureAtlas("goku.pack");
        this.game=  game;
        gameCam = new OrthographicCamera();
        gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);
        hud = new Hud(game.batch);
        maploader= new TmxMapLoader();
        map = maploader.load("level1.tmx");
        renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM);
        gameCam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);
        world = new World(new Vector2(0,-10),true);
        b2dr = new Box2DDebugRenderer();
        new B2WorldCreator(world,map);
        player = new Goku(world, this);
    }

    public TextureAtlas getAtlas(){
        return atlas;
    }

    @Override
    public void show() {

    }

    public void handleInput(float dt){
        if (Gdx.input.isKeyJustPressed(Input.Keys.UP))
            player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && player.b2body.getLinearVelocity().x <= 2)
            player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), player.b2body.getWorldCenter(), true);
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
            player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);

    }

    public void update(float dt){
        handleInput(dt);

        world.step(1/60f, 6, 2);
        player.update(dt);
        gameCam.position.x = player.b2body.getPosition().x;





        gameCam.update();
        renderer.setView(gameCam);

    }

    @Override
    public void render(float delta) {
        update(delta);
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        renderer.render();

        b2dr.render(world, gameCam.combined);

        game.batch.setProjectionMatrix(gameCam.combined);
        game.batch.begin();
        player.draw(game.batch);
        game.batch.end();

        game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
        hud.stage.draw();

    }

    @Override
    public void resize(int width, int height) {
        gamePort.update(width, height);


    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        map.dispose();
        renderer.dispose();
        world.dispose();
        b2dr.dispose();
        hud.dispose();

    }
}

public class DBZ extends Game{
    public SpriteBatch batch;
    public  static final int V_WIDTH = 400;
    public  static final int V_HEIGHT = 208;
    public static final float PPM = 100;


    @Override
    public void create () {
        batch = new SpriteBatch();
        setScreen(new PlayScreen(this));
    }

    @Override
    public void render () {
        super.render();
    }

    @Override
    public void dispose () {
        batch.dispose();
    }
}

public class Goku extends Sprite {
    public World world;
    public Body b2body;
    private TextureRegion gokuStand;

    public Goku(World world, PlayScreen screen){
        super(screen.getAtlas().findRegion("goku_sprite"));
        this.world = world;
        defineGoku();
        gokuStand = new TextureRegion(getTexture(), 5,12,59,85);
        setBounds(0,0,59/DBZ.PPM,85/DBZ.PPM);
        setRegion(gokuStand);

    }

    public void defineGoku(){
        BodyDef bdef = new BodyDef();
        bdef.position.set(32/DBZ.PPM,32/DBZ.PPM);
        bdef.type = BodyDef.BodyType.DynamicBody;
        b2body = world.createBody(bdef);

        FixtureDef fdef = new FixtureDef();
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(59/2/DBZ.PPM, 85/2/DBZ.PPM);

        fdef.shape = shape;
        b2body.createFixture(fdef);

    }

    public void update(float dt){
        setPosition(b2body.getPosition().x - getWidth()/2, b2body.getPosition().y - getHeight()/2 );

    }

}

【问题讨论】:

标签: java android libgdx tiled


【解决方案1】:

问题在于相机的位置,将相机与播放器连接,以便相机的视口覆盖整个屏幕。我正在尝试解决这个问题。

public float gokuStartingPositionX;

public PlayScreen(DBZ game){
    .....
    new B2WorldCreator(world,map);

    gokuStartingPositionX=64/DBZ.PPM;  //added in your method
    player = new Goku(world, this);
} 

public void update(float dt){
    handleInput(dt);

    world.step(1/60f, 6, 2);
    player.update(dt);
    //camera position is decided by player position and keep camera in this way so it cover whole viewport width with screen
    gameCam.position.x = player.b2body.getPosition().x + gamePort.getWorldWidth()/2 - gokuStartingPositionX;

    gameCam.update();
    renderer.setView(gameCam);
}

悟空小改动

public Goku(World world, PlayScreen screen){
    super(screen.getAtlas().findRegion("goku_sprite"));
    this.world = world;
    defineGoku(screen.gokuStartingPositionX);

    gokuStand = new TextureRegion(getTexture(), 5,12,59,85);
    setBounds(0,0,59/DBZ.PPM,85/DBZ.PPM);
    setRegion(gokuStand);

}

public void defineGoku(float startX){
    BodyDef bdef = new BodyDef();
    bdef.position.set(startX,32/DBZ.PPM);
    bdef.type = BodyDef.BodyType.DynamicBody;
    b2body = world.createBody(bdef);
    ... 
}

【讨论】:

  • 我遇到了与其他答案和 Youtube 上某人提供的答案相同的问题。它填充屏幕的整个宽度,但不填充高度或 y 轴。当它在桌面上时,它会填满整个屏幕,但是当我在 Android 上测试它或调整窗口大小时,整个 y 轴都不会被填满。它垂直居中,顶部和底部有一些空间
  • 这是FitViewport亲爱的,否则使用其他视口。
  • 两个答案只需将 fitviewport 更改为 fillviewport 即可。它采用相同的参数,这很好。谢谢。
【解决方案2】:

我相信您正在寻找的是将相机固定在地图上的能力。 这可以使用 MathUtils.clamp 来实现。

gameCam.position.x = MathUtils.clamp(gameCam.position.x, viewportWidth/2 , 38 - viewportWidth/2);
gameCam.position.y = MathUtils.clamp(gameCam.position.y, viewportHeight/2, 208 - viewportHeight/2);

编辑:您更新的 PlayScreen:

package com.edwin.game.Screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.edwin.game.DBZ;
import com.edwin.game.Scenes.Hud;
import com.edwin.game.Sprites.Goku;
import com.edwin.game.Tools.B2WorldCreator;

/**
 * Created by Edwin on 3/20/2017.
 */
public class PlayScreen implements Screen {
private  DBZ game;
private OrthographicCamera gameCam;
private Viewport gamePort;
private Hud hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;

private World world;
private Box2DDebugRenderer b2dr;

private Goku player;
private TextureAtlas atlas;
private float viewportWidth;
private float viewportHeight;


public PlayScreen(DBZ game){
    atlas = new TextureAtlas("goku.pack");
    this.game=  game;
    gameCam = new OrthographicCamera();
    gamePort = new FitViewport(DBZ.V_WIDTH/DBZ.PPM, DBZ.V_HEIGHT/DBZ.PPM, gameCam);


    hud = new Hud(game.batch);
    maploader= new TmxMapLoader();
    map = maploader.load("level1.tmx");


    renderer = new OrthogonalTiledMapRenderer(map, 1/DBZ.PPM);

    viewportWidth = gamePort.getWorldWidth();
    viewportHeight= gamePort.getWorldHeight();

    world = new World(new Vector2(0,-10),true);
    b2dr = new Box2DDebugRenderer();

    new B2WorldCreator(world,map);

    player = new Goku(world, this);


}

public TextureAtlas getAtlas(){
    return atlas;
}

@Override
public void show() {

}

public void handleInput(float dt){
    if (Gdx.input.isKeyJustPressed(Input.Keys.UP))
        player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
    if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && player.b2body.getLinearVelocity().x <= 2)
        player.b2body.applyLinearImpulse(new Vector2(0.5f, 0), player.b2body.getWorldCenter(), true);
    if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
        player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);

}

public void update(float dt){
    handleInput(dt);

    world.step(1/60f, 6, 2);
    player.update(dt);
    gameCam.position.x = player.b2body.getPosition().x;

    // cam pos                          / var to clamp       / min val          / max val
    gameCam.position.x = MathUtils.clamp(gameCam.position.x, viewportWidth/2 , 38 - viewportWidth/2);
    gameCam.position.y = MathUtils.clamp(gameCam.position.y, viewportHeight/2, 208 - viewportHeight/2);

    System.out.println(gameCam.position.x);


    gameCam.update();
    renderer.setView(gameCam);

}

@Override
public void render(float delta) {
    update(delta);
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    renderer.render();
    //

    //

    b2dr.render(world, gameCam.combined);

    game.batch.setProjectionMatrix(gameCam.combined);
    game.batch.begin();
    player.draw(game.batch);
    game.batch.end();

    game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
    hud.stage.draw();

}

@Override
public void resize(int width, int height) {
    gamePort.update(width, height);


}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    map.dispose();
    renderer.dispose();
    world.dispose();
    b2dr.dispose();
    hud.dispose();

}
}

【讨论】:

  • 我用float viewportWidth = gamePort.getWorldWidth(); float viewportHeight= gamePort.getWorldHeight(); gameCam.position.x = MathUtils.clamp(gameCam.position.x, viewportWidth/2 , 400 - viewportWidth/2); gameCam.position.y = MathUtils.clamp(gameCam.position.y, viewportHeight/2, 208 - viewportHeight/2); 替换了gameCam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);,它看起来一样。它没有用。
  • 您需要将此代码添加到您的渲染方法中,以便将其应用于每一帧。仅将其应用于 PlayScreen 构造函数将仅在创建 PlayScreen 时应用一次。
  • 我试过了,还是不行。我在 renderer.render() 正下方添加了该代码;在渲染方法中。如果您可以查看我的 Github 存储库github.com/eochoa5/Dragon-Ball-Z-Bros-,我将不胜感激
  • 现在可以使用了。它填充屏幕的整个宽度,但不填充高度或 y 轴。当它在桌面上时,它会填满整个屏幕,但是当我在 Android 上测试它或调整窗口大小时,整个 y 轴都不会被填满。它垂直居中,顶部和底部有一些空间。
  • 我只能在桌面上进行测试:/ 为了限制 y 轴,您还需要更改 gameCam.position.y 上的 208 = MathUtils.clamp(gameCam.position.y , viewportHeight/2, 208 - viewportHeight/2);换成更合适的数字,比如 15 或者你的等级有多高。
猜你喜欢
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多