7
\$\begingroup\$

I have a libGDX game, in which I'd like to make some ice breath like effect using particles. So far we made a cone like effect. I can obtain and render it on the screen with this.

ParticleEffectPool.PooledEffect effect = breathPool.obtain();
effect.setPosition(x,y);
ps.add(effect);

But I don't really see any way to rotate the entire particle system in a given direction. Is there any way to achieve this?

\$\endgroup\$
  • \$\begingroup\$ No it is not impossible. Read -> here \$\endgroup\$ – Fish Apr 19 '15 at 17:58
  • \$\begingroup\$ is it the same for the 2d particle system? \$\endgroup\$ – Rothens Apr 19 '15 at 18:01
2
\$\begingroup\$

You could try picking out the angle property of your emitter (or emitters if you have many) and manually adjust the values to center around some angle.

ParticleEffect effect = /* your effect */
ParticleEmitter emitter = effect.findEmitter("some_name"); // find the emitter you want to     rotate here
float targetAngle = /* your target angle */

ScaledNumericValue angle = emitter.getAngle();

/* find angle property and adjust that by letting the min, max of low and high span their current size around your angle */

float angleHighMin = angle.getHighMin();
float angleHighMax = angle.getHighMax();
float spanHigh = angleHighMax - angleHighMin;
angle.setHigh(angle - spanHigh / 2.0f, angle + spanHigh / 2.0f);

float angleLowMin = angle.getLowhMin();
float angleLowMax = angle.getLowMax();
float spanLow = angleLowMax - angleLowMin;
angle.setLow(angle - spanLow / 2.0f, angle + spanLow / 2.0f);

Note that the above would just adjust what the high and low are, and you'll most likely need to do something about it wrapping around.

\$\endgroup\$
  • 2
    \$\begingroup\$ This worked! You mean to use targetAngle in setHigh() and setLow(), but forgot...and you there's a typo in getLowMin(). Works fine otherwise. \$\endgroup\$ – Max Apr 12 '16 at 5:03
  • \$\begingroup\$ Does not work if your particles do not have the same width than height. \$\endgroup\$ – Winter Feb 9 '18 at 21:10
1
\$\begingroup\$

Here's my own solution for 90° rotations:

/**
 * Created on 2018-02-09.
 *
 * @author Alexander Winter
 */
public class RotatableParticleEffect extends ParticleEffect {
    public RotatableParticleEffect() {}

    public RotatableParticleEffect(ParticleEffect effect) {
        super(effect);
    }

    public void rotateBy(int turnQuarter) {
        while(turnQuarter < 0)
            turnQuarter += 4;

        turnQuarter %= 4;

        for(ParticleEmitter emitter : getEmitters()) {
            ScaledNumericValue angle = emitter.getAngle();

            angle.setHighMax(angle.getHighMax() + turnQuarter * -90f);
            angle.setHighMin(angle.getHighMin() + turnQuarter * -90f);

            angle.setLowMax(angle.getLowMax() + turnQuarter * -90f);
            angle.setLowMin(angle.getLowMin() + turnQuarter * -90f);

            ScaledNumericValue rot = emitter.getRotation();

            rot.setHighMax(rot.getHighMax() + turnQuarter * -90f);
            rot.setHighMin(rot.getHighMin() + turnQuarter * -90f);

            rot.setLowMax(rot.getLowMax() + turnQuarter * -90f);
            rot.setLowMin(rot.getLowMin() + turnQuarter * -90f);

            for(int i = 0; i < turnQuarter; i++) {
                swapFields(emitter.getXOffsetValue(), emitter.getYOffsetValue());

                emitter.getYOffsetValue().setLowMin(-emitter.getYOffsetValue().getLowMin());
                emitter.getYOffsetValue().setLowMax(-emitter.getYOffsetValue().getLowMax());
            }
        }
    }

    private static void swapFields(Object o1, Object o2) {
        if(o1 == null || o2 == null)
            throw new IllegalArgumentException("Objects must not be null");

        if(!o1.getClass().equals(o2.getClass()))
            throw new IllegalArgumentException("Objects are not the same type");

        Class<?> type = o1.getClass();

        while(type != null) {
            for(Field field : type.getDeclaredFields()) {
                if(!field.isAccessible())
                    field.setAccessible(true);

                try {
                    Object tmp = field.get(o1);
                    field.set(o1, field.get(o2));
                    field.set(o2, tmp);
                } catch(IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }
            }

            type = type.getSuperclass();
        }
    }
}

With this solution, you can't rotate with any angle. If you'd need to, you will need to adjust the X and Y offsets with a rotation. offsetY = originalOffsetY * sin(angle) and same for X with cos(). I didn't implement the full solution for any angle because I didn't need it. However, I can confirm this simpler solution works for me.

\$\endgroup\$
-1
\$\begingroup\$

Add the particle effect to a group with transformation enabled (default).

\$\endgroup\$
  • 2
    \$\begingroup\$ This answer could benefit from additional information. How does this solve the problem and are there any more steps to accomplish the goal? \$\endgroup\$ – MichaelHouse Jul 28 '15 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.