user2997877
user2997877

Reputation: 75

Integer stays 0 even when it says it is not

I am creating a level designer for my game, with tiles you can draw on a User Control. To keep track of the tiles, I have made a int[]:

public int[,] Tiles = new int[35, 35];

Because the editing screen is 560px by 560px, 35 16x16 blocks. Tiles[x, y].Id will give the id of the tile.

Id will be the id of the tile. Whenever a tile is placed, It is recorded under a void:

public void Draw(int x, int y, int bid)
{
    //draw code here
    Program.form.Tiles[x, y].Id = bid;
}

And whenever you click, the void is called:

//In the MouseClick void:
Draw(e.X / 16, e.Y / 16, 1);

0 is an available block id, but using 1 for example.

Whenever I go to save it, (I'm saving to .txt files) It should write down the id of tile:

for (int x = 0; x < 35; x++)
{
    for (int y = 0; y < 35; y++)
    {
        //Write code here
        MessageBox.Show(Tiles[x, y].Id.ToString());
    }
}

I just have it display the Id in a message box to see, and it always gives out '0', even when you edit on the certain x, y tile with a blockid that is definatley not 0. Does anyone know why this is? Thanks. By the way, in the 'Program' class, above the STAThread thing, i put:

public Form1 form;

and then:

form = new Form1();
Application.Run(form);

Upvotes: 1

Views: 84

Answers (3)

John Alexiou
John Alexiou

Reputation: 29244

This should work pretty good, except for the horrible flickering. If I where designing this I would use a PictureBox and hook on its Paint() event.

public partial class Form1 : Form
{
    Random rnd=new Random();
    int[,] id;
    public Form1()
    {
        InitializeComponent();
    }

    void Place(int x, int y, int bid)
    {
        int i=x/16, j=y/16;
        id[i, j]=bid;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        id=new int[36, 36];
    }

    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        int bid=rnd.Next(KnownColor.White-KnownColor.AliceBlue);
        Place(e.X, e.Y, bid);

        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        for(int i=0; i<36; i++)
        {
            for(int j=0; j<36; j++)
            {
                int x=16*i, y=16*j;
                Color color=Color.FromKnownColor(KnownColor.AliceBlue+id[i, j]);
                using(Brush brush = new SolidBrush(color))
                {
                    e.Graphics.FillRectangle(brush, x, y, 16, 16);
                }
                e.Graphics.DrawRectangle(Pens.Black, x, y, 16, 16);
            }
        }

    }

    public string SaveToFile()
    {
        string[] cols=new string[36];
        for(int i=0; i<16; i++)
        {
            string[] rows=new string[36];
            for(int j=0; j<36; j++)
            {
                rows[j]=id[i, j].ToString();
            }
            cols[i]=string.Join(",", rows);
        }
        return string.Join(";", cols);
    }

    public void ReadFromFile(string ids)
    {
        string[] cols=ids.Split(';');
        for(int i=0; i<cols.Length; i++)
        {
            string[] rows=cols[i].Split(',');
            for(int j=0; j<rows.Length; j++)
            {
                int temp_id=0;
                int.TryParse(rows[j], out temp_id);
                id[i, j]=temp_id;
            }
        }
    }
}

Screen

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

This is because Tile is a struct - a value type. Therefore,

Program.form.Tiles[x, y]

gives you a copy. You assign Id of that copy, while the original Tile inside the array remains unchanged. This example illustrates why one should be extremely careful when dealing with value types inside arrays or collections.

You can fix this problem by changing the Tile to class. Note that unlike arrays of value types (structs) that always have a default value, elements of an array of reference objects (classes) need to be initialized manually to avoid the "Object reference not set to an instance of an object." errors:

for (int x = 0; x < 35; x++) {
    for (int y = 0; y < 35; y++) {
        Tiles[x, y] = new Tile();
    }
}

Upvotes: 5

Bura Chuhadar
Bura Chuhadar

Reputation: 3751

In your code you are re-creating your form which re-creates your Tiles object. Do not re-create your form. Use it once:

 public void Draw(int x, int y, int bid)
    {
//If they are in the same form then Program.form is not needed:
        Tiles[x, y].Id = bid;
    }

Or reach your object like this:

 Form1 frm = (Form1)Application.OpenForms[0];

        frm.Tiles[x, y].Id = bid;

Upvotes: 0

Related Questions