Home > Software engineering >  How to constantly alternate between sprites in an array?
How to constantly alternate between sprites in an array?

Time:06-14

Beginner: I'm following a Flappy Bird tutorial and attempting to have my bird player flap its wings continuously. The code in the tutorial video works, but I'm looking use my own code for the same functionality. I don't want to get in the habit of copy/pasting code when there are multiple solutions to solve the same problem.

The code from the video below:

private SpriteRenderer sr;
public Sprite[] sprites;
private int spriteIndex = 0;

private void start()

InvokeRepeating("AnimateSprite", .25f, .25f);


private void AnimateSprite()
{
    spriteIndex  ;
    if (spriteIndex >= sprites.Length)
    {
        spriteIndex = 0;
    }

    sr.sprite = sprites[spriteIndex];
}

This works. However, when attempting to create my own solution, I can not get the sprite to alternate. My code also interferes with the gravity and jump function of my bird. Here is my code.

private SpriteRenderer sr;
public Sprite[] sprites;
private int spriteIndex = 0;

void update()
{
AnimateSprite();
}

 private void AnimateSprite()
{

    for (int i = 0; i < sprites.Length; i  )
    {

        sr.sprite = sprites[spriteIndex];
        StartCoroutine(SpriteChangeTime(.25f));
        spriteIndex  ;
        

        if (spriteIndex >= sprites.Length)
        {
            spriteIndex = 0;
            AnimateSprite();
        }
    }

}

private IEnumerator SpriteChangeTime(float waitTime)
{
    yield return new WaitForSeconds(waitTime);
}

My goal was to use a coroutine combined with a for loop. I also believe I made the function recursive.

Can someone explain why my code does not work? Is there a solution that includes some form of a timer or for loop?

I'd appreciate any input. Thank you, and please let me know how/if I should format my question differently to better follow stackoverflow etiquette and make it easier to read.

CodePudding user response:

It doesn't work because update function is called 60 times/second. Your first solution is fine. As an alternative you could use some sort of timer:

private SpriteRenderer sr;
public Sprite[] sprites;
private int spriteIndex = 0;
private float timeBetweenFrames = 0.25f;
private float currentTimeFrame;

void update()
{
    currentTimeFrame  = Time.deltaTime;
    if(currentTimeFrame >= timeBetweenFrames) 
    {
        currentTimeFrame = 0;
        AnimateSprite();
    }
}

private void AnimateSprite()
{
    spriteIndex  ;
    if (spriteIndex >= sprites.Length)
    {
        spriteIndex = 0;
    }

    sr.sprite = sprites[spriteIndex];
}

CodePudding user response:

You want to wait .25 seconds to replace each sprite and use coroutine for this purpose. Keep in mind that IEnumerator can only include a stop time within itself. So calling it outside the update method does not help at all. To use your own solution, you need to call IEnumerator directly and enter the original code in it, just set the wait time to switch each sprite.

private IEnumerator AnimateSprite(float waitTime)
{
   for (int i = 0; i < sprites.Length; i  )
   {

      sr.sprite = sprites[spriteIndex];
      spriteIndex  ;
      
      if (spriteIndex >= sprites.Length) spriteIndex = 0;
      
      yield return new WaitForSeconds(waitTime);
   }
}
void Start() => StartCoroutine(AnimateSprite(.25f));

Also, if you want your loop to last forever, use the while loop instead of for.

while (true)
{
    sr.sprite = sprites[spriteIndex];
    
    spriteIndex =   spriteIndex % sprites.Length;

    yield return new WaitForSeconds(waitTime);
}
  • Related