Domanda

I wish to make a simple program that is used with a gamepad and can controll mouse and keywords events from outside of the program. My goal is to be able to control the computer from the couch.

My current code in Update()

protected override void Update(GameTime gameTime)
{
    //if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
    //    Exit();

    var gamePadStates = Enum.GetValues(typeof (PlayerIndex)).OfType<PlayerIndex>().Select(GamePad.GetState);
    var mouseState = Mouse.GetState();

    var direction = Vector2.Zero;
    const int speed = 5;


    // Gamepad
    foreach (var input in gamePadStates.Where(x => x.IsConnected))
    {
        if (input.IsButtonDown(Buttons.DPadDown))
            direction.Y += 1;
        if (input.IsButtonDown(Buttons.DPadUp))
            direction.Y -= 1;
        if (input.IsButtonDown(Buttons.DPadLeft))
            direction.X -= 1;
        if (input.IsButtonDown(Buttons.DPadRight))
            direction.X += 1;

        direction.X += input.ThumbSticks.Left.X;
        direction.Y -= input.ThumbSticks.Left.Y;
    }


    var oldPos = new Vector2(mouseState.X, mouseState.Y);

    if (direction != Vector2.Zero)
    {
        var newPos = oldPos;
        direction *= speed;
        newPos += direction;
        //newPos.X = MathHelper.Clamp(newPos.X, 0, GraphicsDevice.DisplayMode.Width);
        //newPos.Y = MathHelper.Clamp(newPos.Y, 0, GraphicsDevice.DisplayMode.Height);
        Mouse.SetPosition((int)newPos.X, (int)newPos.Y);
        System.Diagnostics.Debug.WriteLine("New mouse pos = {0}, {1}", newPos.X, newPos.Y);
    }

    base.Update(gameTime);
}

EDIT: For sending key presses I've found this library

È stato utile?

Soluzione

Doing this in XNA is the same way as normal C#. To use the code below, make sure you are using the System.Runtime.InteropServices; namespace.

Disclaimer: I would consider this somewhat "dirty" code, it uses user32.dll to invoke the click in Windows, but it is really the only way. (Adapted from here)

First off, you need 4 constants to easily use different types of clicks:

private const int MouseEvent_LeftDown = 0x02;
private const int MouseEvent_LeftUp = 0x04;
private const int MouseEvent_RightDown = 0x08;
private const int MouseEvent_RightUp = 0x10;

You will then need to hook into the mouse events:

[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
public static extern void MouseEvent(uint dwFlags, uint dx, uint dy, uint cButtons,uint dwExtraInfo);

You can now write methods to create mouse clicks:

LeftClick(int x, int y)
{
     MouseEvent(MouseEvent_LeftDown | MouseEvent_LeftUp, x, y, 0, 0);
}

RightClick(int x, int y)
{
     MouseEvent(MouseEvent_RightDown | MouseEvent_RightUp, x, y, 0, 0);
}

...etc, etc. You can see how you can adapt this to also create hold/drag events to mimic more functionality.

Note: I'm not sure if this will register with the MouseState, but that shouldn't be needed because you are trying to use it to control the computer, and the game should never need to use the mouse state.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top