Mis on HUD?¶
HUD (Head-Up Display) on mängu kasutajaliidese osa, mis kuvatakse otse ekraanile "mängumaailma peale". Selle eesmärk on edastada mängijale kriitilist infot ilma mängu tegevust katkestamata. Tüüpilised näited on elupunktid (HP), laskemoona seis, minikaart ja skoor.
HUD on staatiline element – erinevalt mängumaailmast, mis liigub koos kaameraga, püsib HUD ekraani suhtes paigal.
HUD-i arhitektuur¶
LibGDX-is kasutatakse HUD-i loomiseks Scene2D moodulit. See võimaldab käsitleda UI-elemente kui objekte (näitlejaid), mis lihtsustab oluliselt paigutust ja sündmuste haldust.
Põhikomponendid:¶
Stage (Lava): Konteiner kõigile UI elementidele. See haldab elementide joonistamist ja sisendite töötlemist.
Viewport (Vaateava): Määrab, kuidas HUD skaleerub erinevatel ekraanidel. HUD-i puhul kasutatakse tavaliselt eraldi kaamerat ja FitViewport-i, et vältida elementide väljavenitamist.
Table (Tabel): Võimas paigutussüsteem, mis jagab ekraani ridadeks ja veergudeks. See on parim viis elementide joondamiseks.
Label (Silt): Komponent teksti kuvamiseks, mis toetab erinevaid fonte ja värve.
Interaktiivsus ja sisendi töötlemine¶
Mängu HUD ei pruugi olla ainult informatiivne, vaid ka interaktiivne (nt nupud, inventar). Selleks, et süsteem tuvastaks hiireklõpsusid HUD-i elementidel, tuleb mängu sisendprotsessoriks määrata HUD-i Stage.
Kui mängus on vaja korraga käsitleda nii maailmas toimuvat (nt tulistamine) kui ka UI-d (nt pausi-nupp), kasutatakse InputMultiplexer-it:
InputMultiplexer multiplexer = new InputMultiplexer();
multiplexer.addProcessor(hud.stage); // HUD saab esimesena võimaluse klikke tuvastada
multiplexer.addProcessor(playerInputProcessor); // Seejärel mängumaailm
Gdx.input.setInputProcessor(multiplexer);
Praktiline näide: Staatiline HUD¶
Allolev klass loob klassikalise mängu HUD-i, mis kuvab aega ja skoori.
public class Hud implements Disposable {
public Stage stage;
private Viewport viewport;
private Integer worldTimer;
private float timeCount;
private static Integer score;
private Label countdownLabel;
private static Label scoreLabel;
public Hud(SpriteBatch sb) {
worldTimer = 300;
timeCount = 0;
score = 0;
// Loome eraldi kaamera ja viewporti HUD-i jaoks
viewport = new FitViewport(800, 480, new OrthographicCamera());
stage = new Stage(viewport, sb);
Table table = new Table();
table.top(); // Joondame sisu ekraani ülaossa
table.setFillParent(true); // Tabel täidab kogu ekraani
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));
Label timeLabel = new Label("AEG", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
Label scoreTitleLabel = new Label("SKOOR", new Label.LabelStyle(new BitmapFont(), Color.WHITE));
// Lisame elemendid tabelisse ja jaotame nad ühtlaselt (expandX)
table.add(scoreTitleLabel).expandX().padTop(10);
table.add(timeLabel).expandX().padTop(10);
table.row();
table.add(scoreLabel).expandX();
table.add(countdownLabel).expandX();
stage.addActor(table);
}
public void update(float dt) {
timeCount += dt;
if (timeCount >= 1) {
worldTimer--;
countdownLabel.setText(String.format("%03d", worldTimer));
timeCount = 0;
}
}
@Override
public void dispose() {
stage.dispose();
}
}
Interaktiivsete elementide lisamine¶
Kui on vaja lisada klikitavaid elemente, nagu nupud, saab kasutada TextButton või ImageButton komponente koos kuulajatega:
TextButton pauseButton = new TextButton("PAUSE", skin);
pauseButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
// Siia lisatakse loogika mängu peatamiseks
isPaused = !isPaused;
}
});
table.add(pauseButton).colspan(2).padTop(20);
HUD-i integreerimine mängutsüklisse¶
Mängu põhiklassis (nt PlayScreen) tuleb HUD-i joonistada eraldi sammuna pärast mängumaailma renderdamist. See tagab, et kasutajaliides jääb alati kõige pealmiseks kihiks.
@Override
public void render(float delta) {
// 1. Uuendame loogikat
hud.update(delta);
// 2. Puhastame ekraani
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// 3. Joonistame mängumaailma
game.batch.setProjectionMatrix(gameCam.combined);
game.batch.begin();
// ... mängijate ja maailma joonistamine ...
game.batch.end();
// 4. Joonistame HUD-i (Stage haldab oma batchi ja projektsiooni ise)
hud.stage.draw();
}
Projektipõhine näide¶
Allpool on näide arendatavast HUD-ist, kuhu on koondatud mängijate nimed, tervisepunktid, taimer ja reaalajas uuenev mängu olekuteade.
Selles lahenduses on elemendid paigutatud Table abil, mis hoiab info (nimed, elupunktid, taimer) ekraani ülaservas korrektselt joondatuna.
Värvikoode ja teksti on kasutatud info selgemaks edastamiseks: * Roheline värv nimes ("You") aitab mängijal end kiiresti tuvastada. * Punane värv on reserveeritud kriitilisele infole, antud juhul mängijate tervisepunktidele (50). * Keskel asuv tekstiteade ("Waiting for other player...") on dünaamiline – see muutub vastavalt mängu olekule, andes mängijale teada, millal saab alustada.
Olulised soovitused:¶
Eraldi kaamera: Ärge kunagi kasutage HUD-i jaoks mängumaailma kaamerat. Mängumaailm võib liikuda ja suumida, kuid HUD peab jääma paigale.
Tabeli silumine: Kasutage arenduse ajal käsku table.setDebug(true);. See joonistab tabeli lahtrite ümber punased jooned, mis aitab elemente täpselt paika saada.
Resursside vabastamine: Kuna Stage on ressurssimahukas, kutsuge alati välja stage.dispose(), kui ekraan suletakse.