added MatrixAnimation
This commit is contained in:
		@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -10,20 +10,125 @@
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
import pp.mdga.client.acoustic.MdgaSound;
 | 
			
		||||
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class MatrixAnimation extends InitControl {
 | 
			
		||||
    private MdgaApp app;
 | 
			
		||||
    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.radarPos = radarPos;
 | 
			
		||||
        this.runnable = runnable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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++){
 | 
			
		||||
           particleStream(
 | 
			
		||||
               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){
 | 
			
		||||
        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.setStartColor(start);
 | 
			
		||||
        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.setStartSize(0.4f);
 | 
			
		||||
        matrix.setEndSize(0.6f);
 | 
			
		||||
        matrix.setGravity(0, 0, 0f);
 | 
			
		||||
        matrix.setGravity(0, 0, 2f);
 | 
			
		||||
        matrix.setLowLife(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);
 | 
			
		||||
        app.getRootNode().attachChild(matrix);
 | 
			
		||||
        activeEmitter.add(matrix);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3f getRandomPosition() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package pp.mdga.client.board;
 | 
			
		||||
 | 
			
		||||
import com.jme3.material.Material;
 | 
			
		||||
import com.jme3.material.RenderState;
 | 
			
		||||
import com.jme3.material.RenderState.BlendMode;
 | 
			
		||||
import com.jme3.math.ColorRGBA;
 | 
			
		||||
import com.jme3.math.Vector3f;
 | 
			
		||||
@@ -12,6 +13,7 @@
 | 
			
		||||
import pp.mdga.client.Asset;
 | 
			
		||||
import pp.mdga.client.MdgaApp;
 | 
			
		||||
import pp.mdga.client.acoustic.MdgaSound;
 | 
			
		||||
import pp.mdga.client.animation.FadeControl;
 | 
			
		||||
import pp.mdga.client.animation.MatrixAnimation;
 | 
			
		||||
import pp.mdga.client.animation.MoveControl;
 | 
			
		||||
import pp.mdga.client.animation.JetAnimation;
 | 
			
		||||
@@ -58,6 +60,8 @@ public class BoardHandler {
 | 
			
		||||
    private PieceControl selectedOwnPiece;
 | 
			
		||||
    private PieceControl selectedEnemyPiece;
 | 
			
		||||
    private DiceControl diceControl;
 | 
			
		||||
    //Radar Position for Matrix animation
 | 
			
		||||
    private Vector3f radarPos;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new BoardHandler.
 | 
			
		||||
@@ -150,12 +154,18 @@ private void initMap() {
 | 
			
		||||
                case node_wait_blue -> addHomeNode(waitingNodesMap, Color.NAVY, assetOnMap);
 | 
			
		||||
                case node_wait_green -> addHomeNode(waitingNodesMap, Color.ARMY, assetOnMap);
 | 
			
		||||
                case node_wait_yellow -> addHomeNode(waitingNodesMap, Color.CYBER, assetOnMap);
 | 
			
		||||
                case radar -> addRadar(assetOnMap);
 | 
			
		||||
 | 
			
		||||
                default -> displayAsset(assetOnMap);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addRadar(AssetOnMap assetOnMap) {
 | 
			
		||||
        radarPos = gridToWorld(assetOnMap.x(), assetOnMap.y());
 | 
			
		||||
        displayAsset(assetOnMap);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.setLocalTranslation(pos);
 | 
			
		||||
        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);
 | 
			
		||||
        mat.setBoolean("UseMaterialColors", true); // Required for Material Colors
 | 
			
		||||
        mat.setColor("Diffuse", new ColorRGBA(1, 1, 1, 1)); // White color with full alpha
 | 
			
		||||
        mat.setColor("Ambient", new ColorRGBA(1, 1, 1, 1)); // Ambient color with full alpha
 | 
			
		||||
        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
 | 
			
		||||
        model.setMaterial(mat);
 | 
			
		||||
        rootNodeBoard.attachChild(model);
 | 
			
		||||
 | 
			
		||||
        rootNodeBoard.attachChild(model);
 | 
			
		||||
        return model;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -728,7 +740,8 @@ 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))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -755,7 +768,17 @@ private void throwBomb(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) {
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 29 KiB  | 
		Reference in New Issue
	
	Block a user