LibGDX问题:Tilemap中按坐标放置纹理显示异常
问题:LibGDX中Tilemap对象层坐标与相机正交模式不匹配导致渲染错位
我正在做一个学校Java游戏项目,使用Tiled工具创建的Tilemap显示正常。为了在地图上实现瀑布动画,我在Tilemap中添加了对象层,并能在Java代码中获取这些对象的坐标、尺寸等信息。
核心问题
加载制作Tilemap时使用的纹理图,分割后将对应瓦片放置到对象坐标处,但纹理显示在地图之外。测试时尝试将纹理放在鼠标坐标位置,发现camera.unproject()方法仅在未调用setToOrtho时有效。
我判断这是缩放问题:移除camera.setToOrtho语句后,纹理能正确跟随鼠标,但添加该语句后,坐标比例似乎被放大了2、3甚至4倍。
相关代码片段
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; // 瀑布动画 private Animation<TextureRegion> waterFallAnimation; private List<Rectangle> waterFallRectangles = new LinkedList<Rectangle>(); private float _waterFallStateTime = 0; @Override public void create() { batch = new SpriteBatch(); // 资源管理器 assetManager = new AssetManager(); assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver())); assetManager.load("Map.tmx", TiledMap.class); // 加载32x32纹理图 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"); // 设置场景相机 camera = new OrthographicCamera(); camera.setToOrtho(false); camera.update(); // 渲染地图 tilemapRenderer = new OrthogonalTiledMapRenderer(map); // 设置全屏模式 Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); // 窗口可调整大小 Gdx.graphics.setResizable(true); // 初始化瀑布动画 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); // 获取对象层组 MapGroupLayer objectsGroupLayer = (MapGroupLayer) map.getLayers().get("ObjectsLayers"); // 获取瀑布对象层 MapLayer waterFallLayer = objectsGroupLayer.getLayers().get("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(); // 处理瀑布动画 _waterFallStateTime += Gdx.graphics.getDeltaTime(); TextureRegion currentFrame = waterFallAnimation.getKeyFrame(_waterFallStateTime, true); // 鼠标位置 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(); } /** * Application销毁时调用,调用前会先执行pause() * <p> * LibGDX推荐在此方法中释放资源 * </p> */ @Override public void dispose() { map.dispose(); tilemapRenderer.dispose(); batch.dispose(); tileSheet.dispose(); } }
内容的提问来源于stack exchange,提问作者BREBION Mathis
相关产品推荐
相关产品推荐

