XNA/Monogame Как определить, когда мышь находится над кнопкой

В настоящее время я изучаю программирование и делаю небольшую игру в моногейме. Однако мой прогресс остановился в меню, я пытаюсь понять, как определить, находится ли моя мышь над кнопкой, но я не могу понять, как я могу проверить это с помощью спрайта?

class Menubutton
{
    public Texture2D texture;
    public Vector2 coords;
    bool isClicked = false;
    bool isHovered = false;

    public Menubutton(Texture2D textur, int X, int Y)
    {
        this.texture = textur;
        this.coords.X = X;
        this.coords.Y = Y;
    }

    public void Update(GameWindow window)
    {


    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, coords, Color.White);
    }
}

}


person E. Flo    schedule 12.01.2016    source источник
comment
Вам нужно проверить, находятся ли координаты мыши внутри ограничивающего прямоугольника в вашем случае (coords.X, coords.Y, texture.Width, texture.Height)   -  person Gusman    schedule 12.01.2016
comment
Чувак, я чувствую себя очень глупо прямо сейчас, я не знал этой текстуры. Ширина и текстура. Высота была вещью, я буквально часами пытался со случайными аргументами и поиском в гугле. Спасибо! :)   -  person E. Flo    schedule 12.01.2016


Ответы (2)


Что-то вроде этого должно помочь:

public void Update(GameWindow window)
{
    var mouseState = Mouse.GetState();
    var mousePoint = new Point(mouseState.X, mouseState.Y);
    var rectangle = new Rectangle(mousePoint.X, mousePoint.Y, this.texture.Width, this.texture.Height);

    if (rectangle.Contains(mousePoint))
    {
        isHovered = true;
        isClicked = mouseState.LeftButton == ButtonState.Pressed;
    }
    else
    {
        isHovered = false;
        isClicked = false;
    }
}

Обратите внимание, что определение того, что на самом деле означает флаг isClicked, может различаться. В этой простой реализации это просто означает, что кнопка мыши нажата над кнопкой, но технически это не совсем «щелчок», поэтому я оставлю это на ваше усмотрение, хотите ли вы чего-то более сложного, чем это.

person craftworkgames    schedule 13.01.2016

Обычно я выделяю как можно больше входной логики в статический класс InputManager:

public static class InputManager
{
    // #region #endregion tags are a nice way of blockifying code in VS.
    #region Fields

    // Store current and previous states for comparison. 
    private static MouseState previousMouseState;
    private static MouseState currentMouseState;

    // Some keyboard states for later use.
    private static KeyboardState previousKeyboardState;
    private static KeyboardState currentKeyboardState;

    #endregion



    #region Update

    // Update the states so that they contain the right data.
    public static void Update()
    {
        previousMouseState = currentMouseState;
        currentMouseState = Mouse.GetState();

        previousKeyboardState = currentKeyboardState;
        currentKeyboardState = Keyboard.GetState();
    }

    #endregion



    #region Mouse Methods

    public static Rectangle GetMouseBounds(bool currentState)
    {
        // Return a 1x1 squre representing the mouse click's bounding box.
        if (currentState)
            return new Rectangle(currentMouseState.X, currentMouseState.Y, 1, 1);
        else
            return new Rectangle(previousMouseState.X, previousMouseState.Y, 1, 1);
    }

    public static bool GetIsMouseButtonUp(MouseButton btn, bool currentState)
    {
        // Simply returns whether the button state is released or not.

        if (currentState)
            switch (btn)
            {
                case MouseButton.Left:
                    return currentMouseState.LeftButton == ButtonState.Released;
                case MouseButton.Middle:
                    return currentMouseState.MiddleButton == ButtonState.Released;
                case MouseButton.Right:
                    return currentMouseState.RightButton == ButtonState.Released;
            }
        else
            switch (btn)
            {
                case MouseButton.Left:
                    return previousMouseState.LeftButton == ButtonState.Released;
                case MouseButton.Middle:
                    return previousMouseState.MiddleButton == ButtonState.Released;
                case MouseButton.Right:
                    return previousMouseState.RightButton == ButtonState.Released;
            }

        return false;
    }

    public static bool GetIsMouseButtonDown(MouseButton btn, bool currentState)
    {
        // This will just call the method above and negate.
        return !GetIsMouseButtonUp(btn, currentState);
    }

    #endregion



    #region Keyboard Methods

    // TODO: Keyboard input stuff goes here.

    #endregion
}

// A simple enum for any mouse buttons - could just pass mouseState.ButtonState instead 
public enum MouseButton
{
    Left,
    Middle,
    Right
}

Тогда ваш класс MenuButton может выглядеть примерно так:

public class MenuButton
{
    #region Properties

    // Some properties that might come is handy
    public Rectangle Bounds { get { return bounds; } }

    public MenuButtonState State { get { return currentState; } }

    // Redundant but handy
    public bool IsClicked { get { return currentState == MenuButtonState.Clicked; } }

    #endregion



    #region Fields

    private Texture2D texture;
    private Vector2 position;
    private Rectangle bounds;

    private MenuButtonState currentState;

    #endregion



    #region Constructor

    public MenuButton(Texture2D texture, Vector2 position)
    {
        this.texture = texture;
        this.position = position;
        // Cast position X and Y to ints for the rectangle's constructor.
        bounds = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);

        // MenuButton starts off as Released.
        currentState = MenuButtonState.Released;
    }

    #endregion



    #region Update

    public void Update()
    {
        // There are much better ways to impliment button interaction than this 
        // but here is a simple example:

        // If the mouse cursor is on our MenuButton...
        if (InputManager.GetMouseBounds(true).Intersects(bounds))
        {
            // And if the Left mouse button is down...
            if (InputManager.GetIsMouseButtonDown(MouseButton.Left, true))
            {
                // Then our MenuButton is down!
                currentState = MenuButtonState.Pressed;
            }
            // Else if the Left mouse button WAS down but isn't any more...
            else if (InputManager.GetIsMouseButtonDown(MouseButton.Left, false))
            {
                // Then our MenuButton has been clicked!
                currentState = MenuButtonState.Clicked;
            }
            // Otherwise...
            else
            {
                // The mouse cursor is simply hovering above our MenuButton!
                currentState = MenuButtonState.Hovered;
            }
        }
        else
        {
            // If the cursor does not intersect with the MenuButton then just set the state to released.
            currentState = MenuButtonState.Released;
        }
    }

    #endregion
}

public enum MenuButtonState
{
    Released,
    Hovered,
    Pressed,
    Clicked
}

Конечно, у вас будет функция Draw() и, возможно, некоторые другие.

Я не тестировал приведенный выше код, но в основном надеюсь, что он поможет вам достичь того, чего вы хотите. Я получил массу удовольствия, пытаясь реализовать различные способы взаимодействия с кнопкой. Например, возможность обрабатывать щелчки, когда кнопка удерживается нажатой, затем курсор перемещается и возвращается к кнопке, а затем отпускается.

person georgeous    schedule 13.12.2016