diff --git a/core/src/main/java/group07/beatbattle/BeatBattle.java b/core/src/main/java/group07/beatbattle/BeatBattle.java index 2871af5..d232c34 100644 --- a/core/src/main/java/group07/beatbattle/BeatBattle.java +++ b/core/src/main/java/group07/beatbattle/BeatBattle.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import group07.beatbattle.controller.LobbyController; import group07.beatbattle.ecs.Engine; import group07.beatbattle.ecs.systems.AudioSystem; import group07.beatbattle.ecs.systems.RoundSystem; @@ -34,7 +35,7 @@ public void create() { engine.addSystem(AudioSystem.getInstance()); engine.addSystem(ScoringSystem.getInstance()); - setScreen(new StartView(this)); + setScreen(new StartView(this, new LobbyController(this))); } private BitmapFont loadFont(String path, int size) { diff --git a/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java b/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java new file mode 100644 index 0000000..eeff9b5 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/controller/LeaderboardController.java @@ -0,0 +1,15 @@ +package group07.beatbattle.controller; + +import group07.beatbattle.BeatBattle; + +public class LeaderboardController { + + private final BeatBattle game; + + public LeaderboardController(BeatBattle game) { + this.game = game; + } + + // TODO: onNextRound() + // TODO: onBackToMenu() +} diff --git a/core/src/main/java/group07/beatbattle/controller/LobbyController.java b/core/src/main/java/group07/beatbattle/controller/LobbyController.java new file mode 100644 index 0000000..488009c --- /dev/null +++ b/core/src/main/java/group07/beatbattle/controller/LobbyController.java @@ -0,0 +1,41 @@ +package group07.beatbattle.controller; + +import group07.beatbattle.BeatBattle; +import group07.beatbattle.model.GameMode; +import group07.beatbattle.view.JoinCreateView; +import group07.beatbattle.view.LobbyView; +import group07.beatbattle.view.StartView; + +public class LobbyController { + + private final BeatBattle game; + + public LobbyController(BeatBattle game) { + this.game = game; + } + + public void onCreateGame() { + game.setScreen(new JoinCreateView(game, GameMode.CREATE, this)); + } + + public void onJoinGame() { + game.setScreen(new JoinCreateView(game, GameMode.JOIN, this)); + } + + public void onReady(GameMode mode) { + // TODO: pass player name and game code to LobbyService/Firebase + game.setScreen(new LobbyView(game, mode, this)); + } + + public void onBackFromJoinCreate() { + game.setScreen(new StartView(game, this)); + } + + public void onBackFromLobby(GameMode mode) { + game.setScreen(new JoinCreateView(game, mode, this)); + } + + public void onStartGame() { + // TODO: trigger game start via GameService/Firebase + } +} diff --git a/core/src/main/java/group07/beatbattle/controller/RoundController.java b/core/src/main/java/group07/beatbattle/controller/RoundController.java new file mode 100644 index 0000000..b11730d --- /dev/null +++ b/core/src/main/java/group07/beatbattle/controller/RoundController.java @@ -0,0 +1,16 @@ +package group07.beatbattle.controller; + +import group07.beatbattle.BeatBattle; + +public class RoundController { + + private final BeatBattle game; + + public RoundController(BeatBattle game) { + this.game = game; + } + + // TODO: onAnswerSubmitted(String answer, float timestamp) + // TODO: onRoundExpired() + // TODO: onLeaveSession() +} diff --git a/core/src/main/java/group07/beatbattle/controller/SettingsController.java b/core/src/main/java/group07/beatbattle/controller/SettingsController.java new file mode 100644 index 0000000..5361686 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/controller/SettingsController.java @@ -0,0 +1,17 @@ +package group07.beatbattle.controller; + +import group07.beatbattle.BeatBattle; + +public class SettingsController { + + private final BeatBattle game; + + public SettingsController(BeatBattle game) { + this.game = game; + } + + // TODO: onLanguageChanged(String language) + // TODO: onTurnsChanged(int turns) + // TODO: onApply() + // TODO: onBack() +} diff --git a/core/src/main/java/group07/beatbattle/model/AnswerSubmission.java b/core/src/main/java/group07/beatbattle/model/AnswerSubmission.java new file mode 100644 index 0000000..2fddbdd --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/AnswerSubmission.java @@ -0,0 +1,25 @@ +package group07.beatbattle.model; + +public class AnswerSubmission { + + private final String playerId; + private final String selectedAnswer; + private final long timestamp; + private final boolean correct; + private final int pointsAwarded; + + public AnswerSubmission(String playerId, String selectedAnswer, long timestamp, + boolean correct, int pointsAwarded) { + this.playerId = playerId; + this.selectedAnswer = selectedAnswer; + this.timestamp = timestamp; + this.correct = correct; + this.pointsAwarded = pointsAwarded; + } + + public String getPlayerId() { return playerId; } + public String getSelectedAnswer() { return selectedAnswer; } + public long getTimestamp() { return timestamp; } + public boolean isCorrect() { return correct; } + public int getPointsAwarded() { return pointsAwarded; } +} diff --git a/core/src/main/java/group07/beatbattle/model/GameSession.java b/core/src/main/java/group07/beatbattle/model/GameSession.java new file mode 100644 index 0000000..463a952 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/GameSession.java @@ -0,0 +1,61 @@ +package group07.beatbattle.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class GameSession { + + public enum State { + LOBBY, IN_ROUND, LEADERBOARD, GAME_OVER + } + + private final String sessionId; + private final String hostId; + private final List players; + private final List questions; + private State state; + private int currentRoundIndex; + + public GameSession(String sessionId, String hostId, int totalRounds) { + this.sessionId = sessionId; + this.hostId = hostId; + this.players = new ArrayList<>(); + this.questions = new ArrayList<>(); + this.state = State.LOBBY; + this.currentRoundIndex = 0; + } + + public String getSessionId() { return sessionId; } + public String getHostId() { return hostId; } + public State getState() { return state; } + public int getCurrentRoundIndex() { return currentRoundIndex; } + public int getTotalRounds() { return questions.size(); } + + public List getPlayers() { return Collections.unmodifiableList(players); } + public List getQuestions() { return Collections.unmodifiableList(questions); } + + public void addPlayer(Player player) { players.add(player); } + public void removePlayer(String playerId) { + players.removeIf(p -> p.getId().equals(playerId)); + } + + public void addQuestion(Question question) { questions.add(question); } + + public Question getCurrentQuestion() { + if (currentRoundIndex < questions.size()) { + return questions.get(currentRoundIndex); + } + return null; + } + + public boolean hasMoreRounds() { + return currentRoundIndex + 1 < questions.size(); + } + + public void setState(State state) { this.state = state; } + + public void advanceRound() { + currentRoundIndex++; + } +} diff --git a/core/src/main/java/group07/beatbattle/model/Leaderboard.java b/core/src/main/java/group07/beatbattle/model/Leaderboard.java new file mode 100644 index 0000000..0b37bbe --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/Leaderboard.java @@ -0,0 +1,31 @@ +package group07.beatbattle.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class Leaderboard { + + private final List entries; + + public Leaderboard(List players) { + List sorted = new ArrayList<>(players); + Collections.sort(sorted, new Comparator() { + @Override + public int compare(Player a, Player b) { + return Integer.compare(b.getScore(), a.getScore()); + } + }); + + entries = new ArrayList<>(); + for (int i = 0; i < sorted.size(); i++) { + Player p = sorted.get(i); + entries.add(new LeaderboardEntry(p.getId(), p.getName(), p.getScore(), i + 1)); + } + } + + public List getEntries() { + return Collections.unmodifiableList(entries); + } +} diff --git a/core/src/main/java/group07/beatbattle/model/LeaderboardEntry.java b/core/src/main/java/group07/beatbattle/model/LeaderboardEntry.java new file mode 100644 index 0000000..85a32f8 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/LeaderboardEntry.java @@ -0,0 +1,21 @@ +package group07.beatbattle.model; + +public class LeaderboardEntry { + + private final String playerId; + private final String playerName; + private final int score; + private final int rank; + + public LeaderboardEntry(String playerId, String playerName, int score, int rank) { + this.playerId = playerId; + this.playerName = playerName; + this.score = score; + this.rank = rank; + } + + public String getPlayerId() { return playerId; } + public String getPlayerName() { return playerName; } + public int getScore() { return score; } + public int getRank() { return rank; } +} diff --git a/core/src/main/java/group07/beatbattle/model/Player.java b/core/src/main/java/group07/beatbattle/model/Player.java new file mode 100644 index 0000000..ef64d05 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/Player.java @@ -0,0 +1,22 @@ +package group07.beatbattle.model; + +public class Player { + + private final String id; + private final String name; + private int score; + + public Player(String id, String name) { + this.id = id; + this.name = name; + this.score = 0; + } + + public String getId() { return id; } + public String getName() { return name; } + public int getScore() { return score; } + + public void addScore(int points) { + this.score += points; + } +} diff --git a/core/src/main/java/group07/beatbattle/model/Question.java b/core/src/main/java/group07/beatbattle/model/Question.java new file mode 100644 index 0000000..57b55f7 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/Question.java @@ -0,0 +1,31 @@ +package group07.beatbattle.model; + +import java.util.List; + +public class Question { + + private final String id; + private final Song song; + private final List options; + private final int roundIndex; + + public Question(String id, Song song, List options, int roundIndex) { + this.id = id; + this.song = song; + this.options = options; + this.roundIndex = roundIndex; + } + + public String getId() { return id; } + public Song getSong() { return song; } + public List getOptions() { return options; } + public int getRoundIndex() { return roundIndex; } + + public String getCorrectAnswer() { + return song.getTitle() + " - " + song.getArtist(); + } + + public boolean isCorrect(String selectedAnswer) { + return getCorrectAnswer().equals(selectedAnswer); + } +} diff --git a/core/src/main/java/group07/beatbattle/model/Song.java b/core/src/main/java/group07/beatbattle/model/Song.java new file mode 100644 index 0000000..d1093e8 --- /dev/null +++ b/core/src/main/java/group07/beatbattle/model/Song.java @@ -0,0 +1,24 @@ +package group07.beatbattle.model; + +public class Song { + + private final String id; + private final String title; + private final String artist; + private final String previewUrl; + private final String albumArtUrl; + + public Song(String id, String title, String artist, String previewUrl, String albumArtUrl) { + this.id = id; + this.title = title; + this.artist = artist; + this.previewUrl = previewUrl; + this.albumArtUrl = albumArtUrl; + } + + public String getId() { return id; } + public String getTitle() { return title; } + public String getArtist() { return artist; } + public String getPreviewUrl() { return previewUrl; } + public String getAlbumArtUrl() { return albumArtUrl; } +} diff --git a/core/src/main/java/group07/beatbattle/view/JoinCreateView.java b/core/src/main/java/group07/beatbattle/view/JoinCreateView.java index 6dd7d85..8d8f1a6 100644 --- a/core/src/main/java/group07/beatbattle/view/JoinCreateView.java +++ b/core/src/main/java/group07/beatbattle/view/JoinCreateView.java @@ -12,6 +12,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.viewport.ScreenViewport; import group07.beatbattle.BeatBattle; +import group07.beatbattle.controller.LobbyController; import group07.beatbattle.model.GameMode; import group07.beatbattle.ui.components.BackButton; import group07.beatbattle.ui.components.JoinCreateButton; @@ -28,11 +29,13 @@ public class JoinCreateView extends ScreenAdapter { private final BeatBattle game; private final GameMode mode; + private final LobbyController controller; private final Stage stage; - public JoinCreateView(BeatBattle game, GameMode mode) { + public JoinCreateView(BeatBattle game, GameMode mode, LobbyController controller) { this.game = game; this.mode = mode; + this.controller = controller; this.stage = new Stage(new ScreenViewport()); Table root = new Table(); @@ -52,14 +55,14 @@ public JoinCreateView(BeatBattle game, GameMode mode) { readyButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - game.setScreen(new LobbyView(game, mode)); + controller.onReady(mode); } }); backButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - game.setScreen(new StartView(game)); + controller.onBackFromJoinCreate(); } }); diff --git a/core/src/main/java/group07/beatbattle/view/LobbyView.java b/core/src/main/java/group07/beatbattle/view/LobbyView.java index 55bdc1f..1da72dd 100644 --- a/core/src/main/java/group07/beatbattle/view/LobbyView.java +++ b/core/src/main/java/group07/beatbattle/view/LobbyView.java @@ -11,18 +11,21 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport; import group07.beatbattle.BeatBattle; -import group07.beatbattle.ui.components.BackButton; +import group07.beatbattle.controller.LobbyController; import group07.beatbattle.model.GameMode; +import group07.beatbattle.ui.components.BackButton; public class LobbyView extends ScreenAdapter { private final BeatBattle game; private final GameMode mode; + private final LobbyController controller; private final Stage stage; - public LobbyView(BeatBattle game, GameMode mode) { + public LobbyView(BeatBattle game, GameMode mode, LobbyController controller) { this.game = game; this.mode = mode; + this.controller = controller; this.stage = new Stage(new ScreenViewport()); Label.LabelStyle titleStyle = new Label.LabelStyle(); @@ -36,7 +39,7 @@ public LobbyView(BeatBattle game, GameMode mode) { backButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - game.setScreen(new JoinCreateView(game, mode)); + controller.onBackFromLobby(mode); } }); diff --git a/core/src/main/java/group07/beatbattle/view/StartView.java b/core/src/main/java/group07/beatbattle/view/StartView.java index 0c4bbe0..4b0b033 100644 --- a/core/src/main/java/group07/beatbattle/view/StartView.java +++ b/core/src/main/java/group07/beatbattle/view/StartView.java @@ -12,8 +12,8 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.Scaling; import group07.beatbattle.BeatBattle; +import group07.beatbattle.controller.LobbyController; import group07.beatbattle.ui.components.JoinCreateButton; -import group07.beatbattle.model.GameMode; public class StartView extends ScreenAdapter { @@ -23,11 +23,13 @@ public class StartView extends ScreenAdapter { private static final float BUTTON_SPACING = 50f; private static final float LOGO_BOTTOM_PADDING = 100f; private final BeatBattle game; + private final LobbyController controller; private final Stage stage; private final Texture logoTexture; - public StartView(BeatBattle game) { + public StartView(BeatBattle game, LobbyController controller) { this.game = game; + this.controller = controller; this.stage = new Stage(new ScreenViewport()); this.logoTexture = new Texture(Gdx.files.internal("logo.png")); @@ -47,14 +49,14 @@ public StartView(BeatBattle game) { createButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - game.setScreen(new JoinCreateView(game, GameMode.CREATE)); + controller.onCreateGame(); } }); joinButton.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { - game.setScreen(new JoinCreateView(game, GameMode.JOIN)); + controller.onJoinGame(); } });