Work of the week #3
@@ -1,18 +1,17 @@
 | 
			
		||||
<component name="ProjectRunConfigurationManager">
 | 
			
		||||
  <configuration default="false" name="MdgaApp" type="Application" factoryName="Application" singleton="false"
 | 
			
		||||
                 nameIsGenerated="true">
 | 
			
		||||
    <option name="MAIN_CLASS_NAME" value="pp.mdga.client.MdgaApp"/>
 | 
			
		||||
    <module name="Projekte.mdga.client.main"/>
 | 
			
		||||
    <option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties"/>
 | 
			
		||||
    <option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$"/>
 | 
			
		||||
  <configuration default="false" name="MdgaApp" type="Application" factoryName="Application" singleton="false" nameIsGenerated="true">
 | 
			
		||||
    <option name="MAIN_CLASS_NAME" value="pp.mdga.client.MdgaApp" />
 | 
			
		||||
    <module name="Projekte.mdga.client.main" />
 | 
			
		||||
    <option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties -ea" />
 | 
			
		||||
    <option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
 | 
			
		||||
    <extension name="coverage">
 | 
			
		||||
      <pattern>
 | 
			
		||||
        <option name="PATTERN" value="pp.mdga.client.*"/>
 | 
			
		||||
        <option name="ENABLED" value="true"/>
 | 
			
		||||
        <option name="PATTERN" value="pp.mdga.client.Board.*" />
 | 
			
		||||
        <option name="ENABLED" value="true" />
 | 
			
		||||
      </pattern>
 | 
			
		||||
    </extension>
 | 
			
		||||
    <method v="2">
 | 
			
		||||
      <option name="Make" enabled="true"/>
 | 
			
		||||
      <option name="Make" enabled="true" />
 | 
			
		||||
    </method>
 | 
			
		||||
  </configuration>
 | 
			
		||||
</component>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,290 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
import com.jme3.system.NanoTimer;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
import pp.mdga.client.MdgaState;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class AcousticHandler {
 | 
			
		||||
    private MdgaApp app;
 | 
			
		||||
 | 
			
		||||
    private MdgaState state = MdgaState.NONE;
 | 
			
		||||
 | 
			
		||||
    private boolean playGame = false;
 | 
			
		||||
    private ArrayList<MusicAsset> gameTracks = new ArrayList<>();
 | 
			
		||||
    private NanoTimer  trackTimer = new NanoTimer();
 | 
			
		||||
 | 
			
		||||
    private boolean fading = false;
 | 
			
		||||
    private NanoTimer fadeTimer = new NanoTimer();
 | 
			
		||||
    private final float FADE_DURATION = 3.0f;
 | 
			
		||||
    private final float CROSSFADE_DURATION = 1.5f;
 | 
			
		||||
 | 
			
		||||
    private float mainVolume = 1.0f;
 | 
			
		||||
    private float musicVolume = 1.0f;
 | 
			
		||||
    private float soundVolume = 1.0f;
 | 
			
		||||
 | 
			
		||||
    private GameMusic scheduled = null;
 | 
			
		||||
    private GameMusic playing = null;
 | 
			
		||||
    private ArrayList<GameSound> sounds = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public AcousticHandler(MdgaApp app) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method updates the acousticHandler and should be called every frame
 | 
			
		||||
     */
 | 
			
		||||
    public void update() {
 | 
			
		||||
        updateVolumeAndTrack();
 | 
			
		||||
 | 
			
		||||
        if(playGame) {
 | 
			
		||||
            updateGameTracks();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Iterator<GameSound> iterator = sounds.iterator();
 | 
			
		||||
        while (iterator.hasNext()) {
 | 
			
		||||
            GameSound s = iterator.next();
 | 
			
		||||
 | 
			
		||||
            s.update(getSoundVolumeTotal());
 | 
			
		||||
 | 
			
		||||
            if (!s.isPlaying()) {
 | 
			
		||||
                iterator.remove();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method instantly plays a sound
 | 
			
		||||
     *
 | 
			
		||||
     * @param sound the sound to be played
 | 
			
		||||
     */
 | 
			
		||||
    public void playSound(MdgaSound sound) {
 | 
			
		||||
        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, 2.0f));
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (SoundAssetDelayVolume sawd : assets) {
 | 
			
		||||
            GameSound gameSound = new GameSound(app, sawd.asset(), getSoundVolumeTotal(), sawd.subVolume(), sawd.delay());
 | 
			
		||||
            sounds.add(gameSound);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method fades the played music to fit the state.
 | 
			
		||||
     *
 | 
			
		||||
     * @param state the state of which the corresponding music should be played to be played
 | 
			
		||||
     */
 | 
			
		||||
    public void playState(MdgaState state) {
 | 
			
		||||
        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.size() > 0) : "no more game music available";
 | 
			
		||||
                asset = gameTracks.remove(0);
 | 
			
		||||
                break;
 | 
			
		||||
            case CEREMONY:
 | 
			
		||||
                playGame = false;
 | 
			
		||||
                asset = MusicAsset.CEREMONY;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assert(null != asset) : "music sceduling went wrong";
 | 
			
		||||
 | 
			
		||||
        scheduled = new GameMusic(app, asset, getMusicVolumeTotal(), asset.getSubVolume(), asset.getLoop());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Performs linear interpolation between two float values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param start The starting value.
 | 
			
		||||
     * @param end The ending value.
 | 
			
		||||
     * @param t The interpolation factor, typically between 0 and 1.
 | 
			
		||||
     * @return The interpolated value between start and end.
 | 
			
		||||
     */
 | 
			
		||||
    private float lerp(float start, float end, float t) {
 | 
			
		||||
        return start + t * (end - start);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the current volume and handles track crossfading logic.
 | 
			
		||||
     * This method is responsible for fading out the currently playing track,
 | 
			
		||||
     * fading in the scheduled track, and handling crossfade between the two tracks.
 | 
			
		||||
     */
 | 
			
		||||
    private void updateVolumeAndTrack() {
 | 
			
		||||
        if (playing == null && scheduled != null && !fading) {
 | 
			
		||||
            playing = scheduled;
 | 
			
		||||
            scheduled = null;
 | 
			
		||||
            playing.play();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (scheduled != null && !fading) {
 | 
			
		||||
            fading = true;
 | 
			
		||||
            fadeTimer.reset();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (fading) {
 | 
			
		||||
            float time = fadeTimer.getTimeInSeconds();
 | 
			
		||||
 | 
			
		||||
            if (time <= FADE_DURATION) {
 | 
			
		||||
                float t = Math.min(time / FADE_DURATION, 1.0f);
 | 
			
		||||
                float oldVolume = lerp(1.0f, 0.0f, t);
 | 
			
		||||
                if (playing != null) {
 | 
			
		||||
                    playing.update(getMusicVolumeTotal()* oldVolume);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (time > FADE_DURATION && time <= FADE_DURATION + CROSSFADE_DURATION) {
 | 
			
		||||
                float t = Math.min((time - FADE_DURATION) / CROSSFADE_DURATION, 1.0f);
 | 
			
		||||
                float newVolume = lerp(0.0f, 1.0f, t);
 | 
			
		||||
 | 
			
		||||
                if (!scheduled.isPlaying()) {
 | 
			
		||||
                    scheduled.play();
 | 
			
		||||
                }
 | 
			
		||||
                scheduled.update(getMusicVolumeTotal() * newVolume);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (time > FADE_DURATION + CROSSFADE_DURATION) {
 | 
			
		||||
                if (playing != null) {
 | 
			
		||||
                    playing.pause();
 | 
			
		||||
                }
 | 
			
		||||
                playing = scheduled;
 | 
			
		||||
                scheduled = null;
 | 
			
		||||
 | 
			
		||||
                fading = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (playing != null) {
 | 
			
		||||
            playing.update(getMusicVolumeTotal());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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() {
 | 
			
		||||
        Random random = new Random();
 | 
			
		||||
 | 
			
		||||
        for (int i = 1; i <= 6; i++) {
 | 
			
		||||
            gameTracks.add(MusicAsset.valueOf("GAME_" + i));
 | 
			
		||||
        }
 | 
			
		||||
        Collections.shuffle(gameTracks, random);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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() {
 | 
			
		||||
        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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves the main volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The current main volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public float getMainVolume() {
 | 
			
		||||
        return  mainVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves the music volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The current music volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public float getMusicVolume() {
 | 
			
		||||
        return musicVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves the sound volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The current sound volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public float getSoundVolume() {
 | 
			
		||||
        return soundVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the main volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mainVolume The desired main volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public void setMainVolume(float mainVolume) {
 | 
			
		||||
        this.mainVolume = mainVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the music volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @param musicVolume The desired music volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public void setMusicVolume(float musicVolume) {
 | 
			
		||||
        this.musicVolume = musicVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the sound volume level.
 | 
			
		||||
     *
 | 
			
		||||
     * @param soundVolume The desired sound volume level.
 | 
			
		||||
     */
 | 
			
		||||
    public void setSoundVolume(float soundVolume) {
 | 
			
		||||
        this.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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,110 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
import com.jme3.audio.AudioData;
 | 
			
		||||
import com.jme3.audio.AudioNode;
 | 
			
		||||
import com.jme3.audio.AudioSource;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a game music track, including its playback controls and volume settings.
 | 
			
		||||
 * This class manages the playback of a music track, allowing for playing, pausing,
 | 
			
		||||
 * volume adjustment, and tracking the current status of the music.
 | 
			
		||||
 */
 | 
			
		||||
class GameMusic {
 | 
			
		||||
    private float volume;
 | 
			
		||||
    private final float subVolume;
 | 
			
		||||
    private final AudioNode music;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new GameMusic object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param app The instance of the application, used to access the asset manager.
 | 
			
		||||
     * @param asset The music asset to be played.
 | 
			
		||||
     * @param volume The total volume of the music, adjusted by the main volume.
 | 
			
		||||
     * @param subVolume A relative volume that modifies the base music volume, typically a percentage.
 | 
			
		||||
     * @param loop A flag indicating whether the music should loop once it finishes.
 | 
			
		||||
     */
 | 
			
		||||
    GameMusic(MdgaApp app, MusicAsset asset, float volume, float subVolume, boolean loop) {
 | 
			
		||||
        this.volume = volume;
 | 
			
		||||
        this.subVolume = subVolume;
 | 
			
		||||
 | 
			
		||||
        music = new AudioNode(app.getAssetManager(), asset.getPath(), AudioData.DataType.Stream);
 | 
			
		||||
        music.setPositional(false);
 | 
			
		||||
        music.setDirectional(false);
 | 
			
		||||
        music.setVolume(volume * subVolume);
 | 
			
		||||
 | 
			
		||||
        music.setLooping(loop);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Plays the current music track.
 | 
			
		||||
     * If the music is already initialized, it starts playback.
 | 
			
		||||
     * If the music is not available, no action is performed.
 | 
			
		||||
     */
 | 
			
		||||
    void play() {
 | 
			
		||||
        if(null == music) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        music.play();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pauses the current music track.
 | 
			
		||||
     * If the music is not available or is not playing, no action is performed.
 | 
			
		||||
     */
 | 
			
		||||
    void pause() {
 | 
			
		||||
        if(null == music) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        music.stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the current music track is playing.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the music is playing, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    boolean isPlaying() {
 | 
			
		||||
 | 
			
		||||
        return music.getStatus() == AudioSource.Status.Playing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the current music track is near the end.
 | 
			
		||||
     *
 | 
			
		||||
     * @param thresholdSeconds The threshold in seconds. If the remaining time is less than or equal to this value,
 | 
			
		||||
     *                         the track is considered near the end.
 | 
			
		||||
     * @return true if the track is near its end (within the threshold), false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    boolean nearEnd(float thresholdSeconds) {
 | 
			
		||||
        if (music == null || !isPlaying()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        float currentTime = music.getPlaybackTime(); // Current playback time in seconds
 | 
			
		||||
        float duration = music.getAudioData().getDuration(); // Total duration in seconds
 | 
			
		||||
 | 
			
		||||
        if (duration <= 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        float remainingTime = duration - currentTime;
 | 
			
		||||
 | 
			
		||||
        return remainingTime <= thresholdSeconds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the volume of the music.
 | 
			
		||||
     * If the volume has changed, it will adjust the music's volume accordingly.
 | 
			
		||||
     *
 | 
			
		||||
     * @param newVolume The new total volume for the music.
 | 
			
		||||
     */
 | 
			
		||||
    void update(float newVolume) {
 | 
			
		||||
        if(volume != newVolume) {
 | 
			
		||||
            volume = newVolume;
 | 
			
		||||
            music.setVolume(volume * subVolume);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,83 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
import com.jme3.audio.AudioData;
 | 
			
		||||
import com.jme3.audio.AudioNode;
 | 
			
		||||
import com.jme3.audio.AudioSource;
 | 
			
		||||
import com.jme3.system.NanoTimer;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a game sound effect, with control over playback, volume, and timing.
 | 
			
		||||
 * This class manages the playback of a sound effect, including starting playback after a delay,
 | 
			
		||||
 * adjusting volume, and tracking whether the sound has finished playing.
 | 
			
		||||
 */
 | 
			
		||||
class GameSound {
 | 
			
		||||
    private float volume;
 | 
			
		||||
    final private float subVolume;
 | 
			
		||||
 | 
			
		||||
    private final AudioNode sound;
 | 
			
		||||
 | 
			
		||||
    private boolean playing = false;
 | 
			
		||||
    private boolean finished = false;
 | 
			
		||||
 | 
			
		||||
    private float delay = 0.0f;
 | 
			
		||||
    private NanoTimer timer = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new GameSound object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param app The instance of the application, used to access the asset manager.
 | 
			
		||||
     * @param asset The sound asset to be played.
 | 
			
		||||
     * @param volume The total volume of the sound, adjusted by the main volume.
 | 
			
		||||
     * @param subVolume A relative volume that modifies the base sound volume, typically a percentage.
 | 
			
		||||
     * @param delay The delay before the sound starts playing, in seconds.
 | 
			
		||||
     */
 | 
			
		||||
    GameSound(MdgaApp app, SoundAsset asset, float volume, float subVolume, float delay) {
 | 
			
		||||
        this.volume = volume;
 | 
			
		||||
        this.subVolume = subVolume;
 | 
			
		||||
        this.delay = delay;
 | 
			
		||||
 | 
			
		||||
        sound = new AudioNode(app.getAssetManager(), asset.getPath(), AudioData.DataType.Buffer);
 | 
			
		||||
        sound.setPositional(false);
 | 
			
		||||
        sound.setDirectional(false);
 | 
			
		||||
        sound.setLooping(false);
 | 
			
		||||
        sound.setVolume(volume * subVolume);
 | 
			
		||||
 | 
			
		||||
        timer = new NanoTimer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if the sound is currently playing.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the sound is playing, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    boolean isPlaying() {
 | 
			
		||||
        return !finished;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the sound playback, adjusting the volume if necessary, and starting
 | 
			
		||||
     * the sound after the specified delay.
 | 
			
		||||
     *
 | 
			
		||||
     * @param newVolume The new total volume for the sound.
 | 
			
		||||
     */
 | 
			
		||||
    void update(float newVolume) {
 | 
			
		||||
        if(!playing && timer.getTimeInSeconds() > delay) {
 | 
			
		||||
            sound.play();
 | 
			
		||||
            playing = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!playing) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(volume != newVolume) {
 | 
			
		||||
            volume = newVolume;
 | 
			
		||||
            sound.setVolume(volume * subVolume);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(sound != null && sound.getStatus() == AudioSource.Status.Playing) {
 | 
			
		||||
            finished = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enum representing the various sound effects used in the game.
 | 
			
		||||
 * Each sound corresponds to an event or action in the game and may consist of one or more
 | 
			
		||||
 * audio files, potentially with time delays between them.
 | 
			
		||||
 *
 | 
			
		||||
 * These sounds are used to play specific audio cues, such as when a dice is rolled,
 | 
			
		||||
 * a turn starts or ends, a piece is moved or lost, and various other events in the game.
 | 
			
		||||
 */
 | 
			
		||||
public enum MdgaSound {
 | 
			
		||||
    DICE_ROLL,
 | 
			
		||||
    TURN_START,
 | 
			
		||||
    TURN_END,
 | 
			
		||||
    PIECE_END,
 | 
			
		||||
    PIECE_MOVE,
 | 
			
		||||
    PIECE_LOST,
 | 
			
		||||
    SELECT,
 | 
			
		||||
    DESELECT,
 | 
			
		||||
    HURRY,
 | 
			
		||||
    VICTORY,
 | 
			
		||||
    LOST;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,76 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enum representing various music assets used in the game.
 | 
			
		||||
 * Each constant corresponds to a specific music track, along with its properties such as file path,
 | 
			
		||||
 * looping behavior, and relative volume (subVolume).
 | 
			
		||||
 * These music assets are used to control the music that plays in different parts of the game, such as menus and in-game music.
 | 
			
		||||
 */
 | 
			
		||||
enum MusicAsset {
 | 
			
		||||
    MAIN_MENU("Spaceship.wav", 1.0f),
 | 
			
		||||
    LOBBY("DeadPlanet.wav", 1.0f),
 | 
			
		||||
    CEREMONY("80s,Disco,Life.wav", 1.0f),
 | 
			
		||||
    GAME_1("NeonRoadTrip.wav", false, 1.0f),
 | 
			
		||||
    GAME_2("NoPressureTrance.wav", false, 1.0f),
 | 
			
		||||
    GAME_3("TheSynthRave.wav", false, 1.0f),
 | 
			
		||||
    GAME_4("LaserParty.wav", false, 1.0f),
 | 
			
		||||
    GAME_5("RetroNoir.wav", false, 1.0f),
 | 
			
		||||
    GAME_6("SpaceInvaders.wav", false, 1.0f);
 | 
			
		||||
 | 
			
		||||
    private final String path;
 | 
			
		||||
    private final boolean loop;
 | 
			
		||||
    private final float subVolume;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new MusicAsset object with the specified name and sub-volume.
 | 
			
		||||
     * The track will not loop by default.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the music file.
 | 
			
		||||
     * @param subVolume A relative volume that modifies the base volume of the track (typically a percentage).
 | 
			
		||||
     */
 | 
			
		||||
    MusicAsset(String name, float subVolume) {
 | 
			
		||||
        this.path = "music/" + name;
 | 
			
		||||
        this.loop = false;
 | 
			
		||||
        this.subVolume = subVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new MusicAsset object with the specified name, loop flag, and sub-volume.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the music file.
 | 
			
		||||
     * @param loop If true, the track will loop; otherwise, it will play once.
 | 
			
		||||
     * @param subVolume A relative volume that modifies the base volume of the track (typically a percentage).
 | 
			
		||||
     */
 | 
			
		||||
    MusicAsset(String name, boolean loop, float subVolume) {
 | 
			
		||||
        this.path = "music/" + name;
 | 
			
		||||
        this.loop = loop;
 | 
			
		||||
        this.subVolume = subVolume;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file path of the music track.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The path to the music file (relative to the music folder).
 | 
			
		||||
     */
 | 
			
		||||
    public String getPath() {
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether the music track should loop.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the track should loop, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean getLoop() {
 | 
			
		||||
        return loop;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the relative volume (subVolume) for the music track.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The relative volume for the track, typically a value between 0.0 and 1.0.
 | 
			
		||||
     */
 | 
			
		||||
    public float getSubVolume() {
 | 
			
		||||
        return subVolume;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enum representing various sound assets used in the game.
 | 
			
		||||
 * Each constant corresponds to a specific sound effect used throughout the game.
 | 
			
		||||
 * These sounds are associated with various events and actions, such as dice rolls,
 | 
			
		||||
 * turn changes, piece movements, and game outcomes.
 | 
			
		||||
 */
 | 
			
		||||
enum SoundAsset {
 | 
			
		||||
    DICE_ROLL(""),
 | 
			
		||||
    TURN_START(""),
 | 
			
		||||
    TURN_END(""),
 | 
			
		||||
    PIECE_END(""),
 | 
			
		||||
    PIECE_MOVE(""),
 | 
			
		||||
    PIECE_LOST(""),
 | 
			
		||||
    SELECT(""),
 | 
			
		||||
    DESELECT(""),
 | 
			
		||||
    HURRY(""),
 | 
			
		||||
    VICTORY("LevelUp2.wav"),
 | 
			
		||||
    LOST("GameOver.wav");
 | 
			
		||||
 | 
			
		||||
    private final String path;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new SoundAsset object with the specified name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the sound file.
 | 
			
		||||
     */
 | 
			
		||||
    SoundAsset(String name) {
 | 
			
		||||
        this.path = "sound/" + name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file path of the sound effect.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The path to the sound file (relative to the sound folder).
 | 
			
		||||
     */
 | 
			
		||||
    public String getPath() {
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package pp.mdga.client.Acoustic;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A record that encapsulates a sound asset along with its playback settings:
 | 
			
		||||
 * the relative volume (subVolume) and a delay before it starts playing.
 | 
			
		||||
 */
 | 
			
		||||
record SoundAssetDelayVolume(SoundAsset asset, float subVolume, float delay) { }
 | 
			
		||||
@@ -11,7 +11,7 @@ public AnimationHandler(MdgaApp app) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void playAnimation(AnimationType type) {
 | 
			
		||||
    public void playAnimation(MdgaAnimation type) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -23,7 +23,7 @@ public void update() {
 | 
			
		||||
        if(animation.isOver()) {
 | 
			
		||||
            animation = null;
 | 
			
		||||
 | 
			
		||||
            //trigger next state
 | 
			
		||||
            //trigger next state in model
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
package pp.mdga.client.Animation;
 | 
			
		||||
 | 
			
		||||
class EmptyAnimation implements Animation {
 | 
			
		||||
class EmptyAnimation extends Animation {
 | 
			
		||||
    @Override
 | 
			
		||||
    void play() {
 | 
			
		||||
        //nothing
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package pp.mdga.client.Animation;
 | 
			
		||||
 | 
			
		||||
public enum AnimationType {
 | 
			
		||||
public enum MdgaAnimation {
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
record AssetOnMap(BoardAsset boardAsset, int x, int y){}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
package pp.mdga.client;
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
public enum Asset {
 | 
			
		||||
enum BoardAsset {
 | 
			
		||||
    bigTent,
 | 
			
		||||
    cardStack,
 | 
			
		||||
    cir,
 | 
			
		||||
@@ -8,13 +8,13 @@ public enum Asset {
 | 
			
		||||
    jet,
 | 
			
		||||
    lw,
 | 
			
		||||
    marine,
 | 
			
		||||
    node_home_blue("./node_home/node_home.j3o", "./node_home/node_home_blue.png"),
 | 
			
		||||
    node_home_black("./node_home/node_home.j3o", "./node_home/node_home_black.png"),
 | 
			
		||||
    node_home_green("./node_home/node_home.j3o", "./node_home/node_home_green.png"),
 | 
			
		||||
    node_home_yellow("./node_home/node_home.j3o", "./node_home/node_home_yellow.png"),
 | 
			
		||||
    node_home_blue("./node_home/node_home.j3o", "./node_home/node_home_blue_diff.png"),
 | 
			
		||||
    node_home_black("./node_home/node_home.j3o", "./node_home/node_home_black_diff.png"),
 | 
			
		||||
    node_home_green("./node_home/node_home.j3o", "./node_home/node_home_green_diff.png"),
 | 
			
		||||
    node_home_yellow("./node_home/node_home.j3o", "./node_home/node_home_yellow_diff.png"),
 | 
			
		||||
    node_normal,
 | 
			
		||||
    node_start("./node_normal/node_normal.j3o", "./node_normal/node_normal_start.png"),
 | 
			
		||||
    node_bonus("./node_normal/node_normal.j3o", "./node_normal/node_normal_bonus.png"),
 | 
			
		||||
    node_start("./node_normal/node_normal.j3o", "./node_normal/node_start_diff.png"),
 | 
			
		||||
    node_bonus("./node_normal/node_normal.j3o", "./node_normal/node_bonus_diff.png"),
 | 
			
		||||
    radar,
 | 
			
		||||
    shieldCard,
 | 
			
		||||
    ship,
 | 
			
		||||
@@ -22,26 +22,26 @@ public enum Asset {
 | 
			
		||||
    swapCard,
 | 
			
		||||
    tank,
 | 
			
		||||
    turboCard,
 | 
			
		||||
    world(1.1f);
 | 
			
		||||
    world(1.2f);
 | 
			
		||||
 | 
			
		||||
    private final String modelPath;
 | 
			
		||||
    private final String diffPath;
 | 
			
		||||
    private final float size;
 | 
			
		||||
 | 
			
		||||
    Asset(){
 | 
			
		||||
    BoardAsset(){
 | 
			
		||||
        String folderFileName = "./" + name() + "/" + name();
 | 
			
		||||
        this.modelPath = folderFileName + ".j3o";
 | 
			
		||||
        this.diffPath = folderFileName + "_diff.png";
 | 
			
		||||
        this.size = 1f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Asset(String modelPath, String diffPath){
 | 
			
		||||
    BoardAsset(String modelPath, String diffPath){
 | 
			
		||||
        this.modelPath = modelPath;
 | 
			
		||||
        this.diffPath = diffPath;
 | 
			
		||||
        this.size = 1f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Asset(float size){
 | 
			
		||||
    BoardAsset(float size){
 | 
			
		||||
        String folderFileName = "./" + name() + "/" + name();
 | 
			
		||||
        this.modelPath = folderFileName + ".j3o";
 | 
			
		||||
        this.diffPath = folderFileName + "_diff.png";
 | 
			
		||||
@@ -1,30 +1,95 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
import com.jme3.light.AmbientLight;
 | 
			
		||||
import com.jme3.light.DirectionalLight;
 | 
			
		||||
import com.jme3.material.Material;
 | 
			
		||||
import com.jme3.math.ColorRGBA;
 | 
			
		||||
import com.jme3.math.Vector3f;
 | 
			
		||||
import com.jme3.renderer.queue.RenderQueue;
 | 
			
		||||
import com.jme3.scene.Spatial;
 | 
			
		||||
import com.jme3.shadow.DirectionalLightShadowRenderer;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class BoardView {
 | 
			
		||||
    private static final float GRID_SIZE = 10.0f;
 | 
			
		||||
    private static final float GRID_SIZE = 1.72f;
 | 
			
		||||
    private static final float GRID_ELEVATION = 0.0f;
 | 
			
		||||
    private static final int GRID_EXTEND = 5;
 | 
			
		||||
    private static final String MAP_NAME = "circle_map.mdga";
 | 
			
		||||
 | 
			
		||||
    private PileControl drawPile = new PileControl();
 | 
			
		||||
    private PileControl discardPile = new PileControl();
 | 
			
		||||
    private final MdgaApp app;
 | 
			
		||||
 | 
			
		||||
    private PileControl drawPile = null;
 | 
			
		||||
    private PileControl discardPile = null;
 | 
			
		||||
 | 
			
		||||
    private ArrayList<NodeControl> infield = new ArrayList<NodeControl>(40);
 | 
			
		||||
    private ArrayList<PieceControl> pieces;
 | 
			
		||||
 | 
			
		||||
    BoardView(int playerCount) {
 | 
			
		||||
        assert(2 <= playerCount && playerCount <= 4);
 | 
			
		||||
    public BoardView(MdgaApp app) {
 | 
			
		||||
        assert(app != null) : "app is null";
 | 
			
		||||
 | 
			
		||||
        pieces = new ArrayList<PieceControl>(4 * playerCount);
 | 
			
		||||
        this.app = app;
 | 
			
		||||
 | 
			
		||||
        pieces = new ArrayList<PieceControl>(4 * 4);
 | 
			
		||||
 | 
			
		||||
        initMap();
 | 
			
		||||
        initCamera();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCamera() {
 | 
			
		||||
        app.getFlyByCamera().setEnabled(true);
 | 
			
		||||
        int zoom = 20;
 | 
			
		||||
        app.getCamera().setLocation(new Vector3f(zoom,0,zoom));
 | 
			
		||||
        app.getCamera().lookAt(new Vector3f(0,0,0), new Vector3f(0,0,1));
 | 
			
		||||
 | 
			
		||||
        DirectionalLight sun = new DirectionalLight();
 | 
			
		||||
        sun.setColor(ColorRGBA.White);
 | 
			
		||||
        sun.setDirection(new Vector3f(-1,0,-1));
 | 
			
		||||
        app.getRootNode().addLight(sun);
 | 
			
		||||
 | 
			
		||||
        AmbientLight ambient = new AmbientLight();
 | 
			
		||||
        ambient.setColor(new ColorRGBA(0.3f,0.3f,0.3f,1));
 | 
			
		||||
        app.getRootNode().addLight(ambient);
 | 
			
		||||
 | 
			
		||||
        final int SHADOWMAP_SIZE= 1024 * 8;
 | 
			
		||||
        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(app.getAssetManager(), SHADOWMAP_SIZE, 4);
 | 
			
		||||
        dlsr.setLight(sun);
 | 
			
		||||
        app.getViewPort().addProcessor(dlsr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initMap() {
 | 
			
		||||
        List<AssetOnMap> assetsOnMap = MapLoader.loadMap(MAP_NAME);
 | 
			
		||||
 | 
			
		||||
        for (AssetOnMap aom : assetsOnMap){
 | 
			
		||||
            int x = aom.x();
 | 
			
		||||
            int y = aom.y();
 | 
			
		||||
            Vector3f pos = gridToWorld(x,y);
 | 
			
		||||
 | 
			
		||||
            if(aom.boardAsset().name().contains("node")) {
 | 
			
		||||
                infield.add(new NodeControl(app, pos, aom.boardAsset()));
 | 
			
		||||
            } else {
 | 
			
		||||
                Spatial model = createModel(aom.boardAsset());
 | 
			
		||||
                model.setLocalTranslation(pos);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Spatial createModel(BoardAsset boardAsset){
 | 
			
		||||
        String modelName = boardAsset.getModelPath();
 | 
			
		||||
        String texName = boardAsset.getDiffPath();
 | 
			
		||||
        Spatial model = app.getAssetManager().loadModel(modelName);
 | 
			
		||||
        model.scale(boardAsset.getSize());
 | 
			
		||||
        model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(90));
 | 
			
		||||
        model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
 | 
			
		||||
        Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
 | 
			
		||||
        mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(texName));
 | 
			
		||||
        model.setMaterial(mat);
 | 
			
		||||
        app.getRootNode().attachChild(model);
 | 
			
		||||
        return model;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Vector3f gridToWorld(int x, int y) {
 | 
			
		||||
        assert(-GRID_EXTEND <= x && x <= GRID_EXTEND);
 | 
			
		||||
        assert(-GRID_EXTEND <= y && y < GRID_EXTEND);
 | 
			
		||||
 | 
			
		||||
        return new Vector3f(GRID_SIZE * x, GRID_ELEVATION, GRID_SIZE * y);
 | 
			
		||||
        return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
class MapLoader {
 | 
			
		||||
    static public List<AssetOnMap> loadMap(String mapName) {
 | 
			
		||||
        List<AssetOnMap> assetsOnMap = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        try (InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(mapName);
 | 
			
		||||
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
 | 
			
		||||
 | 
			
		||||
            while (true) {
 | 
			
		||||
                String entry = reader.readLine();
 | 
			
		||||
                if(entry == null) break;
 | 
			
		||||
 | 
			
		||||
                entry = entry.trim();
 | 
			
		||||
 | 
			
		||||
                if(entry.isEmpty()) continue;
 | 
			
		||||
                if(entry.charAt(0) == '#') continue;
 | 
			
		||||
 | 
			
		||||
                String[] parts = entry.trim().split(" ");
 | 
			
		||||
                assert(parts.length == 2) : "parts.lenghth != 2";
 | 
			
		||||
 | 
			
		||||
                String assetName = parts[0];
 | 
			
		||||
                String[] coordinates = parts[1].split(",");
 | 
			
		||||
 | 
			
		||||
                assert(coordinates.length == 2) : "coordinates.lenghth != 2";
 | 
			
		||||
 | 
			
		||||
                int x = Integer.parseInt(coordinates[0]);
 | 
			
		||||
                int y = Integer.parseInt(coordinates[1]);
 | 
			
		||||
 | 
			
		||||
                BoardAsset boardAsset = getLoadedAsset(assetName);
 | 
			
		||||
                assetsOnMap.add(new AssetOnMap(boardAsset, x, y));
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return assetsOnMap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static private BoardAsset getLoadedAsset(String assetName) {
 | 
			
		||||
        return switch(assetName){
 | 
			
		||||
            case "node" -> BoardAsset.node_normal;
 | 
			
		||||
            case "node_start" -> BoardAsset.node_start;
 | 
			
		||||
            case "node_bonus" -> BoardAsset.node_bonus;
 | 
			
		||||
            case "node_home_blue" -> BoardAsset.node_home_blue;
 | 
			
		||||
            case "node_home_yellow" -> BoardAsset.node_home_yellow;
 | 
			
		||||
            case "node_home_black" -> BoardAsset.node_home_black;
 | 
			
		||||
            case "node_home_green" -> BoardAsset.node_home_green;
 | 
			
		||||
            case "world" -> BoardAsset.world;
 | 
			
		||||
            case "tent_big" -> BoardAsset.bigTent;
 | 
			
		||||
            case "tent_small" -> BoardAsset.smallTent;
 | 
			
		||||
            case "stack" -> BoardAsset.cardStack;
 | 
			
		||||
            case "jet" -> BoardAsset.jet;
 | 
			
		||||
            case "radar" -> BoardAsset.radar;
 | 
			
		||||
            case "ship" -> BoardAsset.ship;
 | 
			
		||||
            case "tank" -> BoardAsset.tank;
 | 
			
		||||
            default -> throw new IllegalStateException("Unexpected asset in .mdga file: " + assetName);
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,30 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
public class NodeControl {
 | 
			
		||||
import com.jme3.material.Material;
 | 
			
		||||
import com.jme3.math.Vector3f;
 | 
			
		||||
import com.jme3.renderer.queue.RenderQueue;
 | 
			
		||||
import com.jme3.scene.Spatial;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
class NodeControl {
 | 
			
		||||
    private final MdgaApp app;
 | 
			
		||||
 | 
			
		||||
    private Spatial model;
 | 
			
		||||
 | 
			
		||||
    NodeControl(MdgaApp app, Vector3f pos, BoardAsset boardAsset) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
 | 
			
		||||
        String modelName = boardAsset.getModelPath();
 | 
			
		||||
        String texName = boardAsset.getDiffPath();
 | 
			
		||||
        Spatial model = app.getAssetManager().loadModel(modelName);
 | 
			
		||||
        model.scale(boardAsset.getSize());
 | 
			
		||||
        model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(90));
 | 
			
		||||
        model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
 | 
			
		||||
        Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
 | 
			
		||||
        mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(texName));
 | 
			
		||||
        model.setMaterial(mat);
 | 
			
		||||
        app.getRootNode().attachChild(model);
 | 
			
		||||
 | 
			
		||||
        model.setLocalTranslation(pos);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
public class PieceControl {
 | 
			
		||||
class PieceControl {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
package pp.mdga.client.Board;
 | 
			
		||||
 | 
			
		||||
public class PileControl {
 | 
			
		||||
class PileControl {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,26 @@
 | 
			
		||||
package pp.mdga.client.Dialog;
 | 
			
		||||
 | 
			
		||||
public class DialogView {
 | 
			
		||||
import pp.dialog.DialogManager;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
public class DialogView {
 | 
			
		||||
    private MdgaApp app;
 | 
			
		||||
 | 
			
		||||
    private DialogManager dialogManager =  new DialogManager(app);
 | 
			
		||||
 | 
			
		||||
    private StartDialog dialog;
 | 
			
		||||
 | 
			
		||||
    public DialogView(MdgaApp app) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DialogManager getDialogManager() {
 | 
			
		||||
        return dialogManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void mainMenu() {
 | 
			
		||||
        //dialogManager = new DialogManager(app);
 | 
			
		||||
        //di
 | 
			
		||||
        //MainMenuDialog mainMenuDialog = new MainMenuDialog(app);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
package pp.mdga.client.Dialog;
 | 
			
		||||
 | 
			
		||||
public class InterruptDialog {
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,35 @@
 | 
			
		||||
package pp.mdga.client.Dialog;
 | 
			
		||||
 | 
			
		||||
public class StartDialog {
 | 
			
		||||
import com.simsilica.lemur.Checkbox;
 | 
			
		||||
import com.simsilica.lemur.Container;
 | 
			
		||||
import com.simsilica.lemur.Label;
 | 
			
		||||
import com.simsilica.lemur.component.SpringGridLayout;
 | 
			
		||||
import pp.dialog.DialogBuilder;
 | 
			
		||||
import pp.dialog.SimpleDialog;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
 | 
			
		||||
public class StartDialog extends SimpleDialog {
 | 
			
		||||
    StartDialog(MdgaApp app) {
 | 
			
		||||
        super(app.getDialogView().getDialogManager());
 | 
			
		||||
 | 
			
		||||
        Checkbox serverHost = new Checkbox("sdgfsdg");
 | 
			
		||||
        serverHost.setChecked(false);
 | 
			
		||||
        //serverHost.addClickCommands(s -> toggleServerHost());
 | 
			
		||||
 | 
			
		||||
        final Container input = new Container(new SpringGridLayout());
 | 
			
		||||
        input.addChild(new Label("sdgsgsdg"));
 | 
			
		||||
        //input.addChild(host, 1);
 | 
			
		||||
        input.addChild(new Label("sdfdsgsdgsdg"));
 | 
			
		||||
        //input.addChild(port, 1);
 | 
			
		||||
        input.addChild(serverHost);
 | 
			
		||||
 | 
			
		||||
        DialogBuilder.simple(app.getDialogView().getDialogManager())
 | 
			
		||||
            .setTitle("server.dialog")
 | 
			
		||||
            .setOkButton("button.connect")
 | 
			
		||||
            .setNoButton("button.cancel")
 | 
			
		||||
            .setOkClose(false)
 | 
			
		||||
            .setNoClose(false)
 | 
			
		||||
            .build(this);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,31 @@
 | 
			
		||||
package pp.mdga.client;
 | 
			
		||||
 | 
			
		||||
import com.jme3.app.SimpleApplication;
 | 
			
		||||
import com.jme3.renderer.RenderManager;
 | 
			
		||||
import com.jme3.system.NanoTimer;
 | 
			
		||||
import pp.mdga.client.Acoustic.AcousticHandler;
 | 
			
		||||
import pp.mdga.client.Acoustic.MdgaSound;
 | 
			
		||||
import pp.mdga.client.Animation.AnimationHandler;
 | 
			
		||||
import com.jme3.light.AmbientLight;
 | 
			
		||||
import com.jme3.light.DirectionalLight;
 | 
			
		||||
import com.jme3.material.Material;
 | 
			
		||||
import com.jme3.math.ColorRGBA;
 | 
			
		||||
import com.jme3.math.Vector3f;
 | 
			
		||||
import com.jme3.renderer.RenderManager;
 | 
			
		||||
import com.jme3.renderer.queue.RenderQueue;
 | 
			
		||||
import com.jme3.scene.Spatial;
 | 
			
		||||
import com.jme3.shadow.DirectionalLightShadowRenderer;
 | 
			
		||||
import com.jme3.system.AppSettings;
 | 
			
		||||
import pp.mdga.client.Board.BoardView;
 | 
			
		||||
import pp.mdga.client.Dialog.DialogView;
 | 
			
		||||
 | 
			
		||||
public class MdgaApp extends SimpleApplication {
 | 
			
		||||
    private AnimationHandler animationHandler;
 | 
			
		||||
    private AcousticHandler acousticHandler;
 | 
			
		||||
    private BoardView boardView;
 | 
			
		||||
    private DialogView dialogView;
 | 
			
		||||
 | 
			
		||||
    NanoTimer test = new NanoTimer();
 | 
			
		||||
    private MdgaState testState = MdgaState.MAIN;
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        MdgaApp app = new MdgaApp();
 | 
			
		||||
        AppSettings settings = new AppSettings(true);
 | 
			
		||||
        settings.setSamples(128);
 | 
			
		||||
        settings.setCenterWindow(true);
 | 
			
		||||
        settings.setWidth(1300);
 | 
			
		||||
        settings.setHeight(1000);
 | 
			
		||||
        settings.setWidth(1280);
 | 
			
		||||
        settings.setHeight(720);
 | 
			
		||||
 | 
			
		||||
        MdgaApp app = new MdgaApp();
 | 
			
		||||
        app.setSettings(settings);
 | 
			
		||||
        app.setShowSettings(false);
 | 
			
		||||
        app.start();
 | 
			
		||||
@@ -32,60 +34,52 @@ public static void main(String[] args) {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void simpleInitApp() {
 | 
			
		||||
        animationHandler = new AnimationHandler(this);
 | 
			
		||||
        acousticHandler = new AcousticHandler(this);
 | 
			
		||||
        boardView = new BoardView(this);
 | 
			
		||||
        dialogView = new DialogView(this);
 | 
			
		||||
 | 
			
		||||
        flyCam.setEnabled(true);
 | 
			
		||||
        int zoom = 20;
 | 
			
		||||
        cam.setLocation(new Vector3f(zoom,0,zoom));
 | 
			
		||||
        cam.lookAt(new Vector3f(0,0,0), new Vector3f(0,0,1));
 | 
			
		||||
        //dialogView.mainMenu();
 | 
			
		||||
        //acousticHandler.playState(MdgaState.GAME);
 | 
			
		||||
 | 
			
		||||
        DirectionalLight sun = new DirectionalLight();
 | 
			
		||||
        sun.setColor(ColorRGBA.White);
 | 
			
		||||
        sun.setDirection(new Vector3f(-1,0,-1));
 | 
			
		||||
        rootNode.addLight(sun);
 | 
			
		||||
        AmbientLight ambient = new AmbientLight();
 | 
			
		||||
        ambient.setColor(new ColorRGBA(0.3f,0.3f,0.3f,1));
 | 
			
		||||
        rootNode.addLight(ambient);
 | 
			
		||||
 | 
			
		||||
        final int SHADOWMAP_SIZE=1024*8;
 | 
			
		||||
        DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, SHADOWMAP_SIZE, 4);
 | 
			
		||||
        dlsr.setLight(sun);
 | 
			
		||||
        viewPort.addProcessor(dlsr);
 | 
			
		||||
 | 
			
		||||
        createModel(Asset.lw).setLocalTranslation(new Vector3f(0,-10,0));
 | 
			
		||||
        createModel(Asset.cir).setLocalTranslation(new Vector3f(0,-8,0));
 | 
			
		||||
        createModel(Asset.marine).setLocalTranslation(new Vector3f(0,-6,0));
 | 
			
		||||
        createModel(Asset.heer).setLocalTranslation(new Vector3f(0,-4,0));
 | 
			
		||||
        createModel(Asset.node_normal).setLocalTranslation(new Vector3f(0,-2.5f,0));
 | 
			
		||||
        createModel(Asset.node_home_blue).setLocalTranslation(new Vector3f(0,-1,0));
 | 
			
		||||
        createModel(Asset.smallTent).setLocalTranslation(new Vector3f(0,1,0));
 | 
			
		||||
        createModel(Asset.tank).setLocalTranslation(new Vector3f(0,5,0));
 | 
			
		||||
        createModel(Asset.jet).setLocalTranslation(new Vector3f(0,12,0));
 | 
			
		||||
        createModel(Asset.ship).setLocalTranslation(new Vector3f(0,17,0));
 | 
			
		||||
        createModel(Asset.radar).setLocalTranslation(new Vector3f(0,20,0));
 | 
			
		||||
 | 
			
		||||
        createModel(Asset.world);
 | 
			
		||||
 | 
			
		||||
        //System.out.println(Asset.node_normal.getModelPath());
 | 
			
		||||
        //System.out.println(Asset.node_normal.getDiffPath());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private Spatial createModel(Asset asset){
 | 
			
		||||
        String modelName = asset.getModelPath();
 | 
			
		||||
        String texName = asset.getDiffPath();
 | 
			
		||||
        Spatial model = assetManager.loadModel(modelName);
 | 
			
		||||
        model.scale(asset.getSize());
 | 
			
		||||
        model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(90));
 | 
			
		||||
        model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
 | 
			
		||||
        Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
 | 
			
		||||
        mat.setTexture("DiffuseMap", assetManager.loadTexture(texName));
 | 
			
		||||
        model.setMaterial(mat);
 | 
			
		||||
        rootNode.attachChild(model);
 | 
			
		||||
        return model;
 | 
			
		||||
        acousticHandler.playSound(MdgaSound.LOST);
 | 
			
		||||
        acousticHandler.playSound(MdgaSound.VICTORY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void simpleUpdate(float tpf) {
 | 
			
		||||
        //this method will be called every game tick and can be used to make updates
 | 
			
		||||
        acousticHandler.update();
 | 
			
		||||
 | 
			
		||||
        //test.reset();
 | 
			
		||||
        if(test.getTimeInSeconds() > 10){
 | 
			
		||||
            if(testState == MdgaState.MAIN) {
 | 
			
		||||
                testState = MdgaState.LOBBY;
 | 
			
		||||
                acousticHandler.playState(MdgaState.MAIN);
 | 
			
		||||
            } else if (testState == MdgaState.LOBBY) {
 | 
			
		||||
                testState = MdgaState.CEREMONY;
 | 
			
		||||
                acousticHandler.playState(MdgaState.LOBBY);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                testState = MdgaState.MAIN;
 | 
			
		||||
                acousticHandler.playState(MdgaState.CEREMONY);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            test.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AnimationHandler getAnimationHandler() {
 | 
			
		||||
        return animationHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AcousticHandler getAcousticHandler() {
 | 
			
		||||
        return acousticHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BoardView getBoardView() {
 | 
			
		||||
        return boardView;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DialogView getDialogView() {
 | 
			
		||||
        return dialogView;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,48 @@
 | 
			
		||||
package pp.mdga.client;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.notification.Notification;
 | 
			
		||||
import pp.mdga.notification.PieceInGameNotification;
 | 
			
		||||
import pp.mdga.notification.PlayerInGameNotification;
 | 
			
		||||
 | 
			
		||||
public enum MdgaState {
 | 
			
		||||
    NONE {
 | 
			
		||||
        @Override
 | 
			
		||||
        void handleNotification(MdgaApp app, Notification notification) {
 | 
			
		||||
            throw new RuntimeException("unexpected notification");
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    MAIN {
 | 
			
		||||
        @Override
 | 
			
		||||
        void handleNotification(MdgaApp app, Notification notification) {
 | 
			
		||||
            throw new RuntimeException("unexpected notification");
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    LOBBY {
 | 
			
		||||
        @Override
 | 
			
		||||
        void handleNotification(MdgaApp app, Notification notification) {
 | 
			
		||||
            throw new RuntimeException("unexpected notification");
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    GAME {
 | 
			
		||||
        @Override
 | 
			
		||||
        void handleNotification(MdgaApp app, Notification notification) {
 | 
			
		||||
            if(notification instanceof PlayerInGameNotification) {
 | 
			
		||||
                //TODO
 | 
			
		||||
            }
 | 
			
		||||
            else if(notification instanceof PieceInGameNotification){
 | 
			
		||||
                //TODO
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                throw new RuntimeException("unexpected notification");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    CEREMONY {
 | 
			
		||||
        @Override
 | 
			
		||||
        void handleNotification(MdgaApp app, Notification notification) {
 | 
			
		||||
            throw new RuntimeException("unexpected notification");
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    abstract void handleNotification(MdgaApp app, Notification notification);
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,22 @@
 | 
			
		||||
 | 
			
		||||
import pp.mdga.notification.Notification;
 | 
			
		||||
 | 
			
		||||
public class NotificationSynchronizer {
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public class NotificationSynchronizer {
 | 
			
		||||
    private final MdgaApp app;
 | 
			
		||||
    private MdgaState state = MdgaState.MAIN;
 | 
			
		||||
 | 
			
		||||
    NotificationSynchronizer(MdgaApp app) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update() {
 | 
			
		||||
        ArrayList<Notification> notifications = new ArrayList<>();
 | 
			
		||||
        //TODO fetch model notifications
 | 
			
		||||
 | 
			
		||||
        for (Notification n : notifications) {
 | 
			
		||||
            state.handleNotification(app, n);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class CeremonyState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class GameState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class LobbyState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class MdgaState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class MusicState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
package pp.mdga.client.State;
 | 
			
		||||
 | 
			
		||||
public class SoundState {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								Projekte/mdga/client/src/main/resources/circle_map.mdga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Projekte/mdga/client/src/main/resources/circle_map.mdga
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
world 0,0
 | 
			
		||||
 | 
			
		||||
# jet 0,0
 | 
			
		||||
 | 
			
		||||
#Nodes für Map
 | 
			
		||||
node_start 8,0
 | 
			
		||||
node 8,1
 | 
			
		||||
node 8,2
 | 
			
		||||
node 7,3
 | 
			
		||||
node_bonus 6,4
 | 
			
		||||
node 5,5
 | 
			
		||||
node 4,6
 | 
			
		||||
node 3,7
 | 
			
		||||
node 2,8
 | 
			
		||||
node 1,8
 | 
			
		||||
node_start 0,8
 | 
			
		||||
node -1,8
 | 
			
		||||
node -2,8
 | 
			
		||||
node -3,7
 | 
			
		||||
node_bonus -4,6
 | 
			
		||||
node -5,5
 | 
			
		||||
node -6,4
 | 
			
		||||
node -7,3
 | 
			
		||||
node -8,2
 | 
			
		||||
node -8,1
 | 
			
		||||
node_start -8,0
 | 
			
		||||
node -8,-1
 | 
			
		||||
node -8,-2
 | 
			
		||||
node -7,-3
 | 
			
		||||
node_bonus -6,-4
 | 
			
		||||
node -5,-5
 | 
			
		||||
node -4,-6
 | 
			
		||||
node -3,-7
 | 
			
		||||
node -2,-8
 | 
			
		||||
node -1,-8
 | 
			
		||||
node_start 0,-8
 | 
			
		||||
node 1,-8
 | 
			
		||||
node 2,-8
 | 
			
		||||
node 3,-7
 | 
			
		||||
node_bonus 4,-6
 | 
			
		||||
node 5,-5
 | 
			
		||||
node 6,-4
 | 
			
		||||
node 7,-3
 | 
			
		||||
node 8,-2
 | 
			
		||||
node 8,-1
 | 
			
		||||
 | 
			
		||||
#Node Home
 | 
			
		||||
node_home_blue 7,0
 | 
			
		||||
node_home_blue 6,0
 | 
			
		||||
node_home_blue 5,0
 | 
			
		||||
node_home_blue 4,0
 | 
			
		||||
 | 
			
		||||
node_home_black 0,4
 | 
			
		||||
node_home_black 0,5
 | 
			
		||||
node_home_black 0,6
 | 
			
		||||
node_home_black 0,7
 | 
			
		||||
 | 
			
		||||
node_home_yellow 0,-4
 | 
			
		||||
node_home_yellow 0,-5
 | 
			
		||||
node_home_yellow 0,-6
 | 
			
		||||
node_home_yellow 0,-7
 | 
			
		||||
 | 
			
		||||
node_home_green -4,0
 | 
			
		||||
node_home_green -5,0
 | 
			
		||||
node_home_green -6,0
 | 
			
		||||
node_home_green -7,0
 | 
			
		||||
							
								
								
									
										64
									
								
								Projekte/mdga/client/src/main/resources/map.mdga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Projekte/mdga/client/src/main/resources/map.mdga
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
world 0,0
 | 
			
		||||
 | 
			
		||||
#Nodes für Map
 | 
			
		||||
node_start -1,-5
 | 
			
		||||
node -1,-4
 | 
			
		||||
node -1,-3
 | 
			
		||||
node -1,-2
 | 
			
		||||
node_bonus -1,-1
 | 
			
		||||
node -2,-1
 | 
			
		||||
node -3,-1
 | 
			
		||||
node -4,-1
 | 
			
		||||
node -5,-1
 | 
			
		||||
node -5,0
 | 
			
		||||
node_start -5,1
 | 
			
		||||
node -4,1
 | 
			
		||||
node -3,1
 | 
			
		||||
node -2,1
 | 
			
		||||
node_bonus -1,1
 | 
			
		||||
node -1,2
 | 
			
		||||
node -1,3
 | 
			
		||||
node -1,4
 | 
			
		||||
node -1,5
 | 
			
		||||
node 0,5
 | 
			
		||||
node_start 1,5
 | 
			
		||||
node 1,4
 | 
			
		||||
node 1,3
 | 
			
		||||
node 1,2
 | 
			
		||||
node_bonus 1,1
 | 
			
		||||
node 2,1
 | 
			
		||||
node 3,1
 | 
			
		||||
node 4,1
 | 
			
		||||
node 5,1
 | 
			
		||||
node 5,0
 | 
			
		||||
node_start 5,-1
 | 
			
		||||
node 4,-1
 | 
			
		||||
node 3,-1
 | 
			
		||||
node 2,-1
 | 
			
		||||
node_bonus 1,-1
 | 
			
		||||
node 1,-2
 | 
			
		||||
node 1,-3
 | 
			
		||||
node 1,-4
 | 
			
		||||
node 1,-5
 | 
			
		||||
node 0,-5
 | 
			
		||||
 | 
			
		||||
#Node Home
 | 
			
		||||
node_home_blue 0,-1
 | 
			
		||||
node_home_blue 0,-2
 | 
			
		||||
node_home_blue 0,-3
 | 
			
		||||
node_home_blue 0,-4
 | 
			
		||||
 | 
			
		||||
node_home_black 0,1
 | 
			
		||||
node_home_black 0,2
 | 
			
		||||
node_home_black 0,3
 | 
			
		||||
node_home_black 0,4
 | 
			
		||||
 | 
			
		||||
node_home_yellow 1,0
 | 
			
		||||
node_home_yellow 2,0
 | 
			
		||||
node_home_yellow 3,0
 | 
			
		||||
node_home_yellow 4,0
 | 
			
		||||
 | 
			
		||||
node_home_green -1,0
 | 
			
		||||
node_home_green -2,0
 | 
			
		||||
node_home_green -3,0
 | 
			
		||||
node_home_green -4,0
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/80s,Disco,Life.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/80s,Disco,Life.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										22
									
								
								Projekte/mdga/client/src/main/resources/music/CREDIT.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Projekte/mdga/client/src/main/resources/music/CREDIT.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
# Credit
 | 
			
		||||
 | 
			
		||||
## Free SynthWave Music Pack
 | 
			
		||||
 | 
			
		||||
See "Free SynthWave Music Pack License.pdf" for LICENCE information.
 | 
			
		||||
 | 
			
		||||
 - 80s,Dico,Live.wav
 | 
			
		||||
 - LaserParty.wav
 | 
			
		||||
 - NeonRoadTrip.wav
 | 
			
		||||
 - NoPressureTrance.wav
 | 
			
		||||
 - RetroNoir.wav
 | 
			
		||||
 - SpaceInvaders.wav
 | 
			
		||||
 - TheSynthRave.SynthWave
 | 
			
		||||
 | 
			
		||||
## Short Loopable Background Music
 | 
			
		||||
 | 
			
		||||
 https://joshuuu.itch.io/short-loopable-background-music
 | 
			
		||||
 | 
			
		||||
 Free for personal or commercial use as long as you don't redistribute as your own. Donations also welcome! Please add jhaeka to your credits. :)
 | 
			
		||||
 | 
			
		||||
 - DeadPlanet.wav
 | 
			
		||||
 - Spaceship.wav
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/DeadPlanet.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/DeadPlanet.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/LaserParty.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/LaserParty.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/NeonRoadTrip.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/NeonRoadTrip.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/RetroNoir.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/RetroNoir.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/SpaceInvaders.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/SpaceInvaders.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/Spaceship.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/Spaceship.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 454 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/TheSynthRave.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/music/TheSynthRave.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/sound/GameOver.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/sound/GameOver.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/sound/LevelUp2.wav
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projekte/mdga/client/src/main/resources/sound/LevelUp2.wav
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -6,7 +6,7 @@
 | 
			
		||||
 * This class will be used to hold all Board relevant data.
 | 
			
		||||
 */
 | 
			
		||||
public class Board {
 | 
			
		||||
    private Map<Color, Player> playerData;
 | 
			
		||||
    private Map<Color, PlayerData> playerData;
 | 
			
		||||
    private Node[] infield;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -16,7 +16,12 @@ public Board() {
 | 
			
		||||
        infield = new Node[40];
 | 
			
		||||
        for (int i = 0; i < 40; i++) {
 | 
			
		||||
            if (i % 10 == 0) {
 | 
			
		||||
                infield[i] = new StartNode();
 | 
			
		||||
                infield[i] = new StartNode(
 | 
			
		||||
                    i == 0 ? Color.ARMY :
 | 
			
		||||
                        i == 10 ? Color.AIRFORCE :
 | 
			
		||||
                            i == 20 ? Color.CYBER :
 | 
			
		||||
                                Color.NAVY
 | 
			
		||||
                );
 | 
			
		||||
            } else if (i == 4 || i == 14 || i == 24 || i == 34) {
 | 
			
		||||
                infield[i] = new BonusNode();
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -30,7 +35,7 @@ public Board() {
 | 
			
		||||
     *
 | 
			
		||||
     * @return the playerData
 | 
			
		||||
     */
 | 
			
		||||
    public Map<Color, Player> getPlayerData() {
 | 
			
		||||
    public Map<Color, PlayerData> getPlayerData() {
 | 
			
		||||
        return playerData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
package pp.mdga.game;
 | 
			
		||||
/**
 | 
			
		||||
 * This class is used to create a card
 | 
			
		||||
 */
 | 
			
		||||
public class Card {
 | 
			
		||||
    private BonusCard type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This constructor is used to create a new card
 | 
			
		||||
     *
 | 
			
		||||
     * @param type the type of the card
 | 
			
		||||
     */
 | 
			
		||||
    public Card(BonusCard type) {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the type of the card
 | 
			
		||||
     *
 | 
			
		||||
     * @return the type of the card
 | 
			
		||||
     */
 | 
			
		||||
    public BonusCard getType() {
 | 
			
		||||
        return type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to set the type of the card
 | 
			
		||||
     *
 | 
			
		||||
     * @param type the new type of the card
 | 
			
		||||
     */
 | 
			
		||||
    public void setType(BonusCard type) {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -5,15 +5,17 @@
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class will be used to handle the data stored in the model
 | 
			
		||||
 * The Game class represents the game state of the Ludo game.
 | 
			
		||||
 * It contains all the information needed to play the game.
 | 
			
		||||
 * The game state is updated by the game logic.
 | 
			
		||||
 */
 | 
			
		||||
public class Game {
 | 
			
		||||
    private int diceModifier = 1;
 | 
			
		||||
    private int diceEyes;
 | 
			
		||||
    private Map <Color, Player> players;
 | 
			
		||||
    private Statistic gameStatistics;
 | 
			
		||||
    private ArrayList<Card> drawPile;
 | 
			
		||||
    private ArrayList<Card> discardPile = new ArrayList<>();
 | 
			
		||||
    private ArrayList<BonusCard> drawPile;
 | 
			
		||||
    private ArrayList<BonusCard> discardPile = new ArrayList<>();
 | 
			
		||||
    private Board board;
 | 
			
		||||
    private Color activeColor;
 | 
			
		||||
    private LinkedList<Color> order;
 | 
			
		||||
@@ -22,16 +24,238 @@ public class Game {
 | 
			
		||||
    private static final int AMOUNT_OF_TURBO_CARDS = 16;
 | 
			
		||||
    private static final int AMOUNT_OF_SHIELD_AND_SWAP_CARDS = 12;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This constructor creates a new Game object.
 | 
			
		||||
     */
 | 
			
		||||
    public Game(){
 | 
			
		||||
        gameStatistics = new Statistic();
 | 
			
		||||
        drawPile = new ArrayList<>();
 | 
			
		||||
        for (int i = 0; i < AMOUNT_OF_TURBO_CARDS; i++) {
 | 
			
		||||
            drawPile.add(new Card(BonusCard.TURBO));
 | 
			
		||||
            drawPile.add(BonusCard.TURBO);
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < AMOUNT_OF_SHIELD_AND_SWAP_CARDS; i++) {
 | 
			
		||||
            drawPile.add(new Card(BonusCard.SHIELD));
 | 
			
		||||
            drawPile.add(new Card(BonusCard.SWAP));
 | 
			
		||||
            drawPile.add(BonusCard.SWAP);
 | 
			
		||||
            drawPile.add(BonusCard.SHIELD);
 | 
			
		||||
        }
 | 
			
		||||
        board = new Board();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the dice modifier.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the dice modifier
 | 
			
		||||
     */
 | 
			
		||||
    public int getDiceModifier() {
 | 
			
		||||
        return diceModifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the dice modifier.
 | 
			
		||||
     *
 | 
			
		||||
     * @param diceModifier the new dice modifier
 | 
			
		||||
     */
 | 
			
		||||
    public void setDiceModifier(int diceModifier) {
 | 
			
		||||
        this.diceModifier = diceModifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the dice eyes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the dice eyes
 | 
			
		||||
     */
 | 
			
		||||
    public int getDiceEyes() {
 | 
			
		||||
        return diceEyes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the dice eyes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param diceEyes the new dice eyes
 | 
			
		||||
     */
 | 
			
		||||
    public void setDiceEyes(int diceEyes) {
 | 
			
		||||
        this.diceEyes = diceEyes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the players.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the players
 | 
			
		||||
     */
 | 
			
		||||
    public Map<Color, Player> getPlayers() {
 | 
			
		||||
        return players;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the players.
 | 
			
		||||
     *
 | 
			
		||||
     * @param players the new players
 | 
			
		||||
     */
 | 
			
		||||
    public void setPlayers(Map<Color, Player> players) {
 | 
			
		||||
        this.players = players;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the game statistics.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the game statistics
 | 
			
		||||
     */
 | 
			
		||||
    public Statistic getGameStatistics() {
 | 
			
		||||
        return gameStatistics;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the game statistics.
 | 
			
		||||
     *
 | 
			
		||||
     * @param gameStatistics the new game statistics
 | 
			
		||||
     */
 | 
			
		||||
    public void setGameStatistics(Statistic gameStatistics) {
 | 
			
		||||
        this.gameStatistics = gameStatistics;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the draw pile.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the draw pile
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayList<BonusCard> getDrawPile() {
 | 
			
		||||
        return drawPile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the draw pile.
 | 
			
		||||
     *
 | 
			
		||||
     * @param drawPile the new draw pile
 | 
			
		||||
     */
 | 
			
		||||
    public void setDrawPile(ArrayList<BonusCard> drawPile) {
 | 
			
		||||
        this.drawPile = drawPile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the discard pile.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the discard pile
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayList<BonusCard> getDiscardPile() {
 | 
			
		||||
        return discardPile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the discard pile.
 | 
			
		||||
     *
 | 
			
		||||
     * @param discardPile the new discard pile
 | 
			
		||||
     */
 | 
			
		||||
    public void setDiscardPile(ArrayList<BonusCard> discardPile) {
 | 
			
		||||
        this.discardPile = discardPile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the board.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the board
 | 
			
		||||
     */
 | 
			
		||||
    public Board getBoard() {
 | 
			
		||||
        return board;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the board.
 | 
			
		||||
     *
 | 
			
		||||
     * @param board the new board
 | 
			
		||||
     */
 | 
			
		||||
    public void setBoard(Board board) {
 | 
			
		||||
        this.board = board;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the active color.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the active color
 | 
			
		||||
     */
 | 
			
		||||
    public Color getActiveColor() {
 | 
			
		||||
        return activeColor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the active color.
 | 
			
		||||
     *
 | 
			
		||||
     * @param activeColor the new active color
 | 
			
		||||
     */
 | 
			
		||||
    public void setActiveColor(Color activeColor) {
 | 
			
		||||
        this.activeColor = activeColor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the order of the players.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the order of the players
 | 
			
		||||
     */
 | 
			
		||||
    public LinkedList<Color> getOrder() {
 | 
			
		||||
        return order;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the order of the players.
 | 
			
		||||
     *
 | 
			
		||||
     * @param order the new order of the players
 | 
			
		||||
     */
 | 
			
		||||
    public void setOrder(LinkedList<Color> order) {
 | 
			
		||||
        this.order = order;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the player connection ID.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the player connection ID
 | 
			
		||||
     */
 | 
			
		||||
    public Map<Color, Integer> getPlayerConnectionID() {
 | 
			
		||||
        return playerConnectionID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the player connection ID.
 | 
			
		||||
     *
 | 
			
		||||
     * @param playerConnectionID the new player connection ID
 | 
			
		||||
     */
 | 
			
		||||
    public void setPlayerConnectionID(Map<Color, Integer> playerConnectionID) {
 | 
			
		||||
        this.playerConnectionID = playerConnectionID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method sets the player connection ID.
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the color of the player
 | 
			
		||||
     * @param connectionID the new connection ID
 | 
			
		||||
     */
 | 
			
		||||
    public void setPlayerConnectionID(Color color, int connectionID) {
 | 
			
		||||
        playerConnectionID.put(color, connectionID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method returns the player connection ID.
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the color of the player
 | 
			
		||||
     * @return the player connection ID
 | 
			
		||||
     */
 | 
			
		||||
    public int getPlayerConnectionID(Color color) {
 | 
			
		||||
        return playerConnectionID.get(color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method adds a player to the game.
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the color of the player
 | 
			
		||||
     * @param player the player to be added
 | 
			
		||||
     */
 | 
			
		||||
    public void addPlayer(Color color, Player player) {
 | 
			
		||||
        players.put(color, player);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method removes a player from the game.
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the color of the player
 | 
			
		||||
     */
 | 
			
		||||
    public void removePlayer(Color color) {
 | 
			
		||||
        players.remove(color);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,75 @@
 | 
			
		||||
package pp.mdga.game;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class will be used to hold all Piece relevant data.
 | 
			
		||||
 */
 | 
			
		||||
public class Piece {
 | 
			
		||||
    private ShieldState shield;
 | 
			
		||||
    private PieceState state;
 | 
			
		||||
    private Color color;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This constructor is used to create a new Piece
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the color of the piece
 | 
			
		||||
     * @param state the state of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public Piece(Color color, PieceState state) {
 | 
			
		||||
        this.color = color;
 | 
			
		||||
        this.state = state;
 | 
			
		||||
        shield = ShieldState.NONE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public void setShield(ShieldState shield) {
 | 
			
		||||
        this.shield = shield;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public ShieldState getShield() {
 | 
			
		||||
        return shield;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @param state the state of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public void setState(PieceState state) {
 | 
			
		||||
        this.state = state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public PieceState getState() {
 | 
			
		||||
        return state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isShielded() {
 | 
			
		||||
        return shield == ShieldState.ACTIVE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the piece
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the piece
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isSuppressed() {
 | 
			
		||||
        return shield == ShieldState.SUPPRESSED;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ public class Player {
 | 
			
		||||
 | 
			
		||||
    private String name;
 | 
			
		||||
    private Statistic playerStatistic;
 | 
			
		||||
    private ArrayList<Card> handCards;
 | 
			
		||||
    private ArrayList<BonusCard> handCards;
 | 
			
		||||
    private final int id;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -53,17 +53,17 @@ public Statistic getPlayerStatistic() {
 | 
			
		||||
     *
 | 
			
		||||
     * @return the handCards of the player
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayList<Card> getHandCards() {
 | 
			
		||||
    public ArrayList<BonusCard> getHandCards() {
 | 
			
		||||
        return handCards;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method adds a new handCard to the player
 | 
			
		||||
     *
 | 
			
		||||
     * @param cards the card to be added to the players hand
 | 
			
		||||
     * @param card the card to be added to the players hand
 | 
			
		||||
     */
 | 
			
		||||
    public void addHandCards(Card cards){
 | 
			
		||||
        handCards.add(cards);
 | 
			
		||||
    public void addHandCards(BonusCard card){
 | 
			
		||||
        handCards.add(card);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -72,8 +72,8 @@ public void addHandCards(Card cards){
 | 
			
		||||
     * @param card the cards type to be removed
 | 
			
		||||
     * @return the removed card or null if there is none of that card type
 | 
			
		||||
     */
 | 
			
		||||
    public Card removeHandCard(Card card) {
 | 
			
		||||
        Card cardToRemove = handCards.stream().filter(card1 -> card1.getType().equals(card.getType())).findFirst().orElse(null);
 | 
			
		||||
    public BonusCard removeHandCard(BonusCard card) {
 | 
			
		||||
        BonusCard cardToRemove = handCards.stream().filter(c -> c.equals(card)).findFirst().orElse(null);
 | 
			
		||||
        if (cardToRemove != null) {
 | 
			
		||||
            handCards.remove(cardToRemove);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,11 @@
 | 
			
		||||
 | 
			
		||||
public class StartNode extends Node {
 | 
			
		||||
 | 
			
		||||
    public StartNode() {}
 | 
			
		||||
    public StartNode(Color color) {
 | 
			
		||||
        this.color = color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Color color;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to set a new Occupant
 | 
			
		||||
@@ -16,4 +20,22 @@ public void setOccupant(Piece occupant) {
 | 
			
		||||
        }
 | 
			
		||||
        this.occupant = occupant;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to get the color of the node
 | 
			
		||||
     *
 | 
			
		||||
     * @return the color of the node
 | 
			
		||||
     */
 | 
			
		||||
    public Color getColor() {
 | 
			
		||||
        return color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is used to set the color of the node
 | 
			
		||||
     *
 | 
			
		||||
     * @param color the new color of the node
 | 
			
		||||
     */
 | 
			
		||||
    public void setColor(Color color) {
 | 
			
		||||
        this.color = color;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,10 @@
 | 
			
		||||
import com.jme3.network.AbstractMessage;
 | 
			
		||||
 | 
			
		||||
public abstract class ClientMessage extends AbstractMessage {
 | 
			
		||||
 | 
			
		||||
    protected ClientMessage() {
 | 
			
		||||
        super(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract void accept(ClientInterpreter interpreter, int from);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class ActivePlayerNotification {
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class ActivePlayerNotification extends Notification {
 | 
			
		||||
    ActivePlayerNotification(Color color) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class DrawCardNotification {
 | 
			
		||||
import pp.mdga.game.BonusCard;
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class DrawCardNotification extends Notification  {
 | 
			
		||||
    DrawCardNotification(Color color, BonusCard card) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class InterruptNotification {
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class InterruptNotification extends Notification {
 | 
			
		||||
    InterruptNotification(Color color) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class MovePieceNotification {
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class MovePieceNotification extends Notification {
 | 
			
		||||
    MovePieceNotification(Color color, int nodeIndex) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public interface Notification {
 | 
			
		||||
public abstract class Notification {
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class PieceInGameNotification extends Notification{
 | 
			
		||||
    PieceInGameNotification(Color color, UUID id) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class PlayCardNotification {
 | 
			
		||||
import pp.mdga.game.BonusCard;
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class PlayCardNotification extends Notification {
 | 
			
		||||
    PlayCardNotification(Color color, BonusCard card) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class PlayerInGameNotification extends Notification {
 | 
			
		||||
    PlayerInGameNotification(Color color, String name) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class ResumeNotification {
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class ResumeNotification extends Notification {
 | 
			
		||||
    ResumeNotification(Color color) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class RollDiceNotification {
 | 
			
		||||
import pp.mdga.game.Color;
 | 
			
		||||
 | 
			
		||||
public class RollDiceNotification extends Notification{
 | 
			
		||||
    RollDiceNotification(Color color, int eyes, int moveNumber) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,9 @@
 | 
			
		||||
package pp.mdga.notification;
 | 
			
		||||
 | 
			
		||||
public class SwapPieceNotification {
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class SwapPieceNotification extends Notification {
 | 
			
		||||
    SwapPieceNotification(UUID a, UUID b) {
 | 
			
		||||
        assert(!a.equals(b));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,3 @@
 | 
			
		||||
}
 | 
			
		||||
include 'mdga:client'
 | 
			
		||||
findProject(':mdga:client')?.name = 'client'
 | 
			
		||||
include 'mdga:client'
 | 
			
		||||
findProject(':mdga:client')?.name = 'client'
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user