-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
made choosing file native and added and stylised the settings to actu…
…llay change the enviroment
- Loading branch information
Showing
44 changed files
with
2,512 additions
and
745 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 108 additions & 17 deletions
125
src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Audio/AudioManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,65 +1,156 @@ | ||
| package edu.ntnu.idi.idatt2003.gruppe42.Audio; | ||
|
|
||
| import javax.sound.sampled.*; | ||
| import javafx.scene.media.Media; | ||
| import javafx.scene.media.MediaPlayer; | ||
| import java.io.IOException; | ||
| import java.util.EnumMap; | ||
| import java.util.Map; | ||
| import javafx.beans.property.DoubleProperty; | ||
| import javafx.beans.property.SimpleDoubleProperty; | ||
| import javafx.scene.media.Media; | ||
| import javafx.scene.media.MediaPlayer; | ||
| import javax.sound.sampled.AudioSystem; | ||
| import javax.sound.sampled.Clip; | ||
| import javax.sound.sampled.FloatControl; | ||
| import javax.sound.sampled.LineEvent; | ||
|
|
||
| /** | ||
| * Represents a AudioManager class. | ||
| */ | ||
| public final class AudioManager { | ||
|
|
||
| public class AudioManager { | ||
| private static final AudioManager INSTANCE = new AudioManager(); | ||
|
|
||
| private static final AudioManager instance = new AudioManager(); | ||
| private final Map<Audio, byte[]> sfxCache = new EnumMap<>(Audio.class); | ||
| private MediaPlayer bgPlayer; | ||
|
|
||
| private final DoubleProperty masterVolume = new SimpleDoubleProperty(0.8); | ||
| private final DoubleProperty sfxVolume = new SimpleDoubleProperty(0.8); | ||
|
|
||
| private AudioManager() { | ||
| for (Audio audio : Audio.values()) { | ||
| if (audio.isSFX()) { | ||
| try (var stream = getClass().getResourceAsStream(audio.getPath())) { | ||
| sfxCache.put(audio, stream.readAllBytes()); | ||
| if (stream != null) { | ||
| sfxCache.put(audio, stream.readAllBytes()); | ||
| } | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| System.err.println("[Audio] Failed to cache " + audio + ": " + e.getMessage()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Keep background music volume in sync with master × 0.5 (bg is quieter) | ||
| masterVolume.addListener((obs, ov, nv) -> { | ||
| if (bgPlayer != null) { | ||
| bgPlayer.setVolume(nv.doubleValue() * 0.5); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| public static AudioManager getInstance() { return instance; } | ||
| public static AudioManager get() { return INSTANCE; } | ||
|
|
||
|
|
||
| public void playSFX(Audio audio) { | ||
| /** | ||
| * Playsfx method. | ||
| */ | ||
| public void playSFX(final Audio audio) { | ||
| byte[] data = sfxCache.get(audio); | ||
| if (data == null) return; | ||
|
|
||
| double volume = masterVolume.get() * sfxVolume.get(); | ||
|
|
||
| new Thread(() -> { | ||
| try { | ||
| var stream = AudioSystem.getAudioInputStream( | ||
| new java.io.ByteArrayInputStream(data)); | ||
| Clip clip = AudioSystem.getClip(); | ||
| var bais = new java.io.ByteArrayInputStream(data); | ||
| var stream = AudioSystem.getAudioInputStream(bais); | ||
| Clip clip = AudioSystem.getClip(); | ||
| clip.open(stream); | ||
|
|
||
| // Apply volume via MASTER_GAIN | ||
| if (clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) { | ||
| FloatControl gain = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); | ||
| float db = volumeToDb(volume); | ||
| gain.setValue(Math.max(gain.getMinimum(), Math.min(gain.getMaximum(), db))); | ||
| } | ||
|
|
||
| clip.addLineListener(e -> { | ||
| if (e.getType() == LineEvent.Type.STOP) clip.close(); | ||
| }); | ||
| clip.start(); | ||
|
|
||
| } catch (Exception e) { | ||
| e.printStackTrace(); | ||
| System.err.println("[Audio] SFX playback failed: " + e.getMessage()); | ||
| } | ||
| }).start(); | ||
| }, "sfx-thread").start(); | ||
| } | ||
|
|
||
| public void playBgMusic(Audio audio) { | ||
|
|
||
| /** | ||
| * Playbgmusic method. | ||
| */ | ||
| public void playBgMusic(final Audio audio) { | ||
| stopBgMusic(); | ||
| var url = getClass().getResource(audio.getPath()).toExternalForm(); | ||
| String url = getClass().getResource(audio.getPath()).toExternalForm(); | ||
| bgPlayer = new MediaPlayer(new Media(url)); | ||
| bgPlayer.setVolume(0.5); | ||
| bgPlayer.setVolume(masterVolume.get() * 0.5); | ||
| bgPlayer.setCycleCount(MediaPlayer.INDEFINITE); | ||
| bgPlayer.play(); | ||
| } | ||
|
|
||
| /** | ||
| * Stopbgmusic method. | ||
| */ | ||
| public void stopBgMusic() { | ||
| if (bgPlayer != null) { | ||
| bgPlayer.stop(); | ||
| bgPlayer.dispose(); | ||
| bgPlayer = null; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Mastervolumeproperty method. | ||
| */ | ||
| public DoubleProperty masterVolumeProperty() { return masterVolume; } | ||
| /** | ||
| * Sfxvolumeproperty method. | ||
| */ | ||
| public DoubleProperty sfxVolumeProperty() { return sfxVolume; } | ||
|
|
||
| /** | ||
| * Returns the mastervolume. | ||
| * | ||
| * @return the value | ||
| */ | ||
| public double getMasterVolume() { return masterVolume.get(); } | ||
| /** | ||
| * Returns the sfxvolume. | ||
| * | ||
| * @return the value | ||
| */ | ||
| public double getSfxVolume() { return sfxVolume.get(); } | ||
|
|
||
| /** | ||
| * Sets the mastervolume. | ||
| * | ||
| * @param value the new value | ||
| */ | ||
| public void setMasterVolume(final double v) { masterVolume.set(clamp(v)); } | ||
| /** | ||
| * Sets the sfxvolume. | ||
| * | ||
| * @param value the new value | ||
| */ | ||
| public void setSfxVolume(final double v) { sfxVolume.set(clamp(v)); } | ||
|
|
||
|
|
||
| /** Converts a 0.0–1.0 linear volume to decibels for FloatControl. */ | ||
| private static float volumeToDb(final double volume) { | ||
| if (volume <= 0.0) return -80.0f; | ||
| return (float) (20.0 * Math.log10(volume)); | ||
| } | ||
|
|
||
| private static double clamp(final double v) { | ||
| return Math.max(0.0, Math.min(1.0, v)); | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.