Reputation: 104
I have a game menu with (for now) 1 picture (button). It's a texture2D and I've put it in a array. I want to know when the mouse hovers over my picture. Actionscript had a built in function called "hitTestObject". But it's starting to look like I have to check every single pixel of the image to see if the mouse is on there. I'm open to changing everything, I just want to be able to pick different pictures.
Texture2D[] clickable_objects = new Texture2D[1];
clickable_objects[0] = Content.Load<Texture2D>("brain-icon");
public bool Intersects(Vector2 mouse_loc, Texture2D[] _objects)
{
int X = (int) mouse_loc.X;
int Y = (int) mouse_loc.Y;
if () //Mouse hovers over object[0]
return true;
else
return false;
}
Upvotes: 2
Views: 1013
Reputation: 4280
How about you add something simple like this:
public delegate void ButtonEvent(Button sender);
public class Button
{
public Vector2 Position { get; set; }
public int Width
{
get
{
return _texture.Width;
}
}
public int Height
{
get
{
return _texture.Height;
}
}
public bool IsMouseOver { get; private set; }
public event ButtonEvent OnClick;
public event ButtonEvent OnMouseEnter;
public event ButtonEvent OnMouseLeave;
Texture2D _texture;
MouseState _previousState;
public Button(Texture2D texture, Vector2 position)
{
_texture = texture;
this.Position = position;
_previousState = Mouse.GetState();
}
public Button(Texture2D texture) : this(texture, Vector2.Zero) { }
public void Update(MouseState mouseState)
{
Rectangle buttonRect = new Rectangle((int)this.Position.X, (int)this.Position.Y, this.Width, this.Height);
Point mousePoint = new Point(mouseState.X, mouseState.Y);
Point previousPoint = new Point(_previousState.X, _previousState.Y);
this.IsMouseOver = false;
if (buttonRect.Contains(mousePoint))
{
this.IsMouseOver = true;
if (!buttonRect.Contains(previousPoint))
if (OnMouseEnter != null)
OnMouseEnter(this);
if (_previousState.LeftButton == ButtonState.Released && mouseState.LeftButton == ButtonState.Pressed)
if (OnClick != null)
OnClick(this);
}
else if (buttonRect.Contains(previousPoint))
{
if (OnMouseLeave != null)
OnMouseLeave(this);
}
_previousState = mouseState;
}
public void Draw(SpriteBatch spriteBatch)
{
//spritebatch has to be started! (.Begin() already called)
spriteBatch.Draw(_texture, Position, Color.White);
}
}
To use it, you need a reference somewhere
Button _button;
In your LoadContent
, you might do something like
button = new Button(Content.Load<Texture2D>("Textures\\Button"), new Vector2(100, 100));
button.OnClick += new ButtonEvent(button_OnClick);
button.OnMouseEnter += new ButtonEvent(button_OnMouseEnter);
button.OnMouseLeave += new ButtonEvent(button_OnMouseLeave);
In your Update
you call
button.Update(Mouse.GetState());
In your Draw
you call
spriteBatch.Begin();
button.Draw(spriteBatch);
spriteBatch.End();
Instead of one button, use an array of buttons (or, if I may recommend, a List<Button>
), and then just loop through to update and draw them all in a similar fashion.
Then it is easy to call custom code on event handlers:
void button_OnClick(Button sender)
{
_gameState = GameStates.MainScreen; //or whatever else you might need
}
You might even consider changing the texture if the mouse hovers, or use a stylish fade - the possibilities are endless, if you can code them!
Upvotes: 2
Reputation: 14153
Use Rectangle.Intersects
int X = (int) mouse_loc.X;
int Y = (int) mouse_loc.Y;
Rectangle MouseRect = new Rectangle(X,Y,1,1)
if (MouseRect.Intersects(TexturePosition.X,TexturePosition.Y,Texture.Width,Texture.Height)) //Mouse hovers over object[0]
return true;
else
return false;
Upvotes: 1
Reputation: 1670
A Texture2D is only a representation of a image - it has only a 2D grid of texels. It does not have a position on the screen, so you can't do a mouse hit check on it.
You would need some containing class, like a Sprite, that contains both the texture and a position. Then you could add a hittest() function to that class, which would check against the position and size of the texture.
Or better yet, find some existing sprite library for XNA to use. I'm sure there exists a few that gives you this functionality.
Upvotes: 2