diff options
Diffstat (limited to 'core/src/ch')
-rw-r--r-- | core/src/ch/asynk/gdx/boardgame/animations/ShellFireAnimation.java | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/core/src/ch/asynk/gdx/boardgame/animations/ShellFireAnimation.java b/core/src/ch/asynk/gdx/boardgame/animations/ShellFireAnimation.java new file mode 100644 index 0000000..e2f0f59 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/animations/ShellFireAnimation.java @@ -0,0 +1,246 @@ +package ch.asynk.gdx.boardgame.animations; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Random; + +import com.badlogic.gdx.utils.Pool; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.MathUtils; + +import ch.asynk.gdx.boardgame.FramedSprite; +import ch.asynk.gdx.boardgame.Piece; + +public class ShellFireAnimation extends TimedAnimation implements Pool.Poolable +{ + private static class Config + { + public float maxFireDelay; + public float maxShootScattering; + public float shellSpeed; + public float smokeDuration; + public float explosionDuration; + public FramedSprite shellSprites; + public FramedSprite explosionSprites; + public Config(float maxFireDelay, float maxShootScattering, float shellSpeed, + float smokeDuration, float explosionDuration, FramedSprite shellSprites, FramedSprite explosionSprites) + { + this.maxFireDelay = maxFireDelay; + this.maxShootScattering = maxShootScattering; + this.shellSpeed = shellSpeed; + this.smokeDuration = smokeDuration; + this.explosionDuration = explosionDuration; + this.shellSprites = shellSprites; + this.explosionSprites = explosionSprites; + } + } + + private static Map<String, Config> configs = new Hashtable<String, Config>(); + + public static void register(final String name, + float maxFireDelay, + float maxShootScattering, + float shellSpeed, + float smokeDuration, + float explosionDuration, + final Texture shellTexture, int shellC, int shellR, + final Texture explosionTexture, int explosionC, int explosionR + ) + { + Config cfg = new Config(maxFireDelay, maxShootScattering, shellSpeed, smokeDuration, explosionDuration, + new FramedSprite(shellTexture, shellC, shellR), + new FramedSprite(explosionTexture, explosionC, explosionR) + ); + configs.put(name, cfg); + } + + public static void free() + { + // for(String key : configs.keySet()) { + // Config cfg = configs.get(key); + // } + configs.clear(); + } + + private static Random random = new Random(); + + private static final Pool<ShellFireAnimation> shellFireAnimationPool = new Pool<ShellFireAnimation>() + { + @Override protected ShellFireAnimation newObject() + { + return new ShellFireAnimation(); + } + }; + + public static Vector2 sv = new Vector2(); + public static Vector2 tv = new Vector2(); + public static ShellFireAnimation obtain(final String configName, Piece shooter, Piece target) + { + shooter.getShootingPoint(sv, target); + target.getImpactPoint(tv); + return obtain(configName, sv.x, sv.y, tv.x, tv.y); + } + + public static ShellFireAnimation obtain(final String configName, float x0, float y0, float x1, float y1) + { + ShellFireAnimation a = shellFireAnimationPool.obtain(); + + Config cfg = configs.get(configName); + if (cfg == null) { + throw new RuntimeException(String.format("ShellFireAnimation : no configuration named : '%s'", configName)); + } + a.cfg = cfg; + a.compute(x0, y0, x1, y1); + + return a; + } + + private Config cfg; + + private boolean fired; + private boolean hit; + private boolean drawFire; + private boolean drawExplosion; + private float fireTime; + private float hitTime; + private float smokeEndTime; + private float explosionEndTime; + + private TextureRegion fireRegion; + private float fireX; + private float fireY; + private float fireA; + private float fireW; + private float fireDx; + private float fireDy; + private float fireDw; + + private int smokeFrame; + private float smokeDf; + + private int explosionStart; + private int explosionFrame; + private float explosionX; + private float explosionY; + private float explosionDf; + + private ShellFireAnimation() + { + } + + @Override public void dispose() + { + shellFireAnimationPool.free(this); + } + + private void compute(float x0, float y0, float x1, float y1) + { + // scattering + x1 = (x1 + (random.nextFloat() * cfg.maxShootScattering) - (cfg.maxShootScattering / 2f)); + y1 = (y1 + (random.nextFloat() * cfg.maxShootScattering) - (cfg.maxShootScattering / 2f)); + + // geometry + float dx = (x1 - x0); + float dy = (y1 - y0); + float a = (float) (MathUtils.atan2(y0 - y1, x0 - x1)) * MathUtils.radiansToDegrees; + float w = (float) Math.sqrt((dx * dx) + (dy * dy)); + + // timing + float fireDuration = (w / cfg.shellSpeed); + float smokeDuration = cfg.smokeDuration; + float explosionDuration = cfg.explosionDuration; + this.fireTime = (random.nextFloat() * cfg.maxFireDelay); + this.hitTime = this.fireTime + fireDuration; + this.smokeEndTime = this.hitTime + smokeDuration; + this.explosionEndTime = this.hitTime + explosionDuration; + float endTime = (this.smokeEndTime > this.explosionEndTime ? this.smokeEndTime : this.explosionEndTime); + + // fire vars + this.fireX = x0; + this.fireY = y0; + this.fireA = a; + this.fireW = 0f; + this.fireDw = (w / fireDuration); + this.fireDx = (dx / fireDuration); + this.fireDy = (dy / fireDuration); + this.fireRegion = new TextureRegion(cfg.shellSprites.frames[0]); + + // smoke vars + this.smokeFrame = 0; + this.smokeDf = (cfg.shellSprites.rows / smokeDuration); + + // explosion vars + this.explosionX = (x1 - (cfg.explosionSprites.width / 2.0f)); + this.explosionY = (y1 - (cfg.explosionSprites.height / 2.0f)); + this.explosionDf = (cfg.explosionSprites.cols / explosionDuration); + this.explosionStart = (random.nextInt(cfg.explosionSprites.rows) * cfg.explosionSprites.cols); + this.explosionFrame = this.explosionStart; + + this.fired = false; + this.hit = false; + this.drawFire = false; + this.drawExplosion = false; + setDuration(endTime); + } + + @Override public void begin() { } + @Override public void end() { } + + @Override public void update(float delta) + { + if (!fired && (elapsed < fireTime)) { + return; + } + + if (!fired) { + fired = true; + drawFire = true; + } + + if (!hit && (elapsed < hitTime)) { + fireW += (fireDw * delta); + fireX += (fireDx * delta); + fireY += (fireDy * delta); + fireRegion.setRegionWidth((int) fireW); + return; + } + + if (!hit) { + hit = true; + drawExplosion = true; + } + + float dt = (elapsed - hitTime); + + if (elapsed < smokeEndTime) { + int frame = (int) (dt * smokeDf); + if (frame != smokeFrame) { + smokeFrame = frame; + fireRegion.setRegion(cfg.shellSprites.frames[smokeFrame]); + fireRegion.setRegionWidth((int) fireW); + } + } else { + drawFire = false; + } + + if (elapsed < explosionEndTime) { + explosionFrame = (explosionStart + (int) (dt * explosionDf)); + } else { + drawExplosion = false; + } + } + + @Override public void draw(Batch batch) + { + if (drawFire) { + batch.draw(fireRegion, fireX, fireY, 0, 0, fireRegion.getRegionWidth(), fireRegion.getRegionHeight(), 1f, 1f, fireA); + } + + if (drawExplosion) { + batch.draw(cfg.explosionSprites.frames[explosionFrame], explosionX, explosionY); + } + } +} |