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\$
2
  • \$\begingroup\$ No it is not impossible. Read -> here \$\endgroup\$
    – Fish
    Commented Apr 19, 2015 at 17:58
  • \$\begingroup\$ is it the same for the 2d particle system? \$\endgroup\$
    – Rothens
    Commented Apr 19, 2015 at 18:01

3 Answers 3

1
\$\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
  • 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
    Commented Apr 12, 2016 at 5:03
  • \$\begingroup\$ Does not work if your particles do not have the same width than height. \$\endgroup\$
    – Winter
    Commented Feb 9, 2018 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\$
0
\$\begingroup\$

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

\$\endgroup\$
1
  • 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\$
    – House
    Commented Jul 28, 2015 at 13:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .