3
\$\begingroup\$

I want to make a sprite blinking like this:

float alpha = .0f;

public void draw(SpriteBatch batch, float delta){
    alpha += delta;
    sprite.draw(batch, (float)Math.sin(alpha));
}

Well, it is blinking, but in a very irregular way. It should go from transparent to non-transparent to transparent and so on. But with that code it is more like non-transparent to transparent - then it almost instantly skips back to non-transparent and goes back to non-transparent.

How can I optimize this?

\$\endgroup\$
1

2 Answers 2

2
\$\begingroup\$

The blinking requires an alpha value that swings 0 and 1. The Sinus function swings between 1 and -1. So to solve the problem, the function has to be multiplied by 0.5 and be added to 0.5, so that the value swings between 0 and 1, like this:

sprite.draw(batch, +5f*(float)Math.sin(alpha) + .5f);
\$\endgroup\$
3
  • \$\begingroup\$ A simpler solution could be to use Math.abs(Math.sin(alpha)); \$\endgroup\$
    – dfour
    Commented Nov 9, 2017 at 15:10
  • 1
    \$\begingroup\$ @dfour actually not; if you call math.abs() on that you wont get that sinus curve. i would not look as good. \$\endgroup\$
    – purpule
    Commented Nov 9, 2017 at 15:27
  • \$\begingroup\$ You do get a sin curve from Math.abs(Math.sin(alpha)); Math.abs will just convert the -0.1 to 0.1. \$\endgroup\$
    – dfour
    Commented Nov 9, 2017 at 15:40
0
\$\begingroup\$

I have tried using 3 methods to create a blinking effect.

  1. The value shifting from @purpule +5f*(float)Math.sin(alpha) + .5f
  2. My suggestion using Math.abs(Math.sin(alpha));
  3. Alternate modulus method.

The Code used to test:

        long startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 0; i < 10000000; i++){
            float val = +5f*(float)Math.sin(i/1000) + 0.5f;
        }
        long endtime = System.currentTimeMillis();
        System.out.println("Total time:"+(endtime - startTime));

        startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 0; i < 10000000; i++){
            float val = (float) Math.abs(Math.sin(i/1000));
        }
        endtime = System.currentTimeMillis();
        System.out.println("Total time:"+(endtime - startTime));

        startTime = System.currentTimeMillis();
        System.out.println(startTime);
        for(int i = 1; i < 10000001; i++){
            float val = i%2;
            float alpha = val>1?1-(val-1):val;              
        }
        endtime = System.currentTimeMillis();
        System.out.println("Total time:"+(endtime - startTime));

The outcome of the tests show that the first 2 methods take about 550-570ms and achive the same sinus wave alpha.

The 3rd method using module takes about 9-15ms which is a lot faster but is not a sine wave, instead it is a saw wave and still achieves the blinking affect.

I suggest you try these and see which one suits you needs the best.

\$\endgroup\$

You must log in to answer this question.

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