Merge branch 'dev/client_koppe' into 'dev_client'
Add acoustics See merge request progproj/gruppen-ht24/Gruppe-01!2
This commit is contained in:
@@ -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) { }
|
||||
@@ -1,5 +0,0 @@
|
||||
package pp.mdga.client;
|
||||
|
||||
public class ActionSynchronizer {
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package pp.mdga.client.Animation;
|
||||
|
||||
public interface Animation {
|
||||
void play();
|
||||
void stop();
|
||||
boolean isOver();
|
||||
abstract class Animation {
|
||||
abstract void play();
|
||||
abstract void stop();
|
||||
abstract boolean isOver();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
public 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 = 11;
|
||||
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(0 <= x && x < GRID_EXTEND);
|
||||
assert(0 <= 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,62 +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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
@@ -1,4 +0,0 @@
|
||||
package pp.mdga.effect;
|
||||
|
||||
public interface Effect {
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class ActivePlayerNotification extends Notification {
|
||||
ActivePlayerNotification(Color color) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.BonusCard;
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class DrawCardNotification extends Notification {
|
||||
DrawCardNotification(Color color, BonusCard card) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class InterruptNotification extends Notification {
|
||||
InterruptNotification(Color color) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class MovePieceNotification extends Notification {
|
||||
MovePieceNotification(Color color, int nodeIndex) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package pp.mdga.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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class ResumeNotification extends Notification {
|
||||
ResumeNotification(Color color) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
public class RollDiceNotification extends Notification{
|
||||
RollDiceNotification(Color color, int eyes, int moveNumber) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package pp.mdga.notification;
|
||||
|
||||
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