diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java index e0f657da..0ae281c7 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java @@ -40,6 +40,11 @@ public class InputSynchronizer { private CardControl hoverCard; private PieceControl hoverPiece; + private boolean clickAllowed = true; + + private boolean isRotateLeft = false; + private boolean isRotateRight = false; + /** * Constructor initializes the InputSynchronizer with the application context. * Sets up input mappings and listeners for user interactions. @@ -55,6 +60,18 @@ public class InputSynchronizer { setupInput(); } + public void update(float tpf) { + if(isRotateLeft && isRotateRight) { + return; + } + if(isRotateLeft) { + rotationAngle += 180 * tpf; + } + if(isRotateRight) { + rotationAngle -= 180 * tpf; + } + } + /** * Configures input mappings for various actions and binds them to listeners. */ @@ -62,22 +79,22 @@ private void setupInput() { inputManager.addMapping("Settings", new KeyTrigger(KeyInput.KEY_ESCAPE)); inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_RETURN)); + inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_Q)); + inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_E)); + inputManager.addMapping("RotateRightMouse", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); inputManager.addMapping("MouseLeft", new MouseAxisTrigger(MouseInput.AXIS_X, false)); // Left movement inputManager.addMapping("MouseRight", new MouseAxisTrigger(MouseInput.AXIS_X, true)); // Right movement - inputManager.addMapping("MouseVertical", new MouseAxisTrigger(MouseInput.AXIS_Y, false), new MouseAxisTrigger(MouseInput.AXIS_Y, true)); //Mouse Up Down movement inputManager.addMapping("MouseScrollUp", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false)); // Scroll up inputManager.addMapping("MouseScrollDown", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)); // Scroll down inputManager.addMapping("Test", new KeyTrigger(KeyInput.KEY_J)); inputManager.addMapping("Click", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); - inputManager.addListener(actionListener, "Settings", "Forward", "RotateRightMouse", "Click", "Test"); + inputManager.addListener(actionListener, "Settings", "Forward", "RotateRightMouse", "Click", "Left", "Right", "Test"); inputManager.addListener(analogListener, "MouseLeft", "MouseRight", "MouseScrollUp", "MouseScrollDown"); } - - private boolean test = false; - + UUID p = null; /** * Handles action-based input events such as key presses and mouse clicks. */ @@ -94,6 +111,10 @@ public void onAction(String name, boolean isPressed, float tpf) { rightMousePressed = isPressed; } if(name.equals("Click") && isPressed) { + if(!clickAllowed) { + return; + } + if (app.getView() instanceof GameView gameView) { DiceControl diceSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), DiceControl.class); CardControl cardLayerSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), CardControl.class); @@ -122,8 +143,25 @@ else if(boardSelect != null) { } - if(name.equals("Test") &&isPressed){ + if (name.equals("Left")) { + isRotateLeft = !isRotateLeft; + } + if (name.equals("Right")) { + isRotateRight = !isRotateRight; + } + if(name.equals("Testx") &&isPressed){ if(app.getView() instanceof GameView gameView){ + + if(p == null) { + p = UUID.randomUUID(); + gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID())); + gameView.getBoardHandler().movePieceStartAnim(p,0); + gameView.getBoardHandler().movePieceAnim(p,0, 8); + } else { + gameView.getBoardHandler().throwBombAnim(p); + //gameView.getBoardHandler().movePieceStartAnim(p,0); + } + // gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1); // gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2); // gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3); @@ -133,9 +171,9 @@ else if(boardSelect != null) { // gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p1,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID())); // gameView.getBoardHandler().movePieceStartAnim(p1,0); - gameView.getGuiHandler().drawCard(Color.ARMY); - gameView.getGuiHandler().addCardOwn(BonusCard.SHIELD); - gameView.getGuiHandler().playCardOwn(BonusCard.SHIELD); + //gameView.getGuiHandler().drawCard(Color.ARMY); + //gameView.getGuiHandler().addCardOwn(BonusCard.SHIELD); + //gameView.getGuiHandler().playCardOwn(BonusCard.SHIELD); @@ -313,4 +351,12 @@ public void setRotation(float rotationAngle){ public int getScroll() { return scrollValue; } + + public void setClickAllowed(boolean allowed) { + clickAllowed = allowed; + } + + public boolean isClickAllowed() { + return clickAllowed; + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java index 69f35012..29ee28ca 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java @@ -9,7 +9,7 @@ import pp.mdga.client.view.*; import javax.imageio.ImageIO; -import java.awt.GraphicsEnvironment; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -48,16 +48,16 @@ public class MdgaApp extends SimpleApplication { private final float imageScale = prefs.getInt("scale", 1); /** The main menu view. */ - private MdgaView mainView; + private MainView mainView; /** The lobby view. */ - private MdgaView lobbyView; + private LobbyView lobbyView; /** The game view. */ - private MdgaView gameView; + private GameView gameView; /** The ceremony view. */ - private MdgaView ceremonyView; + private CeremonyView ceremonyView; /** The client game logic. */ private final ClientGameLogic clientGameLogic; @@ -80,16 +80,29 @@ public MdgaApp() { public static void main(String[] args) { AppSettings settings = new AppSettings(true); settings.setSamples(128); - settings.setWidth(prefs.getInt("width", 1280)); - settings.setHeight(prefs.getInt("height", 720)); - settings.setFullscreen(prefs.getBoolean("fullscreen", false)); + + if(prefs.getBoolean("fullscreen", false)) { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + int screenWidth = (int) screenSize.getWidth(); + int screenHeight = (int) screenSize.getHeight(); + + settings.setResolution(screenWidth, screenHeight); + + settings.setFullscreen(true); + } else { + settings.setWidth(prefs.getInt("width", 1280)); + settings.setHeight(prefs.getInt("height", 720)); + } + settings.setCenterWindow(true); settings.setVSync(false); settings.setTitle("MDGA"); + settings.setVSync(true); MdgaApp app = new MdgaApp(); app.setSettings(settings); app.setShowSettings(false); app.setPauseOnLostFocus(false); + app.setDisplayStatView(false); app.start(); } @@ -115,7 +128,7 @@ public void simpleInitApp() { gameView = new GameView(this); ceremonyView = new CeremonyView(this); - enter(MdgaState.GAME); + enter(MdgaState.MAIN); } /** @@ -128,6 +141,7 @@ public void simpleUpdate(float tpf) { view.update(tpf); acousticHandler.update(); notificationSynchronizer.update(); + inputSynchronizer.update(tpf); } /** @@ -262,6 +276,10 @@ public void updateResolution(int width, int height, float imageFactor, boolean i float scaleFactor = Math.max((float) width / baseWidth, (float) height / baseHeight); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + int screenWidth = (int) screenSize.getWidth(); + int screenHeight = (int) screenSize.getHeight(); + settings.setResolution(screenWidth, screenHeight); settings.setFullscreen(true); prefs.putFloat("scale", scaleFactor); @@ -297,6 +315,8 @@ public void afterGameCleanup() { main.getJoinDialog().disconnect(); main.getHostDialog().shutdownServer(); + + ceremonyView.afterGameCleanup(); } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java index 0b26a305..429b9ade 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java @@ -145,4 +145,8 @@ public void enter(MdgaState state) { public void setSwap(boolean swap){ this.swap = swap; } + + public void force() { + + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java index cc7dd0ee..19606bf8 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java @@ -19,11 +19,6 @@ public class NotificationSynchronizer { this.app = app; } - public void addTestNotification(Notification n) { - notifications.add(n); - handleGame(n); - } - public void update() { Notification n = app.getGameLogic().getNotification(); while (n != null) { @@ -153,7 +148,7 @@ private void handleGame(Notification notification) { boardHandler.addPlayer(n.getColor(),n.getPiecesList()); guiHandler.addPlayer(n.getColor(),n.getName()); } else if (notification instanceof ResumeNotification) { - //ignore + //TODO } else if (notification instanceof RollDiceNotification n) { gameView.getGuiHandler().hideText(); if(n.getColor() == gameView.getOwnColor()){ diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java index 264197d4..447bddb4 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java @@ -109,6 +109,13 @@ public void playSound(MdgaSound sound) { case LEAVE: assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND2, 0.6f, 0.0f)); break; + case JET: + assets.add(new SoundAssetDelayVolume(SoundAsset.JET, 1.0f, 0.0f)); + break; + case EXPLOSION: + assets.add(new SoundAssetDelayVolume(SoundAsset.EXP, 1.0f, 4f)); + assets.add(new SoundAssetDelayVolume(SoundAsset.THUNDER, 1.0f, 4f)); + break; default: break; } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/MdgaSound.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/MdgaSound.java index 78898155..9bdfb54b 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/MdgaSound.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/MdgaSound.java @@ -31,4 +31,6 @@ public enum MdgaSound { OTHER_CONNECTED, NOT_READY, LEAVE, + JET, + EXPLOSION, } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/SoundAsset.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/SoundAsset.java index 24497300..ce90d750 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/SoundAsset.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/SoundAsset.java @@ -28,6 +28,9 @@ enum SoundAsset { POWERUP("powerup.wav"), ROBOT_READY("robotReady.wav"), UNIT_READY("unitReady.wav"), + JET("jet-overhead.wav"), + EXP("exp.ogg"), + THUNDER("thunder.ogg"), CONNECTED("connected.wav"); private final String path; diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Explosion.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Explosion.java new file mode 100644 index 00000000..4fb01568 --- /dev/null +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Explosion.java @@ -0,0 +1,126 @@ +package pp.mdga.client.animation; + +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.control.AbstractControl; +import pp.mdga.client.MdgaApp; + +public class Explosion { + + private final Node rootNode; + private final MdgaApp app; + private final Vector3f location; + private ParticleEmitter fire; + private ParticleEmitter smoke; + + private boolean triggered = false; + + private final Material mat; + + /** + * Konstruktor für die Explosion. + * + * @param app Die Hauptanwendung. + * @param rootNode Der Root-Knoten, an den die Explosion angefügt wird. + * @param location Der Ort der Explosion in World-Koordinaten. + */ + public Explosion(MdgaApp app, Node rootNode, Vector3f location) { + this.app = app; + this.rootNode = rootNode; + this.location = location; + + this.mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md"); + mat.getAdditionalRenderState().setDepthWrite(false); + mat.getAdditionalRenderState().setDepthTest(false); + } + + /** + * Initialisiert den Partikel-Emitter für die Explosion. + */ + private void initializeEmitter() { + fire = new ParticleEmitter("Effect", Type.Triangle,50); + fire.setMaterial(mat); + fire.setStartColor(ColorRGBA.Yellow); + fire.setEndColor(ColorRGBA.Red); + fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0.2f,0.2f,4f)); + fire.getParticleInfluencer().setVelocityVariation(0.4f); + fire.setStartSize(0.1f); + fire.setEndSize(0.8f); + fire.setGravity(0, 0, -0.1f); + fire.setLowLife(0.5f); + fire.setHighLife(2.2f); + fire.setParticlesPerSec(0); + + fire.setLocalTranslation(location); + fire.move(0, 0, 45); + + smoke = new ParticleEmitter("Effect2", Type.Triangle,40); + smoke.setMaterial(mat); + smoke.setImagesX(2); + smoke.setImagesY(2); + smoke.setStartColor(ColorRGBA.DarkGray); + smoke.setEndColor(new ColorRGBA(0.05f, 0.05f, 0.05f, 1)); + smoke.getParticleInfluencer().setInitialVelocity(new Vector3f(0.0f,0.0f,0.7f)); + smoke.getParticleInfluencer().setVelocityVariation(0.5f); + smoke.setStartSize(0.2f); + smoke.setEndSize(0.5f); + smoke.setGravity(0, 0, -0.3f); + smoke.setLowLife(1.2f); + smoke.setHighLife(5.5f); + smoke.setParticlesPerSec(0); + + smoke.setLocalTranslation(location); + smoke.move(0, 0, 45); + } + + /** + * Löst die Explosion aus. + */ + public void trigger() { + if (!triggered) { + triggered = true; + initializeEmitter(); + } + + rootNode.attachChild(fire); + fire.emitAllParticles(); + fire.addControl(new AbstractControl() { + private float elapsedTime = 0; + + @Override + protected void controlUpdate(float tpf) { + elapsedTime += tpf; + if (elapsedTime > 10f) { + rootNode.detachChild(fire); + fire.removeControl(this); + } + } + + @Override + protected void controlRender(com.jme3.renderer.RenderManager rm, com.jme3.renderer.ViewPort vp) {} + }); + + rootNode.attachChild(smoke); + smoke.emitAllParticles(); + smoke.addControl(new AbstractControl() { + private float elapsedTime = 0; + + @Override + protected void controlUpdate(float tpf) { + elapsedTime += tpf; + if (elapsedTime > 10f) { + rootNode.detachChild(smoke); + smoke.removeControl(this); + } + } + + @Override + protected void controlRender(com.jme3.renderer.RenderManager rm, com.jme3.renderer.ViewPort vp) {} + }); + } +} + diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/JetAnimation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/JetAnimation.java new file mode 100644 index 00000000..fc339041 --- /dev/null +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/JetAnimation.java @@ -0,0 +1,175 @@ +package pp.mdga.client.animation; + +import com.jme3.material.Material; +import com.jme3.math.FastMath; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.AbstractControl; +import pp.mdga.client.Asset; +import pp.mdga.client.MdgaApp; +import pp.mdga.client.acoustic.MdgaSound; +import pp.mdga.client.board.BoardHandler; +import pp.mdga.client.view.GameView; + +import java.util.UUID; + +public class JetAnimation { + + private final MdgaApp app; // Referenz auf die Hauptanwendung + private final Node rootNode; // Root-Knoten, an dem die Animation hängt + private Spatial jetModel; // Das Model des "jet" + private final Vector3f spawnPoint; // Spawnpunkt des Jets + private final Vector3f nodePoint; // Punkt des überflogenen Knotens + private final Vector3f despawnPoint; // Punkt, an dem der Jet despawnt + private final float curveHeight; // Maximale Höhe der Kurve + private final float animationDuration; // Dauer der Animation + private Explosion explosion; + private final UUID id; + + /** + * Konstruktor für die ThrowAnimation-Klasse. + * + * @param app Die Hauptanwendung + * @param rootNode Der Root-Knoten, an dem der Jet angefügt wird + * @param uuid Die UUID des pieces + * @param targetPoint Der Punkt, an dem der Jet spawnt + * @param curveHeight Die maximale Höhe der Flugkurve + * @param animationDuration Die Gesamtdauer der Animation in Sekunden + */ + public JetAnimation(MdgaApp app, Node rootNode, UUID uuid, Vector3f targetPoint, float curveHeight, float animationDuration) { + Vector3f spawnPoint = targetPoint.add(170, 50, 50); + + Vector3f controlPoint = targetPoint.add(new Vector3f(0, 0, -45)); + + Vector3f despawnPoint = targetPoint.add(-100, -100, 40); + + this.app = app; + this.rootNode = rootNode; + this.spawnPoint = spawnPoint; + this.nodePoint = controlPoint; + this.despawnPoint = despawnPoint; + this.curveHeight = curveHeight; + this.animationDuration = animationDuration; + + id = uuid; + + explosion = new Explosion(app, rootNode, nodePoint); + } + + /** + * Startet die Animation. + */ + public void start() { + app.getAcousticHandler().playSound(MdgaSound.JET); + spawnJet(); + animateJet(); + } + + /** + * Spawnt den Jet an der spezifizierten Position. + */ + private void spawnJet() { + jetModel = app.getAssetManager().loadModel(Asset.jet.getModelPath()); + jetModel.setLocalTranslation(spawnPoint); + jetModel.scale(Asset.jet.getSize()); + jetModel.rotate(FastMath.HALF_PI, 0, 0); + jetModel.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); + Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); + mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(Asset.jet.getDiffPath())); + jetModel.setMaterial(mat); + + rootNode.attachChild(jetModel); + + app.getAcousticHandler().playSound(MdgaSound.EXPLOSION); + } + + /** + * Animiert den Jet entlang einer Kurve und lässt ihn anschließend verschwinden. + */ + private void animateJet() { + Vector3f controlPoint1 = spawnPoint.add(0, curveHeight, 0); + Vector3f controlPoint2 = nodePoint.add(0, curveHeight, 0); + + BezierCurve3f curve = new BezierCurve3f(spawnPoint, controlPoint1, controlPoint2, despawnPoint); + + app.getRootNode().addControl(new AbstractControl() { + private float elapsedTime = 0; + + @Override + protected void controlUpdate(float tpf) { + elapsedTime += tpf; + float progress = elapsedTime / animationDuration; + + if(elapsedTime > 4.2f) { + explosion.trigger(); + } + + if (progress > 1) { + rootNode.detachChild(jetModel); + this.spatial.removeControl(this); + } else { + Vector3f currentPos = curve.interpolate(progress); + Vector3f direction = curve.interpolateDerivative(progress).normalizeLocal(); + jetModel.setLocalTranslation(currentPos); + jetModel.lookAt(currentPos.add(direction), Vector3f.UNIT_Z); + jetModel.rotate(-FastMath.HALF_PI, 0, (float) Math.toRadians(-25)); + } + + if (elapsedTime > 6.0f) { + GameView gameView = (GameView) app.getView(); + BoardHandler boardHandler = gameView.getBoardHandler(); + + boardHandler.throwPieceAnim(id); + } + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + // Wird hier nicht benötigt + } + }); + } + + /** + * Repräsentiert eine 3D-Bezier-Kurve mit vier Kontrollpunkten. + */ + private static class BezierCurve3f { + private final Vector3f p0, p1, p2, p3; + + public BezierCurve3f(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) { + this.p0 = p0; + this.p1 = p1; + this.p2 = p2; + this.p3 = p3; + } + + public Vector3f interpolate(float t) { + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + Vector3f point = p0.mult(uuu); + point = point.add(p1.mult(3 * uu * t)); + point = point.add(p2.mult(3 * u * tt)); + point = point.add(p3.mult(ttt)); + return point; + } + + public Vector3f interpolateDerivative(float t) { + float u = 1 - t; + float tt = t * t; + + Vector3f derivative = p0.mult(-3 * u * u); + derivative = derivative.add(p1.mult(3 * u * u - 6 * u * t)); + derivative = derivative.add(p2.mult(6 * u * t - 3 * tt)); + derivative = derivative.add(p3.mult(3 * tt)); + return derivative; + } + } +} diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java index a00508e8..a63db8ec 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java @@ -10,9 +10,9 @@ import pp.mdga.client.Asset; import pp.mdga.client.MdgaApp; import pp.mdga.client.animation.MoveControl; +import pp.mdga.client.animation.JetAnimation; import pp.mdga.client.gui.DiceControl; import pp.mdga.game.Color; -import pp.mdga.game.Piece; import java.util.*; @@ -720,10 +720,20 @@ public void movePieceStartAnim(UUID uuid, int moveIndex){ */ public void throwPieceAnim(UUID uuid){ pieces.get(uuid).getSpatial().addControl(new MoveControl( - pieces.get(uuid).getLocation(), - getNextWaitingNode(pieceColor.get(uuid)).getLocation(), - ()->throwPiece(uuid) - )); + pieces.get(uuid).getLocation(), getNextWaitingNode(pieceColor.get(uuid)).getLocation(), ()->throwPiece(uuid)) + ); + } + + /** + * Animates the throwing of a piece to the next available waiting node. + * + * @param uuid the UUID of the piece to animate + */ + public void throwBombAnim(UUID uuid){ + Vector3f targetPoint = pieces.get(uuid).getLocation(); + + JetAnimation anim = new JetAnimation(app, rootNode, uuid, targetPoint, 40, 6); + anim.start(); } /** diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/InterruptDialog.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/InterruptDialog.java index 4fd87803..7b8d63e2 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/InterruptDialog.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/InterruptDialog.java @@ -1,4 +1,43 @@ package pp.mdga.client.dialog; -public class InterruptDialog { +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import pp.mdga.client.MdgaApp; +import pp.mdga.client.button.AbstractButton; +import pp.mdga.client.button.ButtonRight; +import pp.mdga.client.button.LabelButton; +import pp.mdga.client.button.MenuButton; +import pp.mdga.client.view.MdgaView; + +public class InterruptDialog extends Dialog { + private ButtonRight forceButton; + + private LabelButton label; + + public InterruptDialog(MdgaApp app, Node node) { + super(app, node); + + forceButton = new ButtonRight(app, node, () -> app.getModelSynchronize().force(), "Erzwingen", 1); + + label = new LabelButton(app, node, "Warte auf Spieler...", new Vector2f(5.5f * 1.5f, 2), new Vector2f(0.5f, 0f), false); + + float offset = 2.8f; + + label.setPos(new Vector2f(0, MenuButton.VERTICAL - offset)); + } + + @Override + protected void onShow() { + if(app.getGameLogic().isHost()) { + forceButton.show(); + } + + label.show(); + } + + @Override + protected void onHide() { + forceButton.hide(); + label.hide(); + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java index ebf21b6a..0f2eacbd 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java @@ -86,7 +86,7 @@ public void render(RenderManager rm) { public void update(float tpf) { if (init && !cardBuffer.isEmpty()) { for (Spatial spatial : cardBuffer) { -// root.attachChild(spatial); + root.attachChild(spatial); } cardBuffer.clear(); } @@ -94,9 +94,8 @@ public void update(float tpf) { } public void addSpatial(Spatial card) { -// cardBuffer.add(card); - root.attachChild(card); - root = root; + if(root == null) cardBuffer.add(card); + else root.attachChild(card); } public void deleteSpatial(Spatial spatial) { diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/CeremonyView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/CeremonyView.java index 31bda387..4c2971a3 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/CeremonyView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/CeremonyView.java @@ -206,11 +206,19 @@ public void addCeremonyParticipant(Color color, int pos, String name) { ceremonyButtons.add(button); if(state.equals(SubState.AWARD_CEREMONY)) { + button.hide(); button.show(); } } public void addStatisticsRow(String name, int v1, int v2, int v3, int v4, int v5, int v6) { ceremonyDialog.addStatisticsRow(name, v1, v2, v3, v4, v5, v6); + + ceremonyDialog.hide(); + ceremonyDialog.show(); + } + + public void afterGameCleanup() { + ceremonyDialog.prepare(); } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java index 60a2be45..cbf9866d 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java @@ -1,31 +1,16 @@ package pp.mdga.client.view; import com.jme3.post.FilterPostProcessor; -import pp.mdga.client.MdgaState; +import com.jme3.scene.Node; import pp.mdga.client.acoustic.MdgaSound; import pp.mdga.client.board.BoardHandler; import pp.mdga.client.board.CameraHandler; import pp.mdga.client.MdgaApp; import pp.mdga.client.button.ButtonLeft; import pp.mdga.client.button.ButtonRight; +import pp.mdga.client.dialog.InterruptDialog; import pp.mdga.client.gui.GuiHandler; -import pp.mdga.game.BonusCard; import pp.mdga.game.Color; -import pp.mdga.notification.AcquireCardNotification; -import pp.mdga.notification.ActivePlayerNotification; -import pp.mdga.notification.DiceNowNotification; -import pp.mdga.notification.GameNotification; -import pp.mdga.notification.MovePieceNotification; -import pp.mdga.notification.PlayerInGameNotification; -import pp.mdga.notification.RollDiceNotification; -import pp.mdga.notification.SelectableCardsNotification; -import pp.mdga.notification.SelectableMoveNotification; -import pp.mdga.notification.SelectableSwapNotification; -import pp.mdga.notification.ShieldActiveNotification; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; public class GameView extends MdgaView { private BoardHandler boardHandler; @@ -37,21 +22,28 @@ public class GameView extends MdgaView { private Color ownColor = null; + private InterruptDialog interruptDialog; + private FilterPostProcessor fpp; + private Node guiHandlerNode = new Node(); + public GameView(MdgaApp app) { super(app); - leaveButton = new ButtonLeft(app, overlayNode, () -> app.getModelSynchronize().leave(), "Spiel verlassen", 1); + leaveButton = new ButtonLeft(app, settingsNode, () -> app.getModelSynchronize().leave(), "Spiel verlassen", 1); confirmButton = new ButtonRight(app, guiNode, () -> app.getModelSynchronize().confirm(), "Bestätigen", 1); + interruptDialog = new InterruptDialog(app, guiNode); + fpp = new FilterPostProcessor(app.getAssetManager()); this.camera = new CameraHandler(app, fpp); this.boardHandler = new BoardHandler(app, rootNode, fpp); - guiHandler = new GuiHandler(app, guiNode); + guiHandler = new GuiHandler(app, guiHandlerNode); + guiNode.attachChild(guiHandlerNode); } @Override @@ -64,14 +56,6 @@ public void onEnter() { app.getViewPort().addProcessor(fpp); app.getAcousticHandler().playSound(MdgaSound.START); - - guiHandler.addPlayer(Color.AIRFORCE, "Cedric"); - guiHandler.addPlayer(Color.ARMY, "Ben"); - guiHandler.addPlayer(Color.CYBER, "Felix"); - guiHandler.addPlayer(Color.NAVY, "Daniel"); - - - } @Override @@ -132,4 +116,26 @@ public void needConfirm() { public void noConfirm() { confirmButton.hide(); } + + public void enterInterrupt() { + enterOverlay(Overlay.INTERRUPT); + + guiNode.detachChild(guiHandlerNode); + app.getGuiNode().attachChild(guiNode); + + app.getInputSynchronize().setClickAllowed(false); + + interruptDialog.show(); + } + + public void leaveInterrupt() { + leaveOverlay(Overlay.INTERRUPT); + + app.getGuiNode().detachChild(guiNode); + guiNode.attachChild(guiHandlerNode); + + app.getInputSynchronize().setClickAllowed(true); + + interruptDialog.hide(); + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java index d5653f6d..abcd674c 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java @@ -1,19 +1,12 @@ package pp.mdga.client.view; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector2f; import com.jme3.scene.Geometry; import pp.mdga.client.MdgaApp; import pp.mdga.client.acoustic.MdgaSound; -import pp.mdga.client.button.AbstractButton; -import pp.mdga.client.button.LabelButton; import pp.mdga.client.dialog.HostDialog; import pp.mdga.client.dialog.JoinDialog; import pp.mdga.client.dialog.StartDialog; -import java.net.Inet4Address; -import java.net.UnknownHostException; - public class MainView extends MdgaView { private enum SubState { HOST, @@ -67,12 +60,12 @@ public void onUpdate(float tpf) { @Override protected void onEnterOverlay(Overlay overlay) { guiNode.detachChild(background); - overlayNode.attachChild(background); + settingsNode.attachChild(background); } @Override protected void onLeaveOverlay(Overlay overlay) { - overlayNode.detachChild(background); + settingsNode.detachChild(background); guiNode.attachChild(background); } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java index e9bb1b65..a16cc2d7 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java @@ -25,7 +25,7 @@ public enum Overlay { protected MdgaApp app; protected Node rootNode = new Node("View Root"); protected Node guiNode = new Node("View Root GUI"); - protected Node overlayNode = new Node("View Root Overlay"); + protected Node settingsNode = new Node("View Root Overlay"); private SettingsButton settingsButton; @@ -42,9 +42,9 @@ public MdgaView(MdgaApp app) { this.app = app; settingsButton = new SettingsButton(app, guiNode, this::enterSettings); - settingsDialog = new SettingsDialog(app, overlayNode, this); - videoSettingsDialog = new VideoSettingsDialog(app, overlayNode, this); - audioSettingsDialog = new AudioSettingsDialog(app, overlayNode, this); + settingsDialog = new SettingsDialog(app, settingsNode, this); + videoSettingsDialog = new VideoSettingsDialog(app, settingsNode, this); + audioSettingsDialog = new AudioSettingsDialog(app, settingsNode, this); } public void enter() { @@ -124,7 +124,7 @@ protected Geometry createBackground(String texturePath) { public void enterSettings() { enterOverlay(Overlay.SETTINGS); - app.getGuiNode().attachChild(overlayNode); + app.getGuiNode().attachChild(settingsNode); settingsDialog.show(); @@ -134,7 +134,7 @@ public void enterSettings() { public void leaveSettings() { leaveOverlay(Overlay.SETTINGS); - app.getGuiNode().detachChild(overlayNode); + app.getGuiNode().detachChild(settingsNode); settingsDialog.hide(); diff --git a/Projekte/mdga/client/src/main/resources/Sounds/exp.ogg b/Projekte/mdga/client/src/main/resources/Sounds/exp.ogg new file mode 100644 index 00000000..b9c570c7 Binary files /dev/null and b/Projekte/mdga/client/src/main/resources/Sounds/exp.ogg differ diff --git a/Projekte/mdga/client/src/main/resources/Sounds/jet-overhead.wav b/Projekte/mdga/client/src/main/resources/Sounds/jet-overhead.wav new file mode 100644 index 00000000..32fcee18 Binary files /dev/null and b/Projekte/mdga/client/src/main/resources/Sounds/jet-overhead.wav differ diff --git a/Projekte/mdga/client/src/main/resources/Sounds/thunder.ogg b/Projekte/mdga/client/src/main/resources/Sounds/thunder.ogg new file mode 100644 index 00000000..db30aaec Binary files /dev/null and b/Projekte/mdga/client/src/main/resources/Sounds/thunder.ogg differ