Mängija registreerimine

images/registreeri.png

Loo vormi mängija loomiseks

Esialguks kliendi kaustas on vaja luua uue pakki screen ja lisada uue klassi MainScreen. See ekraan on mõeldud mängijate loomiseks. Loo sinna uue stage'i ja lisa 3 toimijad (Label, TextField ja TextButton)

MainScreen.java

@Override
public void show() {
    Stage stage = new Stage();
    Gdx.input.setInputProcessor(stage);
    Label label = new Label("Write your name:", skin);
    TextField field = new TextField("", skin);
    TextButton button = new TextButton("START", skin);
    button.addListener(new RegisterPlayerClickListener(field.getName()));
    Table table = new Table();
    table.setFillParent(true);
    table.defaults().space(10);
    table.add(label).uniform().fillX();
    table.row();
    table.add(field);
    table.row();
    table.add(button).uniform().fillX();

    stage.addActor(table);
}

@Override
public void render(float delta) {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl.glClearColor(0.157f, 0.196f, 0.522f, 1);
    stage.act(delta);
    stage.draw();
}

Saada UDP päringu serverile

Enne päringu saatmist peame serveriga ühenduma. Selleks loome uue ClientLauncher klassi

ClientLauncher

ClientLauncher.java

 public class ClientLauncher extends Client {

    private static ClientLauncher instance;

    private ClientLauncher() {
        KryoHelper.registerClasses(getKryo());
        connectToServer();
    }

    public static ClientLauncher getInstance() {
        if (instance == null) {
            instance = new ClientLauncher();
        }
        return instance;
    }

    public void connectToServer() {
        start();
        try {
            connect(DEFAULT_CONNECTION_TO_SERVER_TIMEOUT, DEFAULT_HOST, DEFAULT_TCP_PORT, DEFAULT_UDP_PORT);
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

Constants

Lisa Constants klassi shared kausta, et hoida konstantseid väärtusi

Constants.java

 public class Constants {

    public static final int DEFAULT_CONNECTION_TO_SERVER_TIMEOUT = 5000;
    public static final int DEFAULT_TCP_PORT = 8080;
    public static final int DEFAULT_UDP_PORT = 8081;
    public static final String DEFAULT_HOST = "localhost";
}

Töötle nupu vajutamist

Nüüd lisa uue klassi RegisterPlayerClickListener, mis pärib ClickListener ja hoiab endas TextField field.

RegisterPlayerClickListener.java

 @AllArgsConstructor
public class RegisterPlayerClickListener extends ClickListener {

    private TextField field;

    @Override
    public void clicked(InputEvent event, float x, float y) {
        String username = field.getText();
        if (username.isBlank()) return;
        ClientLauncher.getInstance().sendUDP(new RegisterPlayerPacket(username));
    }
}

Kui ClientLauncher.getInstance() on kasutatud esimest korda, siis luuakse uue ClientLauncher klassist objekti ja kohe ühendatakse serveriga ja saadatakse päringu.

Registeeri klassid kasutades Kryo

Kui praegu proovida seda koodi, siis tuleb viga. Selleks, et seda parandada peab Kryonet'i registreerima RegisterPlayerPacket. Loome uue KryoHelper klassi shared kausta.

KryoHelper.java

 public class KryoHelper {

    public static void registerClasses(Kryo kryo) {
        kryo.register(RegisterPlayerPacket.class);
        // Register more classes here.
    }
}

*Kõik klassid, mis saadetakse kliendilt serverile ja serverilt kliendile peavad olema registreeritud.

Kasuta see meetod serveril ja kliendil.

ClientLauncher.java

private ClientLauncher() {
   KryoHelper.registerClasses(getKryo());
   ...
}

ServerLauncher.java

public ServerLauncher() {
   KryoHelper.registerClasses(getKryo());
   ...
}

Nüüd klassid registreeritakse nii serveril, kui ka kliendil.

Lombok

Selles juhendis hakkan kasutama Lombok

Selleks, et lisada Lombok ava build.gradle faili ja lisa dependencies alla

build.gradle

annotationProcessor "org.projectlombok:lombok:1.18.34"
compileOnly "org.projectlombok:lombok:1.18.34"

*Võid versiooni muuta uueks, kui on vajadus

Päringu töötlemine serveris

Lisame uue ServerListener klassi.

ServerListener.java

public class ServerListener implements Listener {

   @Override
   public void received(Connection connection, Object object) {
       switch (object) {
           case RegisterPlayerPacket packet -> // if object is instance of RegisterPlayerPacket
               ServerLauncher.getInstance().registerPlayer(connection.getID(), packet.getName());
           default ->
               // leave it like this
               System.out.println("PACKET SKIPPED");
       }
   }
}

ServerLauncher.java

public ServerLauncher() {
   ...
   addListener(new ServerListener());
}

Ja lisa shared kausta mängija klassi.

Player.java

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class Player {

    private int id;
    private String name;
}

Vastuse töötlemine kliendis

Lisame uue ClientListener klassi.

ClientListener.java

public class ClientListener implements Listener {

    @Override
    public void received(Connection connection, Object object) {
        switch (object) {
            case RegisterPlayerPacket packet ->
                Main.getInstance().createPlayer(connection.getID(), packet.getName());
            default -> System.out.println("Skipped package");
        }
    }
}

ClientLauncher.java

private ClientLauncher() {
    addListener(new ClientListener());
    ...
}

Nüüd salvestame mängija ja muudame ekraani.

Main.java

private Player currentPlayer;

public void createPlayer(int id, String username) {
    currentPlayer = new Player(id, username);
    Gdx.app.postRunnable(new SetScreenRunnable(new LobbiesListScreen()));
}

Kasuta Runnable ekraanide muutmiseks

SetScreenRunnable.java

@AllArgsConstructor
public class SetScreenRunnable implements Runnable {

    private Screen screen;

    @Override
    public void run() {
        Main.getInstance().setScreen(screen);
    }
}

*Runnable kasutamine on kohustuslik, sest mäng ja kryonet töötavad erinevatel Thread'idel