libgdx에서 온 스크린 HUD를 만들려면 어떻게해야합니까?


23

나는 libgdx를 처음 사용하고 있으며, 가장 간단한 것들에 푹 빠져 있습니다. 특정 방식으로 작업을 수행하는 것처럼 보이지만 설명서에서 그 내용을 알려주지 않습니다.

플레이어가 우주선을 제어하는 ​​매우 간단한 2D 게임을 만들고 싶습니다. 마우스 휠이 확대 / 축소되고 정보 및 컨트롤이 화면에 표시됩니다.

그러나 마우스 휠이 UI를 확대하지 않도록 할 수 없습니다. 나는 사이에 투영 행렬로 퍼징을 시도했습니다.

내 (현재) 코드는 다음과 같습니다.

public class PlayStage extends Stage {
...
    public void draw() {
    // tell the camera to update its matrices.
    camera.update();

    // tell the SpriteBatch to render in the
    // coordinate system specified by the camera.
    spriteBatch.setProjectionMatrix(camera.combined);

    spriteBatch.begin();

    aButton.draw(spriteBatch, 1F);

    playerShip.draw(spriteBatch, 1F);

    spriteBatch.end();
}
}

camera.zoom은 scrolled (int amount)에 의해 설정됩니다.

버튼이 그려진 후 배가 오기 전에 카메라의 프로젝션 매트릭스를 변경하는 주제에 대해 수십 가지 변형을 시도했지만, 내가 무엇을하든 버튼과 선박에 동일한 일이 발생합니다. 그래서:

카메라의 투영 매트릭스 / 줌으로 변환되지 않은 온 스크린 UI를 구현하는 일반적인 libgdx 방법은 무엇입니까?


를 사용하여 camera.project(Vector3 screenCoords)세계 좌표에서 스크린 코드까지 무언가를 투사 할 수 있습니다 .
— JDSweetBeat

답변:


17

투영 매트릭스를 설정하지 않고 다른 SpriteBatch를 사용하여 HUD를 그릴 수 있습니다.

camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
aButton.draw(spriteBatch, 1F);
playerShip.draw(spriteBatch, 1F);
spriteBatch.end();

hudBatch.begin();
//Draw using hudBatch
hudBatch.end();

1
제가하고있는 일에 대해, 이것은 화면에서 항상 같은 위치에 표시되어야하는 기본 UI에 대한 가장 간단한 접근법 인 것으로 나타났습니다 (점수, 생활 등)
— Richard

나는이 시도 할 때 다른 화면 해상도에 다른 위치에지도 투영 행렬없는의 SpriteBatch를 갖는
— codeulike

8

허드 맵을 달성하는 가장 쉬운 방법은 두 번째 카메라를 사용하여 오버레이하는 것입니다. 이 문제는 얼마 전 libgdx 포럼에서 논의되었으며 허드 코드를 게시하는 누군가를 기억합니다. 당신은 저기 찔러서 당신이 생각 해낸 것을 볼 수 있습니다.


2
네, 정답입니다. 또는 hud에 별도의 스테이지를 사용하고 게임 후에 그립니다.
— Matsemann 2016 년

3
고맙습니다. 두 가지 모두 시도합니다. 화면 당 하나 이상의 스테이지 또는 카메라를 갖는 것이 일반적인 관례라는 것을 알지 못했습니다.
— Devin Carless 2016 년

4
샘플 코드를 추가하거나 @DevinCarless를 추가 할 수 있습니까?
— ashes999

6

단일 배치 작업에 사용하는 방법은 다음과 같습니다.

먼저 다른 모든 것을 그린 다음 마지막으로 HUD를 그립니다.

Matrix4 uiMatrix = cam.combined.cpy();
uiMatrix.setToOrtho2D(0, 0, WIDTH, HEIGHT);
batch.setProjectionMatrix(uiMatrix);
batch.begin();

이후에 더 많은 것을 그리려면 영사 매트릭스를 필요한 것으로 재설정하십시오.


.cpu()매번 새로운 행렬을 생성 하기 때문에 메모리에 많은 행렬이 매우 빠르게 생성 된다는 경고를 받으십시오 . 영구 버퍼 매트릭스를 사용하고 매 프레임마다 값을 설정하는 것이 좋습니다.
— Denis Kniazhev 2016 년

1

