How to offset my mouse cursor

Hi everyone

I have a menu (Myra-Menu) with some buttons on it. The problem that I have is that I have an offset. So, when i move my cursor close to a button (but still not on that button) the hoover effect is already fires.

This is happening since I use the Independent Resolution Rendering, see http://www.david-amador.com/2010/03/xna-2d-independent-resolution-rendering/.

I do not understand how I can adjust my mouse coordinates so that the hoover (or click) effect is happening when the visual cursor is actually on it.

My idea was that everytime Update (GameTime gameTime) is called, I add an offset to my current mouse coordinates. I hope that my offset calculations are correct. Something like:

Vector2 mousePosition = Mouse.GetState().Position.ToVector2();
        
Vector2 viewport = new Vector2 (graphics.GraphicsDevice.Viewport.X, graphics.GraphicsDevice.Viewport.Y);
Vector2 deltaPosition = mousePosition - viewport;

Matrix transformationMatrix = Matrix.CreateScale((float)graphics.GraphicsDevice.Viewport.Width / 1280, (float)graphics.GraphicsDevice.Viewport.Height / 860, 1f);
Matrix invertTransformationMatrix = Matrix.Invert(transformationMatrix);

Vector2 mousePositionAdjusted = Vector2.Transform(deltaPosition, invertTransformationMatrix);
        
Mouse.SetPosition((int)mousePositionAdjusted.X, (int)mousePositionAdjusted.Y);

When I do this, my mouse cursor automatically (everytime Update has been called) moves a bit closer to the coordinate 0,0 (which acutally makes sense to me). But still my problem remains: How can I offset my mouse cursor (all the time)?

Kind Regards
Andru

Changing the position of the mouse sounds like a bad idea. You should instead leave the mouse alone, and just convert the mouse coordinates to virtual coordinates.

virtualPosX = mousePosX * virtualResolutionX / realResolutionX;
virtualPosY = mousePosY * virtualResolutionY / realResolutionY;

And then use the virtual position for intersection tests.

Hi Markus

Thank you for your answer. I use a external library such as Myra. Therefore I would have to tell this external library that it should not use the default mouse coordinates. Instead, it should use the values of virtualPosX and virtualPosY of your example. So, I would have to have a function like ChangeCoordinatesOfMyra (virtualPosX, virtualPosY). Is that correct?

Now I face the problem, how I am going to do that in Myra.

Kind Regards
Andru

Oh I see, I didn’t realize that the intersection testing is done in an external library based on the mouse position. Ideally the UI library would offer some solution for this, but I guess you checked, and it doesn’t.
Some possible solutions I can think of:

  • Add virtual resolution support yourself to Myra.

  • Hide the system mouse cursor and draw your own cursor at the transformed position. The downside with this is that a custom cursor is always a bit more laggy than the system cursor.

  • Use a Mouse.SetPosition hack like you did, but keep it temporary. There’s probably some update function you have to call, where Myra does the intersection testing. If you do Mouse.SetPosition() before updating Myra, and reset it right afterwards, then Myra should be using the transformed coordinates, but the mouse motion stay unchanged.

Hello Markus

Thank you for your advise. I have asked rds (the developer of Myra) and he has given me the technical solution. Usually, Myra calles MouseInfoGetter = DefaultMouseInfoGetter in here https://github.com/rds1983/Myra/blob/61ca37d6778d67bdefe760fcb69adca3b86228da/src/Myra/Graphics2D/UI/Desktop.cs#L422.

From the outside of the library you can change that (similar to a delegate) by using Func <> in c#. My example function MyMouseInfoGetter replaces now the DefaultMouseInfoGetter of Myra

        private void InitializeMyra()
    {
        ... some code...
        desktop = new Desktop();
        desktop.MouseInfoGetter = MyMouseInfoGetter;
    }

    public MouseInfo MyMouseInfoGetter()
    {
        MouseInfo info = desktop.DefaultMouseInfoGetter();

        info.Position.X += 0;
        info.Position.Y += -82;

        return info;
    }

Kind Regards
Andru