package com.bitfire.uracer.game.logic.gametasks.trackeffects.effects; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.g2d.ParticleEffect; import com.badlogic.gdx.graphics.g2d.ParticleEmitter; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.bitfire.uracer.URacer; import com.bitfire.uracer.game.logic.gametasks.trackeffects.TrackEffect; import com.bitfire.uracer.game.logic.gametasks.trackeffects.TrackEffectType; import com.bitfire.uracer.game.player.PlayerCar; import com.bitfire.uracer.resources.Art; public class PlayerSmokeTrails extends TrackEffect { public static final int MaxParticles = 1000; private SmokeEffect fx; private static final int SmokeEffectsCount = 1; private Vector2 position = new Vector2(); public PlayerSmokeTrails () { super(TrackEffectType.CarSmokeTrails); fx = new SmokeEffect(this); fx.setMaxParticleCount(MaxParticles); } @Override public void dispose () { } @Override public void player (PlayerCar player) { super.player(player); if (!hasPlayer) { fx.effect.allowCompletion(); } else { fx.effect.reset(); } } @Override public void tick () { if (hasPlayer) { if (fx.effect.isComplete()) { fx.start(); } } } @Override public void render (SpriteBatch batch) { if (hasPlayer) { float dfactor = player.driftState.driftStrength; float sfactor = player.carState.currSpeedFactor; fx.setLifeMul(2f); fx.setScaleMul(1f + 20f * dfactor * sfactor); float t = 0.5f * dfactor; fx.baseEmitter.getTransparency().setHighMin(t); fx.baseEmitter.getTransparency().setHighMax(t); float[] colors = fx.baseEmitter.getTint().getColors(); float v = 0.3f; colors[0] = v * dfactor; colors[1] = v * dfactor; colors[2] = v * dfactor; float r = 0.7f; float g = 0.8f; float b = 1f; if (MathUtils.randomBoolean()) { r = 0.7f; } float colorscale = 0.15f + 0.3f * dfactor; r *= colorscale; g *= colorscale; b *= colorscale; colors[0] = r; colors[1] = g; colors[2] = b; position.set(player.state().position); } fx.render(batch, position.x, position.y); } @Override public void reset () { // fx.reset(); } @Override public int getMaxParticleCount () { return MaxParticles * SmokeEffectsCount; } @Override public int getParticleCount () { return fx.getParticleCount(); } private static final class SmokeEffect { private TrackEffect owner; protected ParticleEffect effect; private ParticleEmitter baseEmitter; private final float MaxParticleLifeMinMs; private final float MaxParticleLifeMaxMs; private final float OriginalParticleScaling; // private final float MaxParticlesPerEmitterPerSec; public SmokeEffect (TrackEffect owner) { this.owner = owner; effect = new ParticleEffect(); effect.load(Gdx.files.internal("data/partfx/smoke-small.p"), Art.particles, ""); baseEmitter = effect.getEmitters().get(0); MaxParticleLifeMinMs = baseEmitter.getLife().getHighMin(); MaxParticleLifeMaxMs = baseEmitter.getLife().getHighMax(); OriginalParticleScaling = baseEmitter.getScale().getHighMax(); // MaxParticlesPerEmitterPerSec = baseEmitter.getEmission().getHighMax(); effect.start(); } public void setLifeMul (float value) { baseEmitter.getLife().setHighMin(MaxParticleLifeMinMs * value); baseEmitter.getLife().setHighMax(MaxParticleLifeMaxMs * value); } public void setMaxParticleCount (int value) { baseEmitter.setMaxParticleCount(value); } public final void setScaleMul (float value) { baseEmitter.getScale().setHigh(OriginalParticleScaling * value); } // public void setEmissionMul (float value) { // baseEmitter.getEmission().setHigh(MaxParticlesPerEmitterPerSec * value); // } public void start () { for (int i = 0; i < effect.getEmitters().size; i++) { effect.getEmitters().get(i).setContinuous(true); effect.getEmitters().get(i).start(); } } // public void stop () { // for (int i = 0; i < effect.getEmitters().size; i++) { // effect.getEmitters().get(i).allowCompletion(); // } // } // public void reset () { // stop(); // } public void render (SpriteBatch batch, float x, float y) { float delta = owner.isPaused() ? 0 : URacer.Game.getLastDeltaSecs() * URacer.timeMultiplier; effect.setPosition(x, y); effect.draw(batch, delta); } public int getParticleCount () { int count = 0, max = effect.getEmitters().size; for (int i = 0; i < max; i++) { count += effect.getEmitters().get(i).getActiveCount(); } return count; } } }