diff --git a/app/src/main/java/game/Game.java b/app/src/main/java/game/Game.java index ad4d2e6..ed5d78e 100644 --- a/app/src/main/java/game/Game.java +++ b/app/src/main/java/game/Game.java @@ -1,5 +1,6 @@ package game; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -14,10 +15,13 @@ public class Game { GameNotStarted, GameGoing, GameEnd } + public static final int GAME_DURATION = 10 * 60; + private final Map players; private final List leaderboard; private GameState gameState; private MultiDoku doku; + private Instant startTime = null; public Game() { this.players = new HashMap<>(); @@ -49,9 +53,10 @@ public class Game { return players; } - public void startGame(MultiDoku doku) { + public void startGame(MultiDoku doku, Instant startTime) { this.doku = doku; this.gameState = GameState.GameGoing; + this.startTime = startTime; } public GameState getGameState() { @@ -66,4 +71,8 @@ public class Game { return leaderboard; } + public Instant getStartTime() { + return startTime; + } + } diff --git a/app/src/main/java/gui/menu/MultiPlayerDokuView.java b/app/src/main/java/gui/menu/MultiPlayerDokuView.java index b18a12a..b6b09e4 100644 --- a/app/src/main/java/gui/menu/MultiPlayerDokuView.java +++ b/app/src/main/java/gui/menu/MultiPlayerDokuView.java @@ -1,5 +1,6 @@ package gui.menu; +import game.Game; import gui.widget.LeaderboardRenderer; import gui.widget.SudokuRenderer; import gui.widget.TimerRenderer; @@ -8,14 +9,13 @@ import network.client.Client; import network.server.Server; import sudoku.structure.Cell; -public class MultiPlayerDokuView extends BaseView{ +public class MultiPlayerDokuView extends BaseView { private final Client client; private final Server server; private final SudokuRenderer sudokuRenderer; private final LeaderboardRenderer leaderboardRenderer; private final TimerRenderer timerRenderer; - private static final float GAME_DURATION = 10 * 60; public MultiPlayerDokuView(StateMachine stateMachine, Client client, Server server) { super(stateMachine); @@ -25,8 +25,7 @@ public class MultiPlayerDokuView extends BaseView{ this.leaderboardRenderer = new LeaderboardRenderer(client.getGame(), client.getPlayer()); this.sudokuRenderer.onCellChange.connect(this::onCellChange); this.client.onDisconnect.connect(this::onDisconnect); - // TODO: sync timer - this.timerRenderer = new TimerRenderer(GAME_DURATION); + this.timerRenderer = new TimerRenderer(this.client.getGame().getStartTime(), Game.GAME_DURATION); } private void onCellChange(Cell cell) { diff --git a/app/src/main/java/gui/widget/TimerRenderer.java b/app/src/main/java/gui/widget/TimerRenderer.java index 67529b3..476036a 100644 --- a/app/src/main/java/gui/widget/TimerRenderer.java +++ b/app/src/main/java/gui/widget/TimerRenderer.java @@ -1,24 +1,26 @@ package gui.widget; +import java.time.Instant; + import imgui.ImGui; public class TimerRenderer { - private float time; - private final float duration; + private final long endTime; - public TimerRenderer(float duration) { - this.time = 0; - this.duration = duration; + public TimerRenderer(Instant startTime, int duration) { + this.endTime = startTime.getEpochSecond() + duration; + } + + private long getTimeRemaining() { + long currentTime = Instant.now().getEpochSecond(); + return endTime - currentTime; } public void render() { - this.time += ImGui.getIO().getDeltaTime(); - float remainingTime = this.duration - this.time; - int seconds = (int) remainingTime; - int minutes = seconds / 60; - seconds %= 60; - String text = String.format("%02d:%02d", minutes, seconds); + long seconds = getTimeRemaining(); + long minutes = seconds / 60; + String text = String.format("%02d:%02d", minutes, seconds % 60); var textSize = ImGui.calcTextSize(text); ImGui.setCursorPosX(ImGui.getIO().getDisplaySizeX() / 2.0f - textSize.x / 2.0f); ImGui.text(text); diff --git a/app/src/main/java/network/client/ClientConnexion.java b/app/src/main/java/network/client/ClientConnexion.java index 83eadf2..faa8970 100644 --- a/app/src/main/java/network/client/ClientConnexion.java +++ b/app/src/main/java/network/client/ClientConnexion.java @@ -71,7 +71,8 @@ public class ClientConnexion extends Connexion { @Override public void visitPacket(StartGamePacket packet) { - this.client.getGame().startGame(SudokuSerializer.deserializeSudoku(packet.getSerializedSudoku())); + this.client.getGame().startGame(SudokuSerializer.deserializeSudoku(packet.getSerializedSudoku()), + packet.getInstant()); this.client.onGameStarted.emit(); } @@ -84,7 +85,7 @@ public class ClientConnexion extends Connexion { @Override public void visitPacket(UpdatePlayerScorePacket packet) { Player player = this.client.getGame().getPlayerById(packet.getPlayerId()); - assert(player != null); + assert (player != null); this.client.getGame().setPlayerScore(player, packet.getCellsLeft()); System.out.println("Score for " + player.getPseudo() + " : " + packet.getCellsLeft()); } diff --git a/app/src/main/java/network/protocol/packets/StartGamePacket.java b/app/src/main/java/network/protocol/packets/StartGamePacket.java index c8e0ae8..e834821 100644 --- a/app/src/main/java/network/protocol/packets/StartGamePacket.java +++ b/app/src/main/java/network/protocol/packets/StartGamePacket.java @@ -1,5 +1,7 @@ package network.protocol.packets; +import java.time.Instant; + import network.protocol.Packet; import network.protocol.PacketVisitor; import network.protocol.Packets; @@ -9,15 +11,22 @@ public class StartGamePacket extends Packet { static private final long serialVersionUID = Packets.StartGame.ordinal(); private final String serializedSudoku; + // used to resume game + private final Instant instant; - public StartGamePacket(String serializedSudoku) { + public StartGamePacket(String serializedSudoku, Instant instant) { this.serializedSudoku = serializedSudoku; + this.instant = instant; } public String getSerializedSudoku() { return serializedSudoku; } + public Instant getInstant() { + return instant; + } + @Override public void accept(PacketVisitor packetVisitor) { packetVisitor.visitPacket(this); diff --git a/app/src/main/java/network/server/Server.java b/app/src/main/java/network/server/Server.java index 19b2b24..006d0d6 100644 --- a/app/src/main/java/network/server/Server.java +++ b/app/src/main/java/network/server/Server.java @@ -2,6 +2,7 @@ package network.server; import java.io.IOException; import java.net.ServerSocket; +import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -69,11 +70,12 @@ public class Server { } public void startGame(MultiDoku doku) { - this.game.startGame(doku); + Instant now = Instant.now(); + this.game.startGame(doku, now); for (ServerConnexion connexion : this.connexions) { connexion.setSudoku(doku.clone()); } - broadcastPacket(new StartGamePacket(SudokuSerializer.serializeSudoku(doku).toString())); + broadcastPacket(new StartGamePacket(SudokuSerializer.serializeSudoku(doku).toString(), now)); } } diff --git a/app/src/main/java/network/server/ServerConnexion.java b/app/src/main/java/network/server/ServerConnexion.java index 61ba7bb..8b41067 100644 --- a/app/src/main/java/network/server/ServerConnexion.java +++ b/app/src/main/java/network/server/ServerConnexion.java @@ -3,6 +3,7 @@ package network.server; import java.io.IOException; import java.net.Socket; +import game.Game; import game.Player; import game.Game.GameState; import network.Connexion; @@ -69,10 +70,13 @@ public class ServerConnexion extends Connexion { this.server.broadcastPacket(new PlayerJoinPacket(player)); sendPacket(new ConnexionInfoPacket(player.getId())); - if (this.server.getGame().getGameState() == GameState.GameGoing) { - setSudoku(this.server.getGame().getDoku().clone()); + Game game = this.server.getGame(); + + if (game.getGameState() == GameState.GameGoing) { + setSudoku(game.getDoku().clone()); sendPacket( - new StartGamePacket(SudokuSerializer.serializeSudoku(this.server.getGame().getDoku()).toString())); + new StartGamePacket(SudokuSerializer.serializeSudoku(game.getDoku()).toString(), + game.getStartTime())); } }