package com.igorcrevar.goingunder.objects;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.igorcrevar.goingunder.GameData;
import com.igorcrevar.goingunder.GameManager;
public class ParticleEffect implements IGameObject {
private final int MaxParticles = 60;
private Particle[] particles;
private int countAlive;
private boolean isEnabled;
private Player playerObject;
private GameData gameData;
private float timer;
class Particle {
public Sprite sprite = new Sprite();
private float timer;
private float velocityY;
private float timeToLive;
private float alpha;
private float angle;
private float amplitude;
private float initialPositionX;
public Particle(TextureRegion textureRegion) {
sprite.setRegion(textureRegion);
}
public void init(float x, float y, GameData gameData, boolean isLeft) {
initialPositionX = x;
// left
if (isLeft) {
initialPositionX += -gameData.PlayerSizeX / 2.0f + (float)Math.random() * 0.1f;
}
// right
else {
initialPositionX += +gameData.PlayerSizeX / 2.0f - (float)Math.random() * 0.1f;
}
sprite.setSize(gameData.BubbleSize, gameData.BubbleSize);
sprite.setPosition(initialPositionX, y);
this.velocityY = gameData.BubbleSpeedY + (float)Math.random() * gameData.BubbleSpeedYPotential;
this.timeToLive = (float)Math.random() + 1.0f;
this.timer = 0.0f;
this.alpha = 0.0f;
this.angle = (float)Math.random() * 90.0f;
this.amplitude = 0.1f + 0.1f * (float)Math.random();
}
public boolean update(float deltaTime) {
float x = initialPositionX + (float)(Math.sin(angle) * amplitude);
float y = sprite.getY() + velocityY * deltaTime;
sprite.setPosition(x, y);
timer += deltaTime;
alpha = Math.min(timer / timeToLive, 1.0f);
angle += 5 * deltaTime;
if (angle > 360.0f) angle = angle - 360.0f;
return timer <= timeToLive;
}
public void draw(SpriteBatch spriteBatch) {
sprite.draw(spriteBatch, 1 - alpha);
}
}
public ParticleEffect(GameManager gameManager, Player player, GameData gameData) {
this.gameData = gameData;
this.playerObject = player;
this.particles = new Particle[MaxParticles];
for (int i = 0; i < particles.length; ++i) {
particles[i] = new Particle(gameManager.getTextureAtlas("game").findRegion("bubble"));
}
this.countAlive = 0;
}
@Override
public void init(Object data) {
countAlive = 0;
isEnabled = true;
timer = 0;
}
@Override
public void update(float deltaTime) {
if (!isEnabled) return;
// every n seconds fire bubble from player position
if (timer == 0.0f) {
addNew(playerObject.getX(), playerObject.getY());
}
// randomly fire bubble anywhere on screen
if (Math.random() < 0.03f) {
float x = 2 * gameData.CameraHalfWidth * (float)Math.random() - gameData.CameraHalfWidth;
float y = 2 * gameData.CameraHalfHeight * (float)Math.random() - gameData.CameraHalfHeight;
addNew(x, y);
}
int i = countAlive - 1;
while (i >= 0) {
boolean keepIt = particles[i].update(deltaTime);
if (!keepIt) {
--countAlive;
if (countAlive > 1) {
Particle tmp = particles[i];
particles[i] = particles[countAlive];
particles[countAlive] = tmp;
}
}
--i;
}
timer += deltaTime;
if (timer > 0.5f) {
timer = 0.0f;
}
}
@Override
public void draw(SpriteBatch spriteBatch) {
if (!isEnabled) return;
for (int i = 0; i < countAlive; ++i) {
particles[i].draw(spriteBatch);
}
}
@Override
public boolean isEnabled() {
return isEnabled;
}
@Override
public void setIsEnabled(boolean value) {
isEnabled = value;
}
public void addNew() {
int leftCnt = 2 + (int)(Math.random() * 2.1f);
int rightCnt = 2 + (int)(Math.random() * 2.1f);
addNew(playerObject.getX(), playerObject.getY(), leftCnt, rightCnt);
}
private void addNew(float x, float y) {
int leftCnt = (int)(Math.random() * 2.1f);
int rightCnt = (int)(Math.random() * 2.1f);
addNew(x, y, leftCnt, rightCnt);
}
private void addNew(float x, float y, int cntLeft, int cntRight) {
for (int i = 0; i < cntLeft + cntRight; ++i) {
boolean isLeft = i < cntLeft;
int pos = i + countAlive < MaxParticles ? i + countAlive : i;
particles[pos].init(x, y, gameData, isLeft);
}
countAlive += cntLeft + cntRight;
if (countAlive > MaxParticles) {
countAlive = MaxParticles;
}
}
}