added "end card"
This commit is contained in:
parent
c41caeef59
commit
eef8f4ac40
@ -1,23 +1,19 @@
|
|||||||
package eu.jonahbauer.wizard.client.libgdx.actions.overlay;
|
package eu.jonahbauer.wizard.client.libgdx.actions.overlay;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.scenes.scene2d.Action;
|
||||||
import com.badlogic.gdx.math.Interpolation;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.*;
|
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
|
||||||
import com.badlogic.gdx.utils.I18NBundle;
|
import com.badlogic.gdx.utils.I18NBundle;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings;
|
|
||||||
import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas;
|
|
||||||
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
|
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
|
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.run;
|
||||||
|
|
||||||
public abstract class Overlay extends Action {
|
public abstract class Overlay extends Action {
|
||||||
protected final GameScreen screen;
|
protected final GameScreen screen;
|
||||||
|
@ -2,6 +2,8 @@ package eu.jonahbauer.wizard.client.libgdx.actions.overlay;
|
|||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||||
|
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.client.libgdx.WizardGame;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.actors.PadOfTruth;
|
import eu.jonahbauer.wizard.client.libgdx.actors.PadOfTruth;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
|
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
|
||||||
@ -16,17 +18,38 @@ import static eu.jonahbauer.wizard.client.libgdx.screens.GameScreen.PAD_OF_TRUTH
|
|||||||
import static eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings.OVERLAY_SHARED_ELEMENT;
|
import static eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings.OVERLAY_SHARED_ELEMENT;
|
||||||
|
|
||||||
public class ScoreOverlay extends Overlay {
|
public class ScoreOverlay extends Overlay {
|
||||||
private final PadOfTruth padOfTruth;
|
private final boolean finalScores;
|
||||||
|
|
||||||
public ScoreOverlay(@NotNull GameScreen gameScreen) {
|
private final PadOfTruth padOfTruth;
|
||||||
|
private TextButton back;
|
||||||
|
|
||||||
|
public ScoreOverlay(@NotNull GameScreen gameScreen, boolean finalScores) {
|
||||||
super(gameScreen, Long.MAX_VALUE);
|
super(gameScreen, Long.MAX_VALUE);
|
||||||
padOfTruth = Objects.requireNonNull(gameScreen.getPadOfTruth());
|
this.finalScores = finalScores;
|
||||||
|
this.padOfTruth = Objects.requireNonNull(gameScreen.getPadOfTruth());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Actor createContent() {
|
protected Actor createContent() {
|
||||||
var group = new Group();
|
var group = new Group();
|
||||||
group.addActor(padOfTruth);
|
group.addActor(padOfTruth);
|
||||||
|
|
||||||
|
if (finalScores) {
|
||||||
|
back = new TextButton(messages.get("game.overlay.scores.return_to_session"), skin);
|
||||||
|
back.setPosition(
|
||||||
|
(WizardGame.WIDTH - back.getWidth()) / 2,
|
||||||
|
(WizardGame.HEIGHT - padOfTruth.getHeight()) / 2 + 30 - back.getHeight()
|
||||||
|
);
|
||||||
|
back.setVisible(false);
|
||||||
|
back.addListener(new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
|
screen.showSessionScreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
group.addActor(back);
|
||||||
|
}
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +58,17 @@ public class ScoreOverlay extends Overlay {
|
|||||||
var root = getRoot().fill();
|
var root = getRoot().fill();
|
||||||
super.show(parent);
|
super.show(parent);
|
||||||
|
|
||||||
|
if (finalScores) {
|
||||||
|
root.addAction(sequence(
|
||||||
|
run(() -> padOfTruth.setEnabled(false)),
|
||||||
|
parallel(
|
||||||
|
targeting(padOfTruth, scaleTo(1, 1, OVERLAY_SHARED_ELEMENT)),
|
||||||
|
targeting(padOfTruth, moveTo((WizardGame.WIDTH - padOfTruth.getWidth()) / 2,(WizardGame.HEIGHT - padOfTruth.getHeight()) / 2 + 50, OVERLAY_SHARED_ELEMENT))
|
||||||
|
),
|
||||||
|
delay(AnimationTimings.OVERLAY_HOLD),
|
||||||
|
targeting(back, visible(true))
|
||||||
|
));
|
||||||
|
} else {
|
||||||
root.addAction(sequence(
|
root.addAction(sequence(
|
||||||
run(() -> padOfTruth.setEnabled(false)),
|
run(() -> padOfTruth.setEnabled(false)),
|
||||||
parallel(
|
parallel(
|
||||||
@ -52,3 +86,4 @@ public class ScoreOverlay extends Overlay {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ import eu.jonahbauer.wizard.client.libgdx.actors.CardStack;
|
|||||||
import eu.jonahbauer.wizard.client.libgdx.actors.CardsGroup;
|
import eu.jonahbauer.wizard.client.libgdx.actors.CardsGroup;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.actors.PadOfTruth;
|
import eu.jonahbauer.wizard.client.libgdx.actors.PadOfTruth;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.state.Game;
|
import eu.jonahbauer.wizard.client.libgdx.state.Game;
|
||||||
|
import eu.jonahbauer.wizard.client.libgdx.state.Session;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings;
|
import eu.jonahbauer.wizard.client.libgdx.util.AnimationTimings;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.util.CardUtil;
|
import eu.jonahbauer.wizard.client.libgdx.util.CardUtil;
|
||||||
import eu.jonahbauer.wizard.client.libgdx.util.Pair;
|
import eu.jonahbauer.wizard.client.libgdx.util.Pair;
|
||||||
@ -357,6 +358,10 @@ public class GameScreen extends WizardScreen {
|
|||||||
game.getClient().execute(Game.class, (s, c) -> s.onPredictionMade(c, prediction));
|
game.getClient().execute(Game.class, (s, c) -> s.onPredictionMade(c, prediction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showSessionScreen() {
|
||||||
|
game.getClient().execute(Session.class, Session::showInfoScreen);
|
||||||
|
}
|
||||||
|
|
||||||
//<editor-fold desc="UI">
|
//<editor-fold desc="UI">
|
||||||
public void dim(int layer, boolean dim) {
|
public void dim(int layer, boolean dim) {
|
||||||
var old = dimLayer;
|
var old = dimLayer;
|
||||||
@ -773,8 +778,8 @@ public class GameScreen extends WizardScreen {
|
|||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showScoreOverlay() {
|
public void showScoreOverlay(boolean finalScores) {
|
||||||
execute(new ScoreOverlay(this));
|
execute(new ScoreOverlay(this, finalScores));
|
||||||
}
|
}
|
||||||
|
|
||||||
public InteractionOverlay showMakePredictionOverlay(int round, long timeout) {
|
public InteractionOverlay showMakePredictionOverlay(int round, long timeout) {
|
||||||
|
@ -68,6 +68,8 @@ public final class Game extends BaseState {
|
|||||||
private Card juggleCard;
|
private Card juggleCard;
|
||||||
private boolean werewolf;
|
private boolean werewolf;
|
||||||
|
|
||||||
|
private int finishing = 0;
|
||||||
|
|
||||||
public void init(List<ObserverMessage> messages) {
|
public void init(List<ObserverMessage> messages) {
|
||||||
pendingMessages = messages;
|
pendingMessages = messages;
|
||||||
}
|
}
|
||||||
@ -104,11 +106,16 @@ public final class Game extends BaseState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientState> onMessage(ObserverMessage message) {
|
private Optional<ClientState> onMessage(ObserverMessage message) {
|
||||||
|
if (finishing != 0) return onMessageWhileFinishing(message);
|
||||||
|
|
||||||
if (message instanceof StateMessage state) {
|
if (message instanceof StateMessage state) {
|
||||||
switch (state.getState()) {
|
switch (state.getState()) {
|
||||||
case "starting_round" -> onStartRound();
|
case "starting_round" -> {
|
||||||
|
return onStartRound();
|
||||||
|
}
|
||||||
case "starting_trick" -> onStartTrick();
|
case "starting_trick" -> onStartTrick();
|
||||||
case "juggling" -> onJuggle();
|
case "juggling" -> onJuggle();
|
||||||
|
case "finishing_round" -> onFinishingRound();
|
||||||
case "finished" -> {
|
case "finished" -> {
|
||||||
onFinished();
|
onFinished();
|
||||||
return returnToSession();
|
return returnToSession();
|
||||||
@ -129,20 +136,44 @@ public final class Game extends BaseState {
|
|||||||
} else if (message instanceof CardMessage card) {
|
} else if (message instanceof CardMessage card) {
|
||||||
onCardMessage(card.getPlayer(), card.getCard());
|
onCardMessage(card.getPlayer(), card.getCard());
|
||||||
} else if (message instanceof ScoreMessage score) {
|
} else if (message instanceof ScoreMessage score) {
|
||||||
onScoreMessage(score.getPoints());
|
onScoreMessage(score.getPoints(), true);
|
||||||
} else if (message instanceof UserInputMessage input) {
|
} else if (message instanceof UserInputMessage input) {
|
||||||
onUserInputMessage(input.getPlayer(), input.getAction(), input.getTimeout());
|
onUserInputMessage(input.getPlayer(), input.getAction(), input.getTimeout());
|
||||||
} else if (message instanceof TimeoutMessage) {
|
} else if (message instanceof TimeoutMessage) {
|
||||||
onTimeoutMessage();
|
onTimeoutMessage();
|
||||||
} else {
|
} else {
|
||||||
log.fatal("Unknown observer message type {}.", message.getClass());
|
return unexpectedMessage(new GameMessage(message));
|
||||||
// TODO user feedback
|
|
||||||
return Optional.of(new Menu());
|
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onStartRound() {
|
private Optional<ClientState> onMessageWhileFinishing(ObserverMessage message) {
|
||||||
|
if (finishing == 1) { // last "finishing_round" has been received
|
||||||
|
if (message instanceof ScoreMessage score) {
|
||||||
|
onScoreMessage(score.getPoints(), false);
|
||||||
|
return Optional.empty();
|
||||||
|
} else if (message instanceof StateMessage state && "finishing".equals(state.getState())) {
|
||||||
|
finishing++;
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
} else if (finishing == 2) { // "finishing" has been received
|
||||||
|
if (message instanceof ScoreMessage) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else if (message instanceof StateMessage state && "finished".equals(state.getState())) {
|
||||||
|
onFinished();
|
||||||
|
finishing++;
|
||||||
|
return returnToSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unexpectedMessage(new GameMessage(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientState> onStartRound() {
|
||||||
|
if (isLastRound()) {
|
||||||
|
log.fatal("Cannot start round {} with {} players", round + 1, players.size());
|
||||||
|
return unexpectedMessage(new GameMessage(new StateMessage("starting_round")));
|
||||||
|
}
|
||||||
log.info("Round {} is starting...", round + 1);
|
log.info("Round {} is starting...", round + 1);
|
||||||
|
|
||||||
round ++;
|
round ++;
|
||||||
@ -153,6 +184,7 @@ public final class Game extends BaseState {
|
|||||||
trick = -1;
|
trick = -1;
|
||||||
|
|
||||||
if (gameScreen != null) gameScreen.startRound(round);
|
if (gameScreen != null) gameScreen.startRound(round);
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onStartTrick() {
|
private void onStartTrick() {
|
||||||
@ -168,8 +200,15 @@ public final class Game extends BaseState {
|
|||||||
juggleCard = null;
|
juggleCard = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onFinishingRound() {
|
||||||
|
if (isLastRound()) finishing = 1; // start finish procedure
|
||||||
|
}
|
||||||
|
|
||||||
private void onFinished() {
|
private void onFinished() {
|
||||||
log.info("The game has finished.");
|
log.info("The game has finished.");
|
||||||
|
if (gameScreen != null) {
|
||||||
|
gameScreen.showScoreOverlay(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onError() {
|
private void onError() {
|
||||||
@ -256,12 +295,12 @@ public final class Game extends BaseState {
|
|||||||
if (gameScreen != null) gameScreen.playCard(player, handCard, card);
|
if (gameScreen != null) gameScreen.playCard(player, handCard, card);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScoreMessage(@Unmodifiable Map<@NotNull UUID, @NotNull Integer> points) {
|
private void onScoreMessage(@Unmodifiable Map<@NotNull UUID, @NotNull Integer> points, boolean showOverlay) {
|
||||||
log.info("The scores are as follows: " + points);
|
log.info("The scores are as follows: " + points);
|
||||||
scores.put(round, points);
|
scores.put(round, points);
|
||||||
if (gameScreen != null) {
|
if (gameScreen != null) {
|
||||||
gameScreen.addScores(round, points);
|
gameScreen.addScores(round, points);
|
||||||
gameScreen.showScoreOverlay();
|
if (showOverlay) gameScreen.showScoreOverlay(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +431,8 @@ public final class Game extends BaseState {
|
|||||||
players.entrySet().stream()
|
players.entrySet().stream()
|
||||||
.map(entry -> new PlayerData(entry.getKey(), entry.getValue(), false))
|
.map(entry -> new PlayerData(entry.getKey(), entry.getValue(), false))
|
||||||
.toList(),
|
.toList(),
|
||||||
self
|
self,
|
||||||
|
true
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +549,10 @@ public final class Game extends BaseState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isLastRound() {
|
||||||
|
return round + 1 >= 60 / getPlayers().size();
|
||||||
|
}
|
||||||
|
|
||||||
//<editor-fold desc="Logging" defaultState="collapsed">
|
//<editor-fold desc="Logging" defaultState="collapsed">
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,27 +24,29 @@ public final class Session extends BaseState {
|
|||||||
private final String sessionName;
|
private final String sessionName;
|
||||||
private final Configuration configuration;
|
private final Configuration configuration;
|
||||||
private final LinkedHashMap<UUID, PlayerData> players = new LinkedHashMap<>();
|
private final LinkedHashMap<UUID, PlayerData> players = new LinkedHashMap<>();
|
||||||
|
private final boolean dontSwitchScreen;
|
||||||
|
|
||||||
private boolean sending;
|
private boolean sending;
|
||||||
|
|
||||||
public Session(SessionData session, Collection<PlayerData> players, UUID self) {
|
public Session(SessionData session, Collection<PlayerData> players, UUID self) {
|
||||||
|
this(session, players, self, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session(SessionData session, Collection<PlayerData> players, UUID self, boolean dontSwitchScreen) {
|
||||||
this.session = session.getUuid();
|
this.session = session.getUuid();
|
||||||
this.sessionName = session.getName();
|
this.sessionName = session.getName();
|
||||||
this.configuration = session.getConfiguration();
|
this.configuration = session.getConfiguration();
|
||||||
players.forEach(p -> this.players.put(p.getUuid(), p));
|
players.forEach(p -> this.players.put(p.getUuid(), p));
|
||||||
|
this.dontSwitchScreen = dontSwitchScreen;
|
||||||
|
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ClientState> onEnter(Client client) {
|
public Optional<ClientState> onEnter(Client client) {
|
||||||
sessionScreen = new WaitingScreen(client.getGame());
|
if (!dontSwitchScreen) {
|
||||||
client.getGame().setScreen(sessionScreen);
|
showInfoScreen(client);
|
||||||
sessionScreen.setPlayers(players.values().toArray(new PlayerData[0]));
|
}
|
||||||
sessionScreen.setReady(false);
|
|
||||||
sessionScreen.setPlayerName(getName());
|
|
||||||
sessionScreen.setSession(session, sessionName, configuration);
|
|
||||||
|
|
||||||
return super.onEnter(client);
|
return super.onEnter(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +114,16 @@ public final class Session extends BaseState {
|
|||||||
return Optional.of(new AwaitingJoinLobby());
|
return Optional.of(new AwaitingJoinLobby());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<ClientState> showInfoScreen(Client client) {
|
||||||
|
sessionScreen = new WaitingScreen(client.getGame());
|
||||||
|
client.getGame().setScreen(sessionScreen);
|
||||||
|
sessionScreen.setPlayers(players.values().toArray(new PlayerData[0]));
|
||||||
|
sessionScreen.setReady(players.get(self).isReady());
|
||||||
|
sessionScreen.setPlayerName(getName());
|
||||||
|
sessionScreen.setSession(session, sessionName, configuration);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isReady() {
|
private boolean isReady() {
|
||||||
return players.get(self).isReady();
|
return players.get(self).isReady();
|
||||||
}
|
}
|
||||||
|
@ -237,3 +237,5 @@ game.overlay.play_colored_card.cancel=Cancel
|
|||||||
|
|
||||||
game.overlay.play_changeling.prompt=Do you want to play the changeling as a wizard or a jester?
|
game.overlay.play_changeling.prompt=Do you want to play the changeling as a wizard or a jester?
|
||||||
game.overlay.play_changeling.cancel=Cancel
|
game.overlay.play_changeling.cancel=Cancel
|
||||||
|
|
||||||
|
game.overlay.scores.return_to_session=Done
|
@ -227,3 +227,5 @@ game.overlay.play_colored_card.cancel=Abbrechen
|
|||||||
|
|
||||||
game.overlay.play_changeling.prompt=Möchtest du den Gestaltwandler als Zauberer oder als Narr spielen?
|
game.overlay.play_changeling.prompt=Möchtest du den Gestaltwandler als Zauberer oder als Narr spielen?
|
||||||
game.overlay.play_changeling.cancel=Abbrechen
|
game.overlay.play_changeling.cancel=Abbrechen
|
||||||
|
|
||||||
|
game.overlay.scores.return_to_session=Fertig
|
Loading…
x
Reference in New Issue
Block a user