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 7a0e6f9b..85af5ae3 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 @@ -158,7 +158,9 @@ else if(boardSelect != null) { gameView.getBoardHandler().movePieceStartAnim(p,0); gameView.getBoardHandler().movePieceAnim(p,0, 8); } else { - gameView.getBoardHandler().throwBombAnim(p); +// gameView.getBoardHandler().throwBombAnim(p); + gameView.getBoardHandler().throwPiece(p,Color.CYBER); + //gameView.getBoardHandler().movePieceStartAnim(p,0); } 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 index fc339041..0117825c 100644 --- 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 @@ -29,6 +29,7 @@ public class JetAnimation { private final float animationDuration; // Dauer der Animation private Explosion explosion; private final UUID id; + private Runnable actionAfter; /** * Konstruktor für die ThrowAnimation-Klasse. @@ -40,7 +41,7 @@ public class JetAnimation { * @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) { + public JetAnimation(MdgaApp app, Node rootNode, UUID uuid, Vector3f targetPoint, float curveHeight, float animationDuration, Runnable actionAfter) { Vector3f spawnPoint = targetPoint.add(170, 50, 50); Vector3f controlPoint = targetPoint.add(new Vector3f(0, 0, -45)); @@ -58,6 +59,7 @@ public JetAnimation(MdgaApp app, Node rootNode, UUID uuid, Vector3f targetPoint, id = uuid; explosion = new Explosion(app, rootNode, nodePoint); + this.actionAfter = actionAfter; } /** @@ -120,10 +122,7 @@ protected void controlUpdate(float tpf) { } if (elapsedTime > 6.0f) { - GameView gameView = (GameView) app.getView(); - BoardHandler boardHandler = gameView.getBoardHandler(); - - boardHandler.throwPieceAnim(id); + endAnim(); } } @@ -134,6 +133,10 @@ protected void controlRender(RenderManager rm, ViewPort vp) { }); } + private void endAnim(){ + actionAfter.run(); + } + /** * Repräsentiert eine 3D-Bezier-Kurve mit vier Kontrollpunkten. */ diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MatrixAnimation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MatrixAnimation.java new file mode 100644 index 00000000..c0110319 --- /dev/null +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MatrixAnimation.java @@ -0,0 +1,98 @@ +package pp.mdga.client.animation; + +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.material.Material; +import com.jme3.material.RenderState; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import pp.mdga.client.InitControl; +import pp.mdga.client.MdgaApp; +import pp.mdga.client.acoustic.MdgaSound; + +import java.util.Random; +import java.util.Vector; + +public class MatrixAnimation extends InitControl { + private MdgaApp app; + private static final Random RANDOM = new Random(); + + public MatrixAnimation(MdgaApp app){ + this.app = app; + } + + @Override + protected void initSpatial() { + + for(int i = 0; i < 5; i++){ + particleStream( + generateMatrixColor(), + generateMatrixColor(), + getRandomFloat(0,1f), + getRandomPosition(), + getRandomFloat(1,2) + ); + } + } + + @Override + protected void controlUpdate(float tpf) { + } + + private void particleStream(ColorRGBA start, ColorRGBA end, float speedVar, Vector3f pos, float spawnVar){ + Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md"); + mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); + mat.setTexture("Texture", app.getAssetManager().loadTexture("Images/particle/particle_cir.png")); + ParticleEmitter matrix = new ParticleEmitter("Effect", Type.Triangle, 50); + matrix.setMaterial(mat); + matrix.setImagesX(2); // columns + matrix.setImagesY(1); // rows + matrix.setSelectRandomImage(true); + matrix.setStartColor(start); + matrix.setEndColor(end); + matrix.getParticleInfluencer().setInitialVelocity(new Vector3f(0f, 0f, -4f - speedVar)); + matrix.getParticleInfluencer().setVelocityVariation(0f); + matrix.setStartSize(0.4f); + matrix.setEndSize(0.6f); + matrix.setGravity(0, 0, 0f); + matrix.setLowLife(3f); + matrix.setHighLife(3f); + matrix.setLocalTranslation(pos.add(new Vector3f(0,0,15))); + matrix.setParticlesPerSec(spawnVar); + app.getRootNode().attachChild(matrix); + } + + public static Vector3f getRandomPosition() { + // Generate a random angle in radians (0 to 2π) + float angle = (float) (2 * Math.PI * RANDOM.nextDouble()); + + // Generate a random radius with uniform distribution + float radius = (float) Math.sqrt(RANDOM.nextDouble()); + radius *= 1f; + + // Convert polar coordinates to Cartesian + float x = radius * (float) Math.cos(angle); + float y = radius * (float) Math.sin(angle); + + return new Vector3f(x,y,0); + } + + public static float getRandomFloat(float start, float end) { + if (start > end) { + throw new IllegalArgumentException("Start must be less than or equal to end."); + } + return start + RANDOM.nextFloat() * (end - start); + } + + public static ColorRGBA generateMatrixColor() { + // Red is dominant + float red = 0.8f + RANDOM.nextFloat() * 0.2f; // Red channel: 0.8 to 1.0 + // Green is moderately high + float green = 0.4f + RANDOM.nextFloat() * 0.3f; // Green channel: 0.4 to 0.7 + // Blue is minimal + float blue = RANDOM.nextFloat() * 0.2f; // Blue channel: 0.0 to 0.2 + float alpha = 1.0f; // Fully opaque + + return new ColorRGBA(red, green, blue, alpha); + } +} 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 318932e8..0cbbdff3 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 @@ -1,6 +1,8 @@ package pp.mdga.client.board; import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.post.FilterPostProcessor; import com.jme3.renderer.queue.RenderQueue; @@ -10,6 +12,7 @@ import pp.mdga.client.Asset; import pp.mdga.client.MdgaApp; import pp.mdga.client.acoustic.MdgaSound; +import pp.mdga.client.animation.MatrixAnimation; import pp.mdga.client.animation.MoveControl; import pp.mdga.client.animation.JetAnimation; import pp.mdga.client.gui.DiceControl; @@ -188,6 +191,9 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) { model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(texName)); + mat.setColor("Diffuse", new ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f)); // Example: set 50% transparency (alpha = 0.5) + mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); // Enable alpha blending +// mat.getAdditionalRenderState().setDepthWrite(false); model.setMaterial(mat); rootNodeBoard.attachChild(model); @@ -726,18 +732,45 @@ public void throwPieceAnim(UUID uuid){ ); } + public void throwPiece(UUID uuid, Color throwColor){ + switch(throwColor){ + case ARMY -> throwShell(uuid); + case NAVY -> throwMissle(uuid); + case CYBER -> throwMatrix(uuid); + case AIRFORCE -> throwBomb(uuid); + default -> throw new RuntimeException("invalid color"); + } + } + /** * 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){ + private void throwBomb(UUID uuid) { Vector3f targetPoint = pieces.get(uuid).getLocation(); - JetAnimation anim = new JetAnimation(app, rootNode, uuid, targetPoint, 40, 6); + JetAnimation anim = new JetAnimation(app, rootNode, uuid, targetPoint, 40, 6, ()->throwPieceAnim(uuid)); anim.start(); } + private void throwMatrix(UUID uuid) { + pieces.get(uuid).getSpatial().addControl(new MatrixAnimation(app)); + } + + private void throwMissle(UUID uuid) { + + } + + private void throwShell(UUID uuid) { + + } + + + public void throwBombAnim(UUID uuid){ + + } + /** * Animates the swapping of two pieces by swapping their positions and rotations. * diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java index 4a75533d..87da54ee 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java @@ -141,7 +141,7 @@ public void initSpatial(){ } public void rotateInit() { -// rotate(rotation - initRotation); + setRotation(initRotation); } /** @@ -278,4 +278,5 @@ public boolean isSelectable() { public void setHoverable(boolean hoverable) { this.hoverable = hoverable; } + } 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 973327c2..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 @@ -48,6 +48,7 @@ public GameView(MdgaApp app) { @Override public void onEnter() { + setOwnColor(Color.AIRFORCE); camera.init(ownColor); boardHandler.init(); guiHandler.init(ownColor); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java index 5bb880d7..4d784014 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java @@ -42,7 +42,7 @@ protected void handlePowerCard(PlayCardMessage msg){ protected void throwPiece(Piece piece){ logic.getGame().getBoard().getInfield()[logic.getGame().getBoard().getInfieldIndexOfPiece(piece)].clearOccupant(); logic.getGame().getBoard().getPlayerData().get(piece.getColor()).addWaitingPiece(piece); - logic.addNotification(new ThrowPieceNotification(piece.getUuid())); +// logic.addNotification(new ThrowPieceNotification(piece.getUuid())); logic.getGame().getPlayerByColor(piece.getColor()).getPlayerStatistic().increasePiecesBeingThrown(); logic.getGame().getGameStatistics().increasePiecesBeingThrown(); piece.setState(PieceState.WAITING); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/ThrowPieceNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/ThrowPieceNotification.java index 9b0ddd28..208266a4 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/notification/ThrowPieceNotification.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/ThrowPieceNotification.java @@ -1,5 +1,7 @@ package pp.mdga.notification; +import pp.mdga.game.Color; + import java.util.UUID; /** @@ -10,12 +12,14 @@ public class ThrowPieceNotification extends Notification { * The id of the piece that was thrown. */ private final UUID pieceId; + private final Color throwColor; /** * This constructor is used to create a new ThrowPieceNotification */ - public ThrowPieceNotification(UUID pieceId) { + public ThrowPieceNotification(UUID pieceId, Color throwColor) { this.pieceId = pieceId; + this.throwColor = throwColor; } /** @@ -26,4 +30,8 @@ public ThrowPieceNotification(UUID pieceId) { public UUID getPieceId() { return pieceId; } + + public Color getThrowColor() { + return throwColor; + } }