|
|
@ -3,14 +3,17 @@ package eu.jonahbauer.wizard.client.libgdx.screens;
|
|
|
|
import com.badlogic.gdx.Gdx;
|
|
|
|
import com.badlogic.gdx.Gdx;
|
|
|
|
import com.badlogic.gdx.graphics.Color;
|
|
|
|
import com.badlogic.gdx.graphics.Color;
|
|
|
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
|
|
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
|
|
|
|
|
|
|
import com.badlogic.gdx.math.Vector2;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.Action;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.Action;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
|
|
|
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.actions.MoveToAction;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
|
|
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
|
|
|
import com.badlogic.gdx.utils.Align;
|
|
|
|
import com.badlogic.gdx.utils.Align;
|
|
|
|
import com.badlogic.gdx.utils.I18NBundle;
|
|
|
|
import com.badlogic.gdx.utils.I18NBundle;
|
|
|
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.AnimationTimings;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.GameAtlas;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.GameAtlas;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
|
|
|
@ -19,10 +22,11 @@ import eu.jonahbauer.wizard.client.libgdx.actors.game.CardsGroup;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.PadOfTruth;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.PadOfTruth;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.overlay.*;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.overlay.*;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.state.Game;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.state.Game;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.util.Pair;
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.util.Triple;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.client.InteractionMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.client.InteractionMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.observer.UserInputMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.ContinueMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.ContinueMessage;
|
|
|
|
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.JuggleMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.PlayCardMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.PlayCardMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.messages.player.PlayerMessage;
|
|
|
|
import eu.jonahbauer.wizard.common.model.Card;
|
|
|
|
import eu.jonahbauer.wizard.common.model.Card;
|
|
|
@ -46,7 +50,7 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
private final List<UUID> players;
|
|
|
|
private final List<UUID> players;
|
|
|
|
|
|
|
|
|
|
|
|
private Pair<UUID, UserInputMessage.Action> activePlayer;
|
|
|
|
private Triple<UUID, UserInputMessage.Action, Long> activePlayer;
|
|
|
|
|
|
|
|
|
|
|
|
private CardsGroup handCards;
|
|
|
|
private CardsGroup handCards;
|
|
|
|
private CardStack cardStack;
|
|
|
|
private CardStack cardStack;
|
|
|
@ -69,6 +73,9 @@ public class GameScreen extends MenuScreen {
|
|
|
|
private final AtomicBoolean sending = new AtomicBoolean();
|
|
|
|
private final AtomicBoolean sending = new AtomicBoolean();
|
|
|
|
private final AtomicBoolean pendingSync = new AtomicBoolean();
|
|
|
|
private final AtomicBoolean pendingSync = new AtomicBoolean();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean juggling;
|
|
|
|
|
|
|
|
private Card juggledCard;
|
|
|
|
|
|
|
|
|
|
|
|
public GameScreen(WizardGame game) {
|
|
|
|
public GameScreen(WizardGame game) {
|
|
|
|
super(game);
|
|
|
|
super(game);
|
|
|
|
this.state = (Game) game.getClient().getState();
|
|
|
|
this.state = (Game) game.getClient().getState();
|
|
|
@ -88,7 +95,7 @@ public class GameScreen extends MenuScreen {
|
|
|
|
prepareLabels();
|
|
|
|
prepareLabels();
|
|
|
|
|
|
|
|
|
|
|
|
handCards = new CardsGroup(Collections.emptyList(), atlas);
|
|
|
|
handCards = new CardsGroup(Collections.emptyList(), atlas);
|
|
|
|
handCards.setOnClickListener(card -> send(new PlayCardMessage(card.getCard())));
|
|
|
|
handCards.setOnClickListener(this::onCardClicked);
|
|
|
|
var container = new Container<>(handCards);
|
|
|
|
var container = new Container<>(handCards);
|
|
|
|
container.setPosition(360, 75);
|
|
|
|
container.setPosition(360, 75);
|
|
|
|
container.setSize(1200, CardActor.PREF_HEIGHT);
|
|
|
|
container.setSize(1200, CardActor.PREF_HEIGHT);
|
|
|
@ -183,7 +190,7 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
private void prepareLabels() {
|
|
|
|
private void prepareLabels() {
|
|
|
|
for (UUID player : players) {
|
|
|
|
for (UUID player : players) {
|
|
|
|
if (state.getSelf().equals(player)) continue;
|
|
|
|
if (isSelf(player)) continue;
|
|
|
|
var label = new Label("", game.data.skin);
|
|
|
|
var label = new Label("", game.data.skin);
|
|
|
|
var seat = seats.get(player);
|
|
|
|
var seat = seats.get(player);
|
|
|
|
label.setX(seat.getLabelX());
|
|
|
|
label.setX(seat.getLabelX());
|
|
|
@ -199,12 +206,54 @@ public class GameScreen extends MenuScreen {
|
|
|
|
var player = players.get(i);
|
|
|
|
var player = players.get(i);
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
|
padOfTruth.setName(i, name);
|
|
|
|
padOfTruth.setName(i, name);
|
|
|
|
if (!state.getSelf().equals(player)) {
|
|
|
|
if (!isSelf(player)) {
|
|
|
|
nameLabels.get(player).setText(name);
|
|
|
|
nameLabels.get(player).setText(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void onCardClicked(CardActor actor) {
|
|
|
|
|
|
|
|
var card = actor.getCard();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (checkAction(PLAY_CARD)) {
|
|
|
|
|
|
|
|
var timeout = activePlayer.third();
|
|
|
|
|
|
|
|
if (card == Card.CLOUD) {
|
|
|
|
|
|
|
|
execute(new PlayColoredCardOverlay(this,
|
|
|
|
|
|
|
|
timeout,
|
|
|
|
|
|
|
|
Card.CLOUD,
|
|
|
|
|
|
|
|
Card.CLOUD_RED,
|
|
|
|
|
|
|
|
Card.CLOUD_GREEN,
|
|
|
|
|
|
|
|
Card.CLOUD_BLUE,
|
|
|
|
|
|
|
|
Card.CLOUD_YELLOW
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
} else if (card == Card.JUGGLER) {
|
|
|
|
|
|
|
|
execute(new PlayColoredCardOverlay(this,
|
|
|
|
|
|
|
|
timeout,
|
|
|
|
|
|
|
|
Card.JUGGLER,
|
|
|
|
|
|
|
|
Card.JUGGLER_RED,
|
|
|
|
|
|
|
|
Card.JUGGLER_GREEN,
|
|
|
|
|
|
|
|
Card.JUGGLER_BLUE,
|
|
|
|
|
|
|
|
Card.JUGGLER_YELLOW
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
send(new PlayCardMessage(card));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (checkAction(JUGGLE_CARD)) {
|
|
|
|
|
|
|
|
juggledCard = card;
|
|
|
|
|
|
|
|
send(new JuggleMessage(card));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
addMessage("You cannot do that right now.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean checkAction(UserInputMessage.Action action) {
|
|
|
|
|
|
|
|
return activePlayer != null && (activePlayer.first() == null || isSelf(activePlayer.first())) && activePlayer.second() == action;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isSelf(UUID uuid) {
|
|
|
|
|
|
|
|
return state.getSelf().equals(uuid);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void startRound(int round) {
|
|
|
|
public void startRound(int round) {
|
|
|
|
execute(parallel(
|
|
|
|
execute(parallel(
|
|
|
|
run(() -> {
|
|
|
|
run(() -> {
|
|
|
@ -224,35 +273,67 @@ public class GameScreen extends MenuScreen {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void startTrick() {
|
|
|
|
public void startTrick() {
|
|
|
|
setActivePlayer(null, null, 0);
|
|
|
|
clearActivePlayer();
|
|
|
|
execute(() -> cardStack.clearChildren());
|
|
|
|
execute(() -> cardStack.clearChildren());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Indicates that the next call to {@link #setHand(UUID, List)} should be animated.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public void setJuggling(boolean juggling) {
|
|
|
|
|
|
|
|
execute(() -> {
|
|
|
|
|
|
|
|
this.juggling = juggling;
|
|
|
|
|
|
|
|
if (juggling) {
|
|
|
|
|
|
|
|
handCards.setSelectMode(CardsGroup.SelectMode.SINGLE);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
handCards.setSelectMode(CardsGroup.SelectMode.NONE);
|
|
|
|
|
|
|
|
juggledCard = null;
|
|
|
|
|
|
|
|
handCards.setSelected(null);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void finishTrick(UUID player, List<Card> cards) {
|
|
|
|
public void finishTrick(UUID player, List<Card> cards) {
|
|
|
|
var seat = seats.get(player);
|
|
|
|
var seat = seats.get(player);
|
|
|
|
|
|
|
|
|
|
|
|
var action = parallel();
|
|
|
|
var action = parallel();
|
|
|
|
execute(sequence(
|
|
|
|
execute(sequence(
|
|
|
|
run(() -> cardStack.removeAll().forEach(card -> action.addAction(sequence(
|
|
|
|
run(() -> cardStack.removeAll().forEach(card -> {
|
|
|
|
targeting(card, changeParent(game.data.stage.getRoot())),
|
|
|
|
var angle = (card.getRotation() % 360 + 360) % 360;
|
|
|
|
parallel(
|
|
|
|
var rotation = rotateTo(angle < 90 || angle > 270 ? 0 : 180, AnimationTimings.STACK_FINISH_ROTATE);
|
|
|
|
targeting(card, rotateTo(0, 0.1f)),
|
|
|
|
rotation.setUseShortestDirection(true);
|
|
|
|
targeting(card, moveTo(
|
|
|
|
|
|
|
|
seat.getFrontX() - card.getWidth() / 2,
|
|
|
|
action.addAction(sequence(
|
|
|
|
seat.getFrontY() - card.getHeight() / 2,
|
|
|
|
targeting(card, changeParent(game.data.stage.getRoot())),
|
|
|
|
0.25f
|
|
|
|
parallel(
|
|
|
|
))
|
|
|
|
targeting(card, rotation),
|
|
|
|
),
|
|
|
|
targeting(card, moveTo(
|
|
|
|
targeting(card, alpha(0, 0.5f)),
|
|
|
|
seat.getFrontX() - card.getWidth() / 2,
|
|
|
|
removeActor(card)
|
|
|
|
seat.getFrontY() - card.getHeight() / 2,
|
|
|
|
)))),
|
|
|
|
AnimationTimings.STACK_FINISH_MOVE
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
targeting(card, alpha(0, AnimationTimings.STACK_FINISH_FADE)),
|
|
|
|
|
|
|
|
removeActor(card)
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
})),
|
|
|
|
action
|
|
|
|
action
|
|
|
|
));
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setHand(UUID player, List<Card> cards) {
|
|
|
|
public void setHand(UUID player, List<Card> cards) {
|
|
|
|
if (state.getSelf().equals(player)) {
|
|
|
|
if (isSelf(player)) {
|
|
|
|
execute(() -> handCards.update(cards));
|
|
|
|
var sequence = sequence();
|
|
|
|
|
|
|
|
sequence.addAction(run(() -> {
|
|
|
|
|
|
|
|
var changes = handCards.update(cards);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// animate card changes
|
|
|
|
|
|
|
|
if (juggling) {
|
|
|
|
|
|
|
|
setJuggling(false);
|
|
|
|
|
|
|
|
sequence.addAction(animateJuggle(changes.first(), changes.second()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
execute(sequence);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -268,7 +349,7 @@ public class GameScreen extends MenuScreen {
|
|
|
|
String player = null;
|
|
|
|
String player = null;
|
|
|
|
if (activePlayer != null && activePlayer.second() == PICK_TRUMP) {
|
|
|
|
if (activePlayer != null && activePlayer.second() == PICK_TRUMP) {
|
|
|
|
player = state.getPlayers().get(activePlayer.first());
|
|
|
|
player = state.getPlayers().get(activePlayer.first());
|
|
|
|
setActivePlayer(null, null, 0);
|
|
|
|
clearActivePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
execute(new TrumpOverlay(this, player, trumpCard, trumpSuit));
|
|
|
|
execute(new TrumpOverlay(this, player, trumpCard, trumpSuit));
|
|
|
@ -276,12 +357,13 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
public void addPrediction(int round, UUID player, int prediction) {
|
|
|
|
public void addPrediction(int round, UUID player, int prediction) {
|
|
|
|
boolean changed = false;
|
|
|
|
boolean changed = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (activePlayer != null && activePlayer.first().equals(player) && (activePlayer.second() == CHANGE_PREDICTION || activePlayer.second() == MAKE_PREDICTION)) {
|
|
|
|
if (activePlayer != null && activePlayer.first().equals(player) && (activePlayer.second() == CHANGE_PREDICTION || activePlayer.second() == MAKE_PREDICTION)) {
|
|
|
|
changed = activePlayer.second() == CHANGE_PREDICTION;
|
|
|
|
changed = activePlayer.second() == CHANGE_PREDICTION;
|
|
|
|
setActivePlayer(null, null, 0);
|
|
|
|
clearActivePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (state.getSelf().equals(player)) {
|
|
|
|
if (isSelf(player)) {
|
|
|
|
addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.self", prediction));
|
|
|
|
addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.self", prediction));
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
@ -293,10 +375,10 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
public void playCard(UUID player, Card card) {
|
|
|
|
public void playCard(UUID player, Card card) {
|
|
|
|
if (activePlayer != null && activePlayer.first().equals(player) && activePlayer.second() == PLAY_CARD) {
|
|
|
|
if (activePlayer != null && activePlayer.first().equals(player) && activePlayer.second() == PLAY_CARD) {
|
|
|
|
setActivePlayer(null, null, 0);
|
|
|
|
clearActivePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (state.getSelf().equals(player)) {
|
|
|
|
if (isSelf(player)) {
|
|
|
|
addMessage(game.messages.get("game.action.play_card.self"));
|
|
|
|
addMessage(game.messages.get("game.action.play_card.self"));
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
|
var name = state.getPlayers().get(player);
|
|
|
@ -307,18 +389,19 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
var sequence = sequence();
|
|
|
|
var sequence = sequence();
|
|
|
|
sequence.addAction(run(() -> {
|
|
|
|
sequence.addAction(run(() -> {
|
|
|
|
CardActor actor;
|
|
|
|
CardActor actor = null;
|
|
|
|
if (state.getSelf().equals(player)) {
|
|
|
|
if (isSelf(player)) {
|
|
|
|
actor = handCards.remove(card);
|
|
|
|
actor = handCards.remove(card);
|
|
|
|
} else {
|
|
|
|
actor.setOrigin(actor.getWidth() / 2, actor.getHeight() / 2);
|
|
|
|
actor = new CardActor(card, atlas);
|
|
|
|
|
|
|
|
actor.setPosition(seat.getHandX() - actor.getWidth() / 2, seat.getHandY() - actor.getHeight() / 2);
|
|
|
|
|
|
|
|
actor.setRotation(seat.getHandAngle());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actor.setOrigin(actor.getWidth() / 2, actor.getHeight() / 2);
|
|
|
|
|
|
|
|
|
|
|
|
if (actor == null) {
|
|
|
|
|
|
|
|
actor = seat.createHandCard(card, atlas);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cardStack.add(seat, actor);
|
|
|
|
cardStack.add(seat, actor);
|
|
|
|
sequence.addAction(delay(actor));
|
|
|
|
sequence.addAction(delay(actor));
|
|
|
|
sequence.addAction(delay(0.5f));
|
|
|
|
sequence.addAction(delay(AnimationTimings.STACK_HOLD));
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
execute(sequence);
|
|
|
|
execute(sequence);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -332,12 +415,16 @@ public class GameScreen extends MenuScreen {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void clearActivePlayer() {
|
|
|
|
|
|
|
|
setActivePlayer(null, null, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setActivePlayer(UUID player, UserInputMessage.Action action, long timeout) {
|
|
|
|
public void setActivePlayer(UUID player, UserInputMessage.Action action, long timeout) {
|
|
|
|
if (action == SYNC) throw new IllegalArgumentException();
|
|
|
|
if (action == SYNC) throw new IllegalArgumentException();
|
|
|
|
|
|
|
|
|
|
|
|
// reset label color
|
|
|
|
// reset label color
|
|
|
|
if (activePlayer != null && nameLabels.containsKey(activePlayer.getKey())) {
|
|
|
|
if (activePlayer != null && nameLabels.containsKey(activePlayer.first())) {
|
|
|
|
var label = nameLabels.get(activePlayer.getKey());
|
|
|
|
var label = nameLabels.get(activePlayer.first());
|
|
|
|
execute(() -> label.setStyle(labelStyleDefault));
|
|
|
|
execute(() -> label.setStyle(labelStyleDefault));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -347,14 +434,15 @@ public class GameScreen extends MenuScreen {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
activePlayer = Pair.of(player, action);
|
|
|
|
activePlayer = Triple.of(player, action, timeout);
|
|
|
|
// set label color
|
|
|
|
// set label color
|
|
|
|
if (nameLabels.containsKey(player)) {
|
|
|
|
if (nameLabels.containsKey(player)) {
|
|
|
|
var label = nameLabels.get(player);
|
|
|
|
var label = nameLabels.get(player);
|
|
|
|
execute(() -> label.setStyle(labelStyleActive));
|
|
|
|
execute(() -> label.setStyle(labelStyleActive));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (state.getSelf().equals(player)) {
|
|
|
|
boolean isSelf = state.getSelf().equals(player);
|
|
|
|
|
|
|
|
if (isSelf || player == null) {
|
|
|
|
// show interface
|
|
|
|
// show interface
|
|
|
|
setPersistentMessage(null);
|
|
|
|
setPersistentMessage(null);
|
|
|
|
switch (action) {
|
|
|
|
switch (action) {
|
|
|
@ -363,8 +451,9 @@ public class GameScreen extends MenuScreen {
|
|
|
|
case CHANGE_PREDICTION -> execute(new ChangePredictionOverlay(this, timeout, state.getRound(), state.getPredictions().get(state.getSelf())));
|
|
|
|
case CHANGE_PREDICTION -> execute(new ChangePredictionOverlay(this, timeout, state.getRound(), state.getPredictions().get(state.getSelf())));
|
|
|
|
case PLAY_CARD -> setPersistentMessage(game.messages.get("game.message.play_card.self"));
|
|
|
|
case PLAY_CARD -> setPersistentMessage(game.messages.get("game.message.play_card.self"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO do something
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
if (!isSelf) {
|
|
|
|
// show message
|
|
|
|
// show message
|
|
|
|
var key = switch (action) {
|
|
|
|
var key = switch (action) {
|
|
|
|
case CHANGE_PREDICTION -> "game.message.change_prediction.";
|
|
|
|
case CHANGE_PREDICTION -> "game.message.change_prediction.";
|
|
|
@ -391,8 +480,8 @@ public class GameScreen extends MenuScreen {
|
|
|
|
public void addMessage(@Nls String text, boolean immediate) {
|
|
|
|
public void addMessage(@Nls String text, boolean immediate) {
|
|
|
|
var label = new Label(text, game.data.skin);
|
|
|
|
var label = new Label(text, game.data.skin);
|
|
|
|
label.addAction(sequence(
|
|
|
|
label.addAction(sequence(
|
|
|
|
delay(1.5f),
|
|
|
|
delay(AnimationTimings.MESSAGE_HOLD),
|
|
|
|
alpha(0, 0.25f),
|
|
|
|
alpha(0, AnimationTimings.MESSAGE_FADE),
|
|
|
|
removeActor()
|
|
|
|
removeActor()
|
|
|
|
));
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
@ -413,15 +502,18 @@ public class GameScreen extends MenuScreen {
|
|
|
|
|
|
|
|
|
|
|
|
public void setPersistentMessage(@Nls String text) {
|
|
|
|
public void setPersistentMessage(@Nls String text) {
|
|
|
|
execute(() -> {
|
|
|
|
execute(() -> {
|
|
|
|
|
|
|
|
if (persistentMessage != null) {
|
|
|
|
|
|
|
|
persistentMessage.addAction(sequence(
|
|
|
|
|
|
|
|
delay(AnimationTimings.MESSAGE_HOLD),
|
|
|
|
|
|
|
|
alpha(0, AnimationTimings.MESSAGE_FADE),
|
|
|
|
|
|
|
|
removeActor()
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
persistentMessage = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (text != null) {
|
|
|
|
if (text != null) {
|
|
|
|
if (persistentMessage == null) {
|
|
|
|
persistentMessage = new Label(text, getData().skin);
|
|
|
|
persistentMessage = new Label(text, getData().skin);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
persistentMessage.setText(text);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
messages.addActor(persistentMessage);
|
|
|
|
messages.addActor(persistentMessage);
|
|
|
|
} else if (persistentMessage != null) {
|
|
|
|
|
|
|
|
persistentMessage.remove();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -442,11 +534,17 @@ public class GameScreen extends MenuScreen {
|
|
|
|
if (success && currentAction instanceof Overlay overlay && overlay instanceof InteractionOverlay) {
|
|
|
|
if (success && currentAction instanceof Overlay overlay && overlay instanceof InteractionOverlay) {
|
|
|
|
overlay.finish();
|
|
|
|
overlay.finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (checkAction(JUGGLE_CARD) && juggledCard != null) {
|
|
|
|
|
|
|
|
handCards.setSelected(juggledCard);
|
|
|
|
|
|
|
|
juggledCard = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void timeout() {
|
|
|
|
public void timeout() {
|
|
|
|
addMessage(game.messages.get("game.message.timeout"));
|
|
|
|
addMessage(game.messages.get("game.message.timeout"));
|
|
|
|
ready(true);
|
|
|
|
ready(true);
|
|
|
|
|
|
|
|
clearActivePlayer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void sync() {
|
|
|
|
public void sync() {
|
|
|
@ -467,14 +565,64 @@ public class GameScreen extends MenuScreen {
|
|
|
|
return game.messages;
|
|
|
|
return game.messages;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Action animateJuggle(List<CardActor> removed, List<CardActor> added) {
|
|
|
|
|
|
|
|
// find left- and rightmost seat
|
|
|
|
|
|
|
|
Seat tmpLeft = null, tmpRight = null;
|
|
|
|
|
|
|
|
for (Seat seat : seats.values()) {
|
|
|
|
|
|
|
|
if (seat == Seat.BOTTOM) continue;
|
|
|
|
|
|
|
|
if (tmpLeft == null || tmpLeft.compareTo(seat) > 0) tmpLeft = seat;
|
|
|
|
|
|
|
|
if (tmpRight == null || tmpRight.compareTo(seat) < 0) tmpRight = seat;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmpLeft == null) return null;
|
|
|
|
|
|
|
|
var left = tmpLeft;
|
|
|
|
|
|
|
|
var right = tmpRight;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var animation = parallel();
|
|
|
|
|
|
|
|
removed.forEach(actor -> {
|
|
|
|
|
|
|
|
getData().stage.addActor(actor);
|
|
|
|
|
|
|
|
animation.addAction(targeting(actor, left.moveToHand(AnimationTimings.JUGGLE)));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
added.forEach(actor -> {
|
|
|
|
|
|
|
|
// capture old values taking consideration of the animated layout changes in CardsGroup
|
|
|
|
|
|
|
|
float x = actor.getX(), y = actor.getY();
|
|
|
|
|
|
|
|
var actions = actor.getActions();
|
|
|
|
|
|
|
|
for (int i = 0; i < actions.size; i ++) {
|
|
|
|
|
|
|
|
var action = actions.get(i);
|
|
|
|
|
|
|
|
if (action instanceof MoveToAction move) {
|
|
|
|
|
|
|
|
x = move.getX();
|
|
|
|
|
|
|
|
y = move.getY();
|
|
|
|
|
|
|
|
actions.removeIndex(i--);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var rotation = actor.getRotation();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// apply start values
|
|
|
|
|
|
|
|
var startPos = new Vector2(right.getHandX(), right.getHandY());
|
|
|
|
|
|
|
|
handCards.stageToLocalCoordinates(startPos);
|
|
|
|
|
|
|
|
actor.setOrigin(actor.getWidth() / 2, actor.getHeight() / 2);
|
|
|
|
|
|
|
|
animation.addAction(targeting(actor, moveTo(startPos.x, startPos.y)));
|
|
|
|
|
|
|
|
animation.addAction(targeting(actor, rotateTo(right.getHandAngle())));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// animate
|
|
|
|
|
|
|
|
animation.addAction(targeting(actor, moveTo(x, y, AnimationTimings.JUGGLE)));
|
|
|
|
|
|
|
|
animation.addAction(targeting(actor, rotateTo(rotation, AnimationTimings.JUGGLE)));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var cleanup = parallel();
|
|
|
|
|
|
|
|
removed.forEach(actor -> cleanup.addAction(removeActor(actor)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sequence(animation, cleanup);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Getter
|
|
|
|
@Getter
|
|
|
|
public enum Seat {
|
|
|
|
public enum Seat {
|
|
|
|
BOTTOM(WizardGame.WIDTH * 0.5f, 0, 0, 0, Align.bottom, WizardGame.WIDTH * 0.5f, 300),
|
|
|
|
BOTTOM(WizardGame.WIDTH * 0.5f, 0, 0, 0, Align.bottom, WizardGame.WIDTH * 0.5f, 300),
|
|
|
|
LEFT(0, WizardGame.HEIGHT * 0.5f, 50, WizardGame.HEIGHT * 0.5f + 110f, Align.bottomLeft, 117.5f, WizardGame.HEIGHT * 0.5f),
|
|
|
|
LEFT(0, WizardGame.HEIGHT * 0.5f, 50, WizardGame.HEIGHT * 0.5f + 110f, Align.bottomLeft, 117.5f, WizardGame.HEIGHT * 0.5f),
|
|
|
|
RIGHT(WizardGame.WIDTH, WizardGame.HEIGHT * 0.5f, WizardGame.WIDTH - 50, WizardGame.HEIGHT * 0.5f + 110f, Align.bottomRight, WizardGame.WIDTH - 117.5f, WizardGame.HEIGHT * 0.5f),
|
|
|
|
|
|
|
|
TOP_LEFT(WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT - 200),
|
|
|
|
TOP_LEFT(WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.25f, WizardGame.HEIGHT - 200),
|
|
|
|
TOP(WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT - 200),
|
|
|
|
TOP(WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.5f, WizardGame.HEIGHT - 200),
|
|
|
|
TOP_RIGHT(WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT - 200);
|
|
|
|
TOP_RIGHT(WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT, WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT - 50, Align.top, WizardGame.WIDTH * 0.75f, WizardGame.HEIGHT - 200),
|
|
|
|
|
|
|
|
RIGHT(WizardGame.WIDTH, WizardGame.HEIGHT * 0.5f, WizardGame.WIDTH - 50, WizardGame.HEIGHT * 0.5f + 110f, Align.bottomRight, WizardGame.WIDTH - 117.5f, WizardGame.HEIGHT * 0.5f);
|
|
|
|
|
|
|
|
|
|
|
|
// position of the hand, should be offscreen
|
|
|
|
// position of the hand, should be offscreen
|
|
|
|
private final float handX;
|
|
|
|
private final float handX;
|
|
|
@ -502,5 +650,20 @@ public class GameScreen extends MenuScreen {
|
|
|
|
var deltaY = WizardGame.HEIGHT * 0.5f - handY;
|
|
|
|
var deltaY = WizardGame.HEIGHT * 0.5f - handY;
|
|
|
|
this.handAngle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX) + Math.PI / 2);
|
|
|
|
this.handAngle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX) + Math.PI / 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public CardActor createHandCard(Card card, TextureAtlas atlas) {
|
|
|
|
|
|
|
|
var actor = new CardActor(card, atlas);
|
|
|
|
|
|
|
|
actor.setPosition(getHandX() - actor.getWidth() / 2, getHandY() - actor.getHeight() / 2);
|
|
|
|
|
|
|
|
actor.setRotation(getHandAngle());
|
|
|
|
|
|
|
|
actor.setOrigin(actor.getWidth() / 2, actor.getHeight() / 2);
|
|
|
|
|
|
|
|
return actor;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Action moveToHand(float duration) {
|
|
|
|
|
|
|
|
return parallel(
|
|
|
|
|
|
|
|
moveTo(handX, handY, duration),
|
|
|
|
|
|
|
|
rotateTo(handAngle, duration)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|