1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-11 08:15:35 +03:00

Tank animations & FX

This commit is contained in:
Anuken 2021-12-12 20:05:37 -05:00
parent 0d33768f58
commit 53b55a9f0e
11 changed files with 119 additions and 19 deletions

View File

@ -800,12 +800,12 @@ public class EntityProcess extends BaseProcessor{
}
}
write(def.builder, imports.asArray());
write(def.builder, imports.toSeq());
}
//write base classes last
for(TypeSpec.Builder b : baseClasses){
write(b, imports.asArray());
write(b, imports.toSeq());
}
//TODO nulls were an awful idea
@ -878,7 +878,7 @@ public class EntityProcess extends BaseProcessor{
nullsBuilder.addField(FieldSpec.builder(type, Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
write(nullBuilder, imports.asArray());
write(nullBuilder, imports.toSeq());
}
write(nullsBuilder);
@ -934,7 +934,7 @@ public class EntityProcess extends BaseProcessor{
out.addAll(getDependencies(comp));
}
defComponents.put(type, out.asArray());
defComponents.put(type, out.toSeq());
}
return defComponents.get(type);
@ -961,7 +961,7 @@ public class EntityProcess extends BaseProcessor{
//remove it again just in case
out.remove(component);
componentDependencies.put(component, result.asArray());
componentDependencies.put(component, result.toSeq());
}
return componentDependencies.get(component);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -21,8 +21,8 @@ import static arc.math.Angles.*;
import static mindustry.Vars.*;
public class Fx{
private static final Rand rand = new Rand();
private static final Vec2 v = new Vec2();
public static final Rand rand = new Rand();
public static final Vec2 v = new Vec2();
public static final Effect
@ -310,11 +310,19 @@ public class Fx{
unitLand = new Effect(30, e -> {
color(Tmp.c1.set(e.color).mul(1.1f));
//TODO doesn't respect rotation / size
randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f);
});
}).layer(Layer.debris),
unitDust = new Effect(30, e -> {
color(Tmp.c1.set(e.color).mul(1.3f));
randLenVectors(e.id, 3, 8f * e.finpow(), e.rotation, 30f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.3f);
});
}).layer(Layer.debris),
unitLandSmall = new Effect(30, e -> {
color(Tmp.c1.set(e.color).mul(1.1f));
randLenVectors(e.id, (int)(6 * e.rotation), 12f * e.finpow() * e.rotation, (x, y) -> {

View File

@ -2429,6 +2429,10 @@ public class UnitTypes{
vanquish = new TankUnitType("vanquish"){{
hitSize = 28f;
speed = 0.6f;
health = 10000;
armor = 20f;
treadRect = new Rect(22f, 16f, 28f, 130f);
}};
//endregion

View File

@ -166,6 +166,22 @@ public class Effect{
shake(intensity, duration, loc.getX(), loc.getY());
}
public static void floorDust(float x, float y, float size){
Tile tile = world.tileWorld(x, y);
if(tile != null){
Color color = tile.floor().mapColor;
Fx.unitLand.at(x, y, size, color);
}
}
public static void floorDustAngle(Effect effect, float x, float y, float angle){
Tile tile = world.tileWorld(x, y);
if(tile != null){
Color color = tile.floor().mapColor;
effect.at(x, y, angle, color);
}
}
public static void create(Effect effect, float x, float y, float rotation, Color color, Object data){
if(headless || effect == Fx.none || !Core.settings.getBool("effects")) return;

View File

@ -119,7 +119,7 @@ public class EntityCollisions{
@SuppressWarnings("unchecked")
public <T extends Hitboxc> void updatePhysics(EntityGroup<T> group){
QuadTree tree = group.tree();
var tree = group.tree();
tree.clear();
group.each(s -> {

View File

@ -1,15 +1,12 @@
package mindustry.entities.comp;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*;
@ -52,11 +49,7 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
}
if(type.mechStepParticles){
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
Color color = tile.floor().mapColor;
Fx.unitLand.at(cx, cy, hitSize/8f, color);
}
Effect.floorDust(cx, cy, hitSize/8f);
}
}

View File

@ -1,8 +1,10 @@
package mindustry.entities.comp;
import arc.math.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.blocks.environment.*;
@ -11,14 +13,36 @@ import static mindustry.Vars.*;
@Component
abstract class TankComp implements Posc, Flyingc, Hitboxc, Unitc, ElevationMovec{
@Import float x, y, hitSize;
@Import float x, y, hitSize, rotation;
@Import UnitType type;
transient private float treadEffectTime;
transient float treadTime;
transient boolean walked;
@Override
public void update(){
//dust
if(walked && !headless){
treadEffectTime += Time.delta;
if(treadEffectTime >= 6f){
var treadRegion = type.treadRegion;
var treadRect = type.treadRect;
float xOffset = (treadRegion.width/2f - (treadRect.x + treadRect.width/2f)) / 4f;
float yOffset = (treadRegion.height/2f - (treadRect.y + treadRect.height/2f)) / 4f;
for(int i : Mathf.signs){
Tmp.v1.set(xOffset * i, yOffset - treadRect.height / 2f / 4f).rotate(rotation - 90);
Effect.floorDustAngle(type.treadEffect, Tmp.v1.x + x, Tmp.v1.y + y, rotation + 180f);
}
treadEffectTime = 0f;
}
}
//trigger animation only when walking manually
if(walked || net.client()){
float len = deltaLen();

View File

@ -34,6 +34,7 @@ import mindustry.world.blocks.units.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
import static arc.graphics.g2d.Draw.*;
import static mindustry.Vars.*;
//TODO document
@ -92,6 +93,7 @@ public class UnitType extends UnlockableContent{
public Effect fallEffect = Fx.fallSmoke;
public Effect fallThrusterEffect = Fx.fallSmoke;
public Effect deathExplosionEffect = Fx.dynamicExplosion;
public @Nullable Effect treadEffect;
/** Additional sprites that are drawn with the unit. */
public Seq<UnitDecal> decals = new Seq<>();
public Seq<Ability> abilities = new Seq<>();
@ -117,6 +119,9 @@ public class UnitType extends UnlockableContent{
public boolean mechStepParticles = false;
public Color mechLegColor = Pal.darkMetal;
public Rect treadRect = new Rect();
public int treadFrames = 18;
public int itemCapacity = -1;
public int ammoCapacity = -1;
public AmmoType ammoType = new ItemAmmoType(Items.copper);
@ -166,8 +171,7 @@ public class UnitType extends UnlockableContent{
public Seq<Weapon> weapons = new Seq<>();
public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion,
softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion;
public TextureRegion[] wreckRegions;
public TextureRegion[] segmentRegions, segmentOutlineRegions;
public TextureRegion[] wreckRegions, segmentRegions, segmentOutlineRegions, treadRegions;
protected float buildTime = -1f;
protected @Nullable ItemStack[] totalRequirements, cachedRequirements, firstRequirements;
@ -437,6 +441,17 @@ public class UnitType extends UnlockableContent{
mechStepParticles = hitSize > 15f;
}
if(treadEffect == null){
treadEffect = new Effect(45, e -> {
color(Tmp.c1.set(e.color).mul(1.5f));
Fx.rand.setSeed(e.id);
for(int i = 0; i < 3; i++){
Fx.v.trns(e.rotation + Fx.rand.range(40f), Fx.rand.random(6f * e.finpow()));
Fill.circle(e.x + Fx.v.x + Fx.rand.range(3f), e.y + Fx.v.y + Fx.rand.range(3f), e.fout() * hitSize / 28f * 3f * Fx.rand.random(0.8f, 1.1f) + 0.3f);
}
}).layer(Layer.debris);
}
canHeal = weapons.contains(w -> w.bullet.healPercent > 0f);
//add mirrored weapon variants
@ -498,6 +513,12 @@ public class UnitType extends UnlockableContent{
baseJointRegion = Core.atlas.find(name + "-joint-base");
footRegion = Core.atlas.find(name + "-foot");
treadRegion = Core.atlas.find(name + "-treads");
if(treadRegion.found()){
treadRegions = new TextureRegion[treadFrames];
for(int i = 0; i < treadFrames; i++){
treadRegions[i] = Core.atlas.find(name + "-treads" + i);
}
}
legBaseRegion = Core.atlas.find(name + "-leg-base", name + "-leg");
baseRegion = Core.atlas.find(name + "-base");
cellRegion = Core.atlas.find(name + "-cell", Core.atlas.find("power-cell"));
@ -963,6 +984,18 @@ public class UnitType extends UnlockableContent{
public <T extends Unit & Tankc> void drawTank(T unit){
Draw.rect(treadRegion, unit.x, unit.y, unit.rotation - 90);
if(treadRegion.found()){
int frame = (int)(unit.treadTime()) % treadFrames;
var region = treadRegions[frame];
float xOffset = treadRegion.width/2f - (treadRect.x + treadRect.width/2f);
float yOffset = treadRegion.height/2f - (treadRect.y + treadRect.height/2f);
for(int i : Mathf.signs){
Tmp.v1.set(xOffset * i, yOffset).rotate(unit.rotation - 90);
Draw.rect(region, unit.x + Tmp.v1.x / 4f, unit.y + Tmp.v1.y / 4f, treadRect.width / 4f, region.height / 4f, unit.rotation - 90);
}
}
}
public <T extends Unit & Legsc> void drawLegs(T unit){

View File

@ -509,6 +509,28 @@ public class Generators{
}
}
//generate tank animation
if(sample instanceof Tankc){
Pixmap pix = get(type.treadRegion);
//slice is always 1 pixel wide
Pixmap slice = pix.crop((int)type.treadRect.x, (int)type.treadRect.y, 1, (int)type.treadRect.height);
int frames = type.treadFrames;
for(int i = 0; i < frames; i++){
int pullOffset = 4;
Pixmap frame = new Pixmap(slice.width, slice.height);
for(int y = 0; y < slice.height; y++){
int idx = y + i;
if(idx >= slice.height){
idx -= slice.height;
idx += pullOffset;
}
frame.setRaw(0, y, slice.getRaw(0, idx));
}
save(frame, type.name + "-treads" + i);
}
}
outliner.get(type.jointRegion);
outliner.get(type.footRegion);
outliner.get(type.legBaseRegion);