diff --git a/core/src/main/java/group07/beatbattle/ecs/systems/AudioSystem.java b/core/src/main/java/group07/beatbattle/ecs/systems/AudioSystem.java index 015be42..bd837b0 100644 --- a/core/src/main/java/group07/beatbattle/ecs/systems/AudioSystem.java +++ b/core/src/main/java/group07/beatbattle/ecs/systems/AudioSystem.java @@ -9,6 +9,7 @@ public class AudioSystem extends EntitySystem { private static AudioSystem instance; private AudioPlayer audioPlayer; + private boolean muted = false; private AudioSystem() {} @@ -42,9 +43,14 @@ public void stop(Entity round) { } public void setMuted(boolean muted) { + this.muted = muted; if (audioPlayer != null) audioPlayer.setMuted(muted); } + public boolean isMuted() { + return muted; + } + public void dispose() { if (audioPlayer != null) audioPlayer.dispose(); } diff --git a/core/src/main/java/group07/beatbattle/view/GameRoundView.java b/core/src/main/java/group07/beatbattle/view/GameRoundView.java index eed505f..f22631f 100644 --- a/core/src/main/java/group07/beatbattle/view/GameRoundView.java +++ b/core/src/main/java/group07/beatbattle/view/GameRoundView.java @@ -22,6 +22,7 @@ import group07.beatbattle.BeatBattle; import group07.beatbattle.controller.RoundController; import group07.beatbattle.ecs.Engine; +import group07.beatbattle.ecs.systems.AudioSystem; import group07.beatbattle.i18n.Strings; import group07.beatbattle.model.Question; @@ -53,11 +54,16 @@ public class GameRoundView extends ScreenAdapter { private boolean revealed = false; private float resultDelay = RESULT_DISPLAY_DELAY; + private boolean muted = false; + private TextButton muteButton; + private Texture defaultTex; private Texture selectedTex; private Texture disabledTex; private Texture correctTex; private Texture wrongTex; + private Texture iconSoundTex; + private Texture iconMuteTex; private Texture logoTexture; public GameRoundView(BeatBattle game, RoundController controller) { @@ -72,6 +78,8 @@ public GameRoundView(BeatBattle game, RoundController controller) { disabledTex = solidTexture(COLOR_DISABLED); correctTex = solidTexture(COLOR_CORRECT); wrongTex = solidTexture(COLOR_WRONG); + iconSoundTex = createSpeakerTexture(false); + iconMuteTex = createSpeakerTexture(true); logoTexture = new Texture(Gdx.files.internal("logo.png")); Image bgLogo = new Image(logoTexture); @@ -101,9 +109,22 @@ public void changed(ChangeEvent event, Actor actor) { timerLabel = new Label(String.valueOf((int) Math.ceil(controller.getTotalTime())), timerStyle()); timerLabel.setAlignment(Align.center); + muted = AudioSystem.getInstance().isMuted(); + muteButton = makeButton("", muted ? iconMuteTex : iconSoundTex); + muteButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + muted = !muted; + AudioSystem.getInstance().setMuted(muted); + Texture tex = muted ? iconMuteTex : iconSoundTex; + muteButton.getStyle().up = new TextureRegionDrawable(new TextureRegion(tex)); + muteButton.getStyle().down = new TextureRegionDrawable(new TextureRegion(tex)); + } + }); + topBar.add(leaveButton).width(120f).height(100f).padLeft(40f); topBar.add(timerLabel).expandX().center().padTop(60f); - topBar.add().width(120f).padRight(40f); // Spacer + topBar.add(muteButton).width(120f).height(100f).padRight(40f); root.add(topBar).fillX().row(); @@ -197,6 +218,8 @@ public void dispose() { disabledTex.dispose(); correctTex.dispose(); wrongTex.dispose(); + iconSoundTex.dispose(); + iconMuteTex.dispose(); logoTexture.dispose(); } @@ -232,6 +255,65 @@ private Label.LabelStyle timerStyle() { return style; } + private Texture createSpeakerTexture(boolean muted) { + int S = 128; + Pixmap pm = new Pixmap(S, S, Pixmap.Format.RGBA8888); + + // Background + pm.setColor(muted ? new Color(0.45f, 0.15f, 0.15f, 1f) : new Color(0.23f, 0.23f, 0.34f, 1f)); + pm.fill(); + + pm.setColor(Color.WHITE); + + // Speaker body (rectangle) + pm.fillRectangle(18, 46, 20, 36); + + // Speaker horn (trapezoid): narrow at x=38, wide at x=70 + // top diagonal: (38,46) -> (70,18); bottom diagonal: (38,82) -> (70,110) + for (int y = 18; y <= 110; y++) { + int leftX; + if (y <= 46) { + leftX = Math.round(70 - 32f * (y - 18) / 28f); + } else if (y <= 82) { + leftX = 38; + } else { + leftX = Math.round(38 + 32f * (y - 82) / 28f); + } + if (leftX <= 70) pm.drawLine(leftX, y, 70, y); + } + + if (!muted) { + // Sound arcs (two concentric arcs opening to the right) + int cx = 58, cy = 64; + for (int r = 14; r <= 18; r++) { + for (int angle = -55; angle <= 55; angle++) { + double rad = Math.toRadians(angle); + int x = cx + (int) (r * Math.cos(rad)); + int y = cy + (int) (r * Math.sin(rad)); + if (x >= 0 && x < S && y >= 0 && y < S) pm.drawPixel(x, y); + } + } + for (int r = 26; r <= 30; r++) { + for (int angle = -65; angle <= 65; angle++) { + double rad = Math.toRadians(angle); + int x = cx + (int) (r * Math.cos(rad)); + int y = cy + (int) (r * Math.sin(rad)); + if (x >= 0 && x < S && y >= 0 && y < S) pm.drawPixel(x, y); + } + } + } else { + // Mute slash line (top-right to bottom-left through speaker area) + pm.setColor(new Color(1f, 0.6f, 0.6f, 1f)); + for (int t = -3; t <= 3; t++) { + pm.drawLine(92 + t, 20, 20 + t, 108); + } + } + + Texture tex = new Texture(pm); + pm.dispose(); + return tex; + } + private Texture solidTexture(Color color) { Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); pixmap.setColor(color);