added "end card"
This commit is contained in:
parent
87577d5779
commit
c614af3d8d
@ -1,23 +1,19 @@
|
||||
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.TextureRegion;
|
||||
import com.badlogic.gdx.math.Interpolation;
|
||||
import com.badlogic.gdx.scenes.scene2d.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.Action;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
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.screens.GameScreen;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
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 {
|
||||
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.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.actors.PadOfTruth;
|
||||
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;
|
||||
|
||||
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);
|
||||
padOfTruth = Objects.requireNonNull(gameScreen.getPadOfTruth());
|
||||
this.finalScores = finalScores;
|
||||
this.padOfTruth = Objects.requireNonNull(gameScreen.getPadOfTruth());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Actor createContent() {
|
||||
var group = new Group();
|
||||
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;
|
||||
}
|
||||
|
||||
@ -35,20 +58,32 @@ public class ScoreOverlay extends Overlay {
|
||||
var root = getRoot().fill();
|
||||
super.show(parent);
|
||||
|
||||
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, OVERLAY_SHARED_ELEMENT))
|
||||
),
|
||||
delay(AnimationTimings.OVERLAY_HOLD),
|
||||
parallel(
|
||||
targeting(padOfTruth, scaleTo(PadOfTruth.COLLAPSED_SCALE, PadOfTruth.COLLAPSED_SCALE, OVERLAY_SHARED_ELEMENT)),
|
||||
targeting(padOfTruth, moveTo(PAD_OF_TRUTH_POSITION.x, PAD_OF_TRUTH_POSITION.y, OVERLAY_SHARED_ELEMENT))
|
||||
),
|
||||
targeting(padOfTruth, changeParent(screen.getContentRoot())),
|
||||
run(() -> padOfTruth.setEnabled(true)),
|
||||
run(this::close)
|
||||
));
|
||||
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(
|
||||
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, OVERLAY_SHARED_ELEMENT))
|
||||
),
|
||||
delay(AnimationTimings.OVERLAY_HOLD),
|
||||
parallel(
|
||||
targeting(padOfTruth, scaleTo(PadOfTruth.COLLAPSED_SCALE, PadOfTruth.COLLAPSED_SCALE, OVERLAY_SHARED_ELEMENT)),
|
||||
targeting(padOfTruth, moveTo(PAD_OF_TRUTH_POSITION.x, PAD_OF_TRUTH_POSITION.y, OVERLAY_SHARED_ELEMENT) )
|
||||
),
|
||||
targeting(padOfTruth, changeParent(screen.getContentRoot())),
|
||||
run(() -> padOfTruth.setEnabled(true)),
|
||||
run(this::close)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.PadOfTruth;
|
||||
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.CardUtil;
|
||||
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));
|
||||
}
|
||||
|
||||
public void showSessionScreen() {
|
||||
game.getClient().execute(Session.class, Session::showInfoScreen);
|
||||
}
|
||||
|
||||
//<editor-fold desc="UI">
|
||||
public void dim(int layer, boolean dim) {
|
||||
var old = dimLayer;
|
||||
@ -773,8 +778,8 @@ public class GameScreen extends WizardScreen {
|
||||
return overlay;
|
||||
}
|
||||
|
||||
public void showScoreOverlay() {
|
||||
execute(new ScoreOverlay(this));
|
||||
public void showScoreOverlay(boolean finalScores) {
|
||||
execute(new ScoreOverlay(this, finalScores));
|
||||
}
|
||||
|
||||
public InteractionOverlay showMakePredictionOverlay(int round, long timeout) {
|
||||
|
@ -68,6 +68,8 @@ public final class Game extends BaseState {
|
||||
private Card juggleCard;
|
||||
private boolean werewolf;
|
||||
|
||||
private int finishing = 0;
|
||||
|
||||
public void init(List<ObserverMessage> messages) {
|
||||
pendingMessages = messages;
|
||||
}
|
||||
@ -104,11 +106,16 @@ public final class Game extends BaseState {
|
||||
}
|
||||
|
||||
private Optional<ClientState> onMessage(ObserverMessage message) {
|
||||
if (finishing != 0) return onMessageWhileFinishing(message);
|
||||
|
||||
if (message instanceof StateMessage state) {
|
||||
switch (state.getState()) {
|
||||
case "starting_round" -> onStartRound();
|
||||
case "starting_round" -> {
|
||||
return onStartRound();
|
||||
}
|
||||
case "starting_trick" -> onStartTrick();
|
||||
case "juggling" -> onJuggle();
|
||||
case "finishing_round" -> onFinishingRound();
|
||||
case "finished" -> {
|
||||
onFinished();
|
||||
return returnToSession();
|
||||
@ -129,20 +136,44 @@ public final class Game extends BaseState {
|
||||
} else if (message instanceof CardMessage card) {
|
||||
onCardMessage(card.getPlayer(), card.getCard());
|
||||
} else if (message instanceof ScoreMessage score) {
|
||||
onScoreMessage(score.getPoints());
|
||||
onScoreMessage(score.getPoints(), true);
|
||||
} else if (message instanceof UserInputMessage input) {
|
||||
onUserInputMessage(input.getPlayer(), input.getAction(), input.getTimeout());
|
||||
} else if (message instanceof TimeoutMessage) {
|
||||
onTimeoutMessage();
|
||||
} else {
|
||||
log.fatal("Unknown observer message type {}.", message.getClass());
|
||||
// TODO user feedback
|
||||
return Optional.of(new Menu());
|
||||
return unexpectedMessage(new GameMessage(message));
|
||||
}
|
||||
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);
|
||||
|
||||
round ++;
|
||||
@ -153,6 +184,7 @@ public final class Game extends BaseState {
|
||||
trick = -1;
|
||||
|
||||
if (gameScreen != null) gameScreen.startRound(round);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void onStartTrick() {
|
||||
@ -168,8 +200,15 @@ public final class Game extends BaseState {
|
||||
juggleCard = null;
|
||||
}
|
||||
|
||||
private void onFinishingRound() {
|
||||
if (isLastRound()) finishing = 1; // start finish procedure
|
||||
}
|
||||
|
||||
private void onFinished() {
|
||||
log.info("The game has finished.");
|
||||
if (gameScreen != null) {
|
||||
gameScreen.showScoreOverlay(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void onError() {
|
||||
@ -256,12 +295,12 @@ public final class Game extends BaseState {
|
||||
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);
|
||||
scores.put(round, points);
|
||||
if (gameScreen != null) {
|
||||
gameScreen.addScores(round, points);
|
||||
gameScreen.showScoreOverlay();
|
||||
if (showOverlay) gameScreen.showScoreOverlay(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +431,8 @@ public final class Game extends BaseState {
|
||||
players.entrySet().stream()
|
||||
.map(entry -> new PlayerData(entry.getKey(), entry.getValue(), false))
|
||||
.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">
|
||||
|
||||
/**
|
||||
|
@ -24,27 +24,29 @@ public final class Session extends BaseState {
|
||||
private final String sessionName;
|
||||
private final Configuration configuration;
|
||||
private final LinkedHashMap<UUID, PlayerData> players = new LinkedHashMap<>();
|
||||
private final boolean dontSwitchScreen;
|
||||
|
||||
private boolean sending;
|
||||
|
||||
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.sessionName = session.getName();
|
||||
this.configuration = session.getConfiguration();
|
||||
players.forEach(p -> this.players.put(p.getUuid(), p));
|
||||
this.dontSwitchScreen = dontSwitchScreen;
|
||||
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ClientState> onEnter(Client client) {
|
||||
sessionScreen = new WaitingScreen(client.getGame());
|
||||
client.getGame().setScreen(sessionScreen);
|
||||
sessionScreen.setPlayers(players.values().toArray(new PlayerData[0]));
|
||||
sessionScreen.setReady(false);
|
||||
sessionScreen.setPlayerName(getName());
|
||||
sessionScreen.setSession(session, sessionName, configuration);
|
||||
|
||||
if (!dontSwitchScreen) {
|
||||
showInfoScreen(client);
|
||||
}
|
||||
return super.onEnter(client);
|
||||
}
|
||||
|
||||
@ -112,6 +114,16 @@ public final class Session extends BaseState {
|
||||
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() {
|
||||
return players.get(self).isReady();
|
||||
}
|
||||
|
@ -236,4 +236,6 @@ game.overlay.play_colored_card.prompt=Pick a color
|
||||
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.cancel=Cancel
|
||||
game.overlay.play_changeling.cancel=Cancel
|
||||
|
||||
game.overlay.scores.return_to_session=Done
|
@ -226,4 +226,6 @@ game.overlay.play_colored_card.prompt=Wähle eine Farbe
|
||||
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.cancel=Abbrechen
|
||||
game.overlay.play_changeling.cancel=Abbrechen
|
||||
|
||||
game.overlay.scores.return_to_session=Fertig
|
Loading…
x
Reference in New Issue
Block a user