package net.mostlyoriginal.ns2d.system.active;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Wire;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import net.mostlyoriginal.ns2d.api.PassiveSystem;
import net.mostlyoriginal.ns2d.component.*;
import net.mostlyoriginal.ns2d.system.passive.AssetSystem;
/**
* Wrapper for particles. we can make this more efficient later.
*
* @author Daan van Yperen
*/
@Wire
public class ParticleSystem extends PassiveSystem {
public static final float EXPLOSION_FRAME_DURATION = 1/15f;
ComponentMapper<Anim> am;
AssetSystem assetSystem;
private float rotation;
public void spawnParticle(int x, int y, String particle) {
switch ( particle )
{
case "explosion":
createExplosion(x,y, 1f);
break;
case "tiny-explosion":
createExplosion(x, y, 0.5f);
break;
case "muzzle-flare":
createMuzzleFlare(x, y);
break;
case "bulletcasing":
createBulletCasing(x, y);
break;
case "shellcasing":
createShellCasing(x, y);
break;
case "debris":
createDebris(x, y);
break;
case "alienblood":
createAlienBlood(x, y);
break;
case "gasburn":
createGasBurn(x, y);
break;
case "puff":
createPuff(x, y);
break;
case "bile":
createBile(x, y);
break;
}
}
private void createAlienBlood(int x, int y) {
createWoundParticle(x, y, "particle-alienblood");
}
Vector2 vTmp = new Vector2();
private void createDebris(int x, int y) {
createWoundParticle(x, y, "particle-debris");
}
private void createWoundParticle(int x, int y, String animId) {
vTmp.set(MathUtils.random(200, 500), 0).rotate(rotation);
final Physics physics = new Physics();
physics.vr = MathUtils.random(-90, 90)*10f;
physics.vx = vTmp.x;
physics.vy = vTmp.y;
physics.friction = 0.02f;
final TextureRegion frame = assetSystem.get(animId).getKeyFrame(0);
Entity entity = basicCenteredParticle(x, y, animId, 1, 1)
.edit()
.add(new Terminal(4f, 3.5f))
.add(physics)
.add(new Bounds(frame))
.add(new Gravity()).getEntity();
Anim anim = am.get(entity);
anim.speed = 0;
anim.age = MathUtils.random(0,10f);
}
private void createShellCasing(int x, int y) {
Entity entity = basicShellParticle(x, y, "particle-shellcasing");
am.get(entity).layer= Anim.Layer.DIRECTLY_BEHIND_PLAYER;
}
private void createBulletCasing(int x, int y) {
Entity entity = basicShellParticle(x, y, "particle-bulletcasing");
am.get(entity).layer= Anim.Layer.DIRECTLY_BEHIND_PLAYER;
}
private void createGasBurn(int x, int y) {
vTmp.set(50, 0).rotate(rotation-90);
final Physics physics = new Physics();
physics.friction = 0.1f;
physics.vx = vTmp.x;
physics.vy = vTmp.y;
physics.friction = 0.1f;
Animation animation = assetSystem.get("particle-jetpack");
final TextureRegion frame = animation.getKeyFrame(0);
Entity entity = basicCenteredParticle(x, y, "particle-jetpack", 1, 1)
.edit()
.add(new Terminal(animation.getAnimationDuration(), 0.1f))
.add(physics)
.add(new Bounds(frame)).getEntity();
am.get(entity).layer = Anim.Layer.DIRECTLY_BEHIND_PLAYER;
}
private void createPuff(int x, int y) {
vTmp.set(100, 0).rotate(rotation-90);
final Physics physics = new Physics();
physics.friction = 0.1f;
physics.vx = vTmp.x;
physics.vy = vTmp.y;
physics.friction = 0.1f;
Animation animation = assetSystem.get("particle-puff");
final TextureRegion frame = animation.getKeyFrame(0);
Entity entity = basicCenteredParticle(x, y, "particle-puff", 1, 1)
.edit()
.add(new Terminal(3,3))
.add(physics)
.add(new Bounds(frame)).getEntity();
Anim anim = am.get(entity);
anim.layer = Anim.Layer.DIRECTLY_BEHIND_BEHIND_PLAYER;
anim.age = MathUtils.random(999f);
anim.speed = 0;
}
private Entity basicShellParticle(int x, int y, String animId) {
final Physics physics = new Physics();
physics.vr = MathUtils.random(-90, -80)*10f;
physics.vx = MathUtils.random(-90, -80)*1.5f;
physics.vy = MathUtils.random(100, 110)*1.5f;
physics.friction = 0.1f;
final TextureRegion frame = assetSystem.get(animId).getKeyFrame(0);
return basicCenteredParticle(x, y, animId, 1, 1)
.edit()
.add(new Terminal(1.5f,0.5f))
.add(physics)
.add(new Bounds(frame))
.add(new Gravity()).getEntity();
}
private void createBile(int x, int y) {
final Physics physics = new Physics();
physics.vr = MathUtils.random(-90, 90)*10f;
physics.vx = MathUtils.random(-90, 90)*1.5f;
physics.vy = MathUtils.random(100, 110)*1.5f;
physics.friction = 0.1f;
final TextureRegion frame = assetSystem.get("bile-droplet").getKeyFrame(0);
Entity entity = basicCenteredParticle(x, y, "bile-droplet", 1, 1)
.edit()
.add(new Terminal(4f, 3.5f))
.add(physics)
.add(new Bounds(frame))
.add(new Gravity()).getEntity();
am.get(entity).layer = Anim.Layer.DIRECTLY_BEHIND_PLAYER;
}
private void createMuzzleFlare(int x, int y) {
basicCenteredParticle(x, y, "particle-muzzleflare", 1, 1)
.edit()
.add(new Terminal(1 / 15f))
;
}
private void createExplosion(int x, int y, float scale) {
float speed = MathUtils.random(0.8f,1f);
basicCenteredParticle(x, y, "particle-explosion", scale, speed)
.edit().add(new Terminal(EXPLOSION_FRAME_DURATION * 5 * (1 / speed)))
;
}
/**
* Spawns a particle, animation centered on x,y.
*
* @param x
* @param y
* @param animId
* @return
*/
private Entity basicCenteredParticle(int x, int y, String animId, float scale, float speed) {
Anim anim = new Anim(animId);
anim.scale=scale;
anim.speed=speed;
anim.color.a= 0.9f;
anim.rotation=rotation;
TextureRegion frame = assetSystem.get(animId).getKeyFrame(0);
return world.createEntity()
.edit()
.add(new Pos(x - ((frame.getRegionWidth() * anim.scale) / 2), y - (frame.getRegionHeight() * anim.scale) / 2))
.add(anim).getEntity();
}
public void setRotation(float rotation) {
this.rotation = rotation;
}
}