Compare commits
22 Commits
b_malkmus_
...
b_wilkenin
Author | SHA1 | Date | |
---|---|---|---|
|
1f4ebdb630 | ||
|
1f5c8ba4a6 | ||
|
0cdd345ab5 | ||
|
ba837d4016 | ||
|
28d9cb10e5 | ||
|
21553ec52e | ||
|
5f79e8e00c | ||
|
03adf45167 | ||
|
17c4fca078 | ||
|
16620a0a3b | ||
|
2028d936e3 | ||
|
21fc46f9c5 | ||
|
dc52cf4f32 | ||
|
c339f3fc9d | ||
|
de0b2a4054 | ||
|
67e4c1e805 | ||
|
0a66d3cbfd | ||
|
30d129735c | ||
|
5f91ce0947 | ||
|
fae747e504 | ||
|
64834e8bf1 | ||
|
8f08e83358 |
@@ -9,8 +9,6 @@ dependencies {
|
|||||||
implementation project(":battleship:model")
|
implementation project(":battleship:model")
|
||||||
|
|
||||||
implementation libs.jme3.desktop
|
implementation libs.jme3.desktop
|
||||||
implementation 'com.simsilica:lemur:1.14.0'
|
|
||||||
implementation 'com.simsilica:lemur-proto:1.10.0'
|
|
||||||
|
|
||||||
runtimeOnly libs.jme3.awt.dialogs
|
runtimeOnly libs.jme3.awt.dialogs
|
||||||
runtimeOnly libs.jme3.plugins
|
runtimeOnly libs.jme3.plugins
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
# Specifies the map used by the opponent in single mode.
|
# Specifies the map used by the opponent in single mode.
|
||||||
# Single mode is activated if this property is set.
|
# Single mode is activated if this property is set.
|
||||||
#map.opponent=maps/map2.json
|
map.opponent=maps/map2.json
|
||||||
#
|
#
|
||||||
# Specifies the map used by the player in single mode.
|
# Specifies the map used by the player in single mode.
|
||||||
# The player must define their own map if this property is not set.
|
# The player must define their own map if this property is not set.
|
||||||
|
66
Projekte/battleship/client/maps/map3.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 4,
|
||||||
|
"x": 15,
|
||||||
|
"y": 5,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 2,
|
||||||
|
"y": 6,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 4,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 4,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 1,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
66
Projekte/battleship/client/maps/map4.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 4,
|
||||||
|
"x": 0,
|
||||||
|
"y": 5,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 2,
|
||||||
|
"y": 6,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 4,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 1,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
66
Projekte/battleship/client/maps/map5.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 4,
|
||||||
|
"x": 0,
|
||||||
|
"y": 5,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 6,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 4,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 4,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 1,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
60
Projekte/battleship/client/maps/map6.json
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 2,
|
||||||
|
"y": 6,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 4,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 4,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 1,
|
||||||
|
"rot": "DOWN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
66
Projekte/battleship/client/maps/map7.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 4,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 4,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 7,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 2,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 4,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 6,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 7,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 9,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
66
Projekte/battleship/client/maps/map8.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"width": 10,
|
||||||
|
"height": 10,
|
||||||
|
"ships": [
|
||||||
|
{
|
||||||
|
"length": 4,
|
||||||
|
"x": 0,
|
||||||
|
"y": 9,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 8,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 7,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 6,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 5,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 4,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 3,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 2,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"length": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"rot": "RIGHT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -267,6 +267,7 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
|
|||||||
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
|
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
|
||||||
|
|
||||||
attachGameSound();
|
attachGameSound();
|
||||||
|
attachGameMusic();
|
||||||
stateManager.attachAll(new EditorAppState(), new BattleAppState(), new SeaAppState());
|
stateManager.attachAll(new EditorAppState(), new BattleAppState(), new SeaAppState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +281,16 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
|
|||||||
stateManager.attach(gameSound);
|
stateManager.attach(gameSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the music state and sets its initial enabled state.
|
||||||
|
*/
|
||||||
|
private void attachGameMusic() {
|
||||||
|
final GameMusic gameMusic = new GameMusic();
|
||||||
|
gameMusic.setEnabled(GameMusic.enabledInPreferences());
|
||||||
|
stateManager.attach(gameMusic);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the application state every frame.
|
* Updates the application state every frame.
|
||||||
* This method is called once per frame during the game loop.
|
* This method is called once per frame during the game loop.
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
package pp.battleship.client;
|
package pp.battleship.client;
|
||||||
|
|
||||||
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import com.jme3.app.Application;
|
import com.jme3.app.Application;
|
||||||
import com.jme3.app.state.AbstractAppState;
|
import com.jme3.app.state.AbstractAppState;
|
||||||
import com.jme3.app.state.AppStateManager;
|
import com.jme3.app.state.AppStateManager;
|
||||||
@@ -7,79 +13,35 @@ import com.jme3.asset.AssetLoadException;
|
|||||||
import com.jme3.asset.AssetNotFoundException;
|
import com.jme3.asset.AssetNotFoundException;
|
||||||
import com.jme3.audio.AudioData;
|
import com.jme3.audio.AudioData;
|
||||||
import com.jme3.audio.AudioNode;
|
import com.jme3.audio.AudioNode;
|
||||||
import pp.battleship.notification.GameEventListener;
|
|
||||||
import pp.battleship.notification.SoundEvent;
|
|
||||||
|
|
||||||
import java.lang.System.Logger;
|
public class GameMusic extends AbstractAppState{
|
||||||
import java.lang.System.Logger.Level;
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
|
|
||||||
import static pp.util.PreferencesUtils.getPreferences;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An application state that plays music.
|
|
||||||
*/
|
|
||||||
public class GameMusic extends AbstractAppState {
|
|
||||||
private static final Logger LOGGER = System.getLogger(GameMusic.class.getName());
|
private static final Logger LOGGER = System.getLogger(GameMusic.class.getName());
|
||||||
private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
|
private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
|
||||||
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
||||||
private static final String VOLUME_PREF = "volume"; //NON-NLS
|
private static final String VOLUME_PREF = "volume"; //NON-NLS
|
||||||
|
|
||||||
private AudioNode piratenMusic;
|
private AudioNode music;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if sound is enabled in the preferences.
|
* Checks if sound is enabled in the preferences.
|
||||||
*
|
*
|
||||||
* @return {@code true} if sound is enabled, {@code false} otherwise.
|
* @return {@code true} if sound is enabled, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Prüft, ob die Musik eingeschalten ist.
|
|
||||||
public static boolean enabledInPreferences() {
|
public static boolean enabledInPreferences() {
|
||||||
return PREFERENCES.getBoolean(ENABLED_PREF, true);
|
return PREFERENCES.getBoolean(ENABLED_PREF, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks enabled volume in preferences.
|
* Checks if sound is enabled in the preferences.
|
||||||
*
|
*
|
||||||
* @return {@code float} if a volumePreference is set, the volume is set to the Value in PREFERENCES,
|
|
||||||
* {@code 0.25f} if no volumePreference is set in PREFERENCES, the Volume is set to a default of 0.25f
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
public static float volumeInPreferences() {
|
||||||
//Standardeinstellung für Musik
|
return PREFERENCES.getFloat(VOLUME_PREF, 0.5f);
|
||||||
public static float volumePreference() {
|
|
||||||
return PREFERENCES.getFloat(VOLUME_PREF, 0.33f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the game sound on or off.
|
* Initializes the sound effects for the game.
|
||||||
*/
|
|
||||||
public void toggleSound() {
|
|
||||||
setEnabled(!isEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the enabled state of this AppState.
|
|
||||||
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
|
|
||||||
*
|
|
||||||
* @param enabled {@code true} to enable the AppState, {@code false} to disable it.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
if (isEnabled() == enabled) return;
|
|
||||||
else if (!isEnabled() && enabled) {
|
|
||||||
if (piratenMusic != null) piratenMusic.play();
|
|
||||||
} else if (isEnabled() && !enabled) {
|
|
||||||
if (piratenMusic != null) piratenMusic.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setEnabled(enabled);
|
|
||||||
LOGGER.log(Level.INFO, "Music enabled: {0}", enabled); //NON-NLS
|
|
||||||
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the music.
|
|
||||||
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
|
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
|
||||||
*
|
*
|
||||||
* @param stateManager The state manager
|
* @param stateManager The state manager
|
||||||
@@ -88,17 +50,16 @@ public class GameMusic extends AbstractAppState {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(AppStateManager stateManager, Application app) {
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
super.initialize(stateManager, app);
|
super.initialize(stateManager, app);
|
||||||
piratenMusic =loadSound(app, "Sound/BackgroundMusic/Piratenmusik.ogg");
|
music = loadSound(app, "Sound/DasBootMenu.ogg");
|
||||||
setVolume(volumePreference());
|
setVolume(volumeInPreferences());
|
||||||
piratenMusic.setLooping(true);
|
music.setLooping(true);
|
||||||
if (isEnabled() && piratenMusic != null) {
|
if (isEnabled() && music != null) {
|
||||||
piratenMusic.play();
|
music.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the music from the specified file.
|
* Loads a sound from the specified file.
|
||||||
*
|
*
|
||||||
* @param app The application
|
* @param app The application
|
||||||
* @param name The name of the sound file.
|
* @param name The name of the sound file.
|
||||||
@@ -117,11 +78,34 @@ public class GameMusic extends AbstractAppState {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Einstellung der Lautstärke
|
/**
|
||||||
public void setVolume(float vol){
|
* Sets the enabled state of this AppState.
|
||||||
piratenMusic.setVolume(vol);
|
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
|
||||||
PREFERENCES.putFloat(VOLUME_PREF, vol);
|
*
|
||||||
|
* @param enabled {@code true} to enable the AppState, {@code false} to disable it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
if (isEnabled() == enabled) return;
|
||||||
|
else if(!isEnabled() && enabled) {
|
||||||
|
if (music != null) music.play();
|
||||||
|
} else if (isEnabled() && !enabled) {
|
||||||
|
if (music != null) music.stop();
|
||||||
|
}
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled); //NON-NLS
|
||||||
|
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Toggles the game sound on or off.
|
||||||
|
*/
|
||||||
|
public void toggleSound() {
|
||||||
|
setEnabled(!isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume(float vol){
|
||||||
|
music.setVolume(vol);
|
||||||
|
PREFERENCES.putFloat(VOLUME_PREF, vol);
|
||||||
|
}
|
||||||
|
}
|
@@ -34,6 +34,7 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
private AudioNode splashSound;
|
private AudioNode splashSound;
|
||||||
private AudioNode shipDestroyedSound;
|
private AudioNode shipDestroyedSound;
|
||||||
private AudioNode explosionSound;
|
private AudioNode explosionSound;
|
||||||
|
private AudioNode shellFlyingSound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if sound is enabled in the preferences.
|
* Checks if sound is enabled in the preferences.
|
||||||
@@ -78,6 +79,8 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
shipDestroyedSound = loadSound(app, "Sound/Effects/sunken.wav"); //NON-NLS
|
shipDestroyedSound = loadSound(app, "Sound/Effects/sunken.wav"); //NON-NLS
|
||||||
splashSound = loadSound(app, "Sound/Effects/splash.wav"); //NON-NLS
|
splashSound = loadSound(app, "Sound/Effects/splash.wav"); //NON-NLS
|
||||||
explosionSound = loadSound(app, "Sound/Effects/explosion.wav"); //NON-NLS
|
explosionSound = loadSound(app, "Sound/Effects/explosion.wav"); //NON-NLS
|
||||||
|
shellFlyingSound = loadSound(app, "Sound/Effects/shell_flying.wav");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,12 +127,28 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
shipDestroyedSound.playInstance();
|
shipDestroyedSound.playInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the shell flying sound effect.
|
||||||
|
*/
|
||||||
|
public void shellFly() {
|
||||||
|
if (isEnabled() && shellFlyingSound != null) {
|
||||||
|
shellFlyingSound.playInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a recieved {@code SoundEvent} and plays the according sound.
|
||||||
|
*
|
||||||
|
* @param event the Sound event to be processed
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void receivedEvent(SoundEvent event) {
|
public void receivedEvent(SoundEvent event) {
|
||||||
switch (event.sound()) {
|
switch (event.sound()) {
|
||||||
case EXPLOSION -> explosion();
|
case EXPLOSION -> explosion();
|
||||||
case SPLASH -> splash();
|
case SPLASH -> splash();
|
||||||
case DESTROYED_SHIP -> shipDestroyed();
|
case DESTROYED_SHIP -> shipDestroyed();
|
||||||
|
case SHELL_FLYING -> shellFly();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,18 +7,17 @@
|
|||||||
|
|
||||||
package pp.battleship.client;
|
package pp.battleship.client;
|
||||||
|
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Checkbox;
|
import com.simsilica.lemur.Checkbox;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.RangedValueModel;
|
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
import com.simsilica.lemur.Slider;
|
|
||||||
import pp.battleship.client.gui.VolumeSlider;
|
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.dialog.StateCheckboxModel;
|
import pp.dialog.StateCheckboxModel;
|
||||||
import pp.dialog.TextInputDialog;
|
import pp.dialog.TextInputDialog;
|
||||||
|
|
||||||
|
import pp.battleship.client.GameMusic;
|
||||||
|
import pp.battleship.client.VolumeSlider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
@@ -37,7 +36,7 @@ class Menu extends Dialog {
|
|||||||
private final BattleshipApp app;
|
private final BattleshipApp app;
|
||||||
private final Button loadButton = new Button(lookup("menu.map.load"));
|
private final Button loadButton = new Button(lookup("menu.map.load"));
|
||||||
private final Button saveButton = new Button(lookup("menu.map.save"));
|
private final Button saveButton = new Button(lookup("menu.map.save"));
|
||||||
private final VolumeSlider volumeSlider;
|
private final VolumeSlider slider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the Menu dialog for the Battleship application.
|
* Constructs the Menu dialog for the Battleship application.
|
||||||
@@ -47,28 +46,13 @@ class Menu extends Dialog {
|
|||||||
public Menu(BattleshipApp app) {
|
public Menu(BattleshipApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
slider = new VolumeSlider(app.getStateManager().getState(GameMusic.class));
|
||||||
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
|
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
|
||||||
addChild(new Checkbox(lookup("menu.sound-enabled"),
|
|
||||||
new StateCheckboxModel(app, GameSound.class)));
|
|
||||||
addChild(new Label(lookup("battleship.name"), new ElementId("header")));//NON-NLS
|
|
||||||
|
|
||||||
addChild(new Checkbox(lookup("menu.sound-enabled"), new StateCheckboxModel(app, GameSound.class)));
|
addChild(new Checkbox(lookup("menu.sound-enabled"), new StateCheckboxModel(app, GameSound.class)));
|
||||||
|
|
||||||
addChild(new Checkbox(lookup("menu.background-sound-enabled"), new StateCheckboxModel(app, GameMusic.class)));
|
addChild(new Checkbox(lookup("menu.background-sound-enabled"), new StateCheckboxModel(app, GameMusic.class)));
|
||||||
|
|
||||||
volumeSlider = new VolumeSlider(app.getStateManager().getState(GameMusic.class));
|
addChild(slider);
|
||||||
|
|
||||||
addChild(volumeSlider);
|
|
||||||
|
|
||||||
addChild(loadButton)
|
|
||||||
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
|
||||||
addChild(saveButton);
|
|
||||||
saveButton.setEnabled(app.getGameLogic().maySaveMap());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Füge den Slider zum GUI hinzu
|
|
||||||
addChild(volumeSlider);
|
|
||||||
|
|
||||||
addChild(loadButton)
|
addChild(loadButton)
|
||||||
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
||||||
@@ -166,5 +150,12 @@ class Menu extends Dialog {
|
|||||||
fileDialog(app.getGameLogic()::saveMap, lookup("menu.map.save"));
|
fileDialog(app.getGameLogic()::saveMap, lookup("menu.map.save"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of the volume control slider.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float delta) {
|
||||||
|
slider.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
package pp.battleship.client;
|
package pp.battleship.client;
|
||||||
|
|
||||||
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Container;
|
import com.simsilica.lemur.Container;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.TextField;
|
import com.simsilica.lemur.TextField;
|
||||||
import com.simsilica.lemur.component.SpringGridLayout;
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
import com.simsilica.lemur.Button;
|
|
||||||
import pp.battleship.server.BattleshipServer;
|
import pp.battleship.server.BattleshipServer;
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.dialog.DialogBuilder;
|
import pp.dialog.DialogBuilder;
|
||||||
@@ -72,7 +72,6 @@ class NetworkDialog extends SimpleDialog {
|
|||||||
|
|
||||||
//Add the button to start the sever
|
//Add the button to start the sever
|
||||||
addChild(serverButton).addClickCommands(s -> ifTopDialog(this::startServerInThread));
|
addChild(serverButton).addClickCommands(s -> ifTopDialog(this::startServerInThread));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,24 @@
|
|||||||
|
package pp.battleship.client;
|
||||||
|
|
||||||
|
import com.simsilica.lemur.Slider;
|
||||||
|
|
||||||
|
public class VolumeSlider extends Slider {
|
||||||
|
|
||||||
|
private final GameMusic music;
|
||||||
|
|
||||||
|
private double vol;
|
||||||
|
|
||||||
|
public VolumeSlider(GameMusic music) {
|
||||||
|
super();
|
||||||
|
this.music = music;
|
||||||
|
vol = GameMusic.volumeInPreferences();
|
||||||
|
getModel().setPercent(vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
if (vol != getModel().getPercent()) {
|
||||||
|
vol = getModel().getPercent();
|
||||||
|
music.setVolume( (float) vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -28,7 +28,7 @@ import pp.util.Position;
|
|||||||
* and interaction between the model and the view.
|
* and interaction between the model and the view.
|
||||||
*/
|
*/
|
||||||
class MapView {
|
class MapView {
|
||||||
private static final float FIELD_SIZE = 40f;
|
public static final float FIELD_SIZE = 40f;
|
||||||
private static final float GRID_LINE_WIDTH = 2f;
|
private static final float GRID_LINE_WIDTH = 2f;
|
||||||
private static final float BACKGROUND_DEPTH = -4f;
|
private static final float BACKGROUND_DEPTH = -4f;
|
||||||
private static final float GRID_DEPTH = -1f;
|
private static final float GRID_DEPTH = -1f;
|
||||||
|
@@ -7,15 +7,20 @@
|
|||||||
|
|
||||||
package pp.battleship.client.gui;
|
package pp.battleship.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.shape.Sphere;
|
||||||
import pp.battleship.model.Battleship;
|
import pp.battleship.model.Battleship;
|
||||||
import pp.battleship.model.Shell;
|
import pp.battleship.model.Shell;
|
||||||
import pp.battleship.model.Shot;
|
import pp.battleship.model.Shot;
|
||||||
import pp.util.Position;
|
import pp.util.Position;
|
||||||
|
import static com.jme3.material.Materials.UNSHADED;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronizes the visual representation of the ship map with the game model.
|
* Synchronizes the visual representation of the ship map with the game model.
|
||||||
@@ -38,7 +43,6 @@ class MapViewSynchronizer extends ShipMapSynchronizer {
|
|||||||
|
|
||||||
// The MapView associated with this synchronizer
|
// The MapView associated with this synchronizer
|
||||||
private final MapView view;
|
private final MapView view;
|
||||||
private Shell shell;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new MapViewSynchronizer for the given MapView.
|
* Constructs a new MapViewSynchronizer for the given MapView.
|
||||||
@@ -125,19 +129,25 @@ class MapViewSynchronizer extends ShipMapSynchronizer {
|
|||||||
private Geometry shipLine(float x1, float y1, float x2, float y2, ColorRGBA color) {
|
private Geometry shipLine(float x1, float y1, float x2, float y2, ColorRGBA color) {
|
||||||
return view.getApp().getDraw().makeFatLine(x1, y1, x2, y2, SHIP_DEPTH, color, SHIP_LINE_WIDTH);
|
return view.getApp().getDraw().makeFatLine(x1, y1, x2, y2, SHIP_DEPTH, color, SHIP_LINE_WIDTH);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param deltaTime
|
|
||||||
*/
|
|
||||||
public void update(float deltaTime) {
|
|
||||||
if (shell != null) {
|
|
||||||
shell.updatePosition(deltaTime);
|
|
||||||
drawShell(shell.getCurrentPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawShell(Vector3f position) {
|
/**
|
||||||
// Methode zum Zeichnen des Geschosses auf der 2D-Karte TODO
|
* Creates and returns a Spatial representation of the given {@code Shell} object
|
||||||
|
* for 2D visualization in the game. The shell is represented as a circle.
|
||||||
|
*
|
||||||
|
* @param shell The {@code Shell} object to be visualized.
|
||||||
|
* @return A {@code Spatial} object representing the shell on the map.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Spatial visit(Shell shell) {
|
||||||
|
final ColorRGBA color = ColorRGBA.Black;
|
||||||
|
Geometry ellipse = new Geometry("ellipse", new Sphere(50, 50, MapView.FIELD_SIZE / 2 * 0.8f));
|
||||||
|
Material mat = new Material(view.getApp().getAssetManager(), UNSHADED); //NON-NLS
|
||||||
|
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||||
|
mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
|
||||||
|
mat.setColor("Color", color);
|
||||||
|
ellipse.setMaterial(mat);
|
||||||
|
ellipse.addControl(new Shell2DControl(view, shell));
|
||||||
|
return ellipse;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,284 @@
|
|||||||
|
package pp.battleship.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.effect.ParticleEmitter;
|
||||||
|
import com.jme3.effect.ParticleMesh.Type;
|
||||||
|
import com.jme3.effect.shapes.EmitterSphereShape;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
|
||||||
|
import pp.battleship.client.BattleshipApp;
|
||||||
|
|
||||||
|
public class ParticleCreator {
|
||||||
|
private static final int COUNT_FACTOR = 1;
|
||||||
|
private static final float COUNT_FACTOR_F = 1f;
|
||||||
|
private static final boolean POINT_SPRITE = true;
|
||||||
|
private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle;
|
||||||
|
|
||||||
|
private final BattleshipApp app;
|
||||||
|
|
||||||
|
ParticleCreator(BattleshipApp app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a flame particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured flame particle emitter
|
||||||
|
*/
|
||||||
|
|
||||||
|
ParticleEmitter createFlame(){
|
||||||
|
ParticleEmitter flame = new ParticleEmitter("Flame", EMITTER_TYPE, 32 * COUNT_FACTOR);
|
||||||
|
flame.setSelectRandomImage(true);
|
||||||
|
flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (1f / COUNT_FACTOR_F)));
|
||||||
|
flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
|
||||||
|
flame.setStartSize(0.1f);
|
||||||
|
flame.setEndSize(0.5f);
|
||||||
|
flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
|
||||||
|
flame.setParticlesPerSec(0);
|
||||||
|
flame.setGravity(0, -5, 0);
|
||||||
|
flame.setLowLife(.4f);
|
||||||
|
flame.setHighLife(.5f);
|
||||||
|
flame.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 7, 0));
|
||||||
|
flame.getParticleInfluencer().setVelocityVariation(1f);
|
||||||
|
flame.setImagesX(2);
|
||||||
|
flame.setImagesY(2);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/flame.png"));
|
||||||
|
mat.setBoolean("PointSprite", POINT_SPRITE);
|
||||||
|
flame.setMaterial(mat);
|
||||||
|
|
||||||
|
return flame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a flash particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured flash particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createFlash() {
|
||||||
|
ParticleEmitter flash = new ParticleEmitter("Flash", EMITTER_TYPE, 24 * COUNT_FACTOR);
|
||||||
|
flash.setSelectRandomImage(true);
|
||||||
|
flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1f / COUNT_FACTOR_F));
|
||||||
|
flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
|
||||||
|
flash.setStartSize(.1f);
|
||||||
|
flash.setEndSize(0.5f);
|
||||||
|
flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
|
||||||
|
flash.setParticlesPerSec(0);
|
||||||
|
flash.setGravity(0, 0, 0);
|
||||||
|
flash.setLowLife(.2f);
|
||||||
|
flash.setHighLife(.2f);
|
||||||
|
flash.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 5f, 0));
|
||||||
|
flash.getParticleInfluencer().setVelocityVariation(1);
|
||||||
|
flash.setImagesX(2);
|
||||||
|
flash.setImagesY(2);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/flash.png"));
|
||||||
|
mat.setBoolean("PointSprite", POINT_SPRITE);
|
||||||
|
flash.setMaterial(mat);
|
||||||
|
|
||||||
|
return flash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a round spark particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured round spark particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createRoundSpark() {
|
||||||
|
ParticleEmitter roundSpark = new ParticleEmitter("RoundSpark", EMITTER_TYPE, 20 * COUNT_FACTOR);
|
||||||
|
roundSpark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F)));
|
||||||
|
roundSpark.setEndColor(new ColorRGBA(0, 0, 0, 0.5f / COUNT_FACTOR_F));
|
||||||
|
roundSpark.setStartSize(0.2f);
|
||||||
|
roundSpark.setEndSize(0.8f);
|
||||||
|
roundSpark.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
|
||||||
|
roundSpark.setParticlesPerSec(0);
|
||||||
|
roundSpark.setGravity(0, -.5f, 0);
|
||||||
|
roundSpark.setLowLife(1.8f);
|
||||||
|
roundSpark.setHighLife(2f);
|
||||||
|
roundSpark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 3, 0));
|
||||||
|
roundSpark.getParticleInfluencer().setVelocityVariation(.5f);
|
||||||
|
roundSpark.setImagesX(1);
|
||||||
|
roundSpark.setImagesY(1);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/roundspark.png"));
|
||||||
|
mat.setBoolean("PointSprite", POINT_SPRITE);
|
||||||
|
roundSpark.setMaterial(mat);
|
||||||
|
|
||||||
|
return roundSpark;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a spark particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured spark particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createSpark() {
|
||||||
|
ParticleEmitter spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR);
|
||||||
|
spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F));
|
||||||
|
spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
|
||||||
|
spark.setStartSize(.5f);
|
||||||
|
spark.setEndSize(.5f);
|
||||||
|
spark.setFacingVelocity(true);
|
||||||
|
spark.setParticlesPerSec(0);
|
||||||
|
spark.setGravity(0, 5, 0);
|
||||||
|
spark.setLowLife(0.5f);
|
||||||
|
spark.setHighLife(1.5f);
|
||||||
|
spark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 8, 0)); // y20
|
||||||
|
spark.getParticleInfluencer().setVelocityVariation(1);
|
||||||
|
spark.setImagesX(1);
|
||||||
|
spark.setImagesY(1);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/spark.png"));
|
||||||
|
spark.setMaterial(mat);
|
||||||
|
|
||||||
|
return spark;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a smoke trail particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured smoke trail particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createSmokeTrail() {
|
||||||
|
ParticleEmitter smokeTrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR);
|
||||||
|
smokeTrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F));
|
||||||
|
smokeTrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
|
||||||
|
smokeTrail.setStartSize(.2f);
|
||||||
|
smokeTrail.setEndSize(1f);
|
||||||
|
smokeTrail.setFacingVelocity(true);
|
||||||
|
smokeTrail.setParticlesPerSec(0);
|
||||||
|
smokeTrail.setGravity(0, 1, 0);
|
||||||
|
smokeTrail.setLowLife(.4f);
|
||||||
|
smokeTrail.setHighLife(.5f);
|
||||||
|
smokeTrail.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 12, 0));
|
||||||
|
smokeTrail.getParticleInfluencer().setVelocityVariation(1);
|
||||||
|
smokeTrail.setImagesX(1);
|
||||||
|
smokeTrail.setImagesY(3);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/smoketrail.png"));
|
||||||
|
smokeTrail.setMaterial(mat);
|
||||||
|
|
||||||
|
return smokeTrail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a debris particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured debris particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createDebris() {
|
||||||
|
ParticleEmitter debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR);
|
||||||
|
debris.setSelectRandomImage(true);
|
||||||
|
debris.setRandomAngle(true);
|
||||||
|
debris.setRotateSpeed(FastMath.TWO_PI * 4);
|
||||||
|
debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, 1.0f / COUNT_FACTOR_F));
|
||||||
|
debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f));
|
||||||
|
debris.setStartSize(.10f);
|
||||||
|
debris.setEndSize(.15f);
|
||||||
|
debris.setParticlesPerSec(0);
|
||||||
|
debris.setGravity(0, 12f, 0);
|
||||||
|
debris.setLowLife(1.4f);
|
||||||
|
debris.setHighLife(1.5f);
|
||||||
|
debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 15, 0));
|
||||||
|
debris.getParticleInfluencer().setVelocityVariation(.60f);
|
||||||
|
debris.setImagesX(3);
|
||||||
|
debris.setImagesY(3);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/Debris.png"));
|
||||||
|
debris.setMaterial(mat);
|
||||||
|
|
||||||
|
return debris;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shockwave particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured shockwave particle emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createShockwave() {
|
||||||
|
ParticleEmitter shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR);
|
||||||
|
shockwave.setFaceNormal(Vector3f.UNIT_Y);
|
||||||
|
shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, .8f / COUNT_FACTOR_F));
|
||||||
|
shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f));
|
||||||
|
shockwave.setStartSize(0f);
|
||||||
|
shockwave.setEndSize(3f);
|
||||||
|
shockwave.setParticlesPerSec(0);
|
||||||
|
shockwave.setGravity(0, 0, 0);
|
||||||
|
shockwave.setLowLife(0.5f);
|
||||||
|
shockwave.setHighLife(0.5f);
|
||||||
|
shockwave.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0));
|
||||||
|
shockwave.getParticleInfluencer().setVelocityVariation(0f);
|
||||||
|
shockwave.setImagesX(1);
|
||||||
|
shockwave.setImagesY(1);
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Explosion/shockwave.png"));
|
||||||
|
shockwave.setMaterial(mat);
|
||||||
|
|
||||||
|
return shockwave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a moving smoke emitter.
|
||||||
|
*
|
||||||
|
* @return a configured smoke emitter
|
||||||
|
*/
|
||||||
|
ParticleEmitter createMovingSmokeEmitter() {
|
||||||
|
ParticleEmitter smokeEmitter = new ParticleEmitter("SmokeEmitter", Type.Triangle, 300);
|
||||||
|
smokeEmitter.setGravity(0, 0, 0);
|
||||||
|
smokeEmitter.getParticleInfluencer().setVelocityVariation(1);
|
||||||
|
smokeEmitter.setLowLife(1);
|
||||||
|
smokeEmitter.setHighLife(1);
|
||||||
|
smokeEmitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, .5f, 0));
|
||||||
|
smokeEmitter.setImagesX(15); // Assuming the smoke texture is a sprite sheet with 15 frames
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Smoke/Smoke.png"));
|
||||||
|
smokeEmitter.setMaterial(mat);
|
||||||
|
|
||||||
|
return smokeEmitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a one-time water splash particle emitter.
|
||||||
|
*
|
||||||
|
* @return a configured one-time water splash particle emitter
|
||||||
|
*/
|
||||||
|
public ParticleEmitter createWaterSplash() {
|
||||||
|
// Create a new particle emitter for the splash effect
|
||||||
|
ParticleEmitter waterSplash = new ParticleEmitter("WaterSplash", Type.Triangle, 30);
|
||||||
|
|
||||||
|
// Set the shape of the emitter, making particles emit from a point or small area
|
||||||
|
waterSplash.setShape(new EmitterSphereShape(Vector3f.ZERO, 0.2f));
|
||||||
|
|
||||||
|
// Start and end colors for water (blue, fading out)
|
||||||
|
waterSplash.setStartColor(new ColorRGBA(0.4f, 0.4f, 1f, 1f)); // Light blue at start
|
||||||
|
waterSplash.setEndColor(new ColorRGBA(0.4f, 0.4f, 1f, 0f)); // Transparent at the end
|
||||||
|
|
||||||
|
// Particle size: small at start, larger before fading out
|
||||||
|
waterSplash.setStartSize(0.1f);
|
||||||
|
waterSplash.setEndSize(0.3f);
|
||||||
|
|
||||||
|
// Particle lifespan (how long particles live)
|
||||||
|
waterSplash.setLowLife(0.5f);
|
||||||
|
waterSplash.setHighLife(1f);
|
||||||
|
|
||||||
|
// Gravity: Pull the water particles downwards
|
||||||
|
waterSplash.setGravity(0, -9.81f, 0); // Earth's gravity simulation
|
||||||
|
|
||||||
|
// Velocity: Give particles an initial burst upward (simulates splash)
|
||||||
|
waterSplash.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 3, 0));
|
||||||
|
waterSplash.getParticleInfluencer().setVelocityVariation(0.6f); // Add randomness to splash
|
||||||
|
|
||||||
|
// Set how many particles are emitted per second (0 to emit all particles at once)
|
||||||
|
waterSplash.setParticlesPerSec(0);
|
||||||
|
|
||||||
|
// Load a texture for the water splash (assuming a texture exists at this path)
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
|
||||||
|
mat.setTexture("Texture", app.getAssetManager().loadTexture("Effects/Splash/splash.png"));
|
||||||
|
waterSplash.setMaterial(mat);
|
||||||
|
|
||||||
|
return waterSplash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package pp.battleship.client.gui;
|
package pp.battleship.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.effect.ParticleEmitter;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.material.RenderState.BlendMode;
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@@ -19,6 +20,7 @@ import com.jme3.scene.shape.Cylinder;
|
|||||||
import pp.battleship.client.BattleshipApp;
|
import pp.battleship.client.BattleshipApp;
|
||||||
import pp.battleship.model.Battleship;
|
import pp.battleship.model.Battleship;
|
||||||
import pp.battleship.model.Rotation;
|
import pp.battleship.model.Rotation;
|
||||||
|
import pp.battleship.model.Shell;
|
||||||
import pp.battleship.model.ShipMap;
|
import pp.battleship.model.ShipMap;
|
||||||
import pp.battleship.model.Shot;
|
import pp.battleship.model.Shot;
|
||||||
|
|
||||||
@@ -32,13 +34,13 @@ import static pp.util.FloatMath.PI;
|
|||||||
* It extends the {@link ShipMapSynchronizer} to provide specific synchronization
|
* It extends the {@link ShipMapSynchronizer} to provide specific synchronization
|
||||||
* logic for the sea map.
|
* logic for the sea map.
|
||||||
*/
|
*/
|
||||||
//ANPASSEN!!!!
|
|
||||||
class SeaSynchronizer extends ShipMapSynchronizer {
|
class SeaSynchronizer extends ShipMapSynchronizer {
|
||||||
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
|
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
|
||||||
private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o"; //NON-NLS
|
private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o"; //NON-NLS
|
||||||
private static final String FLUGZEUGTRAEGER = "Models/Flugzeugträger_5er/Flugzeugträger.j3o";
|
private static final String SMALL_SHIP_MODEL = "Models/SmallShip/SmallShip.j3o"; //NON-NLS
|
||||||
private static final String KORVETTE = "Models/Korvette_3er/Korvette.j3o";
|
private static final String U_BOAT_MODEL = "Models/WWII_ship_German_Type_II_U-boat_v2/WW2Uboat.j3o"; //NON-NLS
|
||||||
private static final String ZERSTOERER = "Models/Zerstörer_2er/Zerstörer.j3o";
|
private static final String TUG_BOAT_MODEL = "Models/TugBoat/TugBoat.j3o"; //NON-NLS
|
||||||
|
private static final String LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
|
||||||
private static final String COLOR = "Color"; //NON-NLS
|
private static final String COLOR = "Color"; //NON-NLS
|
||||||
private static final String SHIP = "ship"; //NON-NLS
|
private static final String SHIP = "ship"; //NON-NLS
|
||||||
private static final String SHOT = "shot"; //NON-NLS
|
private static final String SHOT = "shot"; //NON-NLS
|
||||||
@@ -48,7 +50,8 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
|
|
||||||
private final ShipMap map;
|
private final ShipMap map;
|
||||||
private final BattleshipApp app;
|
private final BattleshipApp app;
|
||||||
private final ParticleEffectFactory particleFactory;
|
private final ParticleCreator particlecreator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a {@code SeaSynchronizer} object with the specified application, root node, and ship map.
|
* Constructs a {@code SeaSynchronizer} object with the specified application, root node, and ship map.
|
||||||
@@ -61,7 +64,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
super(app.getGameLogic().getOwnMap(), root);
|
super(app.getGameLogic().getOwnMap(), root);
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.particleFactory = new ParticleEffectFactory(app);
|
this.particlecreator = new ParticleCreator(app);
|
||||||
addExisting();
|
addExisting();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,9 +78,48 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Spatial visit(Shot shot) {
|
public Spatial visit(Shot shot) {
|
||||||
return shot.isHit() ? handleHit(shot) : createCylinder(shot);
|
return shot.isHit() ? handleHit(shot) : handleMiss(shot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a miss by representing it with a blue cylinder
|
||||||
|
* and attaching a water splash effect to it.
|
||||||
|
* @param shot the shot to be processed
|
||||||
|
* @return a Spatial simulating a miss with water splash effect
|
||||||
|
*/
|
||||||
|
private Spatial handleMiss(Shot shot) {
|
||||||
|
Node shotNode = new Node("ShotNode");
|
||||||
|
Geometry shotCylinder = createCylinder(shot);
|
||||||
|
shotNode.attachChild(shotCylinder);
|
||||||
|
ParticleEmitter waterSplash = particlecreator.createWaterSplash();
|
||||||
|
waterSplash.setLocalTranslation(shot.getY() + 0.5f, 0f, shot.getX() + 0.5f);
|
||||||
|
shotNode.attachChild(waterSplash);
|
||||||
|
waterSplash.emitAllParticles();
|
||||||
|
|
||||||
|
return shotNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the sinking animation and removal of ship if destroyed
|
||||||
|
* @param ship the ship to be sunk
|
||||||
|
*/
|
||||||
|
private void sinkAndRemoveShip(Battleship ship) {
|
||||||
|
Battleship dasIstGelebteTeamarbeit = ship;
|
||||||
|
final Node shipNode = (Node) getSpatial(dasIstGelebteTeamarbeit);
|
||||||
|
if (shipNode == null) return;
|
||||||
|
|
||||||
|
// Add sinking control to animate the sinking
|
||||||
|
shipNode.addControl(new SinkControl(shipNode));
|
||||||
|
|
||||||
|
// Add particle effects
|
||||||
|
ParticleEmitter bubbles = particlecreator.createWaterSplash();
|
||||||
|
bubbles.setLocalTranslation(shipNode.getLocalTranslation());
|
||||||
|
shipNode.attachChild(bubbles);
|
||||||
|
bubbles.emitAllParticles();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a hit by attaching its representation to the node that
|
* Handles a hit by attaching its representation to the node that
|
||||||
* contains the ship model as a child so that it moves with the ship.
|
* contains the ship model as a child so that it moves with the ship.
|
||||||
@@ -86,39 +128,22 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
* @return always null to prevent the representation from being attached
|
* @return always null to prevent the representation from being attached
|
||||||
* to the items node as well
|
* to the items node as well
|
||||||
*/
|
*/
|
||||||
private Spatial handleMiss(Shot shot) {
|
|
||||||
Node shotNode = new Node("ShotNode");
|
|
||||||
Geometry shotCylinder = createCylinder(shot);
|
|
||||||
shotNode.attachChild(shotCylinder);
|
|
||||||
ParticleEmitter waterSplash = particleFactory.createWaterSplash();
|
|
||||||
waterSplash.setLocalTranslation(shot.getY() + 0.5f, 0f, shot.getX() + 0.5f);
|
|
||||||
shotNode.attachChild(waterSplash);
|
|
||||||
waterSplash.emitAllParticles();
|
|
||||||
|
|
||||||
return shotNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
* @param shot a hit
|
|
||||||
* @return always null to prevent the representation from being attached to the items node as well
|
|
||||||
*/
|
|
||||||
private Spatial handleHit(Shot shot) {
|
private Spatial handleHit(Shot shot) {
|
||||||
final Battleship ship = requireNonNull(map.findShipAt(shot), "Missing ship");
|
final Battleship ship = requireNonNull(map.findShipAt(shot), "Missing ship");
|
||||||
final Node shipNode = requireNonNull((Node) getSpatial(ship), "Missing ship node");
|
final Node shipNode = requireNonNull((Node) getSpatial(ship), "Missing ship node");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create a new node specifically for the hit effects
|
// Create a new node specifically for the hit effects
|
||||||
Node hitEffectNode = new Node("HitEffectNode");
|
Node hitEffectNode = new Node("HitEffectNode");
|
||||||
|
|
||||||
// Create particle effects
|
// Create particle effects
|
||||||
ParticleEmitter flame = particleFactory.createFlame();
|
ParticleEmitter flame = particlecreator.createFlame();
|
||||||
ParticleEmitter flash = particleFactory.createFlash();
|
ParticleEmitter flash = particlecreator.createFlash();
|
||||||
ParticleEmitter spark = particleFactory.createSpark();
|
ParticleEmitter spark = particlecreator.createSpark();
|
||||||
ParticleEmitter roundSpark = particleFactory.createRoundSpark();
|
ParticleEmitter roundSpark = particlecreator.createRoundSpark();
|
||||||
ParticleEmitter smokeTrail = particleFactory.createSmokeTrail();
|
ParticleEmitter smokeTrail = particlecreator.createSmokeTrail();
|
||||||
ParticleEmitter debris = particleFactory.createDebris();
|
ParticleEmitter debris = particlecreator.createDebris();
|
||||||
ParticleEmitter shockwave = particleFactory.createShockwave();
|
ParticleEmitter shockwave = particlecreator.createShockwave();
|
||||||
ParticleEmitter movingSmoke = particleFactory.createMovingSmokeEmitter();
|
ParticleEmitter movingSmoke = particlecreator.createMovingSmokeEmitter();
|
||||||
|
|
||||||
// Attach all effects to the hitEffectNode
|
// Attach all effects to the hitEffectNode
|
||||||
hitEffectNode.attachChild(flame);
|
hitEffectNode.attachChild(flame);
|
||||||
@@ -132,8 +157,8 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
|
|
||||||
// Set the local translation for the hit effect to the point of impact
|
// Set the local translation for the hit effect to the point of impact
|
||||||
hitEffectNode.setLocalTranslation(shot.getY() + 0.5f - shipNode.getLocalTranslation().x,
|
hitEffectNode.setLocalTranslation(shot.getY() + 0.5f - shipNode.getLocalTranslation().x,
|
||||||
0.5f, // Adjust as needed for height above the ship
|
0.5f, // Adjust as needed for height above the ship
|
||||||
shot.getX() + 0.5f - shipNode.getLocalTranslation().z);
|
shot.getX() + 0.5f - shipNode.getLocalTranslation().z);
|
||||||
|
|
||||||
// Attach the hitEffectNode to the shipNode so it moves with the ship
|
// Attach the hitEffectNode to the shipNode so it moves with the ship
|
||||||
shipNode.attachChild(hitEffectNode);
|
shipNode.attachChild(hitEffectNode);
|
||||||
@@ -155,26 +180,6 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the sinking animation and removal of ship if destroyed
|
|
||||||
* @param ship the ship to be sunk
|
|
||||||
*/
|
|
||||||
private void sinkAndRemoveShip(Battleship ship) {
|
|
||||||
|
|
||||||
final Node shipNode = (Node) getSpatial(ship);
|
|
||||||
if (shipNode == null) return;
|
|
||||||
|
|
||||||
// Add sinking control to animate the sinking
|
|
||||||
shipNode.addControl(new SinkingControl(shipNode));
|
|
||||||
|
|
||||||
// Add particle effects
|
|
||||||
ParticleEmitter bubbles = particleFactory.createWaterSplash();
|
|
||||||
bubbles.setLocalTranslation(shipNode.getLocalTranslation());
|
|
||||||
shipNode.attachChild(bubbles);
|
|
||||||
bubbles.emitAllParticles();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a cylinder geometry representing the specified shot.
|
* Creates a cylinder geometry representing the specified shot.
|
||||||
* The appearance of the cylinder depends on whether the shot is a hit or a miss.
|
* The appearance of the cylinder depends on whether the shot is a hit or a miss.
|
||||||
@@ -224,14 +229,20 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
* @param ship the battleship to be represented
|
* @param ship the battleship to be represented
|
||||||
* @return the spatial representing the battleship
|
* @return the spatial representing the battleship
|
||||||
*/
|
*/
|
||||||
//ANPASSEN!!!!!!
|
|
||||||
private Spatial createShip(Battleship ship) {
|
private Spatial createShip(Battleship ship) {
|
||||||
if( ship.getLength() == 4){ createBox(ship); return createBattleship(ship); }
|
switch (ship.getLength()) {
|
||||||
else if(ship.getLength()==5){createBox(ship);return createFlugzeugtraeger(ship); }
|
case 4:
|
||||||
else if(ship.getLength()==3){createBox(ship);return createKorvette(ship); }
|
return createBattleship(ship);
|
||||||
else if(ship.getLength()==2){createBox(ship);return createZerstoerer(ship); }
|
case 3:
|
||||||
else if(ship.getLength()==1){createBox(ship);return createZerstoerer(ship); }
|
return createLargeship(ship);
|
||||||
else throw new IllegalArgumentException("Deine Länge ist nicht definiert!");
|
case 2:
|
||||||
|
return createMediumship(ship);
|
||||||
|
case 1:
|
||||||
|
return createSmallship(ship);
|
||||||
|
default:
|
||||||
|
return createBox(ship);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,7 +287,6 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
* @param ship the battleship to be represented
|
* @param ship the battleship to be represented
|
||||||
* @return the spatial representing the "King George V" battleship
|
* @return the spatial representing the "King George V" battleship
|
||||||
*/
|
*/
|
||||||
//ANPASSEN!!!!
|
|
||||||
private Spatial createBattleship(Battleship ship) {
|
private Spatial createBattleship(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(KING_GEORGE_V_MODEL);
|
final Spatial model = app.getAssetManager().loadModel(KING_GEORGE_V_MODEL);
|
||||||
|
|
||||||
@@ -287,31 +297,31 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Spatial createFlugzeugtraeger(Battleship ship) {
|
private Spatial createSmallship(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(FLUGZEUGTRAEGER);
|
final Spatial model = app.getAssetManager().loadModel(SMALL_SHIP_MODEL);
|
||||||
|
|
||||||
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
||||||
model.scale(1.48f);
|
model.scale(0.0005f);
|
||||||
model.setShadowMode(ShadowMode.CastAndReceive);
|
model.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Spatial createKorvette(Battleship ship) {
|
private Spatial createMediumship(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(KORVETTE);
|
final Spatial model = app.getAssetManager().loadModel(U_BOAT_MODEL);
|
||||||
|
|
||||||
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
||||||
model.scale(1.48f);
|
model.scale(0.27f);
|
||||||
model.setShadowMode(ShadowMode.CastAndReceive);
|
model.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Spatial createZerstoerer(Battleship ship) {
|
private Spatial createLargeship(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(ZERSTOERER);
|
final Spatial model = app.getAssetManager().loadModel(TUG_BOAT_MODEL);
|
||||||
|
|
||||||
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
|
||||||
model.scale(1.48f);
|
model.scale(0.0004f);
|
||||||
model.setShadowMode(ShadowMode.CastAndReceive);
|
model.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
@@ -331,4 +341,25 @@ class SeaSynchronizer extends ShipMapSynchronizer {
|
|||||||
case UP -> PI;
|
case UP -> PI;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a 3D model representation of the given {@code Shell} object
|
||||||
|
* for visualization in the game.
|
||||||
|
*
|
||||||
|
* @param shell The {@code Shell} object to be visualized.
|
||||||
|
* @return A {@code Spatial} object representing the 3D model of the shell.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Spatial visit(Shell shell) {
|
||||||
|
final Spatial model = app.getAssetManager().loadModel("Models/Shell/shell.j3o");
|
||||||
|
model.setLocalScale(.05f);
|
||||||
|
model.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
Material mat = new Material(app.getAssetManager(), LIGHTING);
|
||||||
|
mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture("Models/Shell/shell_color.png"));
|
||||||
|
mat.setReceivesShadows(true);
|
||||||
|
model.setMaterial(mat);
|
||||||
|
|
||||||
|
model.addControl(new ShellControl(shell));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
package pp.battleship.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
import pp.battleship.model.Shell;
|
||||||
|
import pp.util.Position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the 2D representation of a {@code Shell} in the game, updating its position
|
||||||
|
* based on the shell's current state in the game model. The {@code Shell2DControl} class
|
||||||
|
* is responsible for translating the shell's 3D position to a 2D view position within
|
||||||
|
* the game's map view.
|
||||||
|
*/
|
||||||
|
public class Shell2DControl extends AbstractControl {
|
||||||
|
private final Shell shell;
|
||||||
|
private final MapView view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code Shell2DControl} to manage the 2D visualization of the given {@code Shell}.
|
||||||
|
*
|
||||||
|
* @param view The {@code MapView} used to get information about the map to display.
|
||||||
|
* @param shell The {@code Shell} being visualized.
|
||||||
|
*/
|
||||||
|
public Shell2DControl(MapView view, Shell shell){
|
||||||
|
this.shell = shell;
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of the shell's 2D representation based on the shell's current
|
||||||
|
* 3D position in the game model. The position is mapped from model space to view space
|
||||||
|
* coordinates and translated to the appropriate location within the {@code MapView}.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, representing the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
Vector3f shellPos = shell.getPosition();
|
||||||
|
Position viewPos = view.modelToView(shellPos.x, shellPos.z);
|
||||||
|
spatial.setLocalTranslation(viewPos.getX() + MapView.FIELD_SIZE / 2, viewPos.getY() + MapView.FIELD_SIZE / 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
|
// No rendering-specific behavior required for this control
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
package pp.battleship.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
import pp.battleship.model.Shell;
|
||||||
|
|
||||||
|
import static pp.util.FloatMath.PI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the 3D representation of a {@code Shell} in the game, updating its position
|
||||||
|
* and rotation based on the shell's current state in the game model. The {@code ShellControl}
|
||||||
|
* class ensures that the spatial associated with the shell is positioned and oriented correctly
|
||||||
|
* within the world.
|
||||||
|
*/
|
||||||
|
public class ShellControl extends AbstractControl {
|
||||||
|
private final Shell shell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code ShellControl} to manage the 3D visualization of the given {@code Shell}.
|
||||||
|
*
|
||||||
|
* @param shell The {@code Shell} being visualized and controlled.
|
||||||
|
*/
|
||||||
|
public ShellControl(Shell shell){
|
||||||
|
super();
|
||||||
|
this.shell = shell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the 3D position and rotation of the shell based on its current state.
|
||||||
|
* Converts map coordinates to world coordinates and applies the shell's orientation.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, representing the elapsed time since the last update.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
Vector3f pos = shell.getPosition();
|
||||||
|
Vector3f fixed = new Vector3f(pos.z + 0.5f, pos.y, pos.x + 0.5f);
|
||||||
|
fixed.setY(pos.y);
|
||||||
|
spatial.setLocalTranslation(fixed);
|
||||||
|
spatial.setLocalRotation(shell.getRotation());
|
||||||
|
spatial.rotate(PI/2,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
|
// No rendering-specific behavior required for this control
|
||||||
|
}
|
||||||
|
}
|
@@ -10,7 +10,7 @@ import com.jme3.scene.Node;
|
|||||||
* Control that handles the sinking effect for destroyed ships.
|
* Control that handles the sinking effect for destroyed ships.
|
||||||
* It will gradually move the ship downwards and then remove it from the scene.
|
* It will gradually move the ship downwards and then remove it from the scene.
|
||||||
*/
|
*/
|
||||||
class SinkingControl extends AbstractControl {
|
class SinkControl extends AbstractControl {
|
||||||
private static final float SINK_DURATION = 5f; // Duration of the sinking animation
|
private static final float SINK_DURATION = 5f; // Duration of the sinking animation
|
||||||
private static final float SINK_SPEED = 0.1f; // Speed at which the ship sinks
|
private static final float SINK_SPEED = 0.1f; // Speed at which the ship sinks
|
||||||
private float elapsedTime = 0;
|
private float elapsedTime = 0;
|
||||||
@@ -18,10 +18,10 @@ class SinkingControl extends AbstractControl {
|
|||||||
private final Node shipNode;
|
private final Node shipNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a {@code SinkingControl.java} object with the shipNode to be to be sunk
|
* Constructs a {@code SinkingControl} object with the shipNode to be to be sunk
|
||||||
* @param shipNode the node to handeld
|
* @param shipNode the node to handeld
|
||||||
*/
|
*/
|
||||||
public SinkingControl(Node shipNode) {
|
public SinkControl(Node shipNode) {
|
||||||
this.shipNode = shipNode;
|
this.shipNode = shipNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,3 +51,4 @@ class SinkingControl extends AbstractControl {
|
|||||||
// No rendering-related code needed
|
// No rendering-related code needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -1,29 +0,0 @@
|
|||||||
package pp.battleship.client.gui;
|
|
||||||
|
|
||||||
import com.simsilica.lemur.Slider;
|
|
||||||
import pp.battleship.client.GameMusic;
|
|
||||||
|
|
||||||
|
|
||||||
public class VolumeSlider extends Slider {
|
|
||||||
|
|
||||||
private final GameMusic piratenMusic;
|
|
||||||
|
|
||||||
private double vol;
|
|
||||||
|
|
||||||
public VolumeSlider(GameMusic music) {
|
|
||||||
super();
|
|
||||||
this.piratenMusic = music;
|
|
||||||
vol = GameMusic.volumePreference();
|
|
||||||
getModel().setPercent(vol);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
if (vol != getModel().getPercent()) {
|
|
||||||
vol = getModel().getPercent();
|
|
||||||
piratenMusic.setVolume( (float) vol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,183 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
package pp.battleship.server;
|
||||||
|
|
||||||
|
import com.jme3.network.ConnectionListener;
|
||||||
|
import com.jme3.network.HostedConnection;
|
||||||
|
import com.jme3.network.Message;
|
||||||
|
import com.jme3.network.MessageListener;
|
||||||
|
import com.jme3.network.Network;
|
||||||
|
import com.jme3.network.Server;
|
||||||
|
import com.jme3.network.serializing.Serializer;
|
||||||
|
import pp.battleship.BattleshipConfig;
|
||||||
|
import pp.battleship.game.server.Player;
|
||||||
|
import pp.battleship.game.server.ServerGameLogic;
|
||||||
|
import pp.battleship.game.server.ServerSender;
|
||||||
|
import pp.battleship.message.client.ClientMessage;
|
||||||
|
import pp.battleship.message.client.AnimationFinishedMessage;
|
||||||
|
import pp.battleship.message.client.MapMessage;
|
||||||
|
import pp.battleship.message.client.ShootMessage;
|
||||||
|
import pp.battleship.message.server.EffectMessage;
|
||||||
|
import pp.battleship.message.server.GameDetails;
|
||||||
|
import pp.battleship.message.server.ServerMessage;
|
||||||
|
import pp.battleship.message.server.StartBattleMessage;
|
||||||
|
import pp.battleship.model.Battleship;
|
||||||
|
import pp.battleship.model.IntPoint;
|
||||||
|
import pp.battleship.model.Shot;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.logging.LogManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server implementing the visitor pattern as MessageReceiver for ClientMessages
|
||||||
|
*/
|
||||||
|
public class BattleshipServer implements MessageListener<HostedConnection>, ConnectionListener, ServerSender {
|
||||||
|
private static final Logger LOGGER = System.getLogger(BattleshipServer.class.getName());
|
||||||
|
private static final File CONFIG_FILE = new File("server.properties");
|
||||||
|
|
||||||
|
private final BattleshipConfig config = new BattleshipConfig();
|
||||||
|
private Server myServer;
|
||||||
|
private final ServerGameLogic logic;
|
||||||
|
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Configure logging
|
||||||
|
LogManager manager = LogManager.getLogManager();
|
||||||
|
try {
|
||||||
|
manager.readConfiguration(new FileInputStream("logging.properties"));
|
||||||
|
LOGGER.log(Level.INFO, "Successfully read logging properties"); //NON-NLS
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
LOGGER.log(Level.INFO, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the Battleships server.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new BattleshipServer().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the server.
|
||||||
|
*/
|
||||||
|
BattleshipServer() {
|
||||||
|
config.readFromIfExists(CONFIG_FILE);
|
||||||
|
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
|
||||||
|
logic = new ServerGameLogic(this, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
startServer();
|
||||||
|
while (true)
|
||||||
|
processNextMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startServer() {
|
||||||
|
try {
|
||||||
|
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
|
||||||
|
myServer = Network.createServer(config.getPort());
|
||||||
|
initializeSerializables();
|
||||||
|
myServer.start();
|
||||||
|
registerListeners();
|
||||||
|
LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processNextMessage() {
|
||||||
|
try {
|
||||||
|
pendingMessages.take().process(logic);
|
||||||
|
}
|
||||||
|
catch (InterruptedException ex) {
|
||||||
|
LOGGER.log(Level.INFO, "Interrupted while waiting for messages"); //NON-NLS
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeSerializables() {
|
||||||
|
Serializer.registerClass(GameDetails.class);
|
||||||
|
Serializer.registerClass(StartBattleMessage.class);
|
||||||
|
Serializer.registerClass(MapMessage.class);
|
||||||
|
Serializer.registerClass(ShootMessage.class);
|
||||||
|
Serializer.registerClass(EffectMessage.class);
|
||||||
|
Serializer.registerClass(AnimationFinishedMessage.class);
|
||||||
|
Serializer.registerClass(Battleship.class);
|
||||||
|
Serializer.registerClass(IntPoint.class);
|
||||||
|
Serializer.registerClass(Shot.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerListeners() {
|
||||||
|
myServer.addMessageListener(this, MapMessage.class);
|
||||||
|
myServer.addMessageListener(this, ShootMessage.class);
|
||||||
|
myServer.addMessageListener(this, AnimationFinishedMessage.class);
|
||||||
|
myServer.addConnectionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageReceived(HostedConnection source, Message message) {
|
||||||
|
LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS
|
||||||
|
if (message instanceof ClientMessage clientMessage)
|
||||||
|
pendingMessages.add(new ReceivedMessage(clientMessage, source.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionAdded(Server server, HostedConnection hostedConnection) {
|
||||||
|
LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
|
||||||
|
logic.addPlayer(hostedConnection.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionRemoved(Server server, HostedConnection hostedConnection) {
|
||||||
|
LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS
|
||||||
|
final Player player = logic.getPlayerById(hostedConnection.getId());
|
||||||
|
if (player == null)
|
||||||
|
LOGGER.log(Level.INFO, "closed connection does not belong to an active player"); //NON-NLS
|
||||||
|
else { //NON-NLS
|
||||||
|
LOGGER.log(Level.INFO, "closed connection belongs to {0}", player); //NON-NLS
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void exit(int exitValue) { //NON-NLS
|
||||||
|
LOGGER.log(Level.INFO, "close request"); //NON-NLS
|
||||||
|
if (myServer != null)
|
||||||
|
for (HostedConnection client : myServer.getConnections()) //NON-NLS
|
||||||
|
if (client != null) client.close("Game over"); //NON-NLS
|
||||||
|
System.exit(exitValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the specified message to the specified connection.
|
||||||
|
*
|
||||||
|
* @param id the connection id
|
||||||
|
* @param message the message
|
||||||
|
*/
|
||||||
|
public void send(int id, ServerMessage message) {
|
||||||
|
if (myServer == null || !myServer.isRunning()) {
|
||||||
|
LOGGER.log(Level.ERROR, "no server running when trying to send {0}", message); //NON-NLS
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final HostedConnection connection = myServer.getConnection(id);
|
||||||
|
if (connection != null)
|
||||||
|
connection.send(message);
|
||||||
|
else
|
||||||
|
LOGGER.log(Level.ERROR, "there is no connection with id={0}", id); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,18 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
package pp.battleship.server;
|
||||||
|
|
||||||
|
import pp.battleship.message.client.ClientInterpreter;
|
||||||
|
import pp.battleship.message.client.ClientMessage;
|
||||||
|
|
||||||
|
record ReceivedMessage(ClientMessage message, int from) {
|
||||||
|
void process(ClientInterpreter interpreter) {
|
||||||
|
message.accept(interpreter, from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 168 KiB |
@@ -42,13 +42,12 @@ public class ModelExporter extends SimpleApplication {
|
|||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
export("Models/KingGeorgeV/King_George_V.obj", "KingGeorgeV.j3o"); //NON-NLS
|
export("Models/KingGeorgeV/King_George_V.obj", "KingGeorgeV.j3o"); //NON-NLS
|
||||||
export("Models/Flugzeugträger_5er/Flugzeugträger.obj", "Flugzeugträger.j3o");
|
export("Models/SmallShip/12219_boat_v2_L2.obj", "SmallShip.j3o"); //NON-NLS
|
||||||
export("Models/Korvette_3er/caravel.obj", "Korvette.j3o");
|
export("Models/WWII_ship_German_Type_II_U-boat_v2/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj", "WW2Uboat.j3o"); //NON-NLS
|
||||||
export("Models/Zerstörer_2er/ShipV_LOW.obj", "Zerstörer.j3o");
|
export("Models/TugBoat/12218_tugboat_v1_L2.obj", "TugBoat.j3o"); //NON-NLS
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports spatial into a file
|
* Exports spatial into a file
|
||||||
*
|
*
|
||||||
|
@@ -1,112 +0,0 @@
|
|||||||
# Blender 4.2.2 LTS MTL File: 'None'
|
|
||||||
# www.blender.org
|
|
||||||
|
|
||||||
newmtl Main.002
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.490000 0.257495 0.132300
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.016
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.000000 0.000000 0.000000
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.017
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.190000 0.077615 0.017100
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.018
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.266600 0.466860 0.620000
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.019
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.990000 0.990000 0.990000
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.020
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.070000 0.062265 0.058100
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.021
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.160000 0.151680 0.147200
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.022
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.340000 0.164333 0.000000
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.023
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.940000 0.561180 0.206800
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Mat.1_1.002
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.320000 0.151520 0.060800
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
||||||
|
|
||||||
newmtl Sail.002
|
|
||||||
Ns 319.999939
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.070000 0.070000 0.070000
|
|
||||||
Ks 1.000000 1.000000 1.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 2
|
|
@@ -1,52 +0,0 @@
|
|||||||
# Blender 4.2.2 LTS MTL File: 'None'
|
|
||||||
# www.blender.org
|
|
||||||
|
|
||||||
newmtl DeckStuff.003
|
|
||||||
Ns 20.000006
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.184314 0.600000 0.792157
|
|
||||||
Ks 0.000000 0.000000 0.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 1
|
|
||||||
|
|
||||||
newmtl Hull.003
|
|
||||||
Ns 20.000006
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.701961 0.678431 0.019608
|
|
||||||
Ks 0.000000 0.000000 0.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 1
|
|
||||||
|
|
||||||
newmtl MastsRigging.003
|
|
||||||
Ns 20.000006
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.086275 0.768628 0.117647
|
|
||||||
Ks 0.000000 0.000000 0.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 1
|
|
||||||
|
|
||||||
newmtl Poopdeck.003
|
|
||||||
Ns 20.000006
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.976471 0.211765 0.211765
|
|
||||||
Ks 0.000000 0.000000 0.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 1
|
|
||||||
|
|
||||||
newmtl Sail.007
|
|
||||||
Ns 20.000006
|
|
||||||
Ka 1.000000 1.000000 1.000000
|
|
||||||
Kd 0.588000 0.588000 0.588000
|
|
||||||
Ks 0.000000 0.000000 0.000000
|
|
||||||
Ke 0.000000 0.000000 0.000000
|
|
||||||
Ni 1.500000
|
|
||||||
d 1.000000
|
|
||||||
illum 1
|
|
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 2.7 MiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 4.5 MiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 472 KiB |
Before Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 727 KiB |
Before Width: | Height: | Size: 4.1 MiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 1003 KiB |
Before Width: | Height: | Size: 415 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 249 KiB |
Before Width: | Height: | Size: 658 KiB |
Before Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 4.8 MiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 755 KiB |
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 472 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 260 KiB |
@@ -0,0 +1,104 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# File Created: 16.12.2011 14:18:52
|
||||||
|
|
||||||
|
newmtl white
|
||||||
|
Ns 53.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.6667 0.6667 0.6667
|
||||||
|
Kd 0.6667 0.6667 0.6667
|
||||||
|
Ks 0.1800 0.1800 0.1800
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl boat_elements_black
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.0000 0.0000 0.0000
|
||||||
|
Kd 0.0000 0.0000 0.0000
|
||||||
|
Ks 0.3600 0.3600 0.3600
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl boat_glass
|
||||||
|
Ns 60.0000
|
||||||
|
Ni 7.0000
|
||||||
|
d 0.4000
|
||||||
|
Tr 0.6000
|
||||||
|
Tf 0.4000 0.4000 0.4000
|
||||||
|
illum 2
|
||||||
|
Ka 0.1059 0.1569 0.1451
|
||||||
|
Kd 0.1059 0.1569 0.1451
|
||||||
|
Ks 0.6750 0.6750 0.6750
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl boat_screw_hooks_bronze
|
||||||
|
Ns 80.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.2941 0.2157 0.0510
|
||||||
|
Kd 0.2941 0.2157 0.0510
|
||||||
|
Ks 0.7200 0.7200 0.7200
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl boat_silver
|
||||||
|
Ns 80.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.3333 0.3333 0.3333
|
||||||
|
Kd 0.3333 0.3333 0.3333
|
||||||
|
Ks 0.7200 0.7200 0.7200
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl boat_buffer
|
||||||
|
Ns 10.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.2700 0.2700 0.2700
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka boat_buffer_diffuse.jpg
|
||||||
|
map_Kd boat_buffer_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl boat_roof_accessory
|
||||||
|
Ns 15.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.3600 0.3600 0.3600
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka boat_roof_accessory_diffuse.jpg
|
||||||
|
map_Kd boat_roof_accessory_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl boat_body
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.3600 0.3600 0.3600
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka boat_body_diffuse.jpg
|
||||||
|
map_Kd boat_body_diffuse.jpg
|
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 47 KiB |
@@ -0,0 +1,154 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# File Created: 21.12.2011 10:51:13
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_tube
|
||||||
|
Ns 40.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.1800 0.1800 0.1800
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka 12218_tugboat_tube_diffuse.jpg
|
||||||
|
map_Kd 12218_tugboat_tube_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_cabine
|
||||||
|
Ns 40.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.1800 0.1800 0.1800
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka 12218_tugboat_cabine_diffuse.jpg
|
||||||
|
map_Kd 12218_tugboat_cabine_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_boat
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.5400 0.5400 0.5400
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka 12218_tugboat_boat_diffuse.jpg
|
||||||
|
map_Kd 12218_tugboat_boat_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_blackpaint
|
||||||
|
Ns 40.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.1333 0.1333 0.1333
|
||||||
|
Kd 0.1333 0.1333 0.1333
|
||||||
|
Ks 0.1725 0.1725 0.1725
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_yellowpaint
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.8196 0.6588 0.1725
|
||||||
|
Kd 0.8196 0.6588 0.1725
|
||||||
|
Ks 0.6471 0.6471 0.6471
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_crane
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.6314 0.0588 0.0588
|
||||||
|
Kd 0.6314 0.0588 0.0588
|
||||||
|
Ks 0.6471 0.6471 0.6471
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_orangepaint
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.8627 0.2549 0.1137
|
||||||
|
Kd 0.8627 0.2549 0.1137
|
||||||
|
Ks 0.6471 0.6471 0.6471
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_whitepaint
|
||||||
|
Ns 60.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.8667 0.8667 0.8667
|
||||||
|
Kd 0.8667 0.8667 0.8667
|
||||||
|
Ks 0.7765 0.7765 0.7765
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_greypaint
|
||||||
|
Ns 55.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.3373 0.3412 0.3490
|
||||||
|
Kd 0.3373 0.3412 0.3490
|
||||||
|
Ks 0.6471 0.6471 0.6471
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_bronze
|
||||||
|
Ns 75.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.5529 0.4275 0.0000
|
||||||
|
Kd 0.5529 0.4275 0.0000
|
||||||
|
Ks 0.6471 0.6471 0.6471
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_saferound
|
||||||
|
Ns 10.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.2700 0.2700 0.2700
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka 12218_tugboat_saferound_diffuse.jpg
|
||||||
|
map_Kd 12218_tugboat_saferound_diffuse.jpg
|
||||||
|
|
||||||
|
newmtl 12218_tugboat_dirtdark
|
||||||
|
Ns 10.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 0.1216 0.1059 0.0863
|
||||||
|
Kd 0.1216 0.1059 0.0863
|
||||||
|
Ks 0.0000 0.0000 0.0000
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
@@ -0,0 +1,16 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# File Created: 29.03.2012 14:25:39
|
||||||
|
|
||||||
|
newmtl default
|
||||||
|
Ns 35.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 1.0000
|
||||||
|
Tr 0.0000
|
||||||
|
Tf 1.0000 1.0000 1.0000
|
||||||
|
illum 2
|
||||||
|
Ka 1.0000 1.0000 1.0000
|
||||||
|
Kd 1.0000 1.0000 1.0000
|
||||||
|
Ks 0.5400 0.5400 0.5400
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
||||||
|
map_Ka 14084_WWII_ship_German_Type_II_U-boat_diff.jpg
|
||||||
|
map_Kd 14084_WWII_ship_German_Type_II_U-boat_diff.jpg
|