2D Array not being drawn in Form

Viewed 53

I am in the process of creating an escape room game in c#. It is made up of a 10x10 2D array of the class "Tiles" (with a rectangle instance variable), which are drawn onto the form by a method of the "Room" class. There are three different methods involved in the construction of the Room: "buildRoom" (called within the constructer) which builds up the 2D array, "setPoints" which sets up the entry and exit points, and "drawRoom", which uses a graphics object to draw the rectangles on the form. I originally called these methods within Form1 after creating an object of room, but since I have copied this over into a new Form class it is no longer working. The program runs, adding pictures and accepting key presses as movements, but it just doesn't draw on the form. I've tried stepping through the program but everything looks as if it should work. Any help would be appreciated in figuring this out.

This is the code for setting up the Form, and calling the method to draw.

public void GameSetUp()
        {
            this.Height = 560;
            this.Width = 535;

            Room room1 = new Room();

            room1.buildRoom();

            room1.setPoints("room1");

            this.Text = "Room 1";
            
//passing the form into the method
            **room1.displayRoom(this);**

            Character user = new Character();
            StateManager.C = user;

            StateManager.C.addCharacter(room1, this, "room1");

        }

Code for setting up the 2D Array:

public void buildRoom()
        {
            int xPos = 10;
            int yPos = 10;
            int width = 50;
            int height = 50;

            for (int x = 0; x < 10; x++)
            {
                for (int y = 0; y < 10; y++)
                {
                    Tile t = new Tile();
                    t.rect = new Rectangle(xPos, yPos, width, height);
                    Board[x, y] = t;
                    yPos += height;
                }
                xPos += width;
                yPos = 10;
            }
        }

Code for drawing the rectangles onto the Form:

public void displayRoom(Form f)
        {
            Graphics g = f.CreateGraphics();

            Pen p = new Pen(Brushes.Black);
            p.Width = 2;

          
           for (int x = 0; x < 10; x++)
            {
                for (int y = 0; y < 10; y++)
                {
                    g.DrawRectangle(p, Board[x,y].rect);

                    if(Board[x, y].getEntry())
                    {
                        g.FillRectangle(Brushes.Green, Board[x, y].rect);
                    }
                    else if (Board[x, y].getExit())
                    {
                        g.FillRectangle(Brushes.Red, Board[x, y].rect);
                    }
                    else if (Board[x, y].getProblem())
                    {
                        g.FillRectangle(Brushes.SaddleBrown, Board[x, y].rect);
                    }
                    else
                    {
                        g.FillRectangle(Brushes.Bisque, Board[x, y].rect);
                    }
                }
            }
1 Answers

The problem seems not apparent from these code snippets. Try to debug your code. Maybe you are drawing to early, e.g. when the form is not yet visible?

Also, this is not the right way to draw in forms. It is the operating system (Windows), which decides when a form has to be drawn. E.g. when another form on top of yours is removed or when you restore the window from minimized state.

Therefore, you must override OnPaint and do the painting there. When you want to repaint, you can call Invalidate() (a method of a Form and of all controls) and let Windows decide when to repaint (i.e., when to call OnPaint) or call Refresh() to force an immediate repaint.

protected override void OnPaint(PaintEventArgs e) {
    base.OnPaint(e); // Call the OnPaint method of the base class.

    Graphics g = e.Graphics; // Do not create your own Graphics object.

    using Pen p = new Pen(Brushes.Black);  // A using var statement or a plain
                                           // using statement must the pen.
    p.Width = 2;

    for (int x = 0; x < 10; x++)
    {
        for (int y = 0; y < 10; y++)
        {
            g.DrawRectangle(p, Board[x,y].rect);

            if(Board[x, y].getEntry())
            {
                g.FillRectangle(Brushes.Green, Board[x, y].rect);
            }
            else if (Board[x, y].getExit())
            {
                g.FillRectangle(Brushes.Red, Board[x, y].rect);
            }
            else if (Board[x, y].getProblem())
            {
                g.FillRectangle(Brushes.SaddleBrown, Board[x, y].rect);
            }
            else
            {
                g.FillRectangle(Brushes.Bisque, Board[x, y].rect);
            }
        }
    }
}

Btw.: Your code looks Java-ish. In C# one would use PascalCase for methods and properties, where you would use the property syntax for properties instead of plain getXY and setXY methods.

See also:

Related