diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2014-11-26 16:37:42 +0100 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2014-11-26 16:37:42 +0100 | 
| commit | 0d8528f83d914ffaa467da4d056b13ba7a785105 (patch) | |
| tree | e3c3bb79e3e754028c0a052746165cd0aacdf07a /core/src | |
| parent | 1fba1714173bf15e5d160eff81b1e8767f89dd5e (diff) | |
| download | RustAndDust-0d8528f83d914ffaa467da4d056b13ba7a785105.zip RustAndDust-0d8528f83d914ffaa467da4d056b13ba7a785105.tar.gz | |
add animations/ShotAnimation
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/ch/asynk/tankontank/engine/gfx/animations/ShotAnimation.java | 248 | 
1 files changed, 248 insertions, 0 deletions
| diff --git a/core/src/ch/asynk/tankontank/engine/gfx/animations/ShotAnimation.java b/core/src/ch/asynk/tankontank/engine/gfx/animations/ShotAnimation.java new file mode 100644 index 0000000..930570a --- /dev/null +++ b/core/src/ch/asynk/tankontank/engine/gfx/animations/ShotAnimation.java @@ -0,0 +1,248 @@ +package ch.asynk.tankontank.engine.gfx.animations; + +import java.util.Random; + +import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.Pool; + +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.tankontank.engine.gfx.Drawable; +import ch.asynk.tankontank.engine.gfx.Animation; + +class Sprites +{ +    public Texture texture; +    public TextureRegion[] frames; +    public final int width; +    public final int height; +    public final int cols; +    public final int rows; + +    public Sprites(Texture texture, int cols, int rows) +    { +        this.cols = cols; +        this.rows = rows; +        this.width = (texture.getWidth() / cols); +        this.height = (texture.getHeight() / rows); +        this.texture = texture; +        TextureRegion[][] tmp = TextureRegion.split(texture, width, height); +        frames = new TextureRegion[cols * rows]; +        int idx = 0; +        for (int i = 0; i < rows; i++) { +            for (int j = 0; j < cols; j++) { +                frames[idx++] = tmp[i][j]; +            } +        } +    } +} + +public class ShotAnimation implements Disposable, Animation, Pool.Poolable +{ +    private static final float SHOT_SCATTERING = 60f; +    private static final float TIME_SCATTERING = 0.6f; +    private static final float SHOT_SPEED = 700f; +    private static final float EXPLOSION_FRAME_DURATION = 0.05f; + +    private static Random random = new Random(); +    private static Sound sound; +    private static Sprites shot; +    private static Sprites explosion; + +    private TextureRegion shotRegion; +    private float shot_a; +    private float shot_x; +    private float shot_y; +    private float shot_w; +    private float shot_dx; +    private float shot_dy; +    private float shot_dw; + +    private float smoke_dx; +    private float smoke_df; +    private int smoke_frame; + +    private float explosion_x; +    private float explosion_y; +    private float explosion_df; +    private int explosion_frame; + +    private boolean fired; +    private boolean hit; +    private float elapsed; +    private float fire_time; +    private float hit_time; +    private float end_time; + +    private float volume; +    private long soundId; + +    private static final Pool<ShotAnimation> shotAnimationPool = new Pool<ShotAnimation>() { +        @Override +        protected ShotAnimation newObject() { +            return new ShotAnimation(); +        } +    }; + +    public static ShotAnimation get(float volume, float offset, float x0, float y0, float x1, float y1) +    { +        ShotAnimation a = shotAnimationPool.obtain(); +        a.set(volume, offset, x0, y0, x1, y1); +        return a; +    } + +    public static void init(Texture shot_texture, int scols, int srows, Texture explosion_texture, int ecols, int erows, Sound snd) +    { +        sound = snd; +        shot = new Sprites(shot_texture, scols, srows); +        explosion = new Sprites(explosion_texture, ecols, erows); +    } + +    public static void free() +    { +        sound.dispose(); +        shot.texture.dispose(); +        explosion.texture.dispose(); +    } + +    public ShotAnimation() +    { +        this.shotRegion = new TextureRegion(shot.frames[0]); +    } + +    private void set(float volume, float offset, float x0, float y0, float x1, float y1) +    { +        this.fired = false; +        this.hit = false; +        this.volume = volume; + +        // shot geometry +        y0 -= (shot.height / 2.0f); +        x1 += ((SHOT_SCATTERING * random.nextFloat()) - (SHOT_SCATTERING / 2f)); +        y1 += ((SHOT_SCATTERING * random.nextFloat()) - (SHOT_SCATTERING / 2f)); + +        double r = Math.atan2((y0 - y1), (x0 - x1)); +        float xadj = (float) (Math.cos(r) * offset); +        float yadj = (float) (Math.sin(r) * offset); +        x0 -= xadj; +        y0 -= yadj; + +        float a = (float) Math.toDegrees(r); +        float dx = (x1 - x0); +        float dy = (y1 - y0); +        float w = (float) Math.sqrt((dx * dx) + (dy * dy)); + +        // timing +        float delay = (random.nextFloat() * TIME_SCATTERING); +        float shot_duration = ((random.nextFloat() * TIME_SCATTERING) + (w / SHOT_SPEED)); +        float explosion_duration = (explosion.cols * EXPLOSION_FRAME_DURATION); + +        this.elapsed = 0f; +        this.fire_time = delay; +        this.hit_time = (fire_time + shot_duration); +        this.end_time = (hit_time + explosion_duration); + +        // shot vars +        this.shot_a = a; +        this.shot_x = x0; +        this.shot_y = y0; +        this.shot_w = 0; +        this.shot_dx = (dx / shot_duration); +        this.shot_dy = (dy / shot_duration); +        this.shot_dw = (w  / shot_duration); + +        // smoke var +        this.smoke_dx = 0f; +        this.smoke_df = (shot.rows / explosion_duration); +        this.smoke_frame = 0; + +        // explosion vars +        this.explosion_x = (x1 - (explosion.width / 2.0f)); +        this.explosion_y = (y1 - (explosion.height / 2.0f)); +        this.explosion_df = (explosion.cols / explosion_duration); +        this.explosion_frame = (random.nextInt(explosion.rows) * explosion.cols); + +        soundId = -1; +    } + +    @Override +    public void reset() +    { +    } + +    @Override +    public void dispose() +    { +        shotAnimationPool.free(this); +    } + +    @Override +    public boolean animate(float delta) +    { +        elapsed += delta; + +        if (!fired && (elapsed < fire_time)) +            return false; + +        if (!fired) { +            fired = true; +            soundId = sound.play(volume); +        } + +        if (!hit && (elapsed < hit_time)) { +            shot_w += (shot_dw * delta); +            shot_x += (shot_dx * delta); +            shot_y += (shot_dy * delta); +            shotRegion.setRegionWidth((int) shot_w); +            return false; +        } + +        if (!hit) { +            hit = true; +            // TODO hit sound +        } + +        if (elapsed < end_time) { +            int frame = (int) ((elapsed - hit_time) * smoke_df); +            if (frame != smoke_frame) { +                smoke_frame = frame; +                shotRegion.setRegion(shot.frames[smoke_frame]); +                shotRegion.setRegionWidth((int) shot_w); +            } +            return false; +        } + +        return true; +    } + +    @Override +    public void draw(Batch batch) +    { +        if (fired) +            batch.draw(shotRegion, shot_x, shot_y, 0, 0, shotRegion.getRegionWidth(), shotRegion.getRegionHeight(), 1f, 1f, shot_a); + +        if (hit) { +            int frame = (explosion_frame + (int) ((elapsed - hit_time) * explosion_df)); +            batch.draw(explosion.frames[frame], explosion_x, explosion_y); +        } +    } + +    @Override +    public void drawDebug(ShapeRenderer debugShapes) +    { +        debugShapes.end(); +        debugShapes.begin(ShapeRenderer.ShapeType.Line); +        debugShapes.identity(); +        debugShapes.translate(shot_x, shot_y, 0); +        debugShapes.rotate(0, 0, 1, shot_a); +        debugShapes.translate(-shot_x, -shot_y, 0); +        debugShapes.rect(shot_x, shot_y, shot_w, shot.height); +        debugShapes.end(); +        debugShapes.begin(ShapeRenderer.ShapeType.Line); +        debugShapes.identity(); +    } +} | 
