1

I'm making a 2D tile map for a game. I Have a Cell class (tiles) makes cell objects that have 4 attributes: TopWall, BottomWall, LeftWall, RightWall. The wall may or may not be there, so those attributes are boolean true or false, and if they are true, a line will be drawn down that cell wall (not allowing the player to pass through the cell). I want to declare a (2 dimensional? As in, row, and column) array of my cell objects called Map1 (as they will make up a game map). Then i want to set each member of the array to having specific wall attributes. Here is what i have:

Cell.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Map
{
    public class Cell : PictureBox
    {
        bool LeftWall; 
        bool TopWall; 
        bool RightWall;
        bool BottomWall;

        public Cell(bool TopWall, bool RightWall, bool BottomWall, bool LeftWall)
        {
            this.TopWall = TopWall;
            this.RightWall = RightWall;
            this.BottomWall = BottomWall;
            this.LeftWall = LeftWall;
        }
    }
}

This is me starting to attempt making the array of cell objects and set the wall attributes: Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Map
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Array of tiles
        /// </summary>
        //PictureBox[,] Boxes = new PictureBox[4,4];
        public void initiateArray()
        {
            Cell[,] Map1 = new Cell[4, 4];

            for (int row = 0; row < 4; row++)
            {
                for (int column = 0; column < 4; column++)
                {
                    Map1[row, column] = new Cell();
                }
            }

            Map1[0, 0] = new Cell(true, false, false, true);
            Map1[0, 1] = new Cell(false, false, false, true);
        }


      /*int [][] Walls = new int[][] {
      new int[] {0,0}, new int[] {1,0,0,1},
      new int[] {1,0}, new int[] {1,0,1,0},
      new int[] {0,1}, new int[] {0,0,0,1}, 
      new int[] {1,1}, new int[] {1,1,1,0}, 
      new int[] {2,0}, new int[] {1,1,0,0},
      new int[] {2,1}, new int[] {0,0,0,1}, 
      new int[] {3,1}, new int[] {1,0,1,0}, 
      new int[] {0,2}, new int[] {0,0,1,1}, 
      new int[] {1,2}, new int[] {1,0,1,0}, 
      new int[] {2,2}, new int[] {0,1,1,0}};*/



        #region Runtime load
        /// <summary>
        /// Build the map when window is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            BuildMap();
        }
        #endregion

        #region Build grid
        /// <summary>
        /// Draw every tile on the map
        /// </summary>
        public void BuildMap()
        {
            for (int row = 0; row < 3; row++)
            {
                for (int column = 0; column < 3; column++)
                {
                    DrawCell(row, column);
                }
            }
            //draw the exit box
            DrawCell(1, 3);
        }
        #endregion

        #region Draw
        /// <summary>
        /// Draw one tile
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        public void DrawCell(int row, int column)
        {
            Map1[row, column] = new Cell();
            Map1[row, column].Height = 100;
            Map1[row, column].Width = 100;
            Map1[row, column].BorderStyle = BorderStyle.FixedSingle;
            Map1[row, column].BackColor = Color.BurlyWood;
            Map1[row, column].Location = new Point((Map[row, column].Width * column), (Map[row, column].Height * row));
            this.Controls.Add(Map1[row, column]);

           // System.Drawing.Pen myPen;
           // myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
            //System.Drawing.Graphics formGraphics = this.CreateGraphics();


            //formGraphics.DrawLine(myPen, 0, 0, 200, 200);
            //myPen.Dispose();
            //formGraphics.Dispose();
        }



        public void DrawWalls(int row, int column)
        {

        }
        #endregion
    }


}

It is showing a lot of errors and i was wondering if anyone can see where i'm going wrong. Thanks.

4
  • There is a lot but one i would like to know about is when you hover over Map1 it says "a namespace cannot directly contain members such as fields and methods". And before it was saying Map1 is being used as a type when it is not. Hoping someone can see the code and see it's clearly wrong and show the way. It is to do with Map1 Commented Aug 20, 2013 at 4:09
  • Most important issue - you have to put your code into a method. It can't be on a class level. Commented Aug 20, 2013 at 4:32
  • @MarcinJuraszek thanks just updated it, but i try to call the new method straight after i make it, and it won't let me. Also it says Map1 does not exist in the current context. Commented Aug 20, 2013 at 4:45
  • The StackOverflow colors might be a bit off but to me it looks like you are trying to access a method variable from an outside scope. You can not access Map1 variable from outside of the context of the containing method. Did you try to make it a public property in Form1? Commented Aug 20, 2013 at 5:59

2 Answers 2

2

First make sure PictureBox has a non-parameterized constructor implemented.

Second and thrid Map1[i] = new Cell(); You initialized a matrix, you need two nested loops to traverse the whole thing and you need to access it by using the comma notation [row, col]. you use row not i in your loop.

Fourth you are missing a 'new' at the end Map1[0,0] = Cell(true, false, false, true);

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. ` for (int row = 0; row < Map1.length; row++) { for (int column = 0; column < Map1.length; column++) { Map1[row, column] = new Cell(); } } Map1[0,0] = new Cell(true, false, false, true);` Is that right? PictureBox can have an empty constructor
1

Common mistake. Cell[][] is not the same as Cell[,].

Also

var foo = new Cell[4,4];
Console.WriteLine(foo.Length);

Gives 16 and NOT 4, as your code assumed.

This is how you should do it, if you want to use the array's "Length" information.

    public void initiateArray()
    {
        Cell[,] Map1 = new Cell[4, 4];

        for (int row = 0; row < Map1.GetLength(0); row++)
        {
            for (int column = 0; column < Map1.GetLength(1); column++)
            {
                Map1[row, column] = new Cell();
            }
        }

        Map1[0, 0] = new Cell(true, false, false, true);
        Map1[0, 1] = new Cell(false, false, false, true);
    }

or (since I have absolutely no faith in my own ability in Off By One bugs, using Linq)

    public void initiateArray()
    {
        Cell[,] Map1 = new Cell[4, 4];

        foreach(var row in Enumerable.Range(0, Map1.GetLength(0)))
        foreach(var column in Enumerable.Range(0, Map1.GetLength(1)))
        {
                Map1[row, column] = new Cell();         
        }
        Map1[0, 0] = new Cell(true, false, false, true);
        Map1[0, 1] = new Cell(false, false, false, true);
    }

4 Comments

Thanks, i do want 16 cells. I want a 4x4 grid. I should be using [][]?
What I mean is that originally you were iterating over int row = 0 to 15 (to mix my VB/C#). Which obviously would give you an IndexOutOfRangeException when row >= 4.
Thanks. I have copied and pasted the second method you posted. I have called InitiateArray in the constructor of Form1 class. Is there a way i can print the contents of map1 to check that the two Cell members inside Map1 array are correct? I am very new to C# and only really familiar with JavaScript HTML5 canvas apps
Of course you can use Console.WriteLine() however I suggest you learn to use the VS debugger. Just whack in a breakpoint and run the code in debug mode. When the program is paused you have the Local/Watcher windows and you can hover over any variable to see whats inside. Look up a tutorial on how to debug .net.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.