From 17409886294aab6d7422ec3c05d4935a8671d2b8 Mon Sep 17 00:00:00 2001 From: Johannes Schmelz Date: Fri, 11 Oct 2024 16:00:15 +0200 Subject: [PATCH] added a miss effect --- .../client/gui/ParticleEffectFactory.java | 42 ++++++++++++++++ .../client/gui/SeaSynchronizer.java | 47 +++++++++++++++--- .../main/resources/Effects/Splash/splash.png | Bin 0 -> 16543 bytes 3 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 Projekte/battleship/client/src/main/resources/Effects/Splash/splash.png diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ParticleEffectFactory.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ParticleEffectFactory.java index bd84e85..f0a8364 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ParticleEffectFactory.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ParticleEffectFactory.java @@ -240,4 +240,46 @@ public class ParticleEffectFactory { 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; + } } diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java index a328cc2..fc2a538 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java @@ -75,16 +75,33 @@ class SeaSynchronizer extends ShipMapSynchronizer { */ @Override 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 = particleFactory.createWaterSplash(); + waterSplash.setLocalTranslation(shot.getY() + 0.5f, 0f, shot.getX() + 0.5f); + shotNode.attachChild(waterSplash); + waterSplash.emitAllParticles(); + + return shotNode; + } + + /** * 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. * * @param shot a hit - * @return always null to prevent the representation from being attached - * to the items node as well + * @return always null to prevent the representation from being attached to the items node as well */ private Spatial handleHit(Shot shot) { final Battleship ship = requireNonNull(map.findShipAt(shot), "Missing ship"); @@ -131,7 +148,7 @@ class SeaSynchronizer extends ShipMapSynchronizer { shockwave.emitAllParticles(); flame.emitAllParticles(); roundSpark.emitAllParticles(); - + return null; } @@ -246,7 +263,13 @@ class SeaSynchronizer extends ShipMapSynchronizer { return model; } - + + /** + * Creates a detailed 3D model to represent a small tug boat. + * + * @param ship the battleship to be represented + * @return the spatial representing a small tug boat + */ private Spatial createSmallship(Battleship ship) { final Spatial model = app.getAssetManager().loadModel(BOAT_SMALL_MODEL); @@ -257,6 +280,12 @@ class SeaSynchronizer extends ShipMapSynchronizer { return model; } + /** + * Creates a detailed 3D model to represent a "German WWII UBoat". + * + * @param ship the battleship to be represented + * @return the spatial representing the "German WWII UBoat" + */ private Spatial createCV(Battleship ship) { final Spatial model = app.getAssetManager().loadModel(CV_MODEL); @@ -268,6 +297,12 @@ class SeaSynchronizer extends ShipMapSynchronizer { return model; } + /** + * Creates a detailed 3D model to represent a battleship. + * + * @param ship the battleship to be represented + * @return the spatial representing a battleship + */ private Spatial createBattle(Battleship ship) { final Spatial model = app.getAssetManager().loadModel(BATTLE_MODEL); diff --git a/Projekte/battleship/client/src/main/resources/Effects/Splash/splash.png b/Projekte/battleship/client/src/main/resources/Effects/Splash/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..62856bd1c47142df06262d43d3092d62fe227adf GIT binary patch literal 16543 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 T^I~=2`2h@`u6{1-oD!M