Edetabel

Edetabeli loomine

Edetabeli eesmärk on anda ülevaade mängu praegusest seisust, näiteks kas mängijate punktide arv või team deathmatchis mängijate tapmiste ja surmade arv.

Kuna edetabel on usa mängu UI-st siis tuleks luua klass Leaderboard . Edetabeli ekraanile toomiseks saab siduda selle Tab klahvi all hoidmisega, samas võib siduda edetabeli ekraanile ilmumise ka muu sündmusega nagu näiteks mängus matchi lõpuga. Siin loon Leaderboard klassi lihtsustamise jaoks HashMap playerScores mis hoiab mängijate nimesi ja punkte. Päris mängus võiks olla klass Leaderboard puhtalt edetabeli visualiseerimiseks, ning võtta edetabelile vastavad andmed teisest klassist. Lisaks sorteerin need render() funktsiooni sees mis on üldiselt halb lahendus, palju parem oleks sorteerida andmeid ainult siis kui on teada, et on toimunud muudatus ning hoida neid mälus edetabeli visualiseerimiseks.

Üks meetod saada need andmed mängija kliendile on saata serverist iga edetabeliga seotud muudatus otse kliendile, ehk hoida klient up-to-date mängu hetke seisuga. Teine meetod on küsida serverilt vajalikku informatsiooni edetabeli koostamiseks ainult siis kui seda on vaja.

SpriteBatchi asemel võiks kasutada Scene2D UI-d kuna too on paremini hallatav. Ka on soovituslik asendada InputAdapter InputMultiplexer -iga samuti parema hallatavuse eesmärgil.

Leaderboard klass

package io.github.some_example_name.lwjgl3;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import java.util.*;
import java.util.stream.Collectors;

public class Leaderboard {
    private boolean visible;
    private Map<String, Integer> playerScores; // Map mängijatest ja nende punktidest

    public Leaderboard() {
        this.visible = false;
        this.playerScores = new HashMap<>();

        // Ajutine näidiseks
        playerScores.put("Player1", 13);
        playerScores.put("Player2", 3);
        playerScores.put("Player3", 7);
        playerScores.put("Player4", 11);
    }

    // Muuda leaderboardi playerlisti
    public void setPlayerScores(Map<String, Integer> players) {
        playerScores.clear();
        playerScores.putAll(players);
    }

    // Muuda leaderboardi nähtavust
    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    // Rendering
    public void render(SpriteBatch spriteBatch, BitmapFont font) {
        if (this.visible) {
            int y = Gdx.graphics.getHeight() - 20;

            // Lihtne sorteerimine, reaalsuses võiks edetabeli andmed olla kättesaadavad Leaderboardile mujalt juba eelsorteerituna
            List<Map.Entry<String, Integer>> sortedScores = playerScores.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toList());

            for (Map.Entry<String, Integer> entry : sortedScores) {
                String playerName = entry.getKey();
                int points = entry.getValue();
                font.draw(spriteBatch, playerName, 20, y); // Nimi
                font.draw(spriteBatch, String.valueOf(points), 200, y); // Punktide arv
                // Siia saab veel lisada mängijate väärtusi
                y -= 20;
            }
        }
    }
}
  • setPlayerScores() uuendab playerScores uuele mappile.

  • setVisible() muudab UI nähtavust.

Mängu põhikoodis on vaja instantseerida leaderboard ning ühendada Tab klahv nähtavuse muutmisega.

Näide koos libgdxDemoga

package io.github.some_example_name.lwjgl3;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;

public class libgdxDemo extends ApplicationAdapter {
    ShapeRenderer shapeRenderer;
    Leaderboard leaderboard; // Leaderboard klass
    SpriteBatch spriteBatch; // Spritebatch klass
    BitmapFont font; // Bitmap font

    float r = MathUtils.random();
    float g = MathUtils.random();
    float b = MathUtils.random();

    @Override
    public void create () {
        shapeRenderer = new ShapeRenderer();
        leaderboard = new Leaderboard(); // Loo leaderboard
        spriteBatch = new SpriteBatch(); // Loo spritebatch
        font = new BitmapFont(); // Loo font

        Gdx.input.setInputProcessor(new InputAdapter() {
            // Sisendi võtmine leaderboardi jaoks
            @Override
            public boolean keyDown(int keycode) {
                if (keycode == Input.Keys.TAB) {
                    leaderboard.setVisible(true);
                }
                return true;
            }

            @Override
            public boolean keyUp(int keycode) {
                if (keycode == Input.Keys.TAB) {
                    leaderboard.setVisible(false);
                }
                return true;
            }

            @Override
            public boolean keyTyped (char key) {
                r = MathUtils.random();
                g = MathUtils.random();
                b = MathUtils.random();
                return true;
            }

            @Override
            public boolean touchDown (int x, int y, int pointer, int button) {
                r = MathUtils.random();
                g = MathUtils.random();
                b = MathUtils.random();
                return true;
            }
        });
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(r, g, b, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // Spritebatchi renderdamine
        spriteBatch.begin();
        leaderboard.render(spriteBatch, font);
        spriteBatch.end();
    }

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