Enemy audio and sprite sheet won't start/change when player is seen

69 views Asked by At

For my program, I'm generating randomly placed enemies on a windows form and have them wander around when the player is not in sight. When the player gets within range of the player, they will follow and attack the player until the player gets out of range again.

Now, all that code works perfectly fine, but what I'm having trouble with is that when the enemy sees the player, I want to change the enemy's sprite sheet (a black eyed worm-thing, in this case), to a different sprite sheet showing that it is 'hostile'. At the same time, an audio cue will start playing and will not stop until the player is out of range.

Also, I'm not sure if this is relevant or not, but after a certain interval, a new enemy will appear, so there is multiple enemies on the screen

I'm not sure why, but the enemy sprites won't switch sprite sheets and the audio won't start playing when the player's in view with the code I have. What am I doing wrong?

Here's the code:

  //The timer to determine direction, the current sprite sheet for the enemies, and whether or not the audio is enabled
    private void wander_Tick(object sender, EventArgs e)
    {
        int count = 0;
        List<bool> seenOrNot = new List<bool>(); // a List of bools

         //Iterates through a list of enemies
        foreach (Enemies en in enemyList)
        {
            Enemies enemy = en;

                if (CurrentPosition.Hostile[count])
                {
                  //The 'hostile' sprite sheet for the enemy
                    enemy = new Enemies(Properties.Resources.WormSheet, CurrentPosition.enemyX[count], CurrentPosition.enemyY[count], Sapling.ReturnWidth(), Sapling.ReturnHeight());
                    seenOrNot.Add(true); //The player has been seen
                }
                else
                {
                    //The 'neutral' sprite sheet for the enemy
                    enemy = new Enemies(Properties.Resources.WormSheetNeutral, CurrentPosition.enemyX[count], CurrentPosition.enemyY[count], Sapling.ReturnWidth(), Sapling.ReturnHeight());
                    seenOrNot.Add(false); //The player hasn't been seen
                }
                en.Direction(); //Generates a random number every tick of the timer
                count++;
        }

        //This foreach loop will play audio when any of the enemies sees the player
        foreach (Boolean b in seenOrNot)
        {
            if (seenOrNot.Contains(true))
            {
                wplayer.controls.play();//Plays music when player is in view
            }
            else
            {
                wplayer.controls.stop();//Stops the music
            }
        }
    }

Any help is appreciated, as always :)

So I have this code so far for the function to change the sprite sheet:

   public void ChangeSpriteSheet()
    {
        if (Hostile)
        {
            enemySprite = Properties.Resources.WormSheet;
            CurrentPosition.seen = true;

        }
        else
        {
            enemySprite = Properties.Resources.WormSheetNeutral;
        }

    }

And I changed the wander timer to this:

  private void wander_Tick(object sender, EventArgs e)
    {
        CurrentPosition.seen = false;
        int count = 0;
        foreach (Enemies en in enemyList)
        {
            en.ChangeSpriteSheet(); //Changes the sprite sheet for the current enemy

            en.Direction(); //Generates a random number every tick of the timer
            count++;
        }

        //This foreach loop will play audio when any of the enemies sees the player
            if (CurrentPosition.seen)
            {
                wplayer.controls.play();//Plays music when player is in view
            }
            else
            {
                wplayer.controls.stop();//Stops the music
            }           
    }

The function to change the sprite sheet is called in this 'wander' timer, and it should iterate through every enemy to check whether or not the sprite sheet should be changed.

With this, the audio works fine, it'll start when the player is in range, and stop when they're out of it.

But I'm still not too sure how I would go about changing the sprite sheet for the enemies. I changed the code so that the actual image/sprite sheet is set in the Enemies class rather than the Windows Form, so it's all in the same place, but I'm not sure where to go from there.

In response to the comments, do you guys mean something like this?

   public Image NeutralHostile() //Returns the current sprite sheet 
    {
        return enemySprite;
    }

    public void ChangeSpriteSheet(Image image)
    {

        if (Hostile)
        {
             image= Properties.Resources.WormSheet;
            CurrentPosition.seen = true;
        }
        else
        {
            image = Properties.Resources.WormSheetNeutral;

        }
    }

Then in the timer I'd reference to the NeutralHostile function as a parameter for the ChangeSpriteSheet. Am I going in the right direction, or am I completely off?

1

There are 1 answers

7
nvoigt On

enemy = new Enemies( ...

This line is not doing what you think it does. It creates a new Enemy and lets your enemyvariable point at it. Note: the en variable or the instance of the enemy in your list has not changed.

You need to write a method that let's an existing enemy change it's spritesheet and then call it on your en variable.

As for the sound: you don't need a list of bools. You need a single bool starting as false that is only set to true when one is seen. Then you need a simple if. Your loop is not making any sense to me. Try to simplify it down to the single bool.