첫 번째 카메라는 배경이 고정 된 위치입니다. 두 번째는 땅이 움직이는 곳입니다. 왜 스프라이트가 무대에서 움직이는 지 궁금하기 때문에 스프라이트가 스테이지에서 움직이는 이유가 궁금합니다. 스프라이트는 세 번째 카메라를 사용하고 있기 때문에 제자리에 걸어 있습니다. 두 번째 카메라의지면을 스크롤했지만 HUD는 여전히 세 번째에 있습니다. 약속하다, 사실이야! 세 번째 카메라는 작은 애니메이션 코드로 왼쪽 또는 오른쪽으로 이동하든 HUD (즉, 점수, 남은 수명, 사용 된 항목)에 관계없이 방향을 중심으로 스프라이트를 표시하는 위치입니다. 필요한 게 있으면 나 한테 물어봐


두 번째 카메라에서 스프라이트를 분리하려면 어떻게해야합니까? 내가하고 싶은 것은 텍스트를 그리는 것이지만 큰 것입니다 ... 그래서 다른 카메라가 필요합니다.하지만 그렇게 할 때 텍스트가 나와 함께 .. 플레이어와 함께 내 스크린을 사용하면 조금 움직입니다. 화면의 적처럼 여전히 그래도 나와 함께있어 ... 조언 해 주시겠습니까?
— Nimitack

1

나는 이렇게했다 :

먼저 Hud라는 새 클래스를 만들었습니다. Disposable자원 관리로 인해 구현 됩니다. 그런 다음 새 카메라가 사용되므로 Stage콘텐츠에 대한 및 viewport새 카메라 를 정의해야합니다 . 에 Table추가 할 수 있는 새로운 것을 정의해야 합니다 Stage. table평소처럼 콘텐츠를 추가 할 수 있습니다 . 작동 방식을 보여주기 위해 넣을 나머지 코드는 게임마다 다르므로 무시하십시오.

public class Hud implements Disposable{

public Stage stage;
private Viewport viewport;

//score && time tracking variables
private Integer worldTimer;
private float timeCount;
private static Integer score;
private boolean timeUp;

//Scene2D Widgets
private Label countdownLabel, timeLabel, linkLabel;
private static Label scoreLabel;

public Hud (SpriteBatch sb){
    //define tracking variables
    worldTimer = 250;
    timeCount = 0;
    score = 0;

    //setup the HUD viewport using a new camera seperate from gamecam
    //define stage using that viewport and games spritebatch
    viewport = new FitViewport(GetTheTriforce.V_WIDTH, GetTheTriforce.V_HEIGHT, new OrthographicCamera());
    stage = new Stage(viewport, sb);

    //define labels using the String, and a Label style consisting of a font and color
    countdownLabel = new Label(String.format("%03d", worldTimer), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    scoreLabel =new Label(String.format("%06d", score), new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    timeLabel = new Label("LEFTOVER TIME", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
    linkLabel = new Label("POINTS", new Label.LabelStyle(new BitmapFont(), Color.WHITE));

    //define a table used to organize hud's labels
    Table table = new Table();
    table.top();
    table.setFillParent(true);

    //add labels to table, padding the top, and giving them all equal width with expandX
    table.add(linkLabel).expandX().padTop(10);
    table.add(timeLabel).expandX().padTop(10);
    table.row();
    table.add(scoreLabel).expandX();
    table.add(countdownLabel).expandX();

    //add table to the stage
    stage.addActor(table);

}

public void update(float dt){
    timeCount += dt;
    if(timeCount >= 1){
        if (worldTimer > 0) {
            worldTimer--;
        } else {
            timeUp = true;
        }
        countdownLabel.setText(String.format("%03d", worldTimer));
        timeCount = 0;
    }
}

public static void addScore(int value){
    score += value;
    scoreLabel.setText(String.format("%06d", score));
}

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

public boolean isTimeUp() { return timeUp; }


public static Label getScoreLabel() {
    return scoreLabel;
}

public static Integer getScore() {
    return score;
}

}

그런 다음 재생 화면에서 다음과 같이하십시오.

우선 다음과 같이 hud를 참조하는 변수가 필요합니다.

private Hud hud; 

그런 다음 생성자에서 클래스의 새 인스턴스를 만듭니다.

hud= new Hud(); 

업데이트 방법에서는 포인트 또는 수명과 같은 일부 게임 정보를 표시하려고한다고 생각하기 때문에 다음 코드 줄을 넣어야합니다.

hud.update();

render- 메소드에서 다음을 수행하십시오.

//Set batch to now draw what the Hud camera sees.
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();

그리고 결국에는 처분 방법에 허드를 처리하는 것을 잊지 마십시오

나는 그것이 도움이되기를 바랍니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.