added very basic splash effect

This commit is contained in:
Yvonne Schmidt 2024-10-13 18:59:18 +02:00
parent 1288d6d1ca
commit 0e5ffcc501
7 changed files with 76 additions and 19 deletions

View File

@ -8,7 +8,6 @@
package pp.battleship.client.gui; package pp.battleship.client.gui;
import com.jme3.effect.ParticleEmitter; import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.effect.ParticleMesh.Type; import com.jme3.effect.ParticleMesh.Type;
import com.jme3.effect.shapes.EmitterSphereShape; import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.material.Material; import com.jme3.material.Material;
@ -16,7 +15,6 @@ import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
@ -29,12 +27,9 @@ import pp.battleship.model.Rotation;
import pp.battleship.model.ShipMap; import pp.battleship.model.ShipMap;
import pp.battleship.model.Shot; import pp.battleship.model.Shot;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static pp.util.FloatMath.HALF_PI; import static pp.util.FloatMath.HALF_PI;
import static pp.util.FloatMath.PI; import static pp.util.FloatMath.PI;
import static pp.util.FloatMath.QUARTER_PI;
/** /**
* The {@code SeaSynchronizer} class is responsible for synchronizing the graphical * The {@code SeaSynchronizer} class is responsible for synchronizing the graphical
@ -153,6 +148,10 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return roundspark; return roundspark;
} }
/**
* Creates small, thin smoke trails that enhance the flying debris
* @return crates a thin smoke trail texture
*/
private ParticleEmitter createSpark(){ private ParticleEmitter createSpark(){
spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR); spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR);
spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F)); spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, 1.0f / COUNT_FACTOR_F));
@ -176,7 +175,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
} }
/** /**
* creates a dynamic smoke trail * Creates a dynamic smoke trail
* @return smoke texture * @return smoke texture
*/ */
private ParticleEmitter createSmokeTrail(){ private ParticleEmitter createSmokeTrail(){
@ -236,7 +235,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
} }
/** /**
* creates an expanding circular shockwave * Creates an expanding circular shockwave
* @return shockwave texture * @return shockwave texture
*/ */
private ParticleEmitter createShockwave(){ private ParticleEmitter createShockwave(){
@ -266,10 +265,9 @@ class SeaSynchronizer extends ShipMapSynchronizer {
} }
/** /**
* creates an animated smoke column * Creates an animated smoke column.
* @return moving smoke texture * @return moving smoke texture
*/ */
private ParticleEmitter createMovingSmokeEmitter() { private ParticleEmitter createMovingSmokeEmitter() {
ParticleEmitter smokeEmitter = new ParticleEmitter("SmokeEmitter", Type.Triangle, 300); ParticleEmitter smokeEmitter = new ParticleEmitter("SmokeEmitter", Type.Triangle, 300);
smokeEmitter.setGravity(0, 0, 0); smokeEmitter.setGravity(0, 0, 0);
@ -287,8 +285,38 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return smokeEmitter; return smokeEmitter;
} }
/**
* Creates a small burst of bubbles.
*
* @return bubbling water texture.
*/
public ParticleEmitter createWaterSplash() {
ParticleEmitter waterSplash = new ParticleEmitter("WaterSplash", Type.Triangle, 30);
waterSplash.setShape(new EmitterSphereShape(Vector3f.ZERO, 0.2f));
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
waterSplash.setStartSize(0.05f);
waterSplash.setEndSize(0.1f);
waterSplash.setLowLife(0.5f);
waterSplash.setHighLife(1f);
waterSplash.setGravity(0, 0, 0); // No gravity to simulate a horizontal water splash
waterSplash.getParticleInfluencer().setInitialVelocity(new Vector3f(1f, 0f, 1f)); // Horizontal spread
waterSplash.getParticleInfluencer().setVelocityVariation(1f); // Add randomness to splash
waterSplash.setParticlesPerSec(0);
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;
}
/** /**
* Constructs a {@code SeaSynchronizer} object with the specified application, root node, and ship map. * Constructs a {@code SeaSynchronizer} object with the specified application, root node, and ship map.
@ -314,7 +342,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
*/ */
@Override @Override
public Spatial visit(Shot shot) { public Spatial visit(Shot shot) {
return shot.isHit() ? handleHit(shot) : createCylinder(shot); return shot.isHit() ? handleHit(shot) : handleMiss(shot);
} }
/** /**
@ -382,6 +410,25 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return null; return null;
} }
/**
* 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 = createWaterSplash();
waterSplash.setLocalTranslation(shot.getY() + 0.5f, 0f, shot.getX() + 0.5f);
shotNode.attachChild(waterSplash);
waterSplash.emitAllParticles();
return shotNode;
}
/** /**
* Creates a cylinder geometry representing the specified shot. * Creates a cylinder geometry representing the specified shot.
* The appearance of the cylinder depends on whether the shot is a hit or a miss. * The appearance of the cylinder depends on whether the shot is a hit or a miss.
@ -447,12 +494,6 @@ class SeaSynchronizer extends ShipMapSynchronizer {
} }
} }
/** /**
* Creates a simple box to represent a battleship that is not of the "King George V" type. * Creates a simple box to represent a battleship that is not of the "King George V" type.
* *
@ -493,7 +534,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
* Creates a detailed 3D model to represent a "King George V" battleship. * Creates a detailed 3D model to represent a "King George V" battleship.
* *
* @param ship the battleship to be represented * @param ship the battleship to be represented
* @return the spatial representing the "King George V" battleship * @return the spatial representing the "King George V" battleship.
*/ */
private Spatial createBattleship(Battleship ship) { private Spatial createBattleship(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(KING_GEORGE_V_MODEL); final Spatial model = app.getAssetManager().loadModel(KING_GEORGE_V_MODEL);
@ -505,6 +546,12 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return model; return model;
} }
/**
* Creates a detailed 3D model to represent a small tugboat.
*
* @param ship the battleship to be represented
* @return the spatial representing the small tugboat.
*/
private Spatial createSmallShip(Battleship ship) { private Spatial createSmallShip(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(SMALL_BOAT_MODEL); final Spatial model = app.getAssetManager().loadModel(SMALL_BOAT_MODEL);
@ -515,6 +562,12 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return model; return model;
} }
/**
* Creates a detailed 3D model to represent a U-Boat .
*
* @param ship the battleship to be represented
* @return the spatial representing the U-Boat.
*/
private Spatial createBattle(Battleship ship) { private Spatial createBattle(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(BATTLE_MODEL); final Spatial model = app.getAssetManager().loadModel(BATTLE_MODEL);
@ -526,6 +579,12 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return model; return model;
} }
/**
* Creates a detailed 3D model to represent an aircraft carrier
*
* @param ship the battleship to be represented
* @return the spatial representing the aircraft carrier.
*/
private Spatial createCV(Battleship ship) { private Spatial createCV(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(CV_MODEL); final Spatial model = app.getAssetManager().loadModel(CV_MODEL);
@ -537,8 +596,6 @@ class SeaSynchronizer extends ShipMapSynchronizer {
return model; return model;
} }
/** /**
* Calculates the rotation angle for the specified rotation. * Calculates the rotation angle for the specified rotation.
* *

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.