Würfel animation hinzugefügt

This commit is contained in:
Luca Puderbach 2024-11-28 00:13:32 +01:00
parent c346058631
commit 4079c0a32c
2 changed files with 144 additions and 151 deletions

View File

@ -1,19 +1,12 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.simsilica.lemur.Axis; import com.simsilica.lemur.*;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.HAlignment;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.VAlignment;
import com.simsilica.lemur.component.IconComponent; import com.simsilica.lemur.component.IconComponent;
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.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
@ -27,11 +20,7 @@ import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
import pp.monopoly.notification.UpdatePlayerView; import pp.monopoly.notification.UpdatePlayerView;
/** public class Toolbar extends Dialog implements GameEventListener {
* Toolbar Klasse, die am unteren Rand der Szene angezeigt wird.
* Die Buttons bewegen den Würfel auf dem Spielfeld.
*/
public class Toolbar extends Dialog implements GameEventListener{
private final MonopolyApp app; private final MonopolyApp app;
private final Container toolbarContainer; private final Container toolbarContainer;
@ -40,13 +29,9 @@ public class Toolbar extends Dialog implements GameEventListener{
private Container overviewContainer; private Container overviewContainer;
private Container accountContainer; private Container accountContainer;
private PlayerHandler playerHandler; private PlayerHandler playerHandler;
private volatile boolean animatingDice = false;
private volatile DiceRollEvent latestDiceRollEvent = null;
/**
* Konstruktor für die Toolbar.
*
* @param app Die Hauptanwendung (MonopolyApp)
*/
public Toolbar(MonopolyApp app) { public Toolbar(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
@ -56,110 +41,80 @@ public class Toolbar extends Dialog implements GameEventListener{
// Erstelle die Toolbar // Erstelle die Toolbar
toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar"); toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
toolbarContainer.setLocalTranslation(0, 200, 0);
toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0));
// Setze die Position am unteren Rand und die Breite // Account- und Übersichtskontainer
toolbarContainer.setLocalTranslation(
0, // Links bündig
200, // Höhe über dem unteren Rand
0 // Z-Ebene
);
toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0)); // Volle Breite
// Menü-Container: Ein Nested-Container für Kontostand und "Meine Gulag Frei Karten"
accountContainer = toolbarContainer.addChild(new Container()); accountContainer = toolbarContainer.addChild(new Container());
// Menü-Container: Ein Container für Übersicht
overviewContainer = toolbarContainer.addChild(new Container()); overviewContainer = toolbarContainer.addChild(new Container());
receivedEvent(new UpdatePlayerView()); receivedEvent(new UpdatePlayerView());
overviewContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); overviewContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Menü-Container: Ein Container für Würfel // Würfelbereich
Container diceContainer = toolbarContainer.addChild(new Container()); Container diceContainer = toolbarContainer.addChild(new Container());
diceContainer.setLayout(new SpringGridLayout(Axis.X, Axis.Y)); diceContainer.setLayout(new SpringGridLayout(Axis.X, Axis.Y));
// Create a horizontal container to align leftContainer and rightContainer side by side
Container horizontalContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y)); Container horizontalContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
horizontalContainer.setPreferredSize(new Vector3f(200, 150, 0)); // Adjust size as needed horizontalContainer.setPreferredSize(new Vector3f(200, 150, 0));
// Create the first container (leftContainer) // Linker Würfel
Container leftContainer = new Container(); Container leftContainer = new Container();
leftContainer.setPreferredSize(new Vector3f(100, 150, 0)); // Adjust size as needed leftContainer.setPreferredSize(new Vector3f(100, 150, 0));
imageLabel = new Label(""); imageLabel = new Label("");
IconComponent icon = new IconComponent("Pictures/dice/one.png"); // Icon mit Textur erstellen IconComponent icon = new IconComponent("Pictures/dice/one.png");
icon.setIconSize(new Vector2f(100,100)); // Skalierung des Bildes icon.setIconSize(new Vector2f(100, 100));
imageLabel.setIcon(icon); imageLabel.setIcon(icon);
imageLabel2 = new Label(""); // Rechter Würfel
IconComponent icon2 = new IconComponent("Pictures/dice/two.png"); // Icon mit Textur erstellen
icon2.setIconSize(new Vector2f(100,100)); // Skalierung des Bildes
imageLabel2.setIcon(icon2);
// Create the second container (rightContainer)
Container rightContainer = new Container(); Container rightContainer = new Container();
rightContainer.setPreferredSize(new Vector3f(100, 150, 0)); // Adjust size as needed rightContainer.setPreferredSize(new Vector3f(100, 150, 0));
leftContainer.setBackground(null); imageLabel2 = new Label("");
rightContainer.setBackground(null); IconComponent icon2 = new IconComponent("Pictures/dice/two.png");
diceContainer.setBackground(null); icon2.setIconSize(new Vector2f(100, 100));
horizontalContainer.setBackground(null); imageLabel2.setIcon(icon2);
imageLabel.setTextVAlignment(VAlignment.Center);
imageLabel.setTextHAlignment(HAlignment.Center);
imageLabel2.setTextVAlignment(VAlignment.Center);
imageLabel2.setTextHAlignment(HAlignment.Center);
leftContainer.addChild(imageLabel); leftContainer.addChild(imageLabel);
rightContainer.addChild(imageLabel2); rightContainer.addChild(imageLabel2);
// Add leftContainer and rightContainer to the horizontal container
horizontalContainer.addChild(leftContainer); horizontalContainer.addChild(leftContainer);
horizontalContainer.addChild(rightContainer); horizontalContainer.addChild(rightContainer);
// Add the horizontalContainer to the diceContainer (top section)
diceContainer.addChild(horizontalContainer); diceContainer.addChild(horizontalContainer);
// Add the Würfeln button directly below the horizontalContainer // Würfeln-Button
Button diceButton = new Button("Würfeln"); Button diceButton = new Button("Würfeln");
diceButton.setPreferredSize(new Vector3f(200, 50, 0)); // Full width for Würfeln button diceButton.setPreferredSize(new Vector3f(200, 50, 0));
diceButton.addClickCommands(s -> ifTopDialog(() -> { diceButton.addClickCommands(s -> ifTopDialog(() -> {
startDiceAnimation();
app.getGameLogic().send(new RollDice()); app.getGameLogic().send(new RollDice());
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
})); }));
diceContainer.addChild(diceButton); diceContainer.addChild(diceButton);
// Menü-Container für weitere Aktionen
// Menü-Container: Ein Nested-Container für Handeln, Grundstücke und Zug beenden
Container menuContainer = toolbarContainer.addChild(new Container()); Container menuContainer = toolbarContainer.addChild(new Container());
menuContainer.addChild(addTradeMenuButton()); menuContainer.addChild(addTradeMenuButton());
menuContainer.addChild(addPropertyMenuButton()); menuContainer.addChild(addPropertyMenuButton());
menuContainer.addChild(addEndTurnButton()); menuContainer.addChild(addEndTurnButton());
menuContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); menuContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Füge die Toolbar zur GUI hinzu
app.getGuiNode().attachChild(toolbarContainer); app.getGuiNode().attachChild(toolbarContainer);
} }
private Button addTradeMenuButton() { private Button addTradeMenuButton() {
Button tradebutton = new Button("Handeln"); Button tradeButton = new Button("Handeln");
tradebutton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons tradeButton.setPreferredSize(new Vector3f(150, 50, 0));
tradebutton.addClickCommands(s -> ifTopDialog( () -> { tradeButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
new ChoosePartner(app).open(); new ChoosePartner(app).open();
})); }));
return tradebutton; return tradeButton;
} }
private Button addPropertyMenuButton() { private Button addPropertyMenuButton() {
Button propertyMenuButton = new Button("Grundstücke"); Button propertyMenuButton = new Button("Grundstücke");
propertyMenuButton.setFontSize(30.0f); propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0));
propertyMenuButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> { propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
new BuildingAdminMenu(app).open(); new BuildingAdminMenu(app).open();
@ -169,7 +124,7 @@ public class Toolbar extends Dialog implements GameEventListener{
private Button addEndTurnButton() { private Button addEndTurnButton() {
Button endTurnButton = new Button("Zug beenden"); Button endTurnButton = new Button("Zug beenden");
endTurnButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons endTurnButton.setPreferredSize(new Vector3f(150, 50, 0));
endTurnButton.addClickCommands(s -> ifTopDialog(() -> { endTurnButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new EndTurn()); app.getGameLogic().send(new EndTurn());
@ -177,29 +132,76 @@ public class Toolbar extends Dialog implements GameEventListener{
return endTurnButton; return endTurnButton;
} }
@Override private void startDiceAnimation() {
public void close() { animatingDice = true;
app.getGuiNode().detachChild(toolbarContainer);
super.close(); // Starte die Animation und speichere die Startzeit
long startTime = System.currentTimeMillis();
Thread diceAnimation = new Thread(() -> {
int[] currentFace = {1};
try {
while (System.currentTimeMillis() - startTime < 2500) { // Animation läuft für 4 Sekunden
currentFace[0] = (currentFace[0] % 6) + 1;
String rotatingImage1 = diceToString(currentFace[0]);
String rotatingImage2 = diceToString((currentFace[0] % 6) + 1);
IconComponent newIcon1 = new IconComponent(rotatingImage1);
newIcon1.setIconSize(new Vector2f(100, 100));
app.enqueue(() -> imageLabel.setIcon(newIcon1));
IconComponent newIcon2 = new IconComponent(rotatingImage2);
newIcon2.setIconSize(new Vector2f(100, 100));
app.enqueue(() -> imageLabel2.setIcon(newIcon2));
// Warte 100 ms, bevor die Bilder wechseln
Thread.sleep(100);
} }
@Override // Animation beenden
public void escape() { animatingDice = false;
new SettingsMenu(app).open();
// Zeige das finale Ergebnis
if (latestDiceRollEvent != null) {
showFinalDiceResult(latestDiceRollEvent);
}
} catch (InterruptedException e) {
System.err.println("Würfelanimation unterbrochen: " + e.getMessage());
}
});
diceAnimation.start();
}
private void showFinalDiceResult(DiceRollEvent event) {
int diceRoll1 = event.a();
int diceRoll2 = event.b();
String finalImage1 = diceToString(diceRoll1);
String finalImage2 = diceToString(diceRoll2);
IconComponent finalIcon1 = new IconComponent(finalImage1);
finalIcon1.setIconSize(new Vector2f(100, 100));
app.enqueue(() -> imageLabel.setIcon(finalIcon1));
IconComponent finalIcon2 = new IconComponent(finalImage2);
finalIcon2.setIconSize(new Vector2f(100, 100));
app.enqueue(() -> imageLabel2.setIcon(finalIcon2));
app.getGameLogic().playSound(Sound.BUTTON);
} }
@Override @Override
public void receivedEvent(DiceRollEvent event) { public void receivedEvent(DiceRollEvent event) {
updateDiceImages(event.a(), event.b()); latestDiceRollEvent = event; // Speichere das Event
} }
@Override @Override
public void receivedEvent(UpdatePlayerView event) { public void receivedEvent(UpdatePlayerView event) {
// Clear existing accountContainer and overviewContainer content
accountContainer.clearChildren(); accountContainer.clearChildren();
overviewContainer.clearChildren(); overviewContainer.clearChildren();
// Update accountContainer
accountContainer.addChild(new Label("Kontostand", new ElementId("label-Bold"))); accountContainer.addChild(new Label("Kontostand", new ElementId("label-Bold")));
accountContainer.addChild(new Label( accountContainer.addChild(new Label(
playerHandler.getPlayerById(app.getId()).getAccountBalance() + " EUR", playerHandler.getPlayerById(app.getId()).getAccountBalance() + " EUR",
@ -212,10 +214,9 @@ public class Toolbar extends Dialog implements GameEventListener{
)); ));
accountContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); accountContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Update overviewContainer
overviewContainer.addChild(new Label("Übersicht", new ElementId("label-Bold"))); overviewContainer.addChild(new Label("Übersicht", new ElementId("label-Bold")));
for (Player player : playerHandler.getPlayers()) { for (Player player : playerHandler.getPlayers()) {
if (player.getId() != app.getId()) { // Skip the current player if (player.getId() != app.getId()) {
overviewContainer.addChild(new Label( overviewContainer.addChild(new Label(
player.getName() + ": " + player.getAccountBalance() + " EUR", player.getName() + ": " + player.getAccountBalance() + " EUR",
new ElementId("label-Text") new ElementId("label-Text")
@ -225,41 +226,33 @@ public class Toolbar extends Dialog implements GameEventListener{
overviewContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); overviewContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
} }
private void updateDiceImages(int a, int b) {
//TODO dice toll animation
IconComponent icon1 = new IconComponent(diceToString(a));
IconComponent icon2 = new IconComponent(diceToString(b));
icon1.setIconSize(new Vector2f(100, 100));
icon2.setIconSize(new Vector2f(100, 100));
imageLabel.setIcon(icon1);
imageLabel2.setIcon(icon2);
}
private String diceToString(int i) { private String diceToString(int i) {
switch (i) { switch (i) {
case 1: case 1:
return "Pictures/dice/one.png"; return "Pictures/dice/one.png";
case 2: case 2:
return "Pictures/dice/two.png"; return "Pictures/dice/two.png";
case 3: case 3:
return "Pictures/dice/three.png"; return "Pictures/dice/three.png";
case 4: case 4:
return "Pictures/dice/four.png"; return "Pictures/dice/four.png";
case 5: case 5:
return "Pictures/dice/five.png"; return "Pictures/dice/five.png";
case 6: case 6:
return "Pictures/dice/six.png"; return "Pictures/dice/six.png";
default: default:
throw new IllegalArgumentException("Invalid dice number: " + i); throw new IllegalArgumentException("Invalid dice number: " + i);
} }
}
@Override
public void close() {
app.getGuiNode().detachChild(toolbarContainer);
super.close();
}
@Override
public void escape() {
new SettingsMenu(app).open();
} }
} }

View File

@ -519,7 +519,7 @@ public class Player implements FieldVisitor<Void>{
@Override @Override
public DiceResult rollDice() { public DiceResult rollDice() {
throw new UnsupportedOperationException("not allowed"); return null;
} }
@Override @Override