classinstances

C# Instances share same values


programming student here, quite new to what i am about to ask but i'm sure you people will know. I have to make a game where several pictureboxes are created using an array. I also have to make a class that has a health variable of 5. When you click on one of the pictureboxes, its health has to go down by 1. I am as far as this, but the problem is that the health variable is shared by all pictureboxes, where in reality I want every picturebox to have it's own health.

This is my code:

public partial class Form1 : Form
{

    Invader monster; // Invader is the name of the class
    Random rand = new Random();
    PictureBox[] pb = new PictureBox[5];

    private void Spawner()
    {
        for (int i = 0; i < 5; i++)
        {
            this.monster = new Invader();
            this.pb[i] = new PictureBox();
            this.pb[i].Name = "pb" + i.ToString();
            this.pb[i].Location = new Point(rand.Next(10, 300), monster.LocY);
            this.pb[i].BackgroundImageLayout = ImageLayout.Stretch;
            this.pb[i].BackgroundImage = Image.FromFile(@"Path");
            this.pb[i].BackColor = Color.Transparent;
            this.pb[i].Size = new System.Drawing.Size(40, 30);
            this.Controls.Add(this.pb[i]);
            this.pb[i].Click += this.Form1_Click;
        }
    }

    private void Form1_Click(object sender, EventArgs e)
    {
        PictureBox currentpicturebox = (PictureBox)sender;

        this.monster.HealthDown();
        if (this.monster.Health == 0)
        {
            currentpicturebox.Dispose();
        }

    }

and my class:

class Invader
{
    // Fields
    private int health;

    // Properties
    public int Health
    {
        get { return this.health; }
    }

    // Constructor
    public Invader()
    {
        this.health = 5;
    }
    // Methods
    public void HealthDown()
    {
            this.health -= 1;
    }

Lets say i click 1 picture box 4 times, and click another one 1 time. With this code the picturebox last clicked on will be disposed. Any ideas on how to fix this?


Solution

  • Your Invader monster is an instance variable of Form1 and in your method Spawner() inside the for loop you are reassigning it again every time: this.monster = new Invader();

    Basically when you click on a picturebox (isn't different what) in your Form1_Click method happen that is everytime your last monster istance that get it's health down and not the supposed one.

    In order to fix this you can:

    Here an example:

    public partial class Form1 : Form
    {
        // EDIT - Become an array
        Invader[] monster = new Invader[5]; // Invader is the name of the class
        Random rand = new Random();
        PictureBox[] pb = new PictureBox[5];
    
        private void Spawner()
        {
            for (int i = 0; i < 5; i++)
            {
                this.monster[i] = new Invader(); // EDIT
                this.pb[i] = new PictureBox();
                this.pb[i].Name = "pb" + i.ToString();
                this.pb[i].Location = new Point(rand.Next(10, 300), monster.LocY);
                this.pb[i].BackgroundImageLayout = ImageLayout.Stretch;
                this.pb[i].BackgroundImage = Image.FromFile(@"Path");
                this.pb[i].BackColor = Color.Transparent;
                this.pb[i].Size = new System.Drawing.Size(40, 30);
                this.Controls.Add(this.pb[i]);
                this.pb[i].Click += this.Form1_Click;
                this.pb[i].Tag = i; // EDIT - Added tag assignation
            }
        }
    
        private void Form1_Click(object sender, EventArgs e)
        {
            PictureBox currentpicturebox = (PictureBox)sender;
            this.monster[(int)currentpicturebox.Tag].HealthDown(); // EDIT
            if (this.monster[(int)currentpicturebox.Tag].Health == 0) //EDIT
            {
                currentpicturebox.Dispose();
            }
        }