This commit is contained in:
Johannes Schmelz 2024-11-25 06:53:56 +01:00
commit 4703afd656
7 changed files with 141 additions and 68 deletions

View File

@ -1,5 +1,6 @@
// Styling of Lemur components // Styling of Lemur components
// For documentation, see: // For documentation, see:
// For documentation, see:
// https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling // https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
import com.jme3.math.ColorRGBA import com.jme3.math.ColorRGBA
@ -11,7 +12,6 @@ import com.simsilica.lemur.Command
import com.simsilica.lemur.HAlignment import com.simsilica.lemur.HAlignment
import com.simsilica.lemur.Insets3f import com.simsilica.lemur.Insets3f
import com.simsilica.lemur.component.QuadBackgroundComponent import com.simsilica.lemur.component.QuadBackgroundComponent
import com.simsilica.lemur.component.TbtQuadBackgroundComponent
def bgColor = color(1, 1, 1, 1) def bgColor = color(1, 1, 1, 1)
def buttonEnabledColor = color(0, 0, 0, 1) def buttonEnabledColor = color(0, 0, 0, 1)
@ -19,7 +19,7 @@ def buttonDisabledColor = color(0.8, 0.9, 1, 0.2)
def buttonBgColor = color(1, 1, 1, 1) def buttonBgColor = color(1, 1, 1, 1)
def sliderColor = color(0.6, 0.8, 0.8, 1) def sliderColor = color(0.6, 0.8, 0.8, 1)
def sliderBgColor = color(0.5, 0.75, 0.75, 1) def sliderBgColor = color(0.5, 0.75, 0.75, 1)
def gradientColor = color(0.5, 0.75, 0.85, 0.5) def gradientColor = color(1, 1, 1, 1)
def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1) def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
def solidWhiteBackground = new QuadBackgroundComponent(new ColorRGBA(1, 1, 1, 1)) def solidWhiteBackground = new QuadBackgroundComponent(new ColorRGBA(1, 1, 1, 1))
def greyBackground = new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); def greyBackground = new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f));
@ -30,10 +30,8 @@ def lightGrey = color(0.6, 0.6, 0.6, 1.0)
def gradient = TbtQuadBackgroundComponent.create( def gradient = TbtQuadBackgroundComponent.create(
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", generateMips: false),
generateMips: false), 1, 1, 1, 126, 126, 1f, false)
1, 1, 1, 126, 126,
1f, false)
def doubleGradient = new QuadBackgroundComponent(gradientColor) def doubleGradient = new QuadBackgroundComponent(gradientColor)
doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png", doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
@ -79,6 +77,7 @@ selector("header", "pp") {
textVAlignment = VAlignment.Center textVAlignment = VAlignment.Center
} }
// Container Stil
selector("container", "pp") { selector("container", "pp") {
background = solidWhiteBackground.clone() background = solidWhiteBackground.clone()
background.setColor(bgColor) background.setColor(bgColor)
@ -91,8 +90,8 @@ selector("toolbar") {
} }
selector("slider", "pp") { selector("slider", "pp") {
background = gradient.clone() insets = new Insets3f(5, 10, 5, 10) // Abstand
background.setColor(bgColor) background = new QuadBackgroundComponent(sliderBgColor)
} }
def pressedCommand = new Command<Button>() { def pressedCommand = new Command<Button>() {
@ -113,30 +112,6 @@ def enabledCommand = new Command<Button>() {
} }
} }
def repeatCommand = new Command<Button>() {
private long startTime
private long lastClick
void execute(Button source) {
// Only do the repeating click while the mouse is
// over the button (and pressed of course)
if (source.isPressed() && source.isHighlightOn()) {
long elapsedTime = System.currentTimeMillis() - startTime
// After half a second pause, click 8 times a second
if (elapsedTime > 500 && elapsedTime > lastClick + 125) {
source.click()
// Try to quantize the last click time to prevent drift
lastClick = ((elapsedTime - 500) / 125) * 125 + 500
}
}
else {
startTime = System.currentTimeMillis()
lastClick = 0
}
}
}
def stdButtonCommands = [ def stdButtonCommands = [
(ButtonAction.Down) : [pressedCommand], (ButtonAction.Down) : [pressedCommand],
(ButtonAction.Up) : [pressedCommand], (ButtonAction.Up) : [pressedCommand],

View File

@ -1,30 +1,26 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client; package pp.monopoly.client;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.lang.System.Logger.Level; import java.lang.System.Logger.Level;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
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;
import com.jme3.asset.AssetLoadException;
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.monopoly.notification.GameEventListener; import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.SoundEvent; import pp.monopoly.notification.SoundEvent;
import static pp.util.PreferencesUtils.getPreferences; import static pp.util.PreferencesUtils.getPreferences;
/** /**
* An application state that plays sounds. * An application state that plays sounds based on game events.
*/ */
public class GameSound extends AbstractAppState implements GameEventListener { public class GameSound extends AbstractAppState implements GameEventListener {
private static final Logger LOGGER = System.getLogger(GameSound.class.getName()); private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
@ -71,7 +67,6 @@ public class GameSound extends AbstractAppState implements GameEventListener {
/** /**
* Sets the enabled state of this AppState. * 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. * @param enabled {@code true} to enable the AppState, {@code false} to disable it.
*/ */
@ -79,16 +74,15 @@ public class GameSound extends AbstractAppState implements GameEventListener {
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
if (isEnabled() == enabled) return; if (isEnabled() == enabled) return;
super.setEnabled(enabled); super.setEnabled(enabled);
LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled); //NON-NLS LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled);
PREFERENCES.putBoolean(ENABLED_PREF, enabled); PREFERENCES.putBoolean(ENABLED_PREF, enabled);
} }
/** /**
* Initializes the sound effects for the game. * Initializes the sound effects for the game and stores the application reference.
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
* *
* @param stateManager The state manager * @param stateManager The state manager
* @param app The application * @param app The application instance
*/ */
@Override @Override
public void initialize(AppStateManager stateManager, Application app) { public void initialize(AppStateManager stateManager, Application app) {
@ -109,18 +103,16 @@ public class GameSound extends AbstractAppState implements GameEventListener {
/** /**
* Loads a sound from the specified file. * Loads a sound from the specified file.
* *
* @param app The application
* @param name The name of the sound file. * @param name The name of the sound file.
* @return The loaded AudioNode. * @return The loaded AudioNode.
*/ */
private AudioNode loadSound(Application app, String name) { private AudioNode loadSound(String name) {
try { try {
final AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer); AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
sound.setLooping(false); sound.setLooping(false);
sound.setPositional(false); sound.setPositional(false);
return sound; return sound;
} } catch (Exception ex) {
catch (AssetLoadException | AssetNotFoundException ex) {
LOGGER.log(Level.ERROR, ex.getMessage(), ex); LOGGER.log(Level.ERROR, ex.getMessage(), ex);
} }
return null; return null;
@ -239,4 +231,4 @@ public class GameSound extends AbstractAppState implements GameEventListener {
case BUTTON -> button(); case BUTTON -> button();
} }
} }
} }//heloo

View File

@ -18,6 +18,7 @@ import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger; import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import com.jme3.texture.Texture;
import com.simsilica.lemur.GuiGlobals; import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.style.BaseStyles; import com.simsilica.lemur.style.BaseStyles;

View File

@ -3,8 +3,10 @@ package pp.monopoly.client.gui;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import pp.monopoly.model.Board; import pp.monopoly.model.Board;
import pp.monopoly.model.Item; import pp.monopoly.model.Item;
import pp.monopoly.model.Item;
import pp.monopoly.model.Visitor; import pp.monopoly.model.Visitor;
import pp.monopoly.notification.GameEventListener; import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.ItemAddedEvent; import pp.monopoly.notification.ItemAddedEvent;
@ -24,10 +26,14 @@ abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements
* *
* @param board the game board to synchronize * @param board the game board to synchronize
* @param root the root node to which the view representations of the board items are attached * @param root the root node to which the view representations of the board items are attached
* @param board the game board to synchronize
* @param root the root node to which the view representations of the board items are attached
*/ */
protected BoardSynchronizer(Board board, Node root) {
protected BoardSynchronizer(Board board, Node root) { protected BoardSynchronizer(Board board, Node root) {
super(root); super(root);
this.board = board; this.board = board;
this.board = board;
} }
/** /**
@ -42,6 +48,7 @@ abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements
} }
/** /**
* Adds the existing items from the board to the view during initialization.
* Adds the existing items from the board to the view during initialization. * Adds the existing items from the board to the view during initialization.
*/ */
protected void addExisting() { protected void addExisting() {
@ -49,26 +56,36 @@ abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements
} }
/** /**
* Handles the event when an item is removed from the board.
* Handles the event when an item is removed from the board. * Handles the event when an item is removed from the board.
* *
* @param event the event indicating that an item has been removed from the board * @param event the event indicating that an item has been removed from the board
* @param event the event indicating that an item has been removed from the board
*/ */
@Override @Override
public void receivedEvent(ItemRemovedEvent event) { public void receivedEvent(ItemRemovedEvent event) {
if (board == event.getBoard()) { if (board == event.getBoard()) {
delete(event.getItem()); delete(event.getItem());
} }
if (board == event.getBoard()) {
delete(event.getItem());
}
} }
/** /**
* Handles the event when an item is added to the board.
* Handles the event when an item is added to the board. * Handles the event when an item is added to the board.
* *
* @param event the event indicating that an item has been added to the board * @param event the event indicating that an item has been added to the board
* @param event the event indicating that an item has been added to the board
*/ */
@Override @Override
public void receivedEvent(ItemAddedEvent event) { public void receivedEvent(ItemAddedEvent event) {
if (board == event.getBoard()) { if (board == event.getBoard()) {
add(event.getItem()); add(event.getItem());
} }
if (board == event.getBoard()) {
add(event.getItem());
}
} }
} }

View File

@ -6,12 +6,17 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.simsilica.lemur.Axis; import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.HAlignment; import com.simsilica.lemur.HAlignment;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.HAlignment;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.component.SpringGridLayout;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
@ -20,10 +25,12 @@ import pp.monopoly.notification.Sound;
* Constructs the startup menu dialog for the Monopoly application. * Constructs the startup menu dialog for the Monopoly application.
import pp.monopoly.client.gui.GameMenu; import pp.monopoly.client.gui.GameMenu;
*/ */
*/
public class StartMenu extends Dialog { public class StartMenu extends Dialog {
private final MonopolyApp app; private final MonopolyApp app;
/** /**
* Constructs the Startup Menu dialog for the Monopoly application.
* Constructs the Startup Menu dialog for the Monopoly application. * Constructs the Startup Menu dialog for the Monopoly application.
* *
* @param app the MonopolyApp instance * @param app the MonopolyApp instance
@ -41,8 +48,10 @@ public class StartMenu extends Dialog {
Geometry background = new Geometry("Background", quad); Geometry background = new Geometry("Background", quad);
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
backgroundMaterial.setTexture("ColorMap", backgroundImage); backgroundMaterial.setTexture("ColorMap", backgroundImage);
backgroundMaterial.setTexture("ColorMap", backgroundImage);
background.setMaterial(backgroundMaterial); background.setMaterial(backgroundMaterial);
background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
app.getGuiNode().attachChild(background); app.getGuiNode().attachChild(background);
// Center container for title and play button // Center container for title and play button

View File

@ -0,0 +1,80 @@
package pp.monopoly.client.gui;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.system.JmeCanvasContext;
import com.jme3.system.AppSettings;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class TestWorldWithMenu extends SimpleApplication {
public static void createAndShowGUI() {
// Create JFrame
JFrame frame = new JFrame("Test World with Menu");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setSize(800, 600);
// Create Menu Bar
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem exitItem = new JMenuItem(new AbstractAction("Exit") {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
fileMenu.add(exitItem);
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
// Create Canvas for jMonkey
AppSettings settings = new AppSettings(true);
settings.setWidth(800);
settings.setHeight(600);
TestWorldWithMenu app = new TestWorldWithMenu();
app.setSettings(settings);
app.createCanvas(); // Create a canvas for embedding
JmeCanvasContext ctx = (JmeCanvasContext) app.getContext();
ctx.setSystemListener(app);
Canvas canvas = ctx.getCanvas();
canvas.setSize(800, 600);
// Add the canvas to JFrame
frame.add(canvas, BorderLayout.CENTER);
// Show the frame
frame.setVisible(true);
// Start the jMonkeyEngine application
app.startCanvas();
}
@Override
public void simpleInitApp() {
// Erstelle ein Quadrat
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat für die Textur
Geometry geom = new Geometry("Box", box);
// Setze das Material mit Textur
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Texture texture = assetManager.loadTexture("Pictures/board.png"); // Replace with the path to your image
mat.setTexture("ColorMap", texture);
geom.setMaterial(mat);
// Füge das Quadrat zur Szene hinzu
rootNode.attachChild(geom);
// Setze die Kameraposition, um das Quadrat zu fokussieren
cam.setLocation(new Vector3f(0, 0, 3)); // Kamera auf der Z-Achse, nah am Quadrat
cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
}
}

View File

@ -1,26 +1,25 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.notification; package pp.monopoly.notification;
/** /**
* Event when an item is added to a map. * Event when a sound needs to be played.
* *
* @param sound the sound to be played * @param soundFileName the sound file to be played
*/ */
public record SoundEvent(Sound sound) implements GameEvent { public class SoundEvent implements GameEvent {
private final String soundFileName;
public SoundEvent(Sound sound) {
this.soundFileName = sound.getFileName(); // Angenommen, Sound hat eine Methode getFileName()
}
public String getSoundFileName() {
return soundFileName;
}
/**
* Notifies the game event listener of this event.
*
* @param listener the game event listener
*/
@Override @Override
public void notifyListener(GameEventListener listener) { public void notifyListener(GameEventListener listener) {
listener.receivedEvent(this); listener.receivedEvent(this);
} }
} }