LibGDX - 在 Tilemap 上按照坐标放置纹理时出现问题

问题描述 投票:0回答:1

我正在做一个小java游戏作为学校项目。我已经使用平铺工具创建了一个平铺地图,并且地图显示正确。在我的地图上,我想制作瀑布动画,为此,我将对象图层放置在图块地图中,然后在 Java 中检索(地图上的对象坐标、大小等)。

问题就在这里:我以纹理的形式加载图像,该图像也用于制作我的图块地图,我将其分割以获取正确的图块并将其放置在对象坐标处,但纹理显示在地图之外。出于测试目的,我尝试将纹理放置在鼠标的坐标处。

我在互联网上发现你必须使用camera.unproject,它确实可以工作,但只有在没有setToOrtho的情况下。

所以我向堆栈溢出寻求帮助,谢谢!

这里是 github 上的代码,供那些想要运行完整测试的人使用:

https://github.com/UniLasalle-Amiens/TP_JAVA-Boats-Management

其他:

public class MyGdxGame extends ApplicationAdapter {

    private static final int TILESET_COLS = 26, TILESET_ROWS = 15, TILE_WIDTH = 32, TILE_HEIGHT = 32;

    private AssetManager assetManager;

    private TiledMap map;

    private Texture tileSheet;

    private OrthogonalTiledMapRenderer tilemapRenderer;

    // Camera
    private OrthographicCamera camera;

    private SpriteBatch batch;
    private BitmapFont font;

    // Animation des chûtes d'eau
    private Animation<TextureRegion> waterFallAnimation;
    private List<Rectangle> waterFallRectangles = new LinkedList<Rectangle>();
    private float _waterFallStateTime = 0;

    @Override
    public void create() {
        batch = new SpriteBatch();

        // Asset manager
        assetManager = new AssetManager();
        assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
        assetManager.load("Map.tmx", TiledMap.class);

        // Chargement de la texture 32x32.png
        assetManager.setLoader(Texture.class, new TextureLoader(new InternalFileHandleResolver()));
        assetManager.load("Tiles/32x32.png", Texture.class);

        assetManager.finishLoading();

        map = assetManager.get("Map.tmx");
        tileSheet = assetManager.get("Tiles/32x32.png");

        // Mise en place de la caméra dans la scène
        camera = new OrthographicCamera();
        camera.setToOrtho(false);
        camera.update();

        // Rendu de la map
        tilemapRenderer = new OrthogonalTiledMapRenderer(map);

        // Mettre la fenêtre en mode plein écran
        Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());

        // Rendre le fenêtre redimensionnable
        Gdx.graphics.setResizable(true);

        // Animation des chûtes d'eau
        TextureRegion[][] waterFallTmp = TextureRegion.split(tileSheet, TILE_WIDTH, TILE_HEIGHT);
        TextureRegion[] waterFallFrames = new TextureRegion[3];

        waterFallFrames[0] = waterFallTmp[10][14];
        waterFallFrames[1] = waterFallTmp[10][15];
        waterFallFrames[2] = waterFallTmp[10][16];

        waterFallAnimation = new Animation<TextureRegion>(0.150f, waterFallFrames);

        // Récupération du groupe d'object Layers
        MapGroupLayer objectsGroupLayer = (MapGroupLayer) map.getLayers().get("ObjectsLayers");

        // Récupération de l'object Layer "Waterfall"
        MapLayer waterFallLayer = objectsGroupLayer.getLayers().get("Waterfall");

        // Récupération des objets de l'object Layer "Waterfall"
        MapObjects waterFallObjects = waterFallLayer.getObjects();

        batch.begin();
        for (MapObject object : waterFallObjects) {
            // RectangleMapObject rectangleMapObject = (RectangleMapObject) object;
            // waterFallRectangles.add(rectangleMapObject.getRectangle());

            batch.draw(waterFallFrames[0], object.getProperties().get("x", Float.class),
                    object.getProperties().get("y", Float.class),
                    object.getProperties().get("width", Float.class),
                    object.getProperties().get("height", Float.class));
        }
        batch.end();
    }

    @Override
    public void render() {
        ScreenUtils.clear(0, 0, 0, 1);

        camera.update();
        // batch.setProjectionMatrix(camera.combined);

        tilemapRenderer.setView(camera);
        tilemapRenderer.render();

        // Gestion de l'animation des chûtes d'eau
        _waterFallStateTime += Gdx.graphics.getDeltaTime();

        TextureRegion currentFrame = waterFallAnimation.getKeyFrame(_waterFallStateTime, true);

        // Mouse position
        Vector3 mousePosition = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
        Vector3 vc = camera.unproject(mousePosition);

        batch.begin();
        batch.draw(currentFrame, vc.x, vc.y);
        batch.end();

        // batch.begin();

        // for (Rectangle rectangle : waterFallRectangles)
        // batch.draw(currentFrame, rectangle.x / 4, rectangle.y / 3, rectangle.width /
        // 2, rectangle.height / 2);

        // batch.end();
    }

    /**
     * Called when the {@link Application} is destroyed. Preceded by a call to
     * pause().
     * <p>
     * LibGDX recommends disposing of assets in this method.
     * </p>
     */
    @Override
    public void dispose() {
        map.dispose();
        tilemapRenderer.dispose();

        batch.dispose();

        tileSheet.dispose();
    }
}

我认为这是由于缩放问题,因为如果删除camera.setToOrtho,纹理会正确跟随图像,但是当添加这条线时,看起来坐标的比率乘以2、3甚至4 .

java libgdx 2d textures game-development
1个回答
0
投票

create
(
ApplicationAdapter
) 的
MyGdxGame
方法中设置全屏模式会破坏这种情况,因为有些东西预计已经在那里初始化了。

如果删除

// Mettre la fenêtre en mode plein écran
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());

// Rendre le fenêtre redimensionnable
Gdx.graphics.setResizable(true);

create
方法中将
DesktopLauncher
更改为

Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("Boats-Management");
config.setWindowIcon("icon.png");
// Add this line
config.setFullscreenMode(Lwjgl3ApplicationConfiguration.getDisplayMode());
new Lwjgl3Application(new MyGdxGame(), config);

当您点击

create
时,所有相关的事情都应该初始化。

除了这样做之外,我还会更改相机设置,以便它显示设定数量的图块宽度并保持纵横比:

// Mise en place de la caméra dans la scène
float aspectRatio = Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight();
float tilesWide = 65 * TILE_WIDTH;
camera = new OrthographicCamera(tilesWide, tilesWide / aspectRatio);
camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight  /2.0f, 1.0f);
camera.update();

65 更改为游戏中看起来不错的值。

最后,您应该告诉您的

SpriteBatch
在渲染时使用
render
方法中的投影:

// Add this line
batch.setProjectionMatrix(camera.combined); 
batch.begin();
batch.draw(currentFrame, vc.x, vc.y);
batch.end();
© www.soinside.com 2019 - 2024. All rights reserved.