diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardActor.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardActor.java new file mode 100644 index 0000000..837d302 --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardActor.java @@ -0,0 +1,35 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import eu.jonahbauer.wizard.client.libgdx.GameAtlas; +import eu.jonahbauer.wizard.common.model.Card; +import lombok.Getter; + +@Getter +public class CardActor extends Actor { + private final Card card; + private final TextureRegion texture; + float offset; + float baseY; + + public CardActor(Card card, TextureAtlas atlas) { + this.card = card; + this.texture = atlas.findRegion(switch ((int)(Math.random() * 4)) { + case 0 -> GameAtlas.CARDS_BLUE; + case 1 -> GameAtlas.CARDS_GREEN; + case 2 -> GameAtlas.CARDS_RED; + case 3 -> GameAtlas.CARDS_YELLOW; + default -> throw new AssertionError(); + }); + setWidth(100); + setHeight(100); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + batch.draw(texture, getX(), getY() + getHeight() - 100, getWidth(), 100); + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardsGroup.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardsGroup.java new file mode 100644 index 0000000..f54a4d6 --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/CardsGroup.java @@ -0,0 +1,88 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import eu.jonahbauer.wizard.common.model.Card; + +import java.util.List; + +public class CardsGroup extends HorizontalGroup { + private TextureAtlas atlas; + private List actors; + private int hash; + private CardActor target; + + public CardsGroup(List cards, TextureAtlas atlas) { + this.atlas = atlas; + update(cards); + + this.addListener(new InputListener() { + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + if (event.getTarget() instanceof CardActor card) { + CardsGroup.this.target = card; + } + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + if (event.getTarget() == CardsGroup.this.target) { + CardsGroup.this.target = null; + } + } + }); + } + + @Override + public float getMinWidth() { + return 0; + } + + @Override + public void act(float delta) { + super.act(delta); + + float speed = 10; + float offset = 100; + + for (Actor child : getChildren()) { + if (child instanceof CardActor card) { + if (card == target) { + card.offset += speed * delta; + } else { + card.offset -= speed * delta; + } + card.offset = Math.max(0, Math.min(1, card.offset)); + card.setHeight(100 + offset * card.offset); + } + } + } + + @Override + public void layout() { + super.layout(); + var space = getWidth(); + for (Actor child : getChildren()) { + space -= child.getWidth(); + if (child instanceof CardActor card) { + card.baseY = card.getY(); + } + } + space(getChildren().size > 1 ? space / (getChildren().size - 1) : 0); + super.layout(); + } + + public void update(List cards) { + var hash = cards.hashCode(); + if (this.hash != hash) { + this.hash = hash; + this.actors = cards.stream().map(card -> new CardActor(card, atlas)).toList(); + this.clearChildren(); + this.actors.forEach(this::addActor); + this.layout(); + } + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/ChosenCardActor.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/ChosenCardActor.java new file mode 100644 index 0000000..108827a --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/ChosenCardActor.java @@ -0,0 +1,33 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Action; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import eu.jonahbauer.wizard.client.libgdx.WizardGame; +import eu.jonahbauer.wizard.common.model.Card; + +public class ChosenCardActor extends Actor { + private final Card card; + private final TextureRegion texture; + private final Action toCenter; + + public ChosenCardActor(Card card, TextureRegion region) { + this.card = card; + setWidth(100); + setHeight(100); + texture = region; + toCenter = Actions.moveTo(WizardGame.WIDTH * 0.75f * 0.5f - 0.5f * getWidth(), WizardGame.HEIGHT * 0.35f, 0.5f); + this.addAction(toCenter); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + batch.draw(texture, getX(), getY(), getWidth(), getHeight()); + } + + public void action() { + this.addAction(toCenter); + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/InfoTable.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/InfoTable.java new file mode 100644 index 0000000..19aabfe --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/InfoTable.java @@ -0,0 +1,96 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import eu.jonahbauer.wizard.common.model.Card; +import lombok.AccessLevel; +import lombok.Setter; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class InfoTable extends Table { + + private final UUID[] players; + private final Skin skin; + + @Setter(AccessLevel.MODULE) + private int round = -1; + private int playercount; //optional + private Cell cells[][]; + private static final int TABLELENGTH = 4; + private static final int PLAYERNAMES = 0; + private static final int PREDICTIONS = 1; + private static final int TRICKS = 2; + private static final int SCORES = 3; + private final String headers[] = {"Spieler", "Vorhersage", "Stiche", "Punktzahl"}; + + public InfoTable(Skin skin, UUID[] players) { + super(skin); + this.skin = skin; + this.players = players; + playercount = players.length; + cells = new Cell[TABLELENGTH][playercount]; + createHeader(); + //this.columnDefaults(1).width(5); + } + + public void createHeader() { + for (int i = 0; i < headers.length; i++) { + Label header = new Label(headers[i], skin); + //header.setWidth(5); + //header.setEllipsis(true); + add(header).padRight(5); + } + row(); + } + + public void fill(Map names, Map predictions, Map>> tricks, + Map> scores) { + + for(int i = 0; i < players.length; i++) { + //Name + cells[PLAYERNAMES][i] = add(names.get(players[i])); + ((Label) cells[PLAYERNAMES][i].getActor()).setWidth(10); + ((Label) cells[PLAYERNAMES][i].getActor()).setEllipsis(true); + + //Prediction + cells[PREDICTIONS][i] = add(String.valueOf(predictions.get(players[i]))); + ((Label) cells[PLAYERNAMES][i].getActor()).setEllipsis(true); + + //Tricks + cells[TRICKS][i] = add(String.valueOf(tricks.get(players[i]).size())); + ((Label) cells[PLAYERNAMES][i].getActor()).setEllipsis(true); + + //Scores + //TODO Rundencheck - Rundenupdate + cells[SCORES][i] = add(String.valueOf(scores.get(round).get(players[i]))); + ((Label) cells[PLAYERNAMES][i].getActor()).setEllipsis(true); + + row(); + } + } + + public void updatePrediction(Map predictions) { + for(int i = 0; i < players.length; i++) { + ((Label) cells[PREDICTIONS][i].getActor()).setText(String.valueOf(predictions.get(players[i]))); + } + } + + public void updateTricks(Map>> tricks) { + for(int i = 0; i < players.length; i++) { + ((Label) cells[TRICKS][i].getActor()).setText(String.valueOf(tricks.get(players[i]).size())); + } + } + + public void updateScores(Map> scores) { + for(int i = 0; i < players.length; i++) { + ((Label) cells[SCORES][i].getActor()).setText(String.valueOf(scores.get(round).get(players[i]))); + } + } + + //TODO - update/removePlayer +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/PlayedCardActor.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/PlayedCardActor.java new file mode 100644 index 0000000..2af48a9 --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/PlayedCardActor.java @@ -0,0 +1,54 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import eu.jonahbauer.wizard.client.libgdx.GameAtlas; +import eu.jonahbauer.wizard.client.libgdx.WizardGame; +import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen; +import eu.jonahbauer.wizard.common.model.Card; + +public class PlayedCardActor extends Actor { + private final Card playedCard; + private final TextureRegion texture; + + public PlayedCardActor(Card playedCard, TextureAtlas atlas) { + //TODO Texture zur Karte bestimmen + this.playedCard = playedCard; + this.texture = atlas.findRegion(GameAtlas.CARDS_RED); + + setWidth(100); + setHeight(100); + } + + @Override + public void setPosition(float x, float y) { + super.setPosition(x, y); + } + + public void setPositionOne() { + setPosition(WizardGame.WIDTH * GameScreen.BACKGROUND_WIDTH_PORTION * 0.25f, WizardGame.HEIGHT * 0.5f - 0.5f * getHeight()); + } + + public void setPositionTwo() { + setPosition(WizardGame.WIDTH * GameScreen.BACKGROUND_WIDTH_PORTION * 0.75f, WizardGame.HEIGHT * 0.5f - 0.5f * getHeight()); + } + + public void setPositionThree() { + setPosition(WizardGame.WIDTH * GameScreen.BACKGROUND_WIDTH_PORTION * 0.25f, WizardGame.HEIGHT * 0.7f - 0.5f * getHeight()); + } + + public void setPositionFour() { + setPosition(2 * WizardGame.WIDTH * GameScreen.BACKGROUND_WIDTH_PORTION * 0.25f, WizardGame.HEIGHT * 0.75f - 0.5f * getHeight()); + } + + public void setPositionFive() { + setPosition(3 * WizardGame.WIDTH * GameScreen.BACKGROUND_WIDTH_PORTION * 0.25f, WizardGame.HEIGHT * 0.7f - 0.5f * getHeight()); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + batch.draw(texture, getX(), getY(), getWidth(), getHeight()); + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/TrumpCardActor.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/TrumpCardActor.java new file mode 100644 index 0000000..5a8144e --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/TrumpCardActor.java @@ -0,0 +1,27 @@ +package eu.jonahbauer.wizard.client.libgdx.actors.game; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import eu.jonahbauer.wizard.client.libgdx.GameAtlas; +import eu.jonahbauer.wizard.common.model.Card; + +public class TrumpCardActor extends Actor { + private final Card trumpCard; + private final TextureRegion texture; + + public TrumpCardActor(Card trumpCard, TextureAtlas atlas) { + //TODO Texture zur Karte bestimmen + this.trumpCard = trumpCard; + this.texture = atlas.findRegion(GameAtlas.CARDS_RED); + + setWidth(200); + setHeight(200); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + batch.draw(texture, getX(), getY(), getWidth(), getHeight()); + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java new file mode 100644 index 0000000..339d75d --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java @@ -0,0 +1,339 @@ +package eu.jonahbauer.wizard.client.libgdx.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.viewport.ExtendViewport; +import com.badlogic.gdx.utils.viewport.FitViewport; +import eu.jonahbauer.wizard.client.libgdx.GameAtlas; +import eu.jonahbauer.wizard.client.libgdx.WizardGame; +import eu.jonahbauer.wizard.client.libgdx.actors.game.*; +import eu.jonahbauer.wizard.client.libgdx.util.Pair; +import eu.jonahbauer.wizard.common.messages.observer.*; +import eu.jonahbauer.wizard.common.messages.server.GameMessage; +import eu.jonahbauer.wizard.common.messages.server.ServerMessage; +import eu.jonahbauer.wizard.common.model.Card; + +import java.util.*; + +public class GameScreen implements Screen { + private final WizardGame game; + + private ExtendViewport extendViewport; + private FitViewport viewport; + private Stage stage; + private Skin skin; + private TextureAtlas atlas; + private TextureRegion background; + public static final float BACKGROUND_WIDTH_PORTION = 0.7f; + + private final UUID[] players; + + //wahrscheinlich eine Map für Sitzpositionen einfügen + private final Map seats = new HashMap<>(); + + private final UUID self; + private final UUID session; + private final Map names; + private final Map> scores = new HashMap<>(); + + private int round = - 1; + private final Map> hands = new HashMap<>(); + private final Map predictions = new HashMap<>(); + private final Map>> tricks = new HashMap<>(); + private Card.Suit trumpSuit; + private Card trumpCard; + private Label[] playerNames; + + private int trick; + private final List> stack = new ArrayList<>(); + private Pair activePlayer; + private ChosenCardActor chosenCardActor; + + ClickListener clickListener = new ClickListener() { + //TODO - Fehler bei Click auf Objekt während der Bewegung - Behebung durch Entfernung des Click-Listeners + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + var target = event.getTarget(); + if(target instanceof CardActor cardTarget) { + chosenCardActor = new ChosenCardActor(cardTarget.getCard(), cardTarget.getTexture()); + //TODO falsche Koordinaten + chosenCardActor.setPosition(cardTarget.getX(), cardTarget.getParent().getY()); + stage.addActor(chosenCardActor); + target.remove(); + //Todo Message - Server-Antwort abwarten - moveMethode in chosenCardActor aufrufen + } + } + + }; + + public GameScreen(WizardGame game) { + this.game = game; + + int playerCount = 6; + this.session = UUID.randomUUID(); + this.players = new UUID[playerCount]; + this.names = new HashMap<>(); + + HashMap score = new HashMap(); + for (int i = 0; i < playerCount; i++) { + players[i] = UUID.randomUUID(); + names.put(players[i], "Player " + (i + 1)); + + predictions.put(players[i], i + 5); + score.put(players[i], i); + } + scores.put(round, score); + + this.self = players[0]; + + ArrayList> trickList = new ArrayList<>(); + ArrayList trick = new ArrayList(); + trick.add(Card.BLUE_3); + trick.add(Card.YELLOW_1); + trick.add(Card.GREEN_1); + trick.add(Card.RED_5); + trickList.add(trick); + trickList.add(trick); + trickList.add(trick); + + for(int i = 0; i < playerCount; i++) { + tricks.put(players[i], trickList); + var cards = new ArrayList(20); + for(int j = 0; j < 20; j++) { + cards.add(Arrays.stream(Card.values()).toList().get(j)); + } + hands.put(players[i], cards); + } + + //List> stack + stack.add(new Pair<>(players[0], Card.BLUE_11)); + stack.add(new Pair<>(players[1], Card.RED_1)); + stack.add(new Pair<>(players[2], Card.YELLOW_11)); + stack.add(new Pair<>(players[3], Card.BLUE_10)); + stack.add(new Pair<>(players[4], Card.BLUE_9)); + stack.add(new Pair<>(players[5], Card.BLUE_8)); + + determineSeats(players); + } + + @Override + public void show() { + viewport = new FitViewport(WizardGame.WIDTH, WizardGame.HEIGHT); + extendViewport = new ExtendViewport(WizardGame.WIDTH, WizardGame.HEIGHT); + stage = new Stage(viewport); + skin = new Skin(Gdx.files.internal("uiskin.json")); + atlas = new TextureAtlas(Gdx.files.internal(GameAtlas.$PATH)); + background = atlas.findRegion(GameAtlas.BACKGROUND); + + this.stage.addListener(clickListener); + + var container = new Container<>(new CardsGroup(hands.get(players[0]), atlas).wrap(false).grow()); + container.setPosition(100, 75); + container.setSize(1200, 200); + container.fillX(); + + InfoTable infoTable = new InfoTable(skin, players); + infoTable.fill(names, predictions, tricks, scores); + infoTable.setPosition(WizardGame.WIDTH * 0.85f, WizardGame.HEIGHT * 0.8f); + + trumpCard = Card.BLUE_1; + TrumpCardActor trumpCardActor = new TrumpCardActor(trumpCard, atlas); + trumpCardActor.setPosition(WizardGame.WIDTH * 0.85f, WizardGame.HEIGHT * 0.1f); + + this.stage.addListener(clickListener); + + createLabels(); + cardPlayed(stack); + + Gdx.input.setInputProcessor(stage); + + stage.addActor(container); + stage.addActor(infoTable); + stage.addActor(trumpCardActor); + + stage.setDebugAll(true); + } + + @Override + public void render(float delta) { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + //viewport.apply(true); + extendViewport.apply(true); + game.batch.setProjectionMatrix(extendViewport.getCamera().combined); + game.batch.begin(); + float scale = Math.max( + extendViewport.getWorldWidth() / WizardGame.WIDTH, + extendViewport.getWorldHeight() / WizardGame.HEIGHT + ); + game.batch.draw(background, 0,0, scale * WizardGame.WIDTH * BACKGROUND_WIDTH_PORTION, scale * WizardGame.HEIGHT); + game.batch.end(); + + stage.act(delta); + stage.draw(); + } + + @Override + public void resize(int width, int height) { + extendViewport.update(width, height); + viewport.update(width, height); + } + + @Override + public void pause() {} + + @Override + public void resume() {} + + @Override + public void hide() {} + + @Override + public void dispose() { + if (stage != null) stage.dispose(); + if (atlas != null) atlas.dispose(); + if (skin != null) skin.dispose(); + } + + private void createLabels() { + //TODO ggf. Labels für Vorhersage und Stichanzahl einbauen + playerNames = new Label[players.length]; + int count = 0; + for(int i = 0; i < players.length; i++) { + playerNames[i] = new Label(names.get(players[i]), skin); + if(players[i] != self) { + switch (count) { + case 0 -> { + playerNames[i].setPosition(10, WizardGame.HEIGHT * 0.5f - 0.5f * playerNames[i].getHeight()); + stage.addActor(playerNames[i]); + } + case 1 -> { + playerNames[i].setPosition(WizardGame.WIDTH * BACKGROUND_WIDTH_PORTION - playerNames[i].getWidth() - 10, WizardGame.HEIGHT * 0.5f - 0.5f * playerNames[i].getHeight()); + stage.addActor(playerNames[i]); + } + case 2 -> { + playerNames[i].setPosition(WizardGame.WIDTH * BACKGROUND_WIDTH_PORTION / (players.length - 2) - playerNames[i].getWidth() * 0.5f, WizardGame.HEIGHT * 0.8f - 0.5f * playerNames[i].getHeight()); + stage.addActor(playerNames[i]); + } + case 3 -> { + playerNames[i].setPosition(2 * WizardGame.WIDTH * BACKGROUND_WIDTH_PORTION / (players.length - 2) - playerNames[i].getWidth() * 0.5f, WizardGame.HEIGHT * 0.85f - 0.5f * playerNames[i].getHeight()); + stage.addActor(playerNames[i]); + } + case 4 -> { + playerNames[i].setPosition(3 * WizardGame.WIDTH * BACKGROUND_WIDTH_PORTION / (players.length - 2) - playerNames[i].getWidth() * 0.5f, WizardGame.HEIGHT * 0.8f - 0.5f * playerNames[i].getHeight()); + stage.addActor(playerNames[i]); + } + default -> throw new IllegalArgumentException(); + } + count++; + } + else { + playerNames[i].setPosition(WizardGame.WIDTH * 0.35f - 0.5f * playerNames[i].getWidth(), WizardGame.HEIGHT * 0.05f); + stage.addActor(playerNames[i]); + } + } + } + + private void cardPlayed(List> stack) { + while(stack.size() > 0) { + Pair pair = stack.get(stack.size() - 1); + if(pair.first() == self) { + //TODO Action + //chosenCardActor.action() + stack.remove(pair); + } + else { + for(UUID player : players) { + if(player == pair.first()) { + drawPlayedCard(seats.get(player), pair.second()); + stack.remove(pair); + } + } + } + } + } + + private void drawPlayedCard(int pos, Card card) { + PlayedCardActor playedCardActor = new PlayedCardActor(card, atlas); + switch (pos) { + case 1 -> playedCardActor.setPositionOne(); + case 2 -> playedCardActor.setPositionTwo(); + case 3 -> playedCardActor.setPositionThree(); + case 4 -> playedCardActor.setPositionFour(); + case 5 -> playedCardActor.setPositionFive(); + } + stage.addActor(playedCardActor); + } + + private void determineSeats(UUID[] players) { + for(int i = 0; i < players.length; i++) { + if(self == players[i]) { + seats.put(self, 0); + } + else { + seats.put(players[i], i); + } + } + } + + public void onMessage(ServerMessage serverMessage) { + if (serverMessage instanceof GameMessage gameMessage) { + var observerMessage = gameMessage.getObserverMessage(); + if (observerMessage instanceof CardMessage card) { + stack.add(Pair.of(card.getPlayer(), card.getCard())); + } else if (observerMessage instanceof TrickMessage trick) { + stack.clear(); + tricks.computeIfAbsent(trick.getPlayer(), p -> new ArrayList<>()).add(trick.getCards()); + } else if (observerMessage instanceof HandMessage hand) { + var cards = hands.computeIfAbsent(hand.getPlayer(), p -> new ArrayList<>()); + cards.clear(); + cards.addAll(hand.getHand()); + } else if (observerMessage instanceof ScoreMessage score) { + var roundScores = scores.computeIfAbsent(round, r -> new HashMap<>()); + roundScores.putAll(score.getPoints()); + } else if (observerMessage instanceof TrumpMessage trump) { + trumpCard = trump.getCard(); + trumpSuit = trump.getSuit(); + //Todo update TrumpCardActor if trumpSuit != null and trumpCard != null + } else if (observerMessage instanceof PredictionMessage prediction) { + predictions.put(prediction.getPlayer(), prediction.getPrediction()); + //TODO update table and label + } else if (observerMessage instanceof UserInputMessage userInput) { + activePlayer = Pair.of(userInput.getPlayer(), userInput.getAction()); + if (self.equals(userInput.getPlayer())) { + // TODO do something + } + } else if (observerMessage instanceof StateMessage state) { + switch (state.getState()) { + case "starting_round" -> { + round++; + trick = -1; + hands.clear(); + predictions.clear(); + tricks.clear(); + trumpSuit = null; + trumpCard = null; + } + case "starting_trick" -> { + trick++; + stack.clear(); + activePlayer = null; + } + case "finished", "error" -> { + // TODO do something + } + } + } + } + } +} diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/util/Pair.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/util/Pair.java new file mode 100644 index 0000000..74b3715 --- /dev/null +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/util/Pair.java @@ -0,0 +1,25 @@ +package eu.jonahbauer.wizard.client.libgdx.util; + +import java.util.Map; + +public record Pair(F first, S second) implements Map.Entry { + + public static Pair of(F first, S second) { + return new Pair<>(first, second); + } + + @Override + public F getKey() { + return first(); + } + + @Override + public S getValue() { + return second(); + } + + @Override + public S setValue(S value) { + throw new UnsupportedOperationException(); + } +}