diff --git a/core/src/main/java/group07/beatbattle/i18n/Strings.java b/core/src/main/java/group07/beatbattle/i18n/Strings.java index 33534cf..918dafb 100644 --- a/core/src/main/java/group07/beatbattle/i18n/Strings.java +++ b/core/src/main/java/group07/beatbattle/i18n/Strings.java @@ -32,6 +32,8 @@ public static void reload() { // --- Lobby --- public static String party() { return no ? "Lag" : "Party"; } + public static String player() { return no ? "spiller" : "player"; } + public static String players() { return no ? "spillere" : "players"; } public static String loadingPlayers(){ return no ? "Laster spillere..." : "Loading players..."; } public static String noPlayers() { return no ? "Ingen spillere ennĂ¥" : "No players yet"; } public static String leaveLobby() { return no ? "Forlat lobbyen" : "Leave lobby"; } diff --git a/core/src/main/java/group07/beatbattle/ui/components/JoinCreateButton.java b/core/src/main/java/group07/beatbattle/ui/components/JoinCreateButton.java index a29cde8..387b2fe 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/JoinCreateButton.java +++ b/core/src/main/java/group07/beatbattle/ui/components/JoinCreateButton.java @@ -4,54 +4,51 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; public class JoinCreateButton extends TextButton { - private static Texture sharedTexture; + private static Texture sharedBorderedTexture; - private static TextButtonStyle createStyle(BitmapFont font) { - Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); - pixmap.setColor(0.23f, 0.23f, 0.34f, 1f); - pixmap.fill(); - - Texture texture = new Texture(pixmap); - pixmap.dispose(); - - TextureRegionDrawable drawable = - new TextureRegionDrawable(new TextureRegion(texture)); + /** Creates a purple-bordered drawable reusable by any button. */ + public static NinePatchDrawable createBorderedDrawable() { + if (sharedBorderedTexture == null) { + int size = 20, border = 3; + Pixmap pixmap = new Pixmap(size, size, Pixmap.Format.RGBA8888); + pixmap.setColor(0.50f, 0.35f, 0.75f, 1f); // purple border + pixmap.fill(); + pixmap.setColor(0.23f, 0.23f, 0.34f, 1f); // button fill + pixmap.fillRectangle(border, border, size - 2 * border, size - 2 * border); + sharedBorderedTexture = new Texture(pixmap); + pixmap.dispose(); + } + NinePatch np = new NinePatch(sharedBorderedTexture, 3, 3, 3, 3); + return new NinePatchDrawable(np); + } + private static TextButtonStyle createStyle(BitmapFont font) { + NinePatchDrawable drawable = createBorderedDrawable(); TextButtonStyle style = new TextButtonStyle(); style.up = drawable; style.down = drawable; style.font = font; style.fontColor = Color.WHITE; - return style; } - private static void ensureTexture() { - if (sharedTexture == null) { - Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); - pixmap.setColor(0.23f, 0.23f, 0.34f, 1f); - pixmap.fill(); - - sharedTexture = new Texture(pixmap); - pixmap.dispose(); - } - } - public JoinCreateButton(String text, BitmapFont font) { super(text, createStyle(font)); pad(30f, 60f, 30f, 60f); } public static void disposeSharedResources() { - if (sharedTexture != null) { - sharedTexture.dispose(); - sharedTexture = null; + if (sharedBorderedTexture != null) { + sharedBorderedTexture.dispose(); + sharedBorderedTexture = null; } } } diff --git a/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java b/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java index 29dc5a5..a9400aa 100644 --- a/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java +++ b/core/src/main/java/group07/beatbattle/ui/components/StartGameButton.java @@ -1,49 +1,24 @@ package group07.beatbattle.ui.components; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import group07.beatbattle.i18n.Strings; public class StartGameButton extends TextButton { - private static Texture sharedTexture; - private static TextButtonStyle createStyle(BitmapFont font) { - Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); - - pixmap.setColor(0.23f, 0.23f, 0.34f, 1f); - pixmap.fill(); - - Texture texture = new Texture(pixmap); - pixmap.dispose(); - - TextureRegionDrawable drawable = new TextureRegionDrawable(new TextureRegion(texture)); - TextButtonStyle style = new TextButtonStyle(); - style.up = drawable; - style.down = drawable; + style.up = JoinCreateButton.createBorderedDrawable(); + style.down = JoinCreateButton.createBorderedDrawable(); style.font = font; style.fontColor = Color.WHITE; - return style; } public StartGameButton(BitmapFont font) { super(Strings.startGame(), createStyle(font)); - pad(40f, 80f, 40f, 80f); } - public static void disposeSharedResources() { - if (sharedTexture != null) { - sharedTexture.dispose(); - sharedTexture = null; - } - } - } diff --git a/core/src/main/java/group07/beatbattle/ui/style/InputFieldStyles.java b/core/src/main/java/group07/beatbattle/ui/style/InputFieldStyles.java index ad0181e..f5fa9c0 100644 --- a/core/src/main/java/group07/beatbattle/ui/style/InputFieldStyles.java +++ b/core/src/main/java/group07/beatbattle/ui/style/InputFieldStyles.java @@ -28,7 +28,12 @@ public static TextField.TextFieldStyle createDefault(BitmapFont font) { style.fontColor = Color.WHITE; style.messageFont = font; style.messageFontColor = new Color(1f, 1f, 1f, 0.5f); - style.background = new TextureRegionDrawable(new TextureRegion(backgroundTexture)); + TextureRegionDrawable bgDrawable = new TextureRegionDrawable(new TextureRegion(backgroundTexture)); + bgDrawable.setLeftWidth(20f); + bgDrawable.setRightWidth(20f); + bgDrawable.setTopHeight(10f); + bgDrawable.setBottomHeight(10f); + style.background = bgDrawable; style.cursor = new TextureRegionDrawable(new TextureRegion(cursorTexture)); return style; @@ -40,7 +45,12 @@ public static SelectBox.SelectBoxStyle createSelectBoxStyle(BitmapFont font) { SelectBox.SelectBoxStyle style = new SelectBox.SelectBoxStyle(); style.font = font; style.fontColor = Color.WHITE; - style.background = new TextureRegionDrawable(new TextureRegion(backgroundTexture)); + TextureRegionDrawable selectBgDrawable = new TextureRegionDrawable(new TextureRegion(backgroundTexture)); + selectBgDrawable.setLeftWidth(20f); + selectBgDrawable.setRightWidth(20f); + selectBgDrawable.setTopHeight(10f); + selectBgDrawable.setBottomHeight(10f); + style.background = selectBgDrawable; //Dropdown list styling List.ListStyle listStyle = new List.ListStyle(); diff --git a/core/src/main/java/group07/beatbattle/view/LeaderboardView.java b/core/src/main/java/group07/beatbattle/view/LeaderboardView.java index fda0b8b..d93c27a 100644 --- a/core/src/main/java/group07/beatbattle/view/LeaderboardView.java +++ b/core/src/main/java/group07/beatbattle/view/LeaderboardView.java @@ -4,13 +4,16 @@ import com.badlogic.gdx.ScreenAdapter; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Scaling; import com.badlogic.gdx.utils.viewport.ScreenViewport; @@ -58,7 +61,7 @@ public LeaderboardView(BeatBattle game, LeaderboardController controller) { Table root = new Table(); root.setFillParent(true); - root.pad(safeTop, 60f, safeBottom, 60f); + root.pad(safeTop, 80f, safeBottom, 80f); root.top(); // --- Title --- diff --git a/core/src/main/java/group07/beatbattle/view/LobbyView.java b/core/src/main/java/group07/beatbattle/view/LobbyView.java index 0818133..e8ff6c0 100644 --- a/core/src/main/java/group07/beatbattle/view/LobbyView.java +++ b/core/src/main/java/group07/beatbattle/view/LobbyView.java @@ -53,6 +53,8 @@ public class LobbyView extends ScreenAdapter { private Table playersGrid; private Label statusLabel; + private Label playerCountLabel; + private RoundSelector roundSelector; private List currentPlayers = new ArrayList<>(); public LobbyView( @@ -94,8 +96,8 @@ public LobbyView( root.top(); root.add(createHeader()).expandX().fillX().padTop(safeTop).row(); - root.add(createGameCodeSection()).expandX().top().padTop(60).row(); - root.add(createPartySection()).expand().center().padBottom(60).row(); + root.add(createGameCodeSection()).expandX().top().padTop(40).row(); + root.add(createPartySection()).expand().center().padBottom(20).row(); root.add(createFooter()).expandX().bottom().padBottom(safeBottom); stage.addActor(root); @@ -246,18 +248,29 @@ private void showLeaveLobbyConfirmation() { private Table createGameCodeSection() { Table table = new Table(); - String pinText = gamePin.isEmpty() - ? Strings.gameCode() + ": ----" - : Strings.gameCode() + ": " + gamePin; - - Label label = new Label(Strings.gameCode(), infoStyle); - label.setColor(Color.LIGHT_GRAY); - - Label value = new Label(pinText, titleStyle); - - table.add(label).padBottom(5).row(); - table.add(value); - + // Small "Game Code" label above + Label.LabelStyle subtitleStyle = new Label.LabelStyle(); + subtitleStyle.font = game.getMontserratFont(); + subtitleStyle.fontColor = new Color(0.6f, 0.4f, 0.9f, 0.7f); + Label codeLabel = new Label(Strings.gameCode(), subtitleStyle); + + // Big PIN-only label inside the pill + Label.LabelStyle pinStyle = new Label.LabelStyle(); + pinStyle.font = game.getOrbitronFont(); + pinStyle.fontColor = new Color(0.6f, 0.4f, 0.9f, 1f); + String pinOnly = gamePin.isEmpty() ? "----" : gamePin; + Label pinLabel = new Label(pinOnly, pinStyle); + pinLabel.setFontScale(1.8f); + + int cardW = (int) Math.min(500f, Gdx.graphics.getWidth() - 80f); + int cardH = 150; + + Table card = new Table(); + card.setBackground(createRoundedBackground(cardW, cardH, cardH / 2, new Color(0.18f, 0.14f, 0.28f, 1f))); + card.add(pinLabel); + + table.add(codeLabel).padBottom(10).row(); + table.add(card).width(cardW).height(cardH); return table; } @@ -268,11 +281,20 @@ private Table createPartySection() { int boxWidth = (int) Math.min(850f, Gdx.graphics.getWidth() - 60f); int boxHeight = 620; - Label partyLabel = new Label(Strings.party(), infoStyle); + Label partyLabel = new Label(Strings.party(), titleStyle); Table partyBox = createPartyBox(boxWidth, boxHeight); - table.add(partyLabel).padBottom(20).row(); - table.add(partyBox).width(boxWidth).height(boxHeight); + playerCountLabel = new Label("0 " + Strings.players(), infoStyle); + playerCountLabel.setColor(Color.LIGHT_GRAY); + + table.add(partyLabel).padBottom(4).row(); + table.add(playerCountLabel).padBottom(16).row(); + table.add(partyBox).width(boxWidth).height(boxHeight).row(); + + if (mode == GameMode.CREATE) { + roundSelector = new RoundSelector(game.getMontserratFont()); + table.add(roundSelector.getActor()).width(boxWidth).padTop(16).row(); + } return table; } @@ -303,6 +325,11 @@ private void updatePlayersGrid(List players) { float cellWidth = 260f; float cellHeight = 60f; + int count = (players == null) ? 0 : players.size(); + if (playerCountLabel != null) { + playerCountLabel.setText(count + " " + (count == 1 ? Strings.player() : Strings.players())); + } + if (players == null || players.isEmpty()) { playersGrid.add(createPlayerLabel(Strings.noPlayers())) .width(cellWidth).height(cellHeight).pad(15); @@ -312,9 +339,8 @@ private void updatePlayersGrid(List players) { int columnCount = 2; for (int i = 0; i < players.size(); i++) { Player player = players.get(i); - String displayName = player.getName() + (player.isHost() ? " [H]" : ""); - playersGrid.add(createPlayerLabel(displayName)) + playersGrid.add(createPlayerCell(player)) .width(cellWidth).height(cellHeight).pad(15); if ((i + 1) % columnCount == 0) { @@ -335,9 +361,56 @@ private Label createPlayerLabel(String name) { return label; } + private Table createPlayerCell(Player player) { + Table cell = new Table(); + + Label nameLabel = new Label(player.getName(), infoStyle); + nameLabel.setAlignment(Align.center); + cell.add(nameLabel); + + if (player.isHost()) { + cell.add(createHostBadge()).padLeft(10); + } + + return cell; + } + + private Table createHostBadge() { + Label.LabelStyle badgeTextStyle = new Label.LabelStyle(); + badgeTextStyle.font = game.getMontserratFont(); + badgeTextStyle.fontColor = Color.WHITE; + + Label badgeLabel = new Label("HOST", badgeTextStyle); + badgeLabel.setFontScale(0.55f); + + int badgeW = 100, badgeH = 44; + int radius = badgeH / 2; + + Pixmap pixmap = new Pixmap(badgeW, badgeH, Pixmap.Format.RGBA8888); + pixmap.setColor(0.50f, 0.35f, 0.75f, 1f); + pixmap.fillRectangle(radius, 0, badgeW - 2 * radius, badgeH); + pixmap.fillRectangle(0, radius, badgeW, badgeH - 2 * radius); + pixmap.fillCircle(radius, radius, radius); + pixmap.fillCircle(badgeW - radius, radius, radius); + pixmap.fillCircle(radius, badgeH - radius, radius); + pixmap.fillCircle(badgeW - radius, badgeH - radius, radius); + Texture tex = new Texture(pixmap); + pixmap.dispose(); + + Table badge = new Table(); + badge.setBackground(new TextureRegionDrawable(new TextureRegion(tex))); + badge.add(badgeLabel); + + return badge; + } + private Drawable createRoundedBackground(int width, int height, int radius) { + return createRoundedBackground(width, height, radius, new Color(0.25f, 0.25f, 0.35f, 1f)); + } + + private Drawable createRoundedBackground(int width, int height, int radius, Color color) { Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888); - pixmap.setColor(0.25f, 0.25f, 0.35f, 1f); + pixmap.setColor(color); pixmap.fillRectangle(radius, 0, width - 2 * radius, height); pixmap.fillRectangle(0, radius, width, height - 2 * radius); @@ -357,8 +430,6 @@ private Table createFooter() { Table footer = new Table(); if (mode == GameMode.CREATE) { - RoundSelector roundSelector = new RoundSelector(game.getMontserratFont()); - StartGameButton startButton = new StartGameButton(game.getMontserratFont()); startButton.addListener(new ChangeListener() { @Override @@ -368,7 +439,6 @@ public void changed(ChangeEvent event, Actor actor) { }); float btnWidth = Math.min(800f, Gdx.graphics.getWidth() - 80f); - footer.add(roundSelector.getActor()).width(btnWidth).padBottom(20f).row(); footer.add(startButton).width(btnWidth).height(150); }