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\$
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);
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ A simpler solution could be to use Math.abs(Math.sin(alpha)); \$\endgroup\$ – dfour Nov 9 '17 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 Nov 9 '17 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 Nov 9 '17 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.

| improve this answer | |
\$\endgroup\$

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.