improved menus in libGDX client
This commit is contained in:
parent
0fcf612841
commit
b0e6df12c8
@ -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;
|
||||
|
||||
@ -31,33 +25,34 @@ public class LobbyScreen extends MenuScreen {
|
||||
private Label labelSessionName;
|
||||
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) {
|
||||
lobbyScreen.setSessions(list.getSessions().toArray(new SessionData[0]));
|
||||
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 ready;
|
||||
@Setter
|
||||
private Boolean nextReady;
|
||||
private boolean sending;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
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…
x
Reference in New Issue
Block a user