diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 16470fb1..91ed716c 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -15,6 +15,7 @@ import org.apache.commons.cli.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import seng302.model.PolarTable; +import seng302.utilities.Sounds; public class App extends Application { @@ -67,6 +68,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) throws Exception { + Sounds.playMenuMusic(); Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml")); primaryStage.setTitle("Party Parrots at Sea"); Scene scene = new Scene(root, 1530, 960); diff --git a/src/main/java/seng302/model/RaceState.java b/src/main/java/seng302/model/RaceState.java index 501a3417..bab854b6 100644 --- a/src/main/java/seng302/model/RaceState.java +++ b/src/main/java/seng302/model/RaceState.java @@ -15,6 +15,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import seng302.model.stream.parser.RaceStartData; import seng302.model.stream.parser.RaceStatusData; +import seng302.utilities.Sounds; /** * Class for storing race data that does not relate to specific vessels or marks such as time or wind. @@ -34,6 +35,7 @@ public class RaceState { private long serverSystemTime; private long expectedStartTime; private boolean isRaceStarted = false; + private boolean gunFired = false; long timeTillStart; private ObservableList playerPositions; private List collisions = new ArrayList<>(); @@ -64,6 +66,10 @@ public class RaceState { if (raceTime < 0) { return "-" + DATE_TIME_FORMAT.format(-1 * (raceTime - 1000)); } else { + if (!gunFired) { + gunFired = true; + Sounds.playCapGunSound(); + } return DATE_TIME_FORMAT.format(serverSystemTime - expectedStartTime); } } diff --git a/src/main/java/seng302/utilities/Sounds.java b/src/main/java/seng302/utilities/Sounds.java new file mode 100644 index 00000000..bba19f93 --- /dev/null +++ b/src/main/java/seng302/utilities/Sounds.java @@ -0,0 +1,92 @@ +package seng302.utilities; + +import javafx.scene.media.Media; +import javafx.scene.media.MediaPlayer; + +/** + * Static class for playing sounds throughout the program + * + * Created by kre39 on 28/08/17. + */ +public class Sounds { + + private static MediaPlayer musicPlayer; + private static MediaPlayer soundEffect; + private static MediaPlayer soundPlayer; + + private static boolean musicMuted = false; + private static boolean soundEffectsMuted = false; + + + public static void stopMusic() { + musicPlayer.stop(); + } + + public static void toggleMuteMusic() { + musicMuted = !musicMuted; + musicPlayer.setMute(musicMuted); + } + + public static void toggleMuteEffects() { + soundEffectsMuted = !soundEffectsMuted; + if (soundPlayer != null) { + soundPlayer.setMute(soundEffectsMuted); + } + if (soundEffect != null) { + soundEffect.setMute(soundEffectsMuted); + } + } + + public static boolean isMusicMuted() { + return musicMuted; + } + + public static boolean isSoundEffectsMuted() { + return soundEffectsMuted; + } + + public static void playRaceMusic() { +// Media menuMusic = new Media(Sounds.class.getClassLoader().getResource("sounds/Chill-house-music-loop-116-bpm.wav").toString()); + Media raceMusic = new Media(Sounds.class.getClassLoader().getResource("sounds/Music-loop-120-bpm.mp3").toString()); + musicPlayer = new MediaPlayer(raceMusic); + musicPlayer.setCycleCount(MediaPlayer.INDEFINITE); + musicPlayer.play(); + raceMusic = new Media(Sounds.class.getClassLoader().getResource("sounds/Sounds-of-the-ocean.mp3").toString()); + soundEffect = new MediaPlayer(raceMusic); + soundEffect.setCycleCount(MediaPlayer.INDEFINITE); +// soundEffect.setVolume(0.3); + soundEffect.play(); + musicPlayer.setMute(musicMuted); + soundEffect.setMute(soundEffectsMuted); + } + + public static void playMenuMusic() { + Media menuMusic = new Media(Sounds.class.getClassLoader().getResource("sounds/Elevator-music.mp3").toString()); + musicPlayer = new MediaPlayer(menuMusic); + musicPlayer.setCycleCount(MediaPlayer.INDEFINITE); + musicPlayer.play(); + musicPlayer.setMute(musicMuted); + } + + public static void playButtonClick() { + Media buttonClick = new Media(Sounds.class.getClassLoader().getResource("sounds/Button-click-sound.mp3").toString()); + soundPlayer = new MediaPlayer(buttonClick); + soundPlayer.play(); + soundPlayer.setMute(soundEffectsMuted); + } + + public static void playCapGunSound() { + Media gunSound = new Media(Sounds.class.getClassLoader().getResource("sounds/Gunshot-sound.mp3").toString()); + soundPlayer = new MediaPlayer(gunSound); + soundPlayer.play(); + soundPlayer.setMute(soundEffectsMuted); + } + + public static void playCrashSound() { + Media crashSound = new Media(Sounds.class.getClassLoader().getResource("sounds/Large-metal-door-slam.mp3").toString()); + soundPlayer = new MediaPlayer(crashSound); + soundPlayer.play(); + soundPlayer.setMute(soundEffectsMuted); + } + +} diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 63687191..501b8347 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -28,6 +28,7 @@ import seng302.model.stream.parser.RaceStatusData; import seng302.model.stream.parser.YachtEventData; import seng302.model.stream.xml.parser.RaceXMLData; import seng302.model.stream.xml.parser.RegattaXMLData; +import seng302.utilities.Sounds; import seng302.utilities.StreamParser; import seng302.utilities.XMLParser; import seng302.visualiser.controllers.FinishScreenViewController; @@ -421,6 +422,7 @@ public class GameClient { private void showCollisionAlert(YachtEventData yachtEventData) { // 33 is the agreed code to show collision if (yachtEventData.getEventId() == 33) { + Sounds.playCrashSound(); raceState.storeCollision( allBoatsMap.get( yachtEventData.getSubjectId().intValue() diff --git a/src/main/java/seng302/visualiser/controllers/CustomizationController.java b/src/main/java/seng302/visualiser/controllers/CustomizationController.java index 1a5b5e4d..7a81bb8f 100644 --- a/src/main/java/seng302/visualiser/controllers/CustomizationController.java +++ b/src/main/java/seng302/visualiser/controllers/CustomizationController.java @@ -7,6 +7,7 @@ import javafx.scene.control.TextField; import javafx.scene.paint.Color; import javafx.stage.Stage; import seng302.gameServer.messages.CustomizeRequestType; +import seng302.utilities.Sounds; import seng302.visualiser.ClientToServerThread; public class CustomizationController { @@ -34,7 +35,8 @@ public class CustomizationController { @FXML public void submitCustomization() { - System.out.println("Attempting to send"); + Sounds.playButtonClick(); +// System.out.println("Attempting to send"); socketThread.sendCustomizationRequest(CustomizeRequestType.NAME, nameField.getText().getBytes()); // TODO: 16/08/17 ajm412: Turn colors into byte array. Color color = boatColorPicker.getValue(); diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java index 4dc5293f..9d52a7a9 100644 --- a/src/main/java/seng302/visualiser/controllers/LobbyController.java +++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java @@ -23,6 +23,7 @@ import seng302.gameServer.GameStages; import seng302.gameServer.GameState; import seng302.model.Colors; import seng302.model.RaceState; +import seng302.utilities.Sounds; import seng302.visualiser.ClientToServerThread; /** @@ -153,6 +154,7 @@ public class LobbyController { @FXML public void customize() { + Sounds.playButtonClick(); Parent root; try { FXMLLoader fxmlLoader = new FXMLLoader(LobbyController.class.getResource("/views/customizeView.fxml")); @@ -184,6 +186,7 @@ public class LobbyController { @FXML public void leaveLobbyButtonPressed() { + Sounds.playButtonClick(); // TODO: 10/07/17 wmu16 - Finish function! GameState.setCurrentStage(GameStages.CANCELLED); // TODO: 20/07/17 wmu16 - Implement some way of terminating the game @@ -193,6 +196,7 @@ public class LobbyController { @FXML public void readyButtonPressed() { + Sounds.playButtonClick(); GameState.setCurrentStage(GameStages.PRE_RACE); // Do countdown logic here diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index a7cd9718..c4835bc6 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -41,6 +41,7 @@ import seng302.model.RaceState; import seng302.model.mark.CompoundMark; import seng302.model.mark.Mark; import seng302.model.stream.xml.parser.RaceXMLData; +import seng302.utilities.Sounds; import seng302.visualiser.GameView; import seng302.visualiser.controllers.annotations.Annotation; import seng302.visualiser.controllers.annotations.ImportantAnnotationController; @@ -91,6 +92,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel private ImportantAnnotationsState importantAnnotations; public void initialize() { + Sounds.stopMusic(); + Sounds.playRaceMusic(); // Load a default important annotation state importantAnnotations = new ImportantAnnotationsState(); diff --git a/src/main/java/seng302/visualiser/controllers/StartScreenController.java b/src/main/java/seng302/visualiser/controllers/StartScreenController.java index 1a9db1a1..687a52d1 100644 --- a/src/main/java/seng302/visualiser/controllers/StartScreenController.java +++ b/src/main/java/seng302/visualiser/controllers/StartScreenController.java @@ -6,12 +6,15 @@ import java.net.NetworkInterface; import java.net.URL; import java.util.Enumeration; import java.util.ResourceBundle; +import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.TextField; +import javafx.scene.control.ToggleButton; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import seng302.gameServer.GameState; +import seng302.utilities.Sounds; import seng302.visualiser.GameClient; /** @@ -20,6 +23,10 @@ import seng302.visualiser.GameClient; */ public class StartScreenController implements Initializable { + @FXML + private ToggleButton muteMusicButton; + @FXML + private ToggleButton muteSoundsButton; @FXML private TextField ipTextField; @FXML @@ -32,6 +39,17 @@ public class StartScreenController implements Initializable { GameClient gameClient; public void initialize(URL url, ResourceBundle resourceBundle) { + if (Sounds.isMusicMuted()) { + muteMusicButton.setText("UnMute Music"); + } else { + muteMusicButton.setText("Mute Music"); + } + if (Sounds.isSoundEffectsMuted()) { + muteSoundsButton.setText("UnMute Sounds"); + } else { + muteSoundsButton.setText("Mute Sounds"); + } + // gameClient = new GameClient(holder); } // @@ -66,6 +84,7 @@ public class StartScreenController implements Initializable { */ @FXML public void hostButtonPressed() { + Sounds.playButtonClick(); // new GameState(getLocalHostIp()); gameClient = new GameClient(holder); gameClient.runAsHost(getLocalHostIp(), 4942); @@ -104,6 +123,7 @@ public class StartScreenController implements Initializable { @FXML public void connectButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function + Sounds.playButtonClick(); gameClient = new GameClient(holder); gameClient.runAsClient(ipTextField.getText().trim().toLowerCase(), 4942); @@ -165,4 +185,24 @@ public class StartScreenController implements Initializable { // ClientState.setHostIp(ipAddress); return ipAddress; } + + public void toggleMusic(ActionEvent actionEvent) { + Sounds.toggleMuteMusic(); + Sounds.playButtonClick(); + if (Sounds.isMusicMuted()) { + muteMusicButton.setText("UnMute Music"); + } else { + muteMusicButton.setText("Mute Music"); + } + } + + public void toggleSounds(ActionEvent actionEvent) { + Sounds.toggleMuteEffects(); + Sounds.playButtonClick(); + if (Sounds.isSoundEffectsMuted()) { + muteSoundsButton.setText("UnMute Sounds"); + } else { + muteSoundsButton.setText("Mute Sounds"); + } + } } diff --git a/src/main/resources/icons/muteIcon.png b/src/main/resources/icons/muteIcon.png new file mode 100644 index 00000000..47975cb8 Binary files /dev/null and b/src/main/resources/icons/muteIcon.png differ diff --git a/src/main/resources/icons/unMuteIcon.png b/src/main/resources/icons/unMuteIcon.png new file mode 100644 index 00000000..e5d1445e Binary files /dev/null and b/src/main/resources/icons/unMuteIcon.png differ diff --git a/src/main/resources/sounds/Button-click-sound.mp3 b/src/main/resources/sounds/Button-click-sound.mp3 new file mode 100644 index 00000000..70bacd67 Binary files /dev/null and b/src/main/resources/sounds/Button-click-sound.mp3 differ diff --git a/src/main/resources/sounds/Chill-house-music-loop-116-bpm.wav b/src/main/resources/sounds/Chill-house-music-loop-116-bpm.wav new file mode 100644 index 00000000..4119e341 Binary files /dev/null and b/src/main/resources/sounds/Chill-house-music-loop-116-bpm.wav differ diff --git a/src/main/resources/sounds/Crash-sound-effect.mp3 b/src/main/resources/sounds/Crash-sound-effect.mp3 new file mode 100644 index 00000000..672540b9 Binary files /dev/null and b/src/main/resources/sounds/Crash-sound-effect.mp3 differ diff --git a/src/main/resources/sounds/Elevator-music.mp3 b/src/main/resources/sounds/Elevator-music.mp3 new file mode 100644 index 00000000..d637c4c4 Binary files /dev/null and b/src/main/resources/sounds/Elevator-music.mp3 differ diff --git a/src/main/resources/sounds/Gunshot-sound.mp3 b/src/main/resources/sounds/Gunshot-sound.mp3 new file mode 100644 index 00000000..4e81c60b Binary files /dev/null and b/src/main/resources/sounds/Gunshot-sound.mp3 differ diff --git a/src/main/resources/sounds/Large-metal-door-slam.mp3 b/src/main/resources/sounds/Large-metal-door-slam.mp3 new file mode 100644 index 00000000..7844d974 Binary files /dev/null and b/src/main/resources/sounds/Large-metal-door-slam.mp3 differ diff --git a/src/main/resources/sounds/Music-loop-120-bpm.mp3 b/src/main/resources/sounds/Music-loop-120-bpm.mp3 new file mode 100644 index 00000000..68a1d4da Binary files /dev/null and b/src/main/resources/sounds/Music-loop-120-bpm.mp3 differ diff --git a/src/main/resources/sounds/Sounds-of-the-ocean.mp3 b/src/main/resources/sounds/Sounds-of-the-ocean.mp3 new file mode 100644 index 00000000..ed040f3f Binary files /dev/null and b/src/main/resources/sounds/Sounds-of-the-ocean.mp3 differ diff --git a/src/main/resources/views/StartScreenView.fxml b/src/main/resources/views/StartScreenView.fxml index 37ea3885..264da0a8 100644 --- a/src/main/resources/views/StartScreenView.fxml +++ b/src/main/resources/views/StartScreenView.fxml @@ -20,9 +20,7 @@ -