You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LibGDX中实现世界单位与鼠标输入的匹配?

解决LibGDX中世界单位下鼠标输入与UI显示不匹配的问题

你当前的核心问题是直接混用屏幕像素坐标与世界单位坐标:Gdx.input.getX()/getY()返回的是屏幕像素坐标(原点在左上角),而UI绘制使用的是自定义世界单位,屏幕尺寸变化时两者映射关系混乱,必然导致输入偏移。以下是针对性的解决方法:


一、正确初始化Viewport与相机

Viewport是LibGDX处理屏幕适配和坐标映射的核心,必须将其与相机绑定,确保世界单位和屏幕像素的正确对应。推荐使用FitViewport(保持世界宽高比,黑边填充剩余空间),初始化示例:

@Override
public void show() {
    // 初始化正交相机
    camera = new OrthographicCamera();
    // 绑定Viewport,传入世界宽高与相机
    viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera);
    // 将相机原点居中(根据UI布局需求调整)
    camera.position.set(WORLD_WIDTH / 2f, WORLD_HEIGHT / 2f, 0);
    camera.update();

    // 加载按钮纹理
    playButtonActive = new Texture("play_active.png");
    playButtonInactive = new Texture("play_inactive.png");
    playButtonClicked = new Texture("play_clicked.png");
}

// 屏幕尺寸变化时更新Viewport,维持映射关系
@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

二、将鼠标像素坐标转换为世界单位坐标

通过viewport.unproject()方法,将鼠标的屏幕像素坐标转换为世界单位坐标,该方法会自动处理Y轴原点差异(鼠标Y轴原点在左上角,世界坐标Y轴通常在左下角):

// 在render方法中执行坐标转换
Vector2 mouseWorldPos = new Vector2(Gdx.input.getX(), Gdx.input.getY());
viewport.unproject(mouseWorldPos);

// 此时mouseWorldPos.x和mouseWorldPos.y就是世界单位下的鼠标位置

三、统一用世界单位处理UI绘制与输入判断

所有UI布局、输入判断都基于世界单位,彻底摒弃对屏幕像素值的依赖,示例代码:

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

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

    // 转换鼠标坐标到世界单位
    Vector2 mouseWorldPos = new Vector2(Gdx.input.getX(), Gdx.input.getY());
    viewport.unproject(mouseWorldPos);

    // 用世界单位定义按钮位置与尺寸
    float buttonX = WORLD_WIDTH / 9f;
    float buttonY = WORLD_HEIGHT / 2f;
    float buttonWidth = playButtonActive.getWidth();
    float buttonHeight = playButtonActive.getHeight();

    // 判断鼠标是否在按钮范围内(世界单位)
    boolean isHover = mouseWorldPos.x > buttonX 
                    && mouseWorldPos.x < buttonX + buttonWidth 
                    && mouseWorldPos.y > buttonY 
                    && mouseWorldPos.y < buttonY + buttonHeight;

    game.batch.begin();
    if (isHover) {
        game.batch.draw(playButtonInactive, buttonX, buttonY);
        if (Gdx.input.isButtonPressed(Input.Buttons.LEFT)) {
            game.batch.draw(playButtonClicked, buttonX, buttonY);
            game.setScreen(new GameScreen(game));
        }
    } else {
        game.batch.draw(playButtonActive, buttonX, buttonY);
    }
    game.batch.end();
}

关键注意事项

  • 全程统一使用世界单位:绘制、输入判断、布局定位都不要混用像素值,所有坐标转换交给Viewport处理。
  • 必须重写resize方法:屏幕尺寸变化时,viewport.update()是维持坐标映射正确的核心步骤。

内容的提问来源于stack exchange,提问作者Mehrbod Mehrabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:46:16