Skip to content

Commit

Permalink
Better swirl effect
Browse files Browse the repository at this point in the history
Also convert to a dedicated class to make editing easier
  • Loading branch information
MEEPofFaith committed Mar 10, 2024
1 parent 5a74f83 commit 59dd182
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 70 deletions.
72 changes: 3 additions & 69 deletions src/progressed/content/effects/EnergyFx.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import arc.util.*;
import mindustry.entities.*;
import mindustry.graphics.*;
import progressed.entities.effect.*;
import progressed.graphics.*;
import progressed.util.*;

Expand Down Expand Up @@ -78,9 +79,9 @@ public class EnergyFx{
Drawf.light(e.x, e.y, rX * 2f, e.color, 0.8f);
}),

kugelblitzCharge = makeSwirlEffect(30f, 8, 2f, 15f, 90f, false).layer(Layer.bullet - 0.03f),
kugelblitzCharge = new SwirlEffect(30f, 8, 2f, 30f, 90f, false).layer(Layer.bullet - 0.03f),

blackHoleSwirl = makeSwirlEffect(90f, 8, 3f, 180f, 720f, true, true).layer(Layer.effect + 0.005f),
blackHoleSwirl = new SwirlEffect(90f, 8, 3f, 120f, 480f, true, true).layer(Layer.effect + 0.005f),

blackHoleDespawn = new Effect(80f, e -> {
float rad = 24f;
Expand Down Expand Up @@ -133,71 +134,4 @@ public class EnergyFx{

Drawf.light(e.x, e.y, circleRad * 1.6f, Pal.heal, e.fout());
});

public static Effect makeSwirlEffect(Color color, float eLifetime, int length, float maxWidth, float minRot, float maxRot, float minDst, float maxDst, boolean light, boolean lerp){
return new Effect(eLifetime, 400f, e -> {
if(e.time < 1f) return;

float lifetime = e.lifetime - length;
float dst;
if(minDst < 0 || maxDst < 0){
dst = Math.abs(e.rotation);
}else{
dst = Mathf.randomSeed(e.id, minDst, maxDst);
}
float l = Mathf.clamp(e.time / lifetime);
if(lerp){
color(color, e.color, l);
}else{
color(color);
}

int points = (int)Math.min(e.time, length);
float width = Mathf.clamp(e.time / (e.lifetime - length)) * maxWidth;
float size = width / points;
float baseRot = Mathf.randomSeed(e.id + 1, 360f), addRot = Mathf.randomSeed(e.id + 2, minRot, maxRot) * Mathf.sign(e.rotation);

float fout, lastAng = 0f;
for(int i = 0; i < points; i++){
fout = 1f - Mathf.clamp((e.time - points + i) / lifetime);
v1.trns(baseRot + addRot * PMMathf.cbrt(fout), Mathf.maxZero(dst * fout));
fout = 1f - Mathf.clamp((e.time - points + i + 1) / lifetime);
v2.trns(baseRot + addRot * PMMathf.cbrt(fout), Mathf.maxZero(dst * fout));

float a2 = -v1.angleTo(v2) * Mathf.degRad;
float a1 = i == 0 ? a2 : lastAng;

float
cx = Mathf.sin(a1) * i * size,
cy = Mathf.cos(a1) * i * size,
nx = Mathf.sin(a2) * (i + 1) * size,
ny = Mathf.cos(a2) * (i + 1) * size;

Fill.quad(
e.x + v1.x - cx, e.y + v1.y - cy,
e.x + v1.x + cx, e.y + v1.y + cy,
e.x + v2.x + nx, e.y + v2.y + ny,
e.x + v2.x - nx, e.y + v2.y - ny
);
if(light){
Drawf.light(
e.x + v1.x, e.y + v1.y,
e.x + v2.x, e.y + v2.y,
i * size * 6f, Draw.getColor().cpy(), l
);
}

lastAng = a2;
}
Draw.rect("hcircle", e.x + v2.x, e.y + v2.y, width * 2f, width * 2f, -Mathf.radDeg * lastAng);
});
}

public static Effect makeSwirlEffect(float eLifetime, int length, float maxWidth, float minRot, float maxRot, boolean light, boolean lerp){
return makeSwirlEffect(Color.black, eLifetime, length, maxWidth, minRot, maxRot, -1, -1, light, lerp);
}

public static Effect makeSwirlEffect(float eLifetime, int length, float maxWidth, float minRot, float maxRot, boolean lerp){
return makeSwirlEffect(Color.black, eLifetime, length, maxWidth, minRot, maxRot, -1, -1, false, lerp);
}
}
3 changes: 2 additions & 1 deletion src/progressed/content/effects/ModuleFx.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.graphics.*;
import progressed.entities.effect.*;
import progressed.graphics.*;

import static arc.graphics.g2d.Draw.*;
Expand Down Expand Up @@ -107,7 +108,7 @@ public class ModuleFx{
};
}).layer(Layer.effect + 1.004f),

abyssSwirl = EnergyFx.makeSwirlEffect(Color.black, 30f, 5, 1.5f, 0f, 0f, 12f, 40f, false, false).layer(Layer.effect + 1.005f),
abyssSwirl = new SwirlEffect(30f, Color.black, 5, 1.5f, 0f, 0f, 12f, 40f, false, false).layer(Layer.effect + 1.005f),

abyssGrow = new Effect(45f, e -> {
float rad = 2f + e.fin(Interp.pow2Out) * 3f;
Expand Down
120 changes: 120 additions & 0 deletions src/progressed/entities/effect/SwirlEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package progressed.entities.effect;

import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import mindustry.entities.*;
import mindustry.graphics.*;

import static arc.graphics.g2d.Draw.*;
import static arc.util.Tmp.*;

public class SwirlEffect extends Effect{
public static TextureRegion hCircle;

public int length;
public float width;
public float minRot, maxRot;
public float minDst, maxDst;
public boolean light;
public boolean lerp;
public Color centerColor;
public Interp fallterp = Interp.pow2Out;
public Interp spinterp = Interp.pow3Out;

public SwirlEffect(float lifetime, float clipsize, Color centerColor, int length, float width, float minRot, float maxRot, float minDst, float maxDst, boolean light, boolean lerp){
super();
this.lifetime = lifetime;
this.clip = clipsize;
this.centerColor = centerColor;
this.length = length;
this.width = width;
this.minRot = minRot;
this.maxRot = maxRot;
this.minDst = minDst;
this.maxDst = maxDst;
this.light = light;
this.lerp = lerp;
}

public SwirlEffect(float lifetime, Color centerColor, int length, float width, float minRot, float maxRot, float minDst, float maxDst, boolean light, boolean lerp){
this(lifetime, 400f, centerColor, length, width, minRot, maxRot, minDst, maxDst, light, lerp);
}

public SwirlEffect(float lifetime, int length, float width, float minRot, float maxRot, boolean light, boolean lerp){
this(lifetime, Color.black, length, width, minRot, maxRot, -1, -1, light, lerp);
}

public SwirlEffect(float lifetime, int length, float width, float minRot, float maxRot, boolean lerp){
this(lifetime, Color.black, length, width, minRot, maxRot, -1, -1, false, lerp);
}

public SwirlEffect setInterps(Interp fallterp, Interp spinterp){
this.fallterp = fallterp;
this.spinterp = spinterp;
return this;
}

public SwirlEffect setInterps(Interp interp){
return setInterps(interp, interp);
}

@Override
public void render(EffectContainer e){
float lifetime = e.lifetime - length;
float dst;
if(minDst < 0 || maxDst < 0){
dst = Math.abs(e.rotation);
}else{
dst = Mathf.randomSeed(e.id, minDst, maxDst);
}
float l = Mathf.clamp(e.time / lifetime);
if(lerp){
color(centerColor, e.color, l);
}else{
color(centerColor);
}

int points = (int)Math.min(e.time, length);
float width = Mathf.clamp(e.time / (e.lifetime - length)) * this.width;
float size = width / points;
float baseRot = Mathf.randomSeed(e.id + 1, 360f), addRot = Mathf.randomSeed(e.id + 2, minRot, maxRot) * Mathf.sign(e.rotation);

float fout, lastAng = 0f;
for(int i = 0; i < points; i++){
fout = 1f - Mathf.clamp((e.time - points + i) / lifetime);
v1.trns(baseRot + addRot * spinterp.apply(fout), Mathf.maxZero(dst * fallterp.apply(fout)));
fout = 1f - Mathf.clamp((e.time - points + i + 1) / lifetime);
v2.trns(baseRot + addRot * spinterp.apply(fout), Mathf.maxZero(dst * fallterp.apply(fout)));

float a2 = -v1.angleTo(v2) * Mathf.degRad;
float a1 = i == 0 ? a2 : lastAng;

float
cx = Mathf.sin(a1) * i * size,
cy = Mathf.cos(a1) * i * size,
nx = Mathf.sin(a2) * (i + 1) * size,
ny = Mathf.cos(a2) * (i + 1) * size;

Fill.quad(
e.x + v1.x - cx, e.y + v1.y - cy,
e.x + v1.x + cx, e.y + v1.y + cy,
e.x + v2.x + nx, e.y + v2.y + ny,
e.x + v2.x - nx, e.y + v2.y - ny
);
if(light){
Drawf.light(
e.x + v1.x, e.y + v1.y,
e.x + v2.x, e.y + v2.y,
i * size * 6f, Draw.getColor().cpy(), l
);
}

lastAng = a2;
}

if(hCircle == null) hCircle = Core.atlas.find("hcircle");
Draw.rect(hCircle, e.x + v2.x, e.y + v2.y, width * 2f, width * 2f, -Mathf.radDeg * lastAng);
}
}

0 comments on commit 59dd182

Please sign in to comment.