Java 为随相机移动的Libgdx创建用户界面

Java 为随相机移动的Libgdx创建用户界面,java,user-interface,camera,libgdx,box2d,Java,User Interface,Camera,Libgdx,Box2d,我有一个box2d屏幕,你可以在那里移动相机。我希望能够在随相机移动的屏幕周围显示scene2d菜单。现在的问题是我不知道怎么做。下面的BuildScreen从AbstractControllerScreen扩展而来,AbstractControllerScreen是一个实现Screen并使用ViewScreen和ModelScreen的类。这些与MVC模型的一致。下面是一个屏幕,代表我想要菜单和box2d区域的屏幕。如果有太多的代码,我会提前道歉,但这是我必须处理的 公共类BuildScree

我有一个box2d屏幕,你可以在那里移动相机。我希望能够在随相机移动的屏幕周围显示scene2d菜单。现在的问题是我不知道怎么做。下面的BuildScreen从AbstractControllerScreen扩展而来,AbstractControllerScreen是一个实现Screen并使用ViewScreen和ModelScreen的类。这些与MVC模型的一致。下面是一个屏幕,代表我想要菜单和box2d区域的屏幕。如果有太多的代码,我会提前道歉,但这是我必须处理的

公共类BuildScreen扩展了AbstractControllerScreen{

private World world;
private List<BuildPart> ships;


private float r = 70f*BodyConstants.WORLD_TO_BOX;

private Renderable stageRendrable;
private final Stage stage;
private Entity stageEntity;
private InputMultiplexer inputHandler;


public BuildScreen (Nimby game) {
    super(game, new CameraControllerBuild());
    ships = new LinkedList<>();
    World world = new World(Vector2.Zero, true);
    this.world = world;
    inputHandler = new InputMultiplexer();


    stageRendrable = new Renderable() {

        @Override
        public void render(final SpriteBatch batch) {
            Table.drawDebug(stage);

        }

        @Override public void debug(final ShapeRenderer sr) { }
    };

    stageEntity = new Entity() {
        public void update(final float delta, final OrthographicCamera cam) {
            float width = Gdx.graphics.getWidth();
            float height = Gdx.graphics.getHeight();
            stage.act(delta);

        }
    };

    stage = new Stage();
    stage.setCamera(getViewScreen().getCam());
    inputHandler.addProcessor(stage);


    Bundle stageBundle = new Bundle(stageEntity, stageRendrable);

    addBundles(stageBundle);
ViewScreen类(如果感兴趣的话)如下所示

公共类视图屏幕{

private OrthographicCamera cam;
private ShapeRenderer sr;
private SpriteBatch batch;
private List<Renderable> renderables;
private CameraController camControll;
private Stage stage;
private Box2DDebugRenderer d;
/**
 * @return the cam
 */
public OrthographicCamera getCam() {
    return cam;
}

/**
 * @return the camControll
 */
public CameraController getCamControll() {
    return camControll;
}

public ViewScreen(final OrthographicCamera ocam, final CameraController cameraController) {
    this.cam = ocam;
    d = new Box2DDebugRenderer();
    renderables = new LinkedList<Renderable>();
    batch = new SpriteBatch();
    sr = new ShapeRenderer();

    setCamControll(cameraController);
}

public synchronized void render(float delta) {
    getCamControll().update();

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    // RENDER SPRITES

    batch.setProjectionMatrix(cam.combined);
    batch.begin();

    Iterator<Renderable> itr = renderables.iterator();
    while (itr.hasNext()) {
        Renderable r = itr.next();
        r.render(batch);
    }

    batch.end();


    if (ModelScreen.world != null) {
        d.render(ModelScreen.world, cam.combined);
    }


    sr.setProjectionMatrix(cam.combined);
    sr.begin(ShapeType.Line);
    for (Renderable r : renderables) {
        r.debug(sr);
    }
    sr.end();

    // RENDER GUI
    float camzoom = cam.zoom;
    Vector3 camPos = cam.position.cpy();

    batch.setProjectionMatrix(new Matrix4());
    if (stage != null) {
        batch.begin();

        stage.draw();
        batch.end();
    }




}

public synchronized void add(Renderable renderable) {
    renderables.add(renderable);
}

public synchronized void remove(Renderable renderable) {
    renderables.remove(renderable);
}

public void resize(int width, int height) {
    cam.viewportHeight = height;
    cam.viewportWidth = width;
}

/**
 * @param camControll the camControll to set
 */
public void setCamControll(CameraController camControll) {
    this.camControll = camControll;
}

/**
 * @param stage the stage to set
 */
public void setStage(Stage stage) {
    stage.setCamera(cam);
    stage.setViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);

    this.stage = stage;
}
专用正交摄像机;
私人沙佩雷德勒高级;
专用SpriteBatch批次;
私有可渲染列表;
私人摄像机控制器;
私人舞台;
私用盒2dd;
/**
*@返回凸轮
*/
公共正交摄影机getCam(){
回程凸轮;
}
/**
*@返回camControll
*/
公共摄像机控制器getCamControll(){
返回控制;
}
公共视图屏幕(最终正交摄影机ocam、最终摄影机控制器摄影机控制器){
this.cam=ocam;
d=新的Box2DebugRenderer();
renderables=newlinkedlist();
批次=新的SpriteBatch();
sr=新的ShaperEnder();
设置摄像机控制器(摄像机控制器);
}
公共同步无效渲染(浮动增量){
getCamControll().update();
glClearColor(0,0,0,1);
Gdx.gl.glClear(GL10.gl_颜色_缓冲_位| GL10.gl_深度_缓冲_位);
//渲染精灵
batch.setProjectionMatrix(cam.combined);
batch.begin();
迭代器itr=renderables.Iterator();
while(itr.hasNext()){
Renderable r=itr.next();
r、 渲染(批处理);
}
batch.end();
如果(ModelScreen.world!=null){
d、 渲染(ModelScreen.world、cam.combined);
}
sr.setProjectionMatrix(凸轮组合);
sr.begin(ShapeType.Line);
用于(可渲染r:可渲染){
r、 调试(sr);
}
sr.end();
//渲染图形用户界面
浮动camzoom=cam.zoom;
Vector3 camPos=cam.position.cpy();
batch.setProjectionMatrix(新Matrix4());
如果(阶段!=null){
batch.begin();
stage.draw();
batch.end();
}
}
公共同步的空添加(可渲染){
添加(可渲染);
}
公共同步的空心删除(可渲染){
可渲染。移除(可渲染);
}
公共空心调整大小(整型宽度、整型高度){
cam.viewportHeight=高度;
cam.viewportWidth=宽度;
}
/**
*@param camControll将camControll设置为
*/
公共无效设置camControll(CameraController camControll){
this.camControll=camControll;
}
/**
*@param stage要设置的阶段
*/
公共空间设置阶段(阶段){
舞台设置摄像机(cam);
stage.setViewport(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
这个阶段=阶段;
}

}

如果不在实际代码中插入太多内容,我相信典型用法如下:

@Override public void resize(int w, h) {
    ... do your regular stuff, including recreating stage if necessary
    stage.setViewport(w, h, false, 0, 0, w, h);
}

@Override public void render(float dt) {
    ... do your normal rendering, then draw ui on top
    stage.draw();
}

这将使您的UI呈现在屏幕上任何其他内容的顶部,并且它使用一个固定的视口,独立于所有其他内容覆盖整个屏幕。

您的问题是,您将相同的
cam
设置到
阶段和游戏的其余部分。libgdx
阶段
有自己的
摄像头你可以使用它,因为这个
摄像机不会在周围移动。所以你有你的
摄像机和你的
SpriteBatch
来渲染游戏,还有
Stage
s
cam
SpriteBatch
来渲染它上面的用户界面。只要确保在调用
Stage.draw()之前调用
SpriteBatch.end();
,因为如果有两个SpriteBatch处于活动状态,它会把事情搞砸。

我为类ViewScreen安装了第二个摄像头。问题是我会在哪里使用第二个摄像头,因为到目前为止,它只显示按钮,而不显示box2d世界。我不知道如何显示这两个摄像头,只需使用摄像头渲染box2d世界即可您的viewScreen。您只需要一个摄像头。然后调用stage.draw()。这将使用stage摄像头(您不需要实现另一个stage allready有一个)和stage spritebatch来绘制该舞台上的所有演员。只需确保在调用stage.draw()之前结束()box2d spritebatch
@Override public void resize(int w, h) {
    ... do your regular stuff, including recreating stage if necessary
    stage.setViewport(w, h, false, 0, 0, w, h);
}

@Override public void render(float dt) {
    ... do your normal rendering, then draw ui on top
    stage.draw();
}