Merge branch 'development' into 'dev/test'
Testmerge See merge request progproj/gruppen-ht24/Gruppe-01!5
17
Projekte/.run/MdgaApp.run.xml
Normal file
@@ -0,0 +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 -ea" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="pp.mdga.client.Board.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
BIN
Projekte/mdga/client/Screenshot 2024-11-12 184708.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
22
Projekte/mdga/client/build.gradle
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
id 'buildlogic.jme-application-conventions'
|
||||||
|
}
|
||||||
|
|
||||||
|
description = 'mdga client'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(":jme-common")
|
||||||
|
implementation project(":mdga:model")
|
||||||
|
|
||||||
|
implementation libs.jme3.desktop
|
||||||
|
|
||||||
|
runtimeOnly libs.jme3.awt.dialogs
|
||||||
|
runtimeOnly libs.jme3.plugins
|
||||||
|
runtimeOnly libs.jme3.jogg
|
||||||
|
runtimeOnly libs.jme3.testdata
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = 'pp.mdga.client.MdgaApp'
|
||||||
|
applicationName = 'MDGA'
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
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 static final float FADE_DURATION = 3.0f;
|
||||||
|
private static 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.
|
||||||
|
* <p>
|
||||||
|
* 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) {}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package pp.mdga.client.Animation;
|
||||||
|
|
||||||
|
abstract class Animation {
|
||||||
|
|
||||||
|
abstract void play();
|
||||||
|
|
||||||
|
abstract void stop();
|
||||||
|
|
||||||
|
abstract boolean isOver();
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package pp.mdga.client.Animation;
|
||||||
|
|
||||||
|
import pp.mdga.client.MdgaApp;
|
||||||
|
|
||||||
|
public class AnimationHandler {
|
||||||
|
private MdgaApp app;
|
||||||
|
|
||||||
|
private Animation animation = null;
|
||||||
|
|
||||||
|
public AnimationHandler(MdgaApp app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playAnimation(MdgaAnimation type) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
if (null == animation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animation.isOver()) {
|
||||||
|
animation = null;
|
||||||
|
|
||||||
|
//trigger next state in model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package pp.mdga.client.Animation;
|
||||||
|
|
||||||
|
class EmptyAnimation extends Animation {
|
||||||
|
@Override
|
||||||
|
void play() {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void stop() {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isOver() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package pp.mdga.client.Animation;
|
||||||
|
|
||||||
|
public enum MdgaAnimation {
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
record AssetOnMap(BoardAsset asset, int x, int y, float rot) {}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
enum BoardAsset {
|
||||||
|
bigTent,
|
||||||
|
cardStack,
|
||||||
|
cir,
|
||||||
|
heer,
|
||||||
|
jet,
|
||||||
|
lw,
|
||||||
|
marine,
|
||||||
|
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_start_diff.png"),
|
||||||
|
node_bonus("./node_normal/node_normal.j3o", "./node_normal/node_bonus_diff.png"),
|
||||||
|
radar,
|
||||||
|
shieldCard,
|
||||||
|
ship,
|
||||||
|
smallTent,
|
||||||
|
swapCard,
|
||||||
|
tank,
|
||||||
|
turboCard,
|
||||||
|
world(1.2f);
|
||||||
|
|
||||||
|
private final String modelPath;
|
||||||
|
private final String diffPath;
|
||||||
|
private final float size;
|
||||||
|
|
||||||
|
BoardAsset() {
|
||||||
|
String folderFileName = "./" + name() + "/" + name();
|
||||||
|
this.modelPath = folderFileName + ".j3o";
|
||||||
|
this.diffPath = folderFileName + "_diff.png";
|
||||||
|
this.size = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardAsset(String modelPath, String diffPath) {
|
||||||
|
this.modelPath = modelPath;
|
||||||
|
this.diffPath = diffPath;
|
||||||
|
this.size = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardAsset(float size) {
|
||||||
|
String folderFileName = "./" + name() + "/" + name();
|
||||||
|
this.modelPath = folderFileName + ".j3o";
|
||||||
|
this.diffPath = folderFileName + "_diff.png";
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelPath() {
|
||||||
|
return modelPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiffPath() {
|
||||||
|
return diffPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
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.scene.control.AbstractControl;
|
||||||
|
import com.jme3.shadow.DirectionalLightShadowRenderer;
|
||||||
|
import pp.mdga.client.MdgaApp;
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class BoardView {
|
||||||
|
private static final float GRID_SIZE = 1.72f;
|
||||||
|
private static final float GRID_ELEVATION = 0.0f;
|
||||||
|
private static final String MAP_NAME = "map.mdga";
|
||||||
|
|
||||||
|
private final MdgaApp app;
|
||||||
|
|
||||||
|
private PileControl drawPile = null;
|
||||||
|
private PileControl discardPile = null;
|
||||||
|
|
||||||
|
private ArrayList<NodeControl> infield = new ArrayList<>(40);
|
||||||
|
private Map<UUID, PieceControl> pieces;
|
||||||
|
|
||||||
|
private Map<Color, List<AssetOnMap>> playerMap;
|
||||||
|
|
||||||
|
public BoardView(MdgaApp app) {
|
||||||
|
assert (app != null) : "app is null";
|
||||||
|
|
||||||
|
this.app = app;
|
||||||
|
|
||||||
|
this.pieces = new HashMap<>();
|
||||||
|
this.playerMap = new HashMap<>();
|
||||||
|
|
||||||
|
initMap();
|
||||||
|
initCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFigureToPlayerMap(Color col, AssetOnMap assetOnMap) {
|
||||||
|
List<AssetOnMap> inMap = playerMap.getOrDefault(col, new ArrayList<>());
|
||||||
|
inMap.add(assetOnMap);
|
||||||
|
|
||||||
|
assert (inMap.size() <= 4) : "to many assets for one player";
|
||||||
|
|
||||||
|
playerMap.put(col, inMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMap() {
|
||||||
|
List<AssetOnMap> assetOnMaps = MapLoader.loadMap(MAP_NAME);
|
||||||
|
|
||||||
|
for (AssetOnMap assetOnMap : assetOnMaps) {
|
||||||
|
switch (assetOnMap.asset()) {
|
||||||
|
case lw -> addFigureToPlayerMap(assetToColor(BoardAsset.lw), assetOnMap);
|
||||||
|
case heer -> addFigureToPlayerMap(assetToColor(BoardAsset.heer), assetOnMap);
|
||||||
|
case cir -> addFigureToPlayerMap(assetToColor(BoardAsset.cir), assetOnMap);
|
||||||
|
case marine -> addFigureToPlayerMap(assetToColor(BoardAsset.marine), assetOnMap);
|
||||||
|
case node_normal, node_bonus, node_start ->
|
||||||
|
infield.addLast(displayAndControl(assetOnMap, new NodeControl()));
|
||||||
|
default -> displayAsset(assetOnMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(0.3f, 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);
|
||||||
|
|
||||||
|
int SHADOWMAP_SIZE = 1024 * 8;
|
||||||
|
DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(app.getAssetManager(), SHADOWMAP_SIZE, 4);
|
||||||
|
dlsr.setLight(sun);
|
||||||
|
app.getViewPort().addProcessor(dlsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color assetToColor(BoardAsset asset) {
|
||||||
|
return switch (asset) {
|
||||||
|
case lw -> Color.AIRFORCE;
|
||||||
|
case heer -> Color.ARMY;
|
||||||
|
case marine -> Color.NAVY;
|
||||||
|
case cir -> Color.CYBER;
|
||||||
|
default -> throw new RuntimeException("invalid asset");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Spatial createModel(BoardAsset asset, Vector3f pos, float rot) {
|
||||||
|
String modelName = asset.getModelPath();
|
||||||
|
String texName = asset.getDiffPath();
|
||||||
|
Spatial model = app.getAssetManager().loadModel(modelName);
|
||||||
|
model.scale(asset.getSize());
|
||||||
|
model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(90 + rot));
|
||||||
|
model.setLocalTranslation(pos);
|
||||||
|
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) {
|
||||||
|
return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(Color color, UUID uuid) {
|
||||||
|
List<AssetOnMap> playerAssets = playerMap.get(color);
|
||||||
|
assert (playerAssets != null) : "Assets for Player color are not defined";
|
||||||
|
|
||||||
|
for (AssetOnMap assetOnMap : playerAssets) {
|
||||||
|
pieces.put(uuid, displayAndControl(assetOnMap, new PieceControl()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//displays an assets and return the created asset
|
||||||
|
private Spatial displayAsset(AssetOnMap assetOnMap) {
|
||||||
|
int x = assetOnMap.x();
|
||||||
|
int y = assetOnMap.y();
|
||||||
|
return createModel(assetOnMap.asset(), gridToWorld(x, y), assetOnMap.rot());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends AbstractControl> T displayAndControl(AssetOnMap assetOnMap, T control) {
|
||||||
|
Spatial spatial = displayAsset(assetOnMap);
|
||||||
|
spatial.addControl(control);
|
||||||
|
return control;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class MapLoader {
|
||||||
|
private MapLoader() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AssetOnMap> loadMap(String mapName) {
|
||||||
|
List<AssetOnMap> assetsOnMap = new ArrayList<>();
|
||||||
|
|
||||||
|
try (
|
||||||
|
InputStream inputStream = MapLoader.class.getClassLoader().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 == 3) : "MapLoader: line has not 3 parts";
|
||||||
|
|
||||||
|
String assetName = parts[0];
|
||||||
|
String[] coordinates = parts[1].split(",");
|
||||||
|
|
||||||
|
assert (coordinates.length == 2) : "MapLoade: coordinates are wrong";
|
||||||
|
|
||||||
|
int x = Integer.parseInt(coordinates[0]);
|
||||||
|
int y = Integer.parseInt(coordinates[1]);
|
||||||
|
|
||||||
|
float rot = Float.parseFloat(parts[2]);
|
||||||
|
|
||||||
|
BoardAsset asset = getLoadedAsset(assetName);
|
||||||
|
assetsOnMap.add(new AssetOnMap(asset, x, y, rot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetsOnMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BoardAsset getLoadedAsset(String assetName) {
|
||||||
|
return switch (assetName) {
|
||||||
|
case "lw" -> BoardAsset.lw;
|
||||||
|
case "cir" -> BoardAsset.cir;
|
||||||
|
case "marine" -> BoardAsset.marine;
|
||||||
|
case "heer" -> BoardAsset.heer;
|
||||||
|
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 "jet" -> BoardAsset.jet;
|
||||||
|
case "big_tent" -> BoardAsset.bigTent;
|
||||||
|
case "small_tent" -> BoardAsset.smallTent;
|
||||||
|
case "radar" -> BoardAsset.radar;
|
||||||
|
case "ship" -> BoardAsset.ship;
|
||||||
|
case "tank" -> BoardAsset.tank;
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + assetName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
|
||||||
|
public class NodeControl extends AbstractControl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float v) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
|
||||||
|
public class PieceControl extends AbstractControl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float v) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager renderManager, ViewPort viewPort) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Board;
|
||||||
|
|
||||||
|
class PileControl {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
public class Dialog {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
public class MenuDialog {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
public class NetworkDialog {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
public class SoundDialog {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Dialog;
|
||||||
|
|
||||||
|
public class VideoDialog {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package pp.mdga.client.Gui;
|
||||||
|
|
||||||
|
public class GuiView {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package pp.mdga.client;
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
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.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) {
|
||||||
|
AppSettings settings = new AppSettings(true);
|
||||||
|
settings.setSamples(128);
|
||||||
|
settings.setCenterWindow(true);
|
||||||
|
settings.setWidth(1280);
|
||||||
|
settings.setHeight(720);
|
||||||
|
|
||||||
|
MdgaApp app = new MdgaApp();
|
||||||
|
app.setSettings(settings);
|
||||||
|
app.setShowSettings(false);
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp() {
|
||||||
|
animationHandler = new AnimationHandler(this);
|
||||||
|
acousticHandler = new AcousticHandler(this);
|
||||||
|
boardView = new BoardView(this);
|
||||||
|
dialogView = new DialogView(this);
|
||||||
|
|
||||||
|
//dialogView.mainMenu();
|
||||||
|
//acousticHandler.playState(MdgaState.GAME);
|
||||||
|
|
||||||
|
acousticHandler.playSound(MdgaSound.LOST);
|
||||||
|
acousticHandler.playSound(MdgaSound.VICTORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleUpdate(float tpf) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package pp.mdga.client;
|
||||||
|
|
||||||
|
import pp.mdga.notification.Notification;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Projekte/mdga/client/src/main/resources/bigTent/bigTent.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/bigTent/bigTent_diff.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
Projekte/mdga/client/src/main/resources/cardStack/cardStack.j3o
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
Projekte/mdga/client/src/main/resources/cir/cir.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/cir/cir_diff.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
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
|
||||||
BIN
Projekte/mdga/client/src/main/resources/heer/heer.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/heer/heer_diff.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
Projekte/mdga/client/src/main/resources/jet/jet.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/jet/jet_diff.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
Projekte/mdga/client/src/main/resources/lw/lw.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/lw/lw_diff.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
126
Projekte/mdga/client/src/main/resources/map.mdga
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
world 0,0 0
|
||||||
|
|
||||||
|
#Marine Pos
|
||||||
|
marine 4,-5 180
|
||||||
|
marine 4,-4 180
|
||||||
|
marine 5,-4 180
|
||||||
|
marine 5,-5 180
|
||||||
|
|
||||||
|
#Blue (Marine) Home Node
|
||||||
|
node_home_blue 4,-5 0
|
||||||
|
node_home_blue 4,-4 0
|
||||||
|
node_home_blue 5,-4 0
|
||||||
|
node_home_blue 5,-5 0
|
||||||
|
|
||||||
|
#Lw Pos
|
||||||
|
lw -5,4 0
|
||||||
|
lw -4,4 0
|
||||||
|
lw -4,5 0
|
||||||
|
lw -5,5 0
|
||||||
|
|
||||||
|
#Black (Lw) Home Node
|
||||||
|
node_home_black -5,4 0
|
||||||
|
node_home_black -4,4 0
|
||||||
|
node_home_black -4,5 0
|
||||||
|
node_home_black -5,5 0
|
||||||
|
|
||||||
|
#Heer Pos
|
||||||
|
heer -4,-5 90
|
||||||
|
heer -4,-4 90
|
||||||
|
heer -5,-4 90
|
||||||
|
heer -5,-5 90
|
||||||
|
|
||||||
|
#Green (Heer) Home Node
|
||||||
|
node_home_green -4,-5 0
|
||||||
|
node_home_green -4,-4 0
|
||||||
|
node_home_green -5,-4 0
|
||||||
|
node_home_green -5,-5 0
|
||||||
|
|
||||||
|
#CIR Pos
|
||||||
|
cir 4,5 -90
|
||||||
|
cir 4,4 -90
|
||||||
|
cir 5,4 -90
|
||||||
|
cir 5,5 -90
|
||||||
|
|
||||||
|
#Assets
|
||||||
|
jet -10,-1 -45
|
||||||
|
ship 11,0 79
|
||||||
|
big_tent -9,-7 40
|
||||||
|
big_tent 7,-10 135
|
||||||
|
small_tent -9,7 -45
|
||||||
|
small_tent -10,5 -30
|
||||||
|
radar 0,10 -110
|
||||||
|
small_tent 6,8 100
|
||||||
|
small_tent 8,7 70
|
||||||
|
tank -1,-10 45
|
||||||
|
|
||||||
|
|
||||||
|
#Yellow (CIR) Home Node
|
||||||
|
node_home_yellow 4,5 0
|
||||||
|
node_home_yellow 4,4 0
|
||||||
|
node_home_yellow 5,4 0
|
||||||
|
node_home_yellow 5,5 0
|
||||||
|
|
||||||
|
#Nodes für Map
|
||||||
|
node_start -5,1 0
|
||||||
|
node -4,1 0
|
||||||
|
node -3,1 0
|
||||||
|
node -2,1 0
|
||||||
|
node_bonus -1,1 0
|
||||||
|
node -1,2 0
|
||||||
|
node -1,3 0
|
||||||
|
node -1,4 0
|
||||||
|
node -1,5 0
|
||||||
|
node 0,5 0
|
||||||
|
node_start 1,5 0
|
||||||
|
node 1,4 0
|
||||||
|
node 1,3 0
|
||||||
|
node 1,2 0
|
||||||
|
node_bonus 1,1 0
|
||||||
|
node 2,1 0
|
||||||
|
node 3,1 0
|
||||||
|
node 4,1 0
|
||||||
|
node 5,1 0
|
||||||
|
node 5,0 0
|
||||||
|
node_start 5,-1 0
|
||||||
|
node 4,-1 0
|
||||||
|
node 3,-1 0
|
||||||
|
node 2,-1 0
|
||||||
|
node_bonus 1,-1 0
|
||||||
|
node 1,-2 0
|
||||||
|
node 1,-3 0
|
||||||
|
node 1,-4 0
|
||||||
|
node 1,-5 0
|
||||||
|
node 0,-5 0
|
||||||
|
node_start -1,-5 0
|
||||||
|
node -1,-4 0
|
||||||
|
node -1,-3 0
|
||||||
|
node -1,-2 0
|
||||||
|
node_bonus -1,-1 0
|
||||||
|
node -2,-1 0
|
||||||
|
node -3,-1 0
|
||||||
|
node -4,-1 0
|
||||||
|
node -5,-1 0
|
||||||
|
node -5,0 0
|
||||||
|
|
||||||
|
|
||||||
|
#Node Home
|
||||||
|
node_home_green 0,-1 0
|
||||||
|
node_home_green 0,-2 0
|
||||||
|
node_home_green 0,-3 0
|
||||||
|
node_home_green 0,-4 0
|
||||||
|
|
||||||
|
node_home_yellow 0,1 0
|
||||||
|
node_home_yellow 0,2 0
|
||||||
|
node_home_yellow 0,3 0
|
||||||
|
node_home_yellow 0,4 0
|
||||||
|
|
||||||
|
node_home_blue 1,0 0
|
||||||
|
node_home_blue 2,0 0
|
||||||
|
node_home_blue 3,0 0
|
||||||
|
node_home_blue 4,0 0
|
||||||
|
|
||||||
|
node_home_black -1,0 0
|
||||||
|
node_home_black -2,0 0
|
||||||
|
node_home_black -3,0 0
|
||||||
|
node_home_black -4,0 0
|
||||||
BIN
Projekte/mdga/client/src/main/resources/marine/marine.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/marine/marine_diff.png
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
Projekte/mdga/client/src/main/resources/music/80s,Disco,Life.wav
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/LaserParty.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/music/NeonRoadTrip.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/music/RetroNoir.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/music/SpaceInvaders.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/music/Spaceship.wav
Normal file
|
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/node_home/node_home.j3o
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 291 KiB |
|
After Width: | Height: | Size: 292 KiB |
BIN
Projekte/mdga/client/src/main/resources/radar/radar.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/radar/radar_diff.png
Normal file
|
After Width: | Height: | Size: 298 KiB |
|
After Width: | Height: | Size: 39 KiB |
BIN
Projekte/mdga/client/src/main/resources/ship/ship.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/ship/ship_diff.png
Normal file
|
After Width: | Height: | Size: 274 KiB |
BIN
Projekte/mdga/client/src/main/resources/smallTent/smallTent.j3o
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
Projekte/mdga/client/src/main/resources/sound/GameOver.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/sound/LevelUp2.wav
Normal file
BIN
Projekte/mdga/client/src/main/resources/swapCard/swapCard.j3o
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
Projekte/mdga/client/src/main/resources/tank/tank.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/tank/tank_diff.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
Projekte/mdga/client/src/main/resources/turboCard/turboCard.j3o
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
Projekte/mdga/client/src/main/resources/world/world.j3o
Normal file
BIN
Projekte/mdga/client/src/main/resources/world/world_diff.png
Normal file
|
After Width: | Height: | Size: 12 MiB |
@@ -17,10 +17,10 @@ public Board() {
|
|||||||
for (int i = 0; i < 40; i++) {
|
for (int i = 0; i < 40; i++) {
|
||||||
if (i % 10 == 0) {
|
if (i % 10 == 0) {
|
||||||
infield[i] = new StartNode(
|
infield[i] = new StartNode(
|
||||||
i == 0 ? Color.ARMY :
|
i == 0 ? Color.AIRFORCE :
|
||||||
i == 10 ? Color.AIRFORCE :
|
i == 10 ? Color.CYBER :
|
||||||
i == 20 ? Color.CYBER :
|
i == 20 ? Color.NAVY :
|
||||||
Color.NAVY
|
Color.ARMY
|
||||||
);
|
);
|
||||||
} else if (i == 4 || i == 14 || i == 24 || i == 34) {
|
} else if (i == 4 || i == 14 || i == 24 || i == 34) {
|
||||||
infield[i] = new BonusNode();
|
infield[i] = new BonusNode();
|
||||||
@@ -47,4 +47,14 @@ public Map<Color, PlayerData> getPlayerData() {
|
|||||||
public Node[] getInfield() {
|
public Node[] getInfield() {
|
||||||
return infield;
|
return infield;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets a piece on a specific Node in the infield
|
||||||
|
*
|
||||||
|
* @param index the index of the node
|
||||||
|
* @param piece the piece to be set
|
||||||
|
*/
|
||||||
|
public void setPieceOnBoard(int index, Piece piece) {
|
||||||
|
infield[index].setOccupant(piece);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,4 +98,14 @@ public Piece removePieceFromWaitingArea() {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets a piece at the given index in the home area
|
||||||
|
*
|
||||||
|
* @param index the index of the node
|
||||||
|
* @param piece the piece to be set at the given index
|
||||||
|
*/
|
||||||
|
public void setPieceInHome(int index, Piece piece) {
|
||||||
|
homeNodes[index].setOccupant(piece);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that is sent when a card is acquired.
|
||||||
|
*/
|
||||||
|
public class AcquireCardNotification extends Notification{
|
||||||
|
|
||||||
|
private UUID cardId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param cardId The id of the card that was acquired.
|
||||||
|
*/
|
||||||
|
public AcquireCardNotification(UUID cardId) {
|
||||||
|
this.cardId = cardId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id of the card that was acquired.
|
||||||
|
* @return The id of the card that was acquired.
|
||||||
|
*/
|
||||||
|
public UUID getCardId() {
|
||||||
|
return cardId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that the active player has changed
|
||||||
|
*/
|
||||||
|
public class ActivePlayerNotification extends Notification {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the active player
|
||||||
|
*/
|
||||||
|
private Color color;
|
||||||
|
|
||||||
|
ActivePlayerNotification(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the color of the active player
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CeremonyNotification
|
||||||
|
*/
|
||||||
|
public class CeremonyNotification extends Notification{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
CeremonyNotification() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that the dice is now.
|
||||||
|
*/
|
||||||
|
public class DiceNowNotification extends Notification {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
DiceNowNotification() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that is sent when a player has diced.
|
||||||
|
*/
|
||||||
|
public class DicingNotification extends Notification{
|
||||||
|
|
||||||
|
private Color color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param color The color of the player that diced.
|
||||||
|
*/
|
||||||
|
DicingNotification(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color of the player that diced.
|
||||||
|
* @return The color of the player that diced.
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import pp.mdga.game.BonusCard;
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a card has been drawn
|
||||||
|
*/
|
||||||
|
public class DrawCardNotification extends Notification {
|
||||||
|
|
||||||
|
private Color color;
|
||||||
|
private BonusCard card;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param color the color of the player who drew the card
|
||||||
|
* @param card the card that was drawn
|
||||||
|
*/
|
||||||
|
DrawCardNotification(Color color, BonusCard card) {
|
||||||
|
this.color = color;
|
||||||
|
this.card = card;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the color of the player who drew the card
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the card that was drawn
|
||||||
|
*/
|
||||||
|
public BonusCard getCard() {
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GameNotification class
|
||||||
|
*/
|
||||||
|
public class GameNotification extends Notification{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
GameNotification() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a piece has moved to a home.
|
||||||
|
*/
|
||||||
|
public class HomeMoveNotification extends Notification {
|
||||||
|
|
||||||
|
private UUID pieceId;
|
||||||
|
private int homeIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param pieceId the piece id
|
||||||
|
* @param homeIndex the home index
|
||||||
|
*/
|
||||||
|
HomeMoveNotification(UUID pieceId, int homeIndex) {
|
||||||
|
this.pieceId = pieceId;
|
||||||
|
this.homeIndex = homeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the piece id.
|
||||||
|
*
|
||||||
|
* @return the piece id
|
||||||
|
*/
|
||||||
|
public UUID getPieceId() {
|
||||||
|
return pieceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the home index.
|
||||||
|
*
|
||||||
|
* @return the home index
|
||||||
|
*/
|
||||||
|
public int getHomeIndex() {
|
||||||
|
return homeIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a card has been drawn
|
||||||
|
*/
|
||||||
|
public class InterruptNotification extends Notification {
|
||||||
|
|
||||||
|
private Color color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param color the color of the player who drew the card
|
||||||
|
*/
|
||||||
|
InterruptNotification(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the color of the player who drew the card
|
||||||
|
*/
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package pp.mdga.notification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a dialog has been started
|
||||||
|
*/
|
||||||
|
public class LobbyDialogNotification extends Notification{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
LobbyDialogNotification() {
|
||||||
|
}
|
||||||
|
}
|
||||||