2

I have been rendering some custom "buttons" using SpriteBatch.Draw(). However today I realized that the coordinates at which I was supposedly drawing my buttons at was not consistent with the coordinates that my mouse claims they are being rendered at. This is an issue, as it is hard to detect if a button is being clicked if the graphical rendering is off. Another possibility is that the mouse coordinates are off. What is wrong?

If you need more information, please ask. Thank you!

Hardcoded button positions:

    /// <summary>
    /// The x position at which the left part of the buttons on the main menu begin.
    /// </summary>
    public static readonly int ButtonX = 20;

    /// <summary>
    /// How wide the buttons are.
    /// </summary>
    public static readonly int ButtonWidth = 200;

    /// <summary>
    /// How tall the buttons are.
    /// </summary>
    public static readonly int ButtonHeight = 50;



    /// <summary>
    /// The y position of the top of the new game button.
    /// </summary>
    public static readonly int NewGameButtonY = 100;

    /// <summary>
    /// The y position of the top of the new game button.
    /// </summary>
    public static readonly int QuitButtonY = 200;

Method of getting mouse position:

        int x = Mouse.GetState().X;
        int y = Mouse.GetState().Y;

How the buttons are rendered:

    private static void DrawButton(MonoButton button, ref SpriteBatch spBatch)
    {
        if (button.Visible)
        {
            spBatch.Draw(button.Image, button.DrawingBounds, colorMask);
            RenderingPipe.DrawString(MainMenuLayout.MainMenuFont, button.Text, button.DrawingBounds, Alignment.Center, colorMask, ref spBatch);
        }
    }

Visual display of how off SOMETHING is: A visual display of how off something is

The top left corner of the new game button should be (20, 100).

EDIT: The native resolution of my laptop is 1920x1080, yet the game is definitely displaying in a lower resolution then that when in full screen mode.

EDIT #2: I realized later that while the mouse offset works, it is much easier to simply set your monogame window resolution to the native resolution of your moniter. This completely fixed the issue without a mouse offset.

SneakyTactician
  • 130
  • 1
  • 14
  • ButtonX = 20, NewGameButtonY = 100, maybe you mean top-left should be (100,20)? – Gusman Feb 27 '18 at 22:32
  • @Gusman To my knowledge that's not how coordinates work. They should be (x, y). – SneakyTactician Feb 27 '18 at 22:56
  • Then it's not top-left, it's left-top... – Gusman Feb 28 '18 at 00:12
  • I think it's important to know first what exactly is off, the button or the mouse? Can you also show the in-game coördinates of the button as well? – Steven Feb 28 '18 at 07:28
  • @Gusman X is positive to the right Y is positive in the bottom direction. Sorry, I didn't understand your comment before. – SneakyTactician Feb 28 '18 at 21:22
  • @Steven The SpriteBatch is told to draw the button at the coordinates I listed under Hardcoded Button Positions. However, they don't actually draw there, unless my method of getting mouse coordinates is wrong for some reason. – SneakyTactician Feb 28 '18 at 21:24

1 Answers1

2

Your mouse reports coordinates to the center of the cursor, not the tip of the pointer.

To understand why, consider that one person's mouse is another person's touch screen.

You can apply a slight offset to the hitbox of the buttons but it's probably better to just offset the coordinates you get from GetState and encapsulate it into a property:

int offsetX = 3, offsetY = 2;
MouseState _currentState; // assume this is set by main game loop every call to Update()
int MousePositionX => _currentState.X + offsetX;
int MousePositionY => _currentState.Y + offsetY;

The exact offset amount could be dependent upon a variety of factors, including inadvertent coordinate transformations or offsets in your existing Button component (check the bounding box calcs), so trial and error may be in order for an immediate solution. If you do, make sure to test under different resolutions, DPI's, and HID (human interface devices aka mouse, touch, gamepad inputs)

If it really needs to be dynamically computed, you might look at ways to query the environment for information about the cursor icon (if any). Pointers aren't the only cursors people have been known to use, after all!

Josh E
  • 7,390
  • 2
  • 32
  • 44