mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-22 12:38:05 +07:00
Tank animations & FX
This commit is contained in:
parent
0d33768f58
commit
53b55a9f0e
@ -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 |
@ -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) -> {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 -> {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user