improved menus in libGDX client

main
Jonah Bauer 3 years ago
parent a592807dff
commit c89026c6e1

@ -8,6 +8,9 @@ import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import java.util.Optional;
import java.util.function.BiFunction;
@Log4j2
public class Client extends TimeoutContext<ClientState, Client> {
@ -55,4 +58,14 @@ public class Client extends TimeoutContext<ClientState, Client> {
public void send(ClientMessage message) {
getSocket().send(message.toString());
}
public <T extends ClientState> void execute(Class<T> stateClass, BiFunction<T, Client, Optional<ClientState>> transition) {
execute(s -> {
if (stateClass.isInstance(s)) {
return transition.apply(stateClass.cast(s), this);
} else {
return Optional.empty();
}
});
}
}

@ -32,11 +32,13 @@ public class AutoFocusScrollPane extends ScrollPane {
private void init() {
addListener(new InputListener() {
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
getStage().setScrollFocus(AutoFocusScrollPane.this);
var stage = getStage();
if (stage != null) stage.setScrollFocus(AutoFocusScrollPane.this);
}
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
getStage().setScrollFocus(null);
var stage = getStage();
if (stage != null) stage.setScrollFocus(null);
}
});
}

@ -71,10 +71,47 @@ public class CardStack extends Group {
addActor(hover);
}
public List<CardActor> removeAll() {
var out = cards.stream().map(Entry::getActor).toList();
clearChildren(true);
return out;
}
@Override
public Actor removeActorAt(int index, boolean unfocus) {
var actor = super.removeActorAt(index, unfocus);
cards.remove(index);
return actor;
}
public void setHoverBounds(float x, float y, float width, float height) {
hover.setBounds(x, y, width, height);
}
@Override
@Deprecated
public void addActor(Actor actor) {
super.addActor(actor);
}
@Override
@Deprecated
public void addActorAfter(Actor actorAfter, Actor actor) {
super.addActorAfter(actorAfter, actor);
}
@Override
@Deprecated
public void addActorAt(int index, Actor actor) {
super.addActorAt(index, actor);
}
@Override
@Deprecated
public void addActorBefore(Actor actorBefore, Actor actor) {
super.addActorBefore(actorBefore, actor);
}
@Data
private static class Entry {
private final CardActor actor;

@ -7,13 +7,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Align;
import eu.jonahbauer.wizard.client.libgdx.ClientSocket;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.state.AwaitingConnection;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.SneakyThrows;
import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
import java.net.URI;
import java.net.URISyntaxException;
public class ConnectScreen extends MenuScreen {
@ -27,18 +26,19 @@ public class ConnectScreen extends MenuScreen {
}
private final ChangeListener listener = new ChangeListener() {
@SneakyThrows
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonBack) {
game.setScreen(new MainMenuScreen(game));
game.getClient().execute(Menu.class, Menu::showMenuScreen);
sfxClick();
} else if (actor == buttonConnect) {
// TODO error handling, uri syntax, etc.
ClientSocket socket = new ClientSocket(new URI(uri.getText()));
game.getClient().setSocket(socket);
game.getClient().transition(new AwaitingConnection());
socket.connect();
try {
var uri = new URI(ConnectScreen.this.uri.getText());
game.getClient().execute(Menu.class, (s, c) -> s.connect(c, uri));
} catch (URISyntaxException e) {
uri.setStyle(game.data.skin.get("error", TextField.TextFieldStyle.class));
}
sfxClick();
}
}
@ -63,6 +63,7 @@ public class ConnectScreen extends MenuScreen {
uri.setMessageText(game.messages.get("menu.connect.uri.hint"));
uri.setSize(0.4f * WizardGame.WIDTH, 64);
uri.setPosition(0.5f * (WizardGame.WIDTH - uri.getWidth()), 0.45f * (WizardGame.HEIGHT - uri.getHeight()));
uri.addListener(new ResetErrorListener(game.data.skin));
Gdx.input.setInputProcessor(game.data.stage);
game.data.stage.addActor(buttonBack);

@ -7,9 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Array;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener;
import eu.jonahbauer.wizard.client.libgdx.state.AwaitingJoinSession;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage;
import eu.jonahbauer.wizard.common.model.Configuration;
import lombok.extern.log4j.Log4j2;
@ -24,13 +22,16 @@ public class CreateGameScreen extends MenuScreen {
private TextField timeOut;
private SelectBox<String> configurations;
private final Lobby state;
private String oldPlayerName;
private final ChangeListener listener = new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonBack) {
game.setScreen(new LobbyScreen(game));
game.getClient().execute(Lobby.class, (s, c) -> {
s.setPlayerName(playerName.getText());
return s.showListScreen(c);
});
sfxClick();
} else if (actor == buttonContinue) {
create();
@ -39,9 +40,9 @@ public class CreateGameScreen extends MenuScreen {
}
};
public CreateGameScreen(WizardGame game) {
public CreateGameScreen(WizardGame game, String playerName) {
super(game);
this.state = (Lobby) game.getClient().getState();
this.oldPlayerName = playerName;
}
@Override
@ -61,7 +62,7 @@ public class CreateGameScreen extends MenuScreen {
sessionName.addListener(errorListener);
sessionName.setProgrammaticChangeEvents(true);
playerName = new TextField(state.getPlayerName(), game.data.skin);
playerName = new TextField(oldPlayerName, game.data.skin);
playerName.setPosition(WizardGame.WIDTH * 0.3f, WizardGame.HEIGHT * 0.45f);
playerName.setSize(0.4f * WizardGame.WIDTH, 64);
playerName.addListener(errorListener);
@ -70,18 +71,17 @@ public class CreateGameScreen extends MenuScreen {
@Override
public void changed(ChangeEvent event, Actor actor) {
var old = state.getPlayerName();
state.setPlayerName(playerName.getText());
var player = playerName.getText();
var session = sessionName.getText();
if (session.isEmpty() || session.equals(format.formatted(old))) {
if (session.isEmpty() || session.equals(format.formatted(oldPlayerName))) {
if (player.isEmpty()) {
sessionName.setText("");
} else {
sessionName.setText(format.formatted(player));
}
}
oldPlayerName = playerName.getText();
}
};
playerName.addListener(playerNameListener);
@ -163,10 +163,11 @@ public class CreateGameScreen extends MenuScreen {
error = true;
}
var fConfig = config;
var fTimeout = timeout;
if (!error) {
var client = game.getClient();
client.transition(new AwaitingJoinSession(null, sessionName, config, playerName));
client.send(new CreateSessionMessage(sessionName, playerName, 1000 * timeout, config));
client.execute(Lobby.class, (s, c) -> s.createSession(c, sessionName, fConfig, 1000 * fTimeout, playerName));
}
}
}

@ -2,7 +2,6 @@ package eu.jonahbauer.wizard.client.libgdx.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;

@ -7,16 +7,10 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.actors.AutoFocusScrollPane;
import eu.jonahbauer.wizard.client.libgdx.listeners.ResetErrorListener;
import eu.jonahbauer.wizard.client.libgdx.state.AwaitingJoinSession;
import eu.jonahbauer.wizard.client.libgdx.state.Lobby;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage;
import eu.jonahbauer.wizard.common.messages.data.SessionData;
import lombok.extern.log4j.Log4j2;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.StreamSupport;
@ -32,32 +26,33 @@ public class LobbyScreen extends MenuScreen {
private Label labelSessionPlayerCount;
private Label labelSessionConfiguration;
private UUID selectedSession;
private final String oldPlayerName;
private SessionData selectedSession;
private List<SessionData> sessions;
private ScrollPane sessionListContainer;
private final Map<UUID, SessionData> sessionData = new HashMap<>();
private final Lobby state;
private final ChangeListener listener = new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonBack) {
game.getClient().transition(new Menu());
game.getClient().execute(Lobby.class, Lobby::disconnect);
sfxClick();
} else if (actor == buttonJoin) {
join();
sfxClick();
} else if (actor == buttonCreate) {
game.setScreen(new CreateGameScreen(game));
game.getClient().execute(Lobby.class, (s, c) -> {
s.setPlayerName(playerName.getText());
return s.showCreateScreen(c);
});
sfxClick();
}
}
};
public LobbyScreen(WizardGame game) {
public LobbyScreen(WizardGame game, String playerName) {
super(game);
this.state = (Lobby) game.getClient().getState();
this.oldPlayerName = playerName;
}
@Override
@ -112,13 +107,11 @@ public class LobbyScreen extends MenuScreen {
}
public void addSession(SessionData session) {
this.sessionData.put(session.getUuid(), session);
this.sessions.getItems().add(session);
this.sessions.invalidateHierarchy();
}
public void removeSession(UUID session) {
this.sessionData.remove(session);
var items = this.sessions.getItems();
for (int i = 0; i < items.size; i++) {
if (items.get(i).getUuid().equals(session)) {
@ -128,13 +121,12 @@ public class LobbyScreen extends MenuScreen {
}
this.sessions.invalidateHierarchy();
if (session.equals(selectedSession)) {
if (selectedSession != null && selectedSession.getUuid().equals(session)) {
updateData(null);
}
}
public void modifySession(SessionData session) {
this.sessionData.put(session.getUuid(), session);
var items = this.sessions.getItems();
for (int i = 0; i < items.size; i++) {
if (items.get(i).getUuid().equals(session.getUuid())) {
@ -144,17 +136,16 @@ public class LobbyScreen extends MenuScreen {
}
this.sessions.invalidateHierarchy();
if (session.getUuid().equals(selectedSession)) {
if (selectedSession != null && selectedSession.getUuid().equals(session.getUuid())) {
updateData(session);
}
}
public void setSessions(SessionData... sessions) {
this.sessionData.clear();
Arrays.stream(sessions).forEach(s -> this.sessionData.put(s.getUuid(), s));
var items = this.sessions.getItems();
items.clear();
items.addAll(sessions);
this.selectedSession = null;
this.sessions.invalidateHierarchy();
}
@ -163,7 +154,7 @@ public class LobbyScreen extends MenuScreen {
labelSessionName.setText(data.getName());
labelSessionPlayerCount.setText(Integer.toString(data.getPlayerCount()));
labelSessionConfiguration.setText(data.getConfiguration().toString());
selectedSession = data.getUuid();
selectedSession = data;
} else {
labelSessionName.setText("");
labelSessionPlayerCount.setText("");
@ -175,14 +166,8 @@ public class LobbyScreen extends MenuScreen {
private Table createInfoTable() {
float infoTableWidth = 0.3f * WizardGame.WIDTH - 20;
playerName = new TextField(state.getPlayerName(), game.data.skin);
playerName = new TextField(oldPlayerName, game.data.skin);
playerName.addListener(new ResetErrorListener(game.data.skin));
playerName.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
state.setPlayerName(playerName.getText());
}
});
labelSessionName = new Label("", game.data.skin, "textfield");
labelSessionConfiguration = new Label("", game.data.skin, "textfield");
@ -218,8 +203,7 @@ public class LobbyScreen extends MenuScreen {
error = true;
}
SessionData session = sessionData.get(selectedSession);
if (session == null) {
if (selectedSession == null) {
log.warn("Please select a session.");
this.sessionListContainer.setStyle(game.data.skin.get("error", ScrollPane.ScrollPaneStyle.class));
error = true;
@ -227,8 +211,7 @@ public class LobbyScreen extends MenuScreen {
if (!error) {
var client = game.getClient();
client.transition(new AwaitingJoinSession(session.getUuid(), session.getName(), session.getConfiguration(), playerName));
client.send(new JoinSessionMessage(selectedSession, playerName));
client.execute(Lobby.class, (s, c) -> s.joinSession(client, selectedSession, playerName));
}
}
}

@ -5,7 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import eu.jonahbauer.wizard.client.libgdx.state.Menu;
public class MainMenuScreen extends MenuScreen {
@ -16,11 +16,10 @@ public class MainMenuScreen extends MenuScreen {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonPlay) {
game.setScreen(new ConnectScreen(game));
game.getClient().execute(Menu.class, Menu::showConnectScreen);
sfxClick();
} else if (actor == buttonQuit) {
sfxClick();
dispose = true;
Gdx.app.exit();
}
}

@ -10,9 +10,6 @@ public abstract class MenuScreen implements Screen {
protected WizardGame game;
// shared game.data between all menu screens
protected boolean dispose;
public MenuScreen(WizardGame game) {
this.game = game;
}
@ -71,26 +68,16 @@ public abstract class MenuScreen implements Screen {
}
@Override
public void pause() {
}
public void pause() {}
@Override
public void resume() {
}
public void resume() {}
@Override
public void hide() {
}
public void hide() {}
@Override
public void dispose() {
if (dispose) {
game.data.dispose();
}
}
public void dispose() {}
protected void sfxClick() {
game.data.buttonClickSound.play(0.6f);

@ -1,15 +1,18 @@
package eu.jonahbauer.wizard.client.libgdx.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Align;
import eu.jonahbauer.wizard.client.libgdx.MenuAtlas;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.actors.AutoFocusScrollPane;
import eu.jonahbauer.wizard.client.libgdx.state.AwaitingJoinLobby;
import eu.jonahbauer.wizard.client.libgdx.state.Session;
import eu.jonahbauer.wizard.common.messages.client.LeaveSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.ReadyMessage;
import eu.jonahbauer.wizard.common.messages.data.PlayerData;
import eu.jonahbauer.wizard.common.model.Configuration;
@ -33,14 +36,10 @@ public class WaitingScreen extends MenuScreen {
@Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == buttonLeave) {
game.getClient().transition(new AwaitingJoinLobby());
game.getClient().send(new LeaveSessionMessage());
game.getClient().execute(Session.class, Session::leave);
sfxClick();
} else if (actor == buttonReady) {
var state = (Session) game.getClient().getState();
state.setNextReady(!state.isReady());
game.getClient().send(new ReadyMessage(!state.isReady()));
buttonReady.setDisabled(true);
game.getClient().execute(Session.class, Session::toggleReady);
sfxClick();
}
}
@ -60,10 +59,26 @@ public class WaitingScreen extends MenuScreen {
buttonReady.setPosition(WizardGame.WIDTH * 0.725f - buttonReady.getWidth(), BUTTON_BAR_Y);
players = new List<>(game.data.skin) {
private final TextureRegion ready = game.data.menuAtlas.findRegion(MenuAtlas.READY);
private final TextureRegion notReady = game.data.menuAtlas.findRegion(MenuAtlas.NOT_READY);
@Override
public String toString(PlayerData player) {
return player.getName();
}
@Override
@SuppressWarnings("SuspiciousNameCombination")
protected GlyphLayout drawItem(Batch batch, BitmapFont font, int index, PlayerData item, float x, float y, float width) {
String string = toString(item);
var height = font.getCapHeight();
if (item.isReady()) {
batch.draw(ready, x, y - height, height, height);
} else {
batch.draw(notReady, x, y - height, height, height);
}
return font.draw(batch, string, x + height + 8, y, 0, string.length(), width - height - 8, Align.left, false, "...");
}
};
listContainer = new AutoFocusScrollPane(players, game.data.skin);
@ -85,8 +100,11 @@ public class WaitingScreen extends MenuScreen {
buttonReady.addListener(listener);
}
public void setSending(boolean sending) {
buttonReady.setDisabled(sending);
}
public void setReady(boolean ready) {
buttonReady.setDisabled(false);
buttonReady.setText(game.messages.get(ready ? "menu.waiting.not_ready" : "menu.waiting.ready"));
}

@ -12,7 +12,7 @@ public class AwaitingConnection extends Awaiting {
@Override
public Optional<ClientState> onEnter(Client client) {
log.info("Awaiting connection...");
client.getGame().setScreen(new LoadingScreen(client.getGame()));
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.connecting"));
return super.onEnter(client);
}
@ -24,6 +24,7 @@ public class AwaitingConnection extends Awaiting {
@Override
public Optional<ClientState> onClose(Client client, int code, String reason, boolean remote) {
// TODO user feedback
log.error("Connection could not be established. (code={}, reason={}, remote={})", code, reason, remote);
return Optional.of(new Menu());
}

@ -14,7 +14,7 @@ public final class AwaitingJoinLobby extends Awaiting {
@Override
public Optional<ClientState> onEnter(Client client) {
log.info("Waiting for session list...");
client.getGame().setScreen(new LoadingScreen(client.getGame()));
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_lobby"));
return super.onEnter(client);
}

@ -2,6 +2,7 @@ package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.LoadingScreen;
import eu.jonahbauer.wizard.common.messages.data.SessionData;
import eu.jonahbauer.wizard.common.messages.server.*;
import eu.jonahbauer.wizard.common.model.Configuration;
import lombok.Getter;
@ -24,7 +25,7 @@ public final class AwaitingJoinSession extends Awaiting {
@Override
public Optional<ClientState> onEnter(Client client) {
log.info("Waiting for acknowledgment...");
client.getGame().setScreen(new LoadingScreen(client.getGame()));
client.getGame().setScreen(new LoadingScreen(client.getGame(), "menu.loading.joining_session"));
return super.onEnter(client);
}
@ -37,7 +38,11 @@ public final class AwaitingJoinSession extends Awaiting {
log.info("There are {} players in this session.", joined.getPlayers().size());
log.info("Your uuid is {}.", joined.getPlayer());
log.info("Your secret is {}.", joined.getSecret());
return Optional.of(new Session(joined, sessionName, configuration, playerName));
return Optional.of(new Session(
new SessionData(joined.getSession(), sessionName, -1, configuration),
joined.getPlayers(),
joined.getPlayer(), joined.getSecret()
));
}
} else if (message instanceof NackMessage nack) {
switch (nack.getCode()) {

@ -1,17 +1,22 @@
package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.CreateGameScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.LobbyScreen;
import eu.jonahbauer.wizard.common.messages.client.CreateSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.JoinSessionMessage;
import eu.jonahbauer.wizard.common.messages.data.SessionData;
import eu.jonahbauer.wizard.common.messages.server.*;
import eu.jonahbauer.wizard.common.model.Configuration;
import lombok.Getter;
import lombok.Setter;
import java.util.Optional;
import java.util.*;
public final class Lobby extends BaseState {
private SessionListMessage list;
private final Map<UUID, SessionData> sessions = new HashMap<>();
private LobbyScreen lobbyScreen;
@Getter
@ -19,35 +24,75 @@ public final class Lobby extends BaseState {
private String playerName = "";
public Lobby(SessionListMessage list) {
this.list = list;
list.getSessions().forEach(s -> sessions.put(s.getUuid(), s));
}
@Override
public Optional<ClientState> onEnter(Client client) {
lobbyScreen = new LobbyScreen(client.getGame());
client.getGame().setScreen(lobbyScreen);
lobbyScreen.setSessions(list.getSessions().toArray(new SessionData[0]));
list = null;
showListScreen(client);
return super.onEnter(client);
}
@Override
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof SessionCreatedMessage created) {
lobbyScreen.addSession(created.getSession());
var session = created.getSession();
sessions.put(session.getUuid(), session);
if (lobbyScreen != null) {
lobbyScreen.addSession(session);
}
return Optional.empty();
} else if (message instanceof SessionRemovedMessage removed) {
lobbyScreen.removeSession(removed.getSession());
var session = removed.getSession();
sessions.remove(session);
if (lobbyScreen != null) {
lobbyScreen.removeSession(session);
}
return Optional.empty();
} else if (message instanceof SessionModifiedMessage modified) {
lobbyScreen.modifySession(modified.getSession());
var session = modified.getSession();
sessions.put(session.getUuid(), session);
if (lobbyScreen != null) {
lobbyScreen.modifySession(session);
}
return Optional.empty();
} else if (message instanceof SessionListMessage list) {
list.getSessions().forEach(s -> sessions.put(s.getUuid(), s));
if (lobbyScreen != null) {
lobbyScreen.setSessions(list.getSessions().toArray(new SessionData[0]));
}
return Optional.empty();
} else {
return unexpectedMessage(client, message);
}
}
public Optional<ClientState> disconnect(@SuppressWarnings("unused") Client client) {
return Optional.of(new Menu());
}
public Optional<ClientState> createSession(Client client, String sessionName, Configuration config, long timeout, String playerName) {
client.send(new CreateSessionMessage(sessionName, playerName, timeout, config));
return Optional.of(new AwaitingJoinSession(null, sessionName, config, playerName));
}
public Optional<ClientState> joinSession(Client client, SessionData session, String playerName) {
client.send(new JoinSessionMessage(session.getUuid(), playerName));
return Optional.of(new AwaitingJoinSession(session.getUuid(), session.getName(), session.getConfiguration(), playerName));
}
public Optional<ClientState> showCreateScreen(Client client) {
var game = client.getGame();
lobbyScreen = null;
game.setScreen(new CreateGameScreen(game, playerName));
return Optional.empty();
}
public Optional<ClientState> showListScreen(Client client) {
var game = client.getGame();
lobbyScreen = new LobbyScreen(game, playerName);
game.setScreen(lobbyScreen);
lobbyScreen.setSessions(sessions.values().toArray(SessionData[]::new));
return Optional.empty();
}
}

@ -1,13 +1,18 @@
package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.ClientSocket;
import eu.jonahbauer.wizard.client.libgdx.screens.ConnectScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen;
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.java_websocket.framing.CloseFrame;
import java.net.URI;
import java.util.Optional;
@Log4j2
public final class Menu extends BaseState {
@Override
@ -16,7 +21,7 @@ public final class Menu extends BaseState {
if (client.getSocket() != null && client.getSocket().isOpen()) {
client.getSocket().close(CloseFrame.GOING_AWAY);
}
client.getGame().setScreen(new MainMenuScreen(client.getGame()));
showMenuScreen(client);
return super.onEnter(client);
}
@ -24,6 +29,7 @@ public final class Menu extends BaseState {
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
// it is possible that there are messages still queued after
// returning to the menu as a result of a previous message
log.debug("Dropped message {}.", message);
return Optional.empty();
}
@ -32,4 +38,23 @@ public final class Menu extends BaseState {
super.onClose(client, code, reason, remote);
return Optional.empty();
}
public Optional<ClientState> showConnectScreen(Client client) {
var game = client.getGame();
game.setScreen(new ConnectScreen(game));
return Optional.empty();
}
public Optional<ClientState> showMenuScreen(Client client) {
var game = client.getGame();
game.setScreen(new MainMenuScreen(game));
return Optional.empty();
}
public Optional<ClientState> connect(Client client, URI uri) {
ClientSocket socket = new ClientSocket(uri);
client.setSocket(socket);
socket.connect();
return Optional.of(new AwaitingConnection());
}
}

@ -1,23 +1,22 @@
package eu.jonahbauer.wizard.client.libgdx.state;
import eu.jonahbauer.wizard.client.libgdx.Client;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.client.libgdx.screens.WaitingScreen;
import eu.jonahbauer.wizard.common.messages.client.LeaveSessionMessage;
import eu.jonahbauer.wizard.common.messages.client.ReadyMessage;
import eu.jonahbauer.wizard.common.messages.data.PlayerData;
import eu.jonahbauer.wizard.common.messages.data.SessionData;
import eu.jonahbauer.wizard.common.messages.server.*;
import eu.jonahbauer.wizard.common.model.Configuration;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
@Log4j2
@Getter
public final class Session extends BaseState {
private SessionJoinedMessage joined;
private WaitingScreen sessionScreen;
private final UUID self;
@ -26,32 +25,29 @@ public final class Session extends BaseState {
private final UUID session;
private final String sessionName;
private final Configuration configuration;
private final String playerName;
private final List<PlayerData> players = new ArrayList<>();
private boolean sending;
private boolean ready;
@Setter
private Boolean nextReady;
public Session(SessionData session, Collection<PlayerData> players, UUID self, String secret) {
this.session = session.getUuid();
this.sessionName = session.getName();
this.configuration = session.getConfiguration();
this.players.addAll(players);
public Session(SessionJoinedMessage joined, String sessionName, Configuration configuration, String playerName) {
this.self = joined.getPlayer();
this.secret = joined.getSecret();
this.session = joined.getSession();
this.sessionName = sessionName;
this.configuration = configuration;
this.joined = joined;
this.playerName = playerName;
this.self = self;
this.secret = secret;
}
@Override
public Optional<ClientState> onEnter(Client client) {
sessionScreen = new WaitingScreen(client.getGame());
client.getGame().setScreen(sessionScreen);
sessionScreen.setPlayers(joined.getPlayers().toArray(new PlayerData[0]));
sessionScreen.setPlayers(players.toArray(new PlayerData[0]));
sessionScreen.setReady(false);
sessionScreen.setPlayerName(playerName);
sessionScreen.setPlayerName(getName());
sessionScreen.setSession(session, sessionName, configuration);
joined = null;
return super.onEnter(client);
}
@ -59,29 +55,80 @@ public final class Session extends BaseState {
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof PlayerJoinedMessage join) {
sessionScreen.addPlayer(join.getPlayer());
players.add(join.getPlayer());
return Optional.empty();
} else if (message instanceof PlayerLeftMessage leave) {
sessionScreen.removePlayer(leave.getPlayer());
players.remove(new PlayerData(leave.getPlayer(), null, false));
return Optional.empty();
} else if (message instanceof PlayerModifiedMessage modified) {
sessionScreen.modifyPlayer(modified.getPlayer());
var player = modified.getPlayer();
sessionScreen.modifyPlayer(player);
players.remove(player);
players.add(player);
if (self.equals(player.getUuid())) {
sessionScreen.setReady(player.isReady());
}
return Optional.empty();
} else if (message instanceof StartingGameMessage) {
client.getGame().setScreen(new GameScreen(client.getGame()));
return Optional.empty();
} else if (nextReady != null && message instanceof NackMessage nack) {
// return Optional.of(new Game(
// self, session, sessionName, secret,
// players.stream().collect(Collectors.toMap(PlayerData::getUuid, PlayerData::getName))
// ));
} else if (sending && message instanceof NackMessage nack) {
// TODO display error
log.error(nack.getMessage());
sessionScreen.setReady(!nextReady);
nextReady = null;
sending = false;
sessionScreen.setSending(false);
return Optional.empty();
} else if (nextReady != null && message instanceof AckMessage) {
sessionScreen.setReady(nextReady);
ready = nextReady;
nextReady = null;
} else if (sending && message instanceof AckMessage) {
sending = false;
sessionScreen.setSending(false);
return Optional.empty();
} else {
return unexpectedMessage(client, message);
}
}
public Optional<ClientState> setReady(Client client, boolean ready) {
if (sending) {
log.warn("Please slow down");
} else {
sending = true;
sessionScreen.setSending(true);
client.send(new ReadyMessage(ready));
}
return Optional.empty();
}
public Optional<ClientState> toggleReady(Client client) {
return setReady(client, !isReady());
}
public Optional<ClientState> leave(Client client) {
client.send(new LeaveSessionMessage());
return Optional.of(new AwaitingJoinLobby());
}
private boolean isReady() {
for (PlayerData player : players) {
if (self.equals(player.getUuid())) {
return player.isReady();
}
}
throw new NoSuchElementException();
}
private String getName() {
for (PlayerData player : players) {
if (self.equals(player.getUuid())) {
return player.getName();
}
}
throw new NoSuchElementException();
}
}

@ -23,6 +23,9 @@ menu.create_game.back=Back
menu.create_game.create=Create
menu.loading.loading=Loading...
menu.loading.connecting=Connecting...
menu.loading.joining_session=Joining session...
menu.loading.joining_lobby=Joining lobby...
menu.loading.back=Return To Main Menu
menu.waiting.ready=Ready

@ -10,7 +10,7 @@ menu.lobby.join=Beitreten
menu.lobby.create=Erstellen
menu.lobby.back=Verlassen
menu.lobby.player_name.label=Spielername
menu.lobby.session_name.label=Session Name
menu.lobby.session_name.label=Sitzungsname
menu.lobby.session_player_count.label=Spieleranzahl
menu.lobby.session_configuration.label=Spielvariante
@ -23,6 +23,9 @@ menu.create_game.back=Zurück
menu.create_game.create=Erstellen
menu.loading.loading=Laden...
menu.loading.connecting=Verbinde...
menu.loading.joining_session=Trete Sitzung bei...
menu.loading.joining_lobby=Trete Warteraum bei...
menu.loading.back=Zurück zum Hauptmenü
menu.waiting.ready=Bereit
@ -30,6 +33,6 @@ menu.waiting.not_ready=Nicht Bereit
menu.waiting.leave=Verlassen
menu.waiting.player_name.label=Eigener Name
menu.waiting.session_name.label=Session Name
menu.waiting.session_uuid.label=Session UUID
menu.waiting.session_name.label=Sitzungsname
menu.waiting.session_uuid.label=Sitzungs-ID
menu.waiting.session_configuration.label=Spielvariante

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

After

Width:  |  Height:  |  Size: 102 B

Loading…
Cancel
Save