added MatrixAnimation

This commit is contained in:
Cedric Beck
2024-12-06 17:09:06 +01:00
parent 2ac2de645b
commit 29c6b13300
4 changed files with 225 additions and 15 deletions

View File

@@ -0,0 +1,84 @@
package pp.mdga.client.animation;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import pp.mdga.client.InitControl;
public class FadeControl extends InitControl {
private float duration; // Duration of the fade effect
private float timeElapsed = 0;
private boolean init = false;
private float startAlpha;
private float endAlpha;
private Runnable actionAfter;
public FadeControl(float duration, float startAlpha, float endAlpha, Runnable actionAfter) {
this.duration = duration;
this.startAlpha = startAlpha;
this.endAlpha = endAlpha;
this.actionAfter = actionAfter;
}
public FadeControl(float duration, float startAlpha, float endAlpha) {
this.duration = duration;
this.startAlpha = startAlpha;
this.endAlpha = endAlpha;
this.actionAfter = null;
}
@Override
protected void initSpatial() {
init = true;
}
@Override
protected void controlUpdate(float tpf) {
if (!init) return;
timeElapsed += tpf;
float t = timeElapsed / duration; // Calculate progress (0 to 1)
if (t >= 1) {
// Fade complete
t = 1;
init = false;
spatial.removeControl(this);
if(actionAfter != null) actionAfter.run();
}
float alpha = linInt(startAlpha, endAlpha, t); // Interpolate alpha
// Update the material's alpha
if (spatial instanceof Geometry geometry) {
Material mat = geometry.getMaterial();
if (mat != null) {
ColorRGBA diffuse = (ColorRGBA) mat.getParam("Diffuse").getValue();
mat.setColor("Diffuse", new ColorRGBA(diffuse.r, diffuse.g, diffuse.b, alpha));
ColorRGBA ambient = (ColorRGBA) mat.getParam("Ambient").getValue();
mat.setColor("Ambient", new ColorRGBA(ambient.r, ambient.g, ambient.b, alpha));
// Disable shadows when the object is nearly invisible
if (alpha <= 0.1f) {
geometry.setShadowMode(RenderQueue.ShadowMode.Off);
} else {
geometry.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
}
} else throw new RuntimeException("Material is null");
} else throw new RuntimeException("Spatial is not instance of Geometry");
}
/**
* Performs linear interpolation between two values.
*
* @param start The starting value.
* @param end The ending value.
* @param t A parameter between 0 and 1 representing the interpolation progress.
* @return The interpolated value.
*/
private float linInt(float start, float end, float t) {
return start + t * (end - start);
}
}

View File

@@ -10,20 +10,125 @@
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound; import pp.mdga.client.acoustic.MdgaSound;
import java.util.Random; import java.util.*;
import java.util.Vector;
public class MatrixAnimation extends InitControl { public class MatrixAnimation extends InitControl {
private MdgaApp app; private MdgaApp app;
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
private Vector3f radarPos;
private Runnable runnable;
private boolean init = false;
private List<ParticleEmitter> activeEmitter = new ArrayList<>();
private ParticleEmitter radarEmitter = null;
private float timeElapsed = 0f;
public MatrixAnimation(MdgaApp app){ private enum MatrixState{
RADAR_ON,
RADAR_OFF,
MATRIX_ON,
MATRIX_OFF
}
private MatrixState state;
public MatrixAnimation(MdgaApp app, float duration, Vector3f radarPos, Runnable runnable){
this.app = app; this.app = app;
this.radarPos = radarPos;
this.runnable = runnable;
} }
@Override @Override
protected void initSpatial() { protected void initSpatial() {
state = MatrixState.RADAR_ON;
System.out.println("RADAR ON");
timeElapsed = 0;
init = true;
radar();
}
@Override
protected void controlUpdate(float tpf) {
if(!init) return;
timeElapsed += tpf;
switch(state){
case RADAR_ON -> {
if(timeElapsed >= 2f){
state = MatrixState.RADAR_OFF;
timeElapsed = 0;
radarEmitter.setParticlesPerSec(0);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
app.getRootNode().detachChild(radarEmitter);
}
}, 3000);
}
}
case RADAR_OFF -> {
if(timeElapsed >= 0.1f){
state = MatrixState.MATRIX_ON;
timeElapsed = 0;
matrix();
}
}
case MATRIX_ON -> {
if(timeElapsed >= 3f){
state = MatrixState.MATRIX_OFF;
timeElapsed = 0;
turnOff();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
for (ParticleEmitter particleEmitter : activeEmitter){
app.getRootNode().detachChild(particleEmitter);
}
}
}, 3000);
}
}
case MATRIX_OFF -> {
if(timeElapsed >= 0.5f){
init = false;
runnable.run();
spatial.removeControl(this);
}
}
}
}
private void turnOff(){
for (ParticleEmitter particleEmitter : activeEmitter){
particleEmitter.setParticlesPerSec(0f);
}
}
private void radar(){
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("Texture", app.getAssetManager().loadTexture("Images/particle/radar_beam.png"));
ParticleEmitter emitter = new ParticleEmitter("Effect", Type.Triangle, 50);
emitter.setMaterial(mat);
emitter.setImagesX(1); // columns
emitter.setImagesY(1); // rows
emitter.setSelectRandomImage(true);
emitter.setStartColor(ColorRGBA.White);
emitter.setEndColor(ColorRGBA.Black);
emitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0f, 0f, 2));
emitter.getParticleInfluencer().setVelocityVariation(0f);
emitter.setStartSize(0.1f);
emitter.setEndSize(10);
emitter.setGravity(0, 0, 0);
float life = 2.6f;
emitter.setLowLife(life);
emitter.setHighLife(life);
emitter.setLocalTranslation(radarPos.add(new Vector3f(0,0,5)));
emitter.setParticlesPerSec(1.8f);
app.getRootNode().attachChild(emitter);
radarEmitter = emitter;
}
private void matrix(){
for(int i = 0; i < 5; i++){ for(int i = 0; i < 5; i++){
particleStream( particleStream(
generateMatrixColor(), generateMatrixColor(),
@@ -35,9 +140,6 @@ protected void initSpatial() {
} }
} }
@Override
protected void controlUpdate(float tpf) {
}
private void particleStream(ColorRGBA start, ColorRGBA end, float speedVar, Vector3f pos, float spawnVar){ private void particleStream(ColorRGBA start, ColorRGBA end, float speedVar, Vector3f pos, float spawnVar){
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md"); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
@@ -50,16 +152,17 @@ private void particleStream(ColorRGBA start, ColorRGBA end, float speedVar, Vect
matrix.setSelectRandomImage(true); matrix.setSelectRandomImage(true);
matrix.setStartColor(start); matrix.setStartColor(start);
matrix.setEndColor(end); matrix.setEndColor(end);
matrix.getParticleInfluencer().setInitialVelocity(new Vector3f(0f, 0f, -4f - speedVar)); matrix.getParticleInfluencer().setInitialVelocity(new Vector3f(0f, 0f, -6f - speedVar));
matrix.getParticleInfluencer().setVelocityVariation(0f); matrix.getParticleInfluencer().setVelocityVariation(0f);
matrix.setStartSize(0.4f); matrix.setStartSize(0.4f);
matrix.setEndSize(0.6f); matrix.setEndSize(0.6f);
matrix.setGravity(0, 0, 0f); matrix.setGravity(0, 0, 2f);
matrix.setLowLife(3f); matrix.setLowLife(3f);
matrix.setHighLife(3f); matrix.setHighLife(3f);
matrix.setLocalTranslation(pos.add(new Vector3f(0,0,15))); matrix.setLocalTranslation(spatial.getLocalTranslation().add(pos).add(new Vector3f(0,0,15)));
matrix.setParticlesPerSec(spawnVar); matrix.setParticlesPerSec(spawnVar);
app.getRootNode().attachChild(matrix); app.getRootNode().attachChild(matrix);
activeEmitter.add(matrix);
} }
public static Vector3f getRandomPosition() { public static Vector3f getRandomPosition() {

View File

@@ -1,6 +1,7 @@
package pp.mdga.client.board; package pp.mdga.client.board;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
@@ -12,6 +13,7 @@
import pp.mdga.client.Asset; import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound; import pp.mdga.client.acoustic.MdgaSound;
import pp.mdga.client.animation.FadeControl;
import pp.mdga.client.animation.MatrixAnimation; import pp.mdga.client.animation.MatrixAnimation;
import pp.mdga.client.animation.MoveControl; import pp.mdga.client.animation.MoveControl;
import pp.mdga.client.animation.JetAnimation; import pp.mdga.client.animation.JetAnimation;
@@ -58,6 +60,8 @@ public class BoardHandler {
private PieceControl selectedOwnPiece; private PieceControl selectedOwnPiece;
private PieceControl selectedEnemyPiece; private PieceControl selectedEnemyPiece;
private DiceControl diceControl; private DiceControl diceControl;
//Radar Position for Matrix animation
private Vector3f radarPos;
/** /**
* Creates a new BoardHandler. * Creates a new BoardHandler.
@@ -150,12 +154,18 @@ private void initMap() {
case node_wait_blue -> addHomeNode(waitingNodesMap, Color.NAVY, assetOnMap); case node_wait_blue -> addHomeNode(waitingNodesMap, Color.NAVY, assetOnMap);
case node_wait_green -> addHomeNode(waitingNodesMap, Color.ARMY, assetOnMap); case node_wait_green -> addHomeNode(waitingNodesMap, Color.ARMY, assetOnMap);
case node_wait_yellow -> addHomeNode(waitingNodesMap, Color.CYBER, assetOnMap); case node_wait_yellow -> addHomeNode(waitingNodesMap, Color.CYBER, assetOnMap);
case radar -> addRadar(assetOnMap);
default -> displayAsset(assetOnMap); default -> displayAsset(assetOnMap);
} }
} }
} }
private void addRadar(AssetOnMap assetOnMap) {
radarPos = gridToWorld(assetOnMap.x(), assetOnMap.y());
displayAsset(assetOnMap);
}
/** /**
* Converts an asset to its corresponding color. * Converts an asset to its corresponding color.
* *
@@ -189,14 +199,16 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) {
model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(rot)); model.rotate((float) Math.toRadians(0), 0, (float) Math.toRadians(rot));
model.setLocalTranslation(pos); model.setLocalTranslation(pos);
model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); model.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(texName)); 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.setBoolean("UseMaterialColors", true); // Required for Material Colors
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); // Enable alpha blending mat.setColor("Diffuse", new ColorRGBA(1, 1, 1, 1)); // White color with full alpha
// mat.getAdditionalRenderState().setDepthWrite(false); mat.setColor("Ambient", new ColorRGBA(1, 1, 1, 1)); // Ambient color with full alpha
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
model.setMaterial(mat); model.setMaterial(mat);
rootNodeBoard.attachChild(model);
rootNodeBoard.attachChild(model);
return model; return model;
} }
@@ -728,7 +740,8 @@ public void movePieceStartAnim(UUID uuid, int moveIndex){
*/ */
public void throwPieceAnim(UUID uuid){ public void throwPieceAnim(UUID uuid){
pieces.get(uuid).getSpatial().addControl(new MoveControl( 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))
); );
} }
@@ -755,7 +768,17 @@ private void throwBomb(UUID uuid) {
} }
private void throwMatrix(UUID uuid) { private void throwMatrix(UUID uuid) {
pieces.get(uuid).getSpatial().addControl(new MatrixAnimation(app)); Spatial piece = pieces.get(uuid).getSpatial();
piece.addControl(new MatrixAnimation(app, 1, radarPos,()->{
piece.addControl(new FadeControl(1,1,0,
() -> {
throwPiece(uuid);
piece.addControl(new FadeControl(1,0,1));
}
));
}));
} }
private void throwMissle(UUID uuid) { private void throwMissle(UUID uuid) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB