Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

What I am attempting to do probably has a very simple answer but I can't make heads or tails of it no matter how hard I try. Provided I'm a newb.

What I am trying to do is after I create a grid of rectangles, when the cursor moves into the grid, it changes the color of the rectangle the cursor is currently in (or highlights it), then changes back when the cursor leaves. Here's what I've coded so far:

namespace MapGenie
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Rectangle[,] gameGrid;

        MouseState currentMouseState;
        MouseState previousMouseState;

        bool colorChange = false;

        Color color;
        Color previousColor;

    protected override void Initialize()
    {
        //Creates the array
        gameGrid = new Rectangle[10, 10];

        color = Color.Black;

        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        this.IsMouseVisible = true;

        int Gridsize = 20;

        //Creates the grid
        for(int x = 0;x <10;x++)
            for (int y = 0; y < 10; y++)
            {
                gameGrid[x, y] = new Rectangle(x * Gridsize, y * Gridsize, Gridsize, Gridsize);
            }
    }

    protected override void Update(GameTime gameTime)
    {
        currentMouseState = Mouse.GetState();
        var mousePoint = new Point(currentMouseState.X, currentMouseState.Y);
        previousMouseState = currentMouseState;

        //Checks each rectangle in the gameGrid array to see if cursor is there?
        foreach (Rectangle grid in gameGrid)
        {
            if (grid.Contains(mousePoint))
            {
                previousColor = color;
                color = Color.Blue;
                colorChange = true;
            }
            if (colorChange == true)
                color = previousColor;
        }

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();

        var t = new Texture2D(GraphicsDevice, 1, 1);
        t.SetData(new[] { Color.White });

        foreach (Rectangle grid in gameGrid)
            spriteBatch.Draw(t, grid, color);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}
}

Before I added the else statement (Which I am also aware does not work, but I am working to fix that after asking this), the entire grid would turn blue. So, I am not sure if it is the right question or not, but how do you get just the one the cursor is in to turn [color]? Appreciate any input!

share|improve this question
    
Can you copy your constructor too? –  Luis Estrada Feb 26 '12 at 16:05
add comment

2 Answers

To get started remove the previousColor and colorChanged code.

Use these member variables instead:

Color color; //color of unselected rects
Color selectedColor; //color of selected rect
Rectangle currentRect; //current selected rectangle

In your Initialize method:

  color = Color.Black;
  selectedColor = Color.Blue;

change your update method to this:

  //Checks each rectangle in the gameGrid array to see if cursor is there?
  foreach (Rectangle grid in gameGrid)
  {
    if (grid.Contains(mousePoint))
    {
      currentRect = grid;
    }
  }

and your draw code to this:

  foreach (Rectangle grid in gameGrid)
  {
    if (grid == currentRect)
    {
      spriteBatch.Draw(t, grid, selectedColor);
    }
    else
    {
      spriteBatch.Draw(t, grid, color);
    }
  }

For the complete code go here: http://pastebin.com/ecS7bq3m

EDIT (Functastic's Comment):

Okay I don't know C# and this is (obviously) untested, but to convert pixel coordinates to map coordinates it's just:

pixelCoord -= renderOffset;
Point mapCoord = new Point( Math.Floor(pixelCoord.x / cellWidth), Math.Floor(pixelCoord.y / cellHeight) );

Where 'renderOffset' denotes the offset with which the map is rendered (basically its top left corner, in pixels).

share|improve this answer
    
There's really no need to iterate over every grid cell. Finding the cell containing any point in a uniform grid should be O(1). Also, why not just draw the whole grid one colour, then just overlay the selected cell colour? That would save a lot of branching, no? –  Functastic Feb 26 '12 at 20:55
    
Ah, see. I knew it was something elementary as defining a variable. I just couldn't figure it out for the life of me. Perfect. Could you elaborate on what you mean Functastic? –  JFoxx64 Feb 26 '12 at 23:15
    
Another note; the code works great, however if the cursor leaves the grid, the last highlighted grid member remains highlighted (which should be a simple fix, just figured I'd mention it). –  JFoxx64 Feb 26 '12 at 23:34
    
Okay I don't know C# and this is (obviously) untested, but to convert pixel coordinates to map coordinates it's just: [code] pixelCoord -= renderOffset; Point mapCoord = new Point( Math.Floor(pixelCoord.x / cellWidth), Math.Floor(pixelCoord.y / cellHeight) ); [/code] Where 'renderOffset' denotes the offset with which the map is rendered (basically its top left corner, in pixels). –  Functastic Feb 27 '12 at 1:06
    
That turned out almost completely unreadable >_< –  Functastic Feb 27 '12 at 1:14
show 1 more comment
up vote 0 down vote accepted

Alright, from what both of you brought to the table, I was able to modify the code to (in what I believe) make it more simple (and removes the need for excess variables).

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Rectangle[,] gameGrid;

        MouseState MS;

        Color color;
        Color currentColor;
    }
        protected override void Initialize()
        {
            gameGrid = new Rectangle[10, 10];

            color = Color.Black;
            currentColor = Color.Blue;

            base.Initialize();
        }
//---Code Snip---

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            var t = new Texture2D(GraphicsDevice, 1, 1);
            t.SetData(new[] { Color.White });

            foreach (Rectangle grid in gameGrid)
            {
                //Creates a new point and checks to see if it is within the grid, if so, draws the selected color 
                //on the rectangle it is currently within.  If not, then draws the normal color.
                if (grid.Contains(new Point(MS.X, MS.Y)))
                    spriteBatch.Draw(t, grid, currentColor);
                else
                    spriteBatch.Draw(t, grid, color);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

Thanks for getting my creative juices flowing.

share|improve this answer
    
I also noticed that you are using the single pixel texture to create your rectangles. Take a look at this library i made to draw simple shapes in XNA: drippingflames.com/xna –  Luis Estrada Feb 28 '12 at 21:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.