Як зробити екран на HUD у libgdx?


23

Я новачок у libgdx, і я знаходжу, що мене натикають найпростіші речі. Здається, я хочу, щоб я робив справи певним чином, але документація не скаже мені, що це таке.

Я хочу зробити дуже просту 2d гру, в якій гравець управляє космічним кораблем. Колесо миші збільшить масштаб і зменшить, а на екрані відобразиться інформація та елементи керування.

Але я не можу зробити так, щоб колесо миші НЕ збільшувало інтерфейс користувача. Я спробував ф'юшинг з матрицями проекції між ними

Ось мій (поточний) код:

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 встановлюється прокручуванням (int кількість).

Я спробував близько десятка варіацій на тему зміни матриці проекції камери після того, як кнопка намальована, але до того, як корабель буде, але що б я не робив, те ж саме відбувається і з кнопкою, і з кораблем. Так:

Який звичайний спосіб 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
Що я робив, я вважав, що це найпростіший підхід, для базового інтерфейсу користувача, який завжди повинен з’являтися на одному і тому ж місці на екрані (як, наприклад, рахунки, життя тощо)
Річард,

Наявність spritebatch без проекційної матриці призвело до різного розміщення в різних роздільних здатностях екрана, коли я спробував це
кодоподібний

8

Я думаю, що найпростішим способом скласти карту hud було б використовувати другу камеру та накладати їх. Це питання обговорювалося на форумах libgdx деякий час назад, і я пам'ятаю, як хтось там розміщував свій hud-код. Можливо, ви захочете поскакати там і побачити, що ви придумали.


2
Так, це правильна відповідь. Або скористайтеся окремим Етапом для hud і намалюйте його після ігор.
Мацеманн

3
Дякую. Я спробую і те, і інше. Я не усвідомлював, що це звичайна практика мати більше однієї сцени або камери на екран.
Девін Карлес

4
Чи можете ви, будь ласка, додати зразок коду чи, можливо, @DevinCarless?
ashes999

6

Ось метод, який я використовую для роботи з однією партією:

Спочатку намалюйте все інше, а потім намалюйте свій HUD останнім:

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

Якщо ви хочете намалювати більше, переконайтеся, що ви скинули матрицю проекцій на те, що потрібно.


Попереджуйте, що у вас буде дуже багато матриць у пам'яті дуже швидко (адже .cpu()кожен раз створюється нова матриця). Краще мати постійну буферну матрицю і встановлювати її значення для кожного кадру.
Денис Княжев

1

Пам’ятайте, перша камера - це місце, де фіксується фон. Другий - там, де рухається земля. Якщо вам цікаво, чому спрайт рухається по сцені, тому що таємна його земля, яка рухається. Спрайт просто ходить на місці, оскільки ви використовуєте третю камеру. Ви можете прокрутити землю другої камери, але HUD все ще знаходиться на третій. Обіцяйте, це правда! Третя камера - там, де вона відображає спрайт у центрі напрямку, чи йде він ліворуч або праворуч за допомогою невеликого анімаційного коду та HUD (тобто оцінка, решта життя, використаний предмет). Якщо вам щось потрібно, запитайте мене.


Як я можу від'єднати спрайт від другої камери? Що я хочу зробити, це намалювати текст, але це великий ... Тому мені потрібна інша камера, але коли я це роблю, текст іде зі мною .. з програвачем, з мого екрана ... він трохи рухається як ворог на екрані, але він все ще залишається зі мною ... Чи можете ви порадити?
Німітак

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;
}

}

а потім на Playscreen таким чином:

Перш за все вам потрібна змінна для посилання на ваш hud, наприклад:

private Hud hud; 

а потім у конструкторі ви створюєте новий екземпляр свого класу:

hud= new Hud(); 

у методі оновлення вам потрібно ввести ці рядки коду, оскільки я думаю, що ви хочете відобразити інформацію про ігри, наприклад, очки чи життя, що залишилося:

hud.update();

у методі візуалізації зробіть це:

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

і врешті-решт не забудьте розпоряджатись своєю хадою методом утилізації

Я сподіваюся, що це допомагає

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.