merge dev into test #33
@@ -106,7 +106,7 @@ public void simpleInitApp() {
|
|||||||
gameView = new GameView(this);
|
gameView = new GameView(this);
|
||||||
ceremonyView = new CeremonyView(this);
|
ceremonyView = new CeremonyView(this);
|
||||||
|
|
||||||
enter(MdgaState.GAME);
|
enter(MdgaState.MAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ public void selectTsk(Color color) {
|
|||||||
app.getGameLogic().selectTsk(color);
|
app.getGameLogic().selectTsk(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unselectTsk() {
|
public void unselectTsk(Color color) {
|
||||||
app.getGameLogic().selectTsk(Color.NONE);
|
app.getGameLogic().deselectTSK(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rolledDice() {
|
public void rolledDice() {
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ private void handleLobby(Notification notification) {
|
|||||||
|
|
||||||
if (notification instanceof TskSelectNotification n) {
|
if (notification instanceof TskSelectNotification n) {
|
||||||
lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName());
|
lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName());
|
||||||
lobbyView.setTaken(n.getColor(), true, false, n.getName());
|
|
||||||
} else if (notification instanceof StartDialogNotification) {
|
} else if (notification instanceof StartDialogNotification) {
|
||||||
app.enter(MdgaState.MAIN);
|
app.enter(MdgaState.MAIN);
|
||||||
} else if (notification instanceof TskUnselectNotification n) {
|
} else if (notification instanceof TskUnselectNotification n) {
|
||||||
|
|||||||
@@ -7,46 +7,41 @@
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the acoustic functionality for the game, including music playback, sound effects,
|
|
||||||
* volume management, and transitions between game states.
|
|
||||||
*/
|
|
||||||
public class AcousticHandler {
|
public class AcousticHandler {
|
||||||
private MdgaApp app; // Reference to the main application
|
private MdgaApp app;
|
||||||
private MdgaState state = MdgaState.NONE; // Current state of the game
|
|
||||||
private boolean playGame = false; // Whether the game tracks are currently playing
|
|
||||||
private ArrayList<MusicAsset> gameTracks = new ArrayList<>(); // List of available game music tracks
|
|
||||||
private NanoTimer trackTimer = new NanoTimer(); // Timer for managing track transitions
|
|
||||||
|
|
||||||
private boolean fading = false; // Whether a fade transition is in progress
|
private MdgaState state = MdgaState.NONE;
|
||||||
private NanoTimer fadeTimer = new NanoTimer(); // Timer for fade transitions
|
|
||||||
private static final float FADE_DURATION = 3.0f; // Duration of fade-out
|
|
||||||
private static final float CROSSFADE_DURATION = 1.5f; // Duration of fade-in
|
|
||||||
private GameMusic playing = null; // Currently playing music track
|
|
||||||
private GameMusic scheduled = null; // Track scheduled to play next
|
|
||||||
private GameMusic old = null; // Track being faded out
|
|
||||||
|
|
||||||
private float mainVolume = 0.0f; // Main volume level
|
private boolean playGame = false;
|
||||||
private float musicVolume = 1.0f; // Music volume level
|
private ArrayList<MusicAsset> gameTracks = new ArrayList<>();
|
||||||
private float soundVolume = 1.0f; // Sound effects volume level
|
private NanoTimer trackTimer = new NanoTimer();
|
||||||
|
|
||||||
private ArrayList<GameSound> sounds = new ArrayList<>(); // List of active sound effects
|
private boolean fading = false; // Indicates if a fade is in progress
|
||||||
private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class); // User preferences for volume settings
|
private NanoTimer fadeTimer = new NanoTimer(); // Timer to track fade progress
|
||||||
|
private static final float FADE_DURATION = 3.0f; // Duration for outfade
|
||||||
|
private static final float CROSSFADE_DURATION = 1.5f; // Duration for infade
|
||||||
|
private GameMusic playing = null; // Currently playing track
|
||||||
|
private GameMusic scheduled = null; // Scheduled track to play next
|
||||||
|
private GameMusic old = null; // Old track being faded out
|
||||||
|
|
||||||
|
private float mainVolume = 0.0f;
|
||||||
|
private float musicVolume = 1.0f;
|
||||||
|
private float soundVolume = 1.0f;
|
||||||
|
|
||||||
|
private ArrayList<GameSound> sounds = new ArrayList<>();
|
||||||
|
|
||||||
|
private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the AcousticHandler with the main application and loads user volume settings.
|
|
||||||
*
|
|
||||||
* @param app The main application instance.
|
|
||||||
*/
|
|
||||||
public AcousticHandler(MdgaApp app) {
|
public AcousticHandler(MdgaApp app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
mainVolume = prefs.getFloat("mainVolume", 1.0f);
|
mainVolume = prefs.getFloat("mainVolume", 1.0f);
|
||||||
musicVolume = prefs.getFloat("musicVolume", 1.0f);
|
musicVolume = prefs.getFloat("musicVolume", 1.0f);
|
||||||
soundVolume = prefs.getFloat("soundVolume", 1.0f);
|
soundVolume = prefs.getFloat("soundVolume", 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the state of the AcousticHandler. Should be called every frame.
|
* This method updates the acousticHandler and should be called every frame
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public void update() {
|
||||||
updateVolumeAndTrack();
|
updateVolumeAndTrack();
|
||||||
@@ -58,7 +53,9 @@ public void update() {
|
|||||||
Iterator<GameSound> iterator = sounds.iterator();
|
Iterator<GameSound> iterator = sounds.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
GameSound s = iterator.next();
|
GameSound s = iterator.next();
|
||||||
|
|
||||||
s.update(getSoundVolumeTotal());
|
s.update(getSoundVolumeTotal());
|
||||||
|
|
||||||
if (!s.isPlaying()) {
|
if (!s.isPlaying()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
@@ -66,76 +63,314 @@ public void update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays a sound effect immediately.
|
* This method instantly plays a sound
|
||||||
*
|
*
|
||||||
* @param sound The sound effect to play.
|
* @param sound the sound to be played
|
||||||
*/
|
*/
|
||||||
public void playSound(MdgaSound sound) {
|
public void playSound(MdgaSound sound) {
|
||||||
// Implementation for playing predefined sound effects based on game events
|
ArrayList<SoundAssetDelayVolume> assets = new ArrayList<SoundAssetDelayVolume>();
|
||||||
|
switch (sound) {
|
||||||
|
case LOST:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.LOST, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case VICTORY:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.VICTORY, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case BUTTON_PRESSED:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.BUTTON_PRESS, 0.7f, 0.0f));
|
||||||
|
break;
|
||||||
|
case WRONG_INPUT:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.ERROR, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case UI_CLICK:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.UI_CLICK, 0.8f, 0.0f));
|
||||||
|
break;
|
||||||
|
case START:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.START, 0.8f, 0.5f));
|
||||||
|
break;
|
||||||
|
case THROW:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.LAUGHT, 1.0f, 0.2f));
|
||||||
|
break;
|
||||||
|
case POWERUP:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.POWERUP, 1.0f, 0.2f));
|
||||||
|
break;
|
||||||
|
case SELF_READY:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.ROBOT_READY, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case OTHER_READY:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.UNIT_READY, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case OTHER_CONNECTED:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.CONNECTED, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case NOT_READY:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND, 1.0f, 0.0f));
|
||||||
|
break;
|
||||||
|
case LEAVE:
|
||||||
|
assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND2, 0.6f, 0.0f));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SoundAssetDelayVolume sawd : assets) {
|
||||||
|
GameSound gameSound = new GameSound(app, sawd.asset(), getSoundVolumeTotal(), sawd.subVolume(), sawd.delay());
|
||||||
|
sounds.add(gameSound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitions music playback to match the specified game state.
|
* This method fades the played music to fit the state.
|
||||||
*
|
*
|
||||||
* @param state The new game state.
|
* @param state the state of which the corresponding music should be played to be played
|
||||||
*/
|
*/
|
||||||
public void playState(MdgaState state) {
|
public void playState(MdgaState state) {
|
||||||
// Implementation for managing state-specific music playback
|
if (this.state == state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MusicAsset asset = null;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case MAIN:
|
||||||
|
playGame = false;
|
||||||
|
asset = MusicAsset.MAIN_MENU;
|
||||||
|
break;
|
||||||
|
case LOBBY:
|
||||||
|
playGame = false;
|
||||||
|
asset = MusicAsset.LOBBY;
|
||||||
|
break;
|
||||||
|
case GAME:
|
||||||
|
addGameTracks();
|
||||||
|
playGame = true;
|
||||||
|
assert (!gameTracks.isEmpty()) : "no more game music available";
|
||||||
|
asset = gameTracks.remove(0);
|
||||||
|
break;
|
||||||
|
case CEREMONY:
|
||||||
|
playGame = false;
|
||||||
|
asset = MusicAsset.CEREMONY;
|
||||||
|
break;
|
||||||
|
case NONE:
|
||||||
|
throw new RuntimeException("no music for state NONE");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (null != asset) : "music sceduling went wrong";
|
||||||
|
|
||||||
|
scheduled = new GameMusic(app, asset, getMusicVolumeTotal(), asset.getSubVolume(), asset.getLoop(), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs linear interpolation between two values.
|
* Performs linear interpolation between two float values.
|
||||||
*
|
*
|
||||||
* @param start The starting value.
|
* @param start The starting value.
|
||||||
* @param end The ending value.
|
* @param end The ending value.
|
||||||
* @param t The interpolation factor (0 to 1).
|
* @param t The interpolation factor, typically between 0 and 1.
|
||||||
* @return The interpolated value.
|
* @return The interpolated value between start and end.
|
||||||
*/
|
*/
|
||||||
private float lerp(float start, float end, float t) {
|
private float lerp(float start, float end, float t) {
|
||||||
return start + t * (end - start);
|
return start + t * (end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages audio playback transitions and volume adjustments.
|
* Updates the state of audio playback, handling track transitions and volume adjustments.
|
||||||
|
*
|
||||||
|
* This method ensures smooth transitions between tracks using fade-in and fade-out effects.
|
||||||
|
* It also handles cases where no track is playing, starting a scheduled track immediately at full volume.
|
||||||
|
* The method prioritizes the latest scheduled track if multiple scheduling occurs quickly.
|
||||||
|
*
|
||||||
|
* Behavior:
|
||||||
|
* 1. If nothing is scheduled and no track is playing, it exits early.
|
||||||
|
* 2. If a scheduled track exists and no track is playing, the scheduled track starts immediately at full volume.
|
||||||
|
* 3. If a scheduled track exists while a track is playing, it initiates a fade-out for the currently playing track
|
||||||
|
* and prepares for the new track to fade in.
|
||||||
|
* 4. If a track transition is in progress (fading), it processes the fade-out and fade-in states.
|
||||||
|
* If a new track is scheduled during this process, it interrupts the current transition and prioritizes the new track.
|
||||||
|
* 5. If no fading is needed and a track is playing, it ensures the track's volume is updated.
|
||||||
|
*
|
||||||
|
* Special cases:
|
||||||
|
* - If no track is playing and a new track is scheduled, it starts the track immediately without fading.
|
||||||
|
* - If a new track is scheduled during fading, it resets the transition to prioritize the new track.
|
||||||
*/
|
*/
|
||||||
private void updateVolumeAndTrack() {
|
private void updateVolumeAndTrack() {
|
||||||
// Implementation for handling fade-ins, fade-outs, and volume updates
|
if (scheduled == null && !fading && playing == null) {
|
||||||
|
// Nothing to do, early exit
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduled != null && playing == null && !fading) {
|
||||||
|
// No current track, start scheduled track immediately at full volume
|
||||||
|
playing = scheduled;
|
||||||
|
scheduled = null;
|
||||||
|
playing.play();
|
||||||
|
playing.update(getMusicVolumeTotal()); // Set volume to full
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduled != null && !fading) {
|
||||||
|
// Initiate a fade process if a new track is scheduled
|
||||||
|
fading = true;
|
||||||
|
fadeTimer.reset();
|
||||||
|
old = playing; // The currently playing track becomes the old track
|
||||||
|
playing = null; // Clear the playing track during the fade process
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fading) {
|
||||||
|
handleFadeProcess();
|
||||||
|
|
||||||
|
// Handle any interruptions due to newly scheduled tracks
|
||||||
|
if (scheduled != null && playing != null && playing != scheduled) {
|
||||||
|
// Interrupt the current infade and switch to the new scheduled track
|
||||||
|
old = playing; // Treat the currently infading track as the old track
|
||||||
|
playing = null; // Reset playing to allow switching
|
||||||
|
fadeTimer.reset(); // Restart fade timer for the new track
|
||||||
|
}
|
||||||
|
} else if (playing != null) {
|
||||||
|
// Update volume for the currently playing track
|
||||||
|
playing.update(getMusicVolumeTotal());
|
||||||
|
} else if (scheduled != null) {
|
||||||
|
// If no track is playing and one is scheduled, start it immediately at full volume
|
||||||
|
playing = scheduled;
|
||||||
|
scheduled = null;
|
||||||
|
playing.play();
|
||||||
|
playing.update(getMusicVolumeTotal()); // Set volume to full
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the fade-out and fade-in processes for audio transitions.
|
* Manages the fading process during audio track transitions.
|
||||||
|
*
|
||||||
|
* This method handles the fade-out of the currently playing (old) track, manages any pause between the fade-out
|
||||||
|
* and fade-in, and initiates the fade-in for the new track if applicable. It ensures smooth transitions between
|
||||||
|
* tracks while maintaining the correct volume adjustments.
|
||||||
|
*
|
||||||
|
* Behavior:
|
||||||
|
* 1. **Outfade:** Gradually decreases the volume of the `old` track over the duration of `FADE_DURATION`.
|
||||||
|
* Once the outfade completes, the `old` track is paused and cleared.
|
||||||
|
* 2. **Pause Handling:** Waits for a defined pause (if applicable) before initiating the infade for the next track.
|
||||||
|
* 3. **Infade:** If a `scheduled` track exists and the outfade and pause are complete, it begins playing
|
||||||
|
* the new track (`playing`) and initiates the infade process.
|
||||||
|
*
|
||||||
|
* Key Details:
|
||||||
|
* - The outfade volume adjustment is interpolated linearly from full volume to zero using the `lerp` function.
|
||||||
|
* - The pause duration is retrieved from the scheduled track if it is specified.
|
||||||
|
* - If a new track is scheduled during the fade process, it is handled by external logic to prioritize transitions.
|
||||||
|
*
|
||||||
|
* Preconditions:
|
||||||
|
* - `fading` is expected to be `true` when this method is called.
|
||||||
|
* - The method is invoked as part of the `updateVolumeAndTrack` process.
|
||||||
*/
|
*/
|
||||||
private void handleFadeProcess() {
|
private void handleFadeProcess() {
|
||||||
// Implementation for managing fade transitions
|
float time = fadeTimer.getTimeInSeconds();
|
||||||
|
|
||||||
|
// Handle outfade for the old track
|
||||||
|
if (old != null && time <= FADE_DURATION) {
|
||||||
|
float t = Math.min(time / FADE_DURATION, 1.0f);
|
||||||
|
float oldVolume = lerp(1.0f, 0.0f, t);
|
||||||
|
old.update(getMusicVolumeTotal() * oldVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old != null && time > FADE_DURATION) {
|
||||||
|
// Complete outfade
|
||||||
|
old.pause();
|
||||||
|
old = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle pause duration before infade
|
||||||
|
float pause = (scheduled != null) ? scheduled.getPause() : 0.0f;
|
||||||
|
if (time > FADE_DURATION + pause) {
|
||||||
|
if (playing == null && scheduled != null) {
|
||||||
|
// Begin infade for the new track
|
||||||
|
playing = scheduled;
|
||||||
|
scheduled = null;
|
||||||
|
playing.play(); // Start playing the new track
|
||||||
|
}
|
||||||
|
handleInfade(time - FADE_DURATION - pause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the fade-in process for the currently playing track.
|
* Manages the fade-in process for the currently playing track.
|
||||||
*
|
*
|
||||||
* @param infadeTime Time elapsed since the fade-in process started.
|
* This method gradually increases the volume of the `playing` track from zero to full volume
|
||||||
|
* over the duration of `CROSSFADE_DURATION`. It ensures a smooth transition into the new track.
|
||||||
|
*
|
||||||
|
* Behavior:
|
||||||
|
* 1. If no track is set as `playing`, the method exits early, as there is nothing to fade in.
|
||||||
|
* 2. Linearly interpolates the volume of the `playing` track from 0.0 to 1.0 based on the elapsed
|
||||||
|
* `infadeTime` and the specified `CROSSFADE_DURATION`.
|
||||||
|
* 3. Once the fade-in is complete (when `infadeTime` exceeds `CROSSFADE_DURATION`), the method:
|
||||||
|
* - Marks the fade process (`fading`) as complete.
|
||||||
|
* - Ensures the `playing` track is updated to its full volume.
|
||||||
|
*
|
||||||
|
* Key Details:
|
||||||
|
* - Uses the `lerp` function to calculate the volume level for the `playing` track during the fade-in.
|
||||||
|
* - Ensures the volume is always a value between 0.0 and 1.0.
|
||||||
|
* - The `infadeTime` parameter should be relative to the start of the fade-in process.
|
||||||
|
*
|
||||||
|
* Preconditions:
|
||||||
|
* - The `playing` track must be initialized and actively fading in for this method to have an effect.
|
||||||
|
* - The method is invoked as part of the `updateVolumeAndTrack` process.
|
||||||
|
*
|
||||||
|
* @param infadeTime The elapsed time (in seconds) since the fade-in process started.
|
||||||
*/
|
*/
|
||||||
private void handleInfade(float infadeTime) {
|
private void handleInfade(float infadeTime) {
|
||||||
// Implementation for handling the fade-in process
|
if (playing == null) {
|
||||||
|
// Nothing to infade
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proceed with the infade for the current playing track
|
||||||
|
float t = Math.min(infadeTime / CROSSFADE_DURATION, 1.0f);
|
||||||
|
float newVolume = lerp(0.0f, 1.0f, t);
|
||||||
|
playing.update(getMusicVolumeTotal() * newVolume);
|
||||||
|
|
||||||
|
if (infadeTime > CROSSFADE_DURATION) {
|
||||||
|
// Infade is complete, finalize state
|
||||||
|
fading = false;
|
||||||
|
playing.update(getMusicVolumeTotal()); // Ensure full volume
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds and shuffles game music tracks.
|
* Adds a list of game tracks to the gameTracks collection and shuffles them.
|
||||||
|
* This method adds predefined game tracks to the track list and shuffles the order.
|
||||||
*/
|
*/
|
||||||
private void addGameTracks() {
|
private void addGameTracks() {
|
||||||
// Adds predefined game music tracks to the list and shuffles them
|
Random random = new Random();
|
||||||
|
|
||||||
|
for (int i = 1; i <= 6; i++) {
|
||||||
|
gameTracks.add(MusicAsset.valueOf("GAME_" + i));
|
||||||
|
}
|
||||||
|
Collections.shuffle(gameTracks, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the game music tracks, scheduling new ones as needed.
|
* Updates the current game tracks. If the currently playing track is nearing its end,
|
||||||
|
* a new track will be scheduled to play. If the list of game tracks is empty, it will be refreshed.
|
||||||
*/
|
*/
|
||||||
private void updateGameTracks() {
|
private void updateGameTracks() {
|
||||||
// Handles scheduling and transitioning between game tracks
|
if(null == playing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing.nearEnd(10)) {
|
||||||
|
if (gameTracks.isEmpty()) {
|
||||||
|
addGameTracks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing != null && playing.nearEnd(3) && trackTimer.getTimeInSeconds() > 20) {
|
||||||
|
trackTimer.reset();
|
||||||
|
|
||||||
|
MusicAsset nextTrack = gameTracks.remove(0);
|
||||||
|
|
||||||
|
scheduled = new GameMusic(app, nextTrack, getMusicVolumeTotal(), nextTrack.getSubVolume(), nextTrack.getLoop(), 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the main volume level.
|
* Retrieves the main volume level.
|
||||||
*
|
*
|
||||||
* @return The main volume level.
|
* @return The current main volume level.
|
||||||
*/
|
*/
|
||||||
public float getMainVolume() {
|
public float getMainVolume() {
|
||||||
return mainVolume;
|
return mainVolume;
|
||||||
@@ -160,7 +395,7 @@ public float getSoundVolume() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the main volume level and saves the setting.
|
* Sets the main volume level.
|
||||||
*
|
*
|
||||||
* @param mainVolume The desired main volume level.
|
* @param mainVolume The desired main volume level.
|
||||||
*/
|
*/
|
||||||
@@ -169,27 +404,6 @@ public void setMainVolume(float mainVolume) {
|
|||||||
prefs.putFloat("mainVolume", mainVolume);
|
prefs.putFloat("mainVolume", mainVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar getters and setters for musicVolume and soundVolume...
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the total music volume (main volume × music volume).
|
|
||||||
*
|
|
||||||
* @return The total music volume.
|
|
||||||
*/
|
|
||||||
float getMusicVolumeTotal() {
|
|
||||||
return musicVolume * mainVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the total sound volume (main volume × sound volume).
|
|
||||||
*
|
|
||||||
* @return The total sound volume.
|
|
||||||
*/
|
|
||||||
float getSoundVolumeTotal() {
|
|
||||||
return soundVolume * mainVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the music volume level.
|
* Sets the music volume level.
|
||||||
*
|
*
|
||||||
@@ -209,4 +423,23 @@ public void setSoundVolume(float soundVolume) {
|
|||||||
this.soundVolume = soundVolume;
|
this.soundVolume = soundVolume;
|
||||||
prefs.putFloat("soundVolume", soundVolume);
|
prefs.putFloat("soundVolume", soundVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the total music volume by multiplying the music volume by the main volume.
|
||||||
|
*
|
||||||
|
* @return The total music volume.
|
||||||
|
*/
|
||||||
|
float getMusicVolumeTotal() {
|
||||||
|
|
||||||
|
return getMusicVolume() * getMainVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the total sound volume by multiplying the sound volume by the main volume.
|
||||||
|
*
|
||||||
|
* @return The total sound volume.
|
||||||
|
*/
|
||||||
|
float getSoundVolumeTotal() {
|
||||||
|
return getSoundVolume() * getMainVolume();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,23 @@ public void setTaken(Color color, boolean isTaken, boolean isSelf, String name)
|
|||||||
|
|
||||||
if(isTaken) {
|
if(isTaken) {
|
||||||
if(isSelf) {
|
if(isSelf) {
|
||||||
|
/*if(own != null) {
|
||||||
|
switch (color) {
|
||||||
|
case CYBER:
|
||||||
|
cyberButton.setTaken(LobbyButton.Taken.NOT, name);
|
||||||
|
break;
|
||||||
|
case AIRFORCE:
|
||||||
|
airforceButton.setTaken(LobbyButton.Taken.NOT, name);
|
||||||
|
break;
|
||||||
|
case ARMY:
|
||||||
|
armyButton.setTaken(LobbyButton.Taken.NOT, name);
|
||||||
|
break;
|
||||||
|
case NAVY:
|
||||||
|
navyButton.setTaken(LobbyButton.Taken.NOT, name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
own = color;
|
own = color;
|
||||||
taken = LobbyButton.Taken.SELF;
|
taken = LobbyButton.Taken.SELF;
|
||||||
} else {
|
} else {
|
||||||
@@ -228,7 +245,7 @@ private void toggleTsk(Color color) {
|
|||||||
app.getModelSynchronize().selectTsk(color);
|
app.getModelSynchronize().selectTsk(color);
|
||||||
break;
|
break;
|
||||||
case SELF:
|
case SELF:
|
||||||
app.getModelSynchronize().unselectTsk();
|
app.getModelSynchronize().unselectTsk(color);
|
||||||
break;
|
break;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
//nothing
|
//nothing
|
||||||
|
|||||||
@@ -239,6 +239,10 @@ public void selectTsk(Color color){
|
|||||||
state.selectTSK(color);
|
state.selectTSK(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deselectTSK(Color color){
|
||||||
|
state.deselectTSK(color);
|
||||||
|
}
|
||||||
|
|
||||||
public void selectDice(){
|
public void selectDice(){
|
||||||
state.selectDice();
|
state.selectDice();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,9 +101,13 @@ public void received(LobbyPlayerJoinedMessage msg){
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(UpdateTSKMessage msg){
|
public void received(UpdateTSKMessage msg){
|
||||||
logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
|
if(msg.isTaken()) {
|
||||||
|
logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
|
||||||
|
} else {
|
||||||
|
logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
|
||||||
|
}
|
||||||
|
|
||||||
logic.getGame().getPlayers().get(msg.getId()).setColor(msg.getColor());
|
logic.getGame().getPlayers().get(msg.getId()).setColor(msg.getColor());
|
||||||
logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,23 +18,26 @@ public class UpdateTSKMessage extends ServerMessage {
|
|||||||
*/
|
*/
|
||||||
private final Color color;
|
private final Color color;
|
||||||
|
|
||||||
|
private final boolean isTaken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new UpdateTSK instance with the specified id and color.
|
* Constructs a new UpdateTSK instance with the specified id and color.
|
||||||
*
|
*
|
||||||
* @param id the name associated with the update
|
* @param id the name associated with the update
|
||||||
* @param color the color associated with the update
|
* @param color the color associated with the update
|
||||||
*/
|
*/
|
||||||
public UpdateTSKMessage(int id, Color color) {
|
public UpdateTSKMessage(int id, Color color, boolean isTaken) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
this.isTaken = isTaken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for serialization purposes.
|
* Default constructor for serialization purposes.
|
||||||
*/
|
*/
|
||||||
private UpdateTSKMessage() {
|
private UpdateTSKMessage() {
|
||||||
this(0, null);
|
this(0, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,4 +87,8 @@ public String toString() {
|
|||||||
public String getInfoTextKey() {
|
public String getInfoTextKey() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTaken() {
|
||||||
|
return isTaken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import pp.mdga.message.server.*;
|
import pp.mdga.message.server.*;
|
||||||
import pp.mdga.server.ServerGameLogic;
|
import pp.mdga.server.ServerGameLogic;
|
||||||
|
|
||||||
|
import java.lang.foreign.StructLayout;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,8 +85,13 @@ public void received(SelectTSKMessage msg, int from) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) {
|
||||||
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, this.logic.getGame().getPlayerById(from).getColor(), false));
|
||||||
|
}
|
||||||
|
|
||||||
this.logic.getGame().getPlayerById(from).setColor(msg.getColor());
|
this.logic.getGame().getPlayerById(from).setColor(msg.getColor());
|
||||||
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor()));
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +104,7 @@ public void received(SelectTSKMessage msg, int from) {
|
|||||||
@Override
|
@Override
|
||||||
public void received(DeselectTSKMessage msg, int from) {
|
public void received(DeselectTSKMessage msg, int from) {
|
||||||
this.logic.getGame().getPlayerById(from).setColor(Color.NONE);
|
this.logic.getGame().getPlayerById(from).setColor(Color.NONE);
|
||||||
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE));
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user