【问题标题】:XNA / Monogame How to detect when the mouse hovers over a buttonXNA / Monogame 如何检测鼠标何时悬停在按钮上
【发布时间】:2016-12-13 23:44:40
【问题描述】:

我目前正在学习编程,并且正在制作一个单人游戏的小游戏。但是,我的进度在菜单上停止了,我正在尝试找出如何检测我的鼠标是否在按钮上方,但我无法弄清楚如何使用精灵进行检查?

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);
    }
}

}

【问题讨论】:

  • 您需要检查鼠标坐标是否在边界矩形内,在您的情况下(coords.X、coords.Y、texture.Width、texture.Height)
  • 伙计,我现在真的很蠢,我不知道 texture.Width 和 texture.Height 是一回事,我花了几个小时尝试随机参数和谷歌搜索。谢谢! :)

标签: c# xna monogame


【解决方案1】:

这样的事情应该可以解决问题:

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 标志实际含义的定义可能会有所不同。在这个简单的实现中,它只是意味着在按钮上方按下鼠标按钮,但从技术上讲,这并不是真正的“点击”,所以如果你想要比这更复杂的东西,我会让你自己考虑。

【讨论】:

    【解决方案2】:

    我通常将尽可能多的 Input 逻辑分离到一个静态 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() 函数,可能还有其他一些函数。

    我没有测试过上面的代码,但主要是希望它能帮助你到达你想要的地方。我在尝试实现与按钮交互的不同方式时获得了很多乐趣。例如,当按钮被按住时能够处理点击,然后光标移开,然后移回按钮,然后释放。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多