SneakyTactician
SneakyTactician

Reputation: 130

Texture2D Coordinates Not Displaying In Proper Location

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.

Upvotes: 2

Views: 71

Answers (1)

Josh E
Josh E

Reputation: 7424

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!

Upvotes: 2

Related Questions