开发者

How can I get an IBeam cursor in an XNA Game?

I've managed to get the cursor to change to an IBeam in a trivial XNA 'Game' with Update as:

protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // TODO: Add your update logic here

        if (Keyboard.GetState().IsKeyDown(Keys.A))
        {
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Arrow;
        }
        if (Keyboard.GetState().IsKeyDown(Keys.I))
        {
            System.Windows.Forms.Cursor.Current 开发者_如何学编程= System.Windows.Forms.Cursors.IBeam;
        }

        base.Update(gameTime);
    }

The mouse changes to the IBeam cursor when 'I' is pressed, but immediately changes back to an arrow when you move the mouse. Is there a way to get it to stay as the default Windows IBeam, or will I need to create and track a custom cursor?

[EDIT] I should also point out that setting the cursor every single frame causes it to flicker when the mouse is moved. It seems the XNA (or Windows) is internally resetting the cursor to an arrow every frame?


Before resorting to drawing it manually, I'd try to set the Cursor property of the underlying System.Windows.Forms.Form:

Form f = (Form)Control.FromHandle(Game.Window.Handle);
f.Cursor = System.Windows.Forms.Cursors.IBeam;

As I don't have XNA installed right now, I don't know if this will work, or if it will be permenant, but I don't see why it wouldn't.


Sounds like your going to have to draw it manually. It shouldn't be too hard - just draw a sprite via SpriteBatch at the location of the cursor.

// ex.
protected override void Draw(GameTime gameTime)
{
    // Other stuff...

    base.Draw(gameTime);

    // Retrieve mouse position
    MouseState mState = Mouse.GetState();
    Vector2 mousePos = new Vector2(mState.X, mState.Y);

    // Use this instead to optionally center the texture:
    // Vector2 mousePos = new Vector2(mState.X - cursorTexture.Width / 2, mState.Y - cursorTexture.Height / 2);

    // Draw cursor after base.Draw in order to draw it after any DrawableGameComponents.
    this.spriteBatch.Begin(); // Optionally save state
    this.spriteBatch.Draw(cursorTexture, mousePos, Color.White);
    this.spriteBatch.End();
}

And here's some code to extract the cursor image. Keep in mind you'll need an extra reference to System.Drawing.

protected override void LoadContent()
{
    // Other stuff...

    // The size of the cursor in pixels.
    int cursorSize = 32;

    // Draw the cursor to a Bitmap
    Cursor cursor = Cursors.IBeam;
    Bitmap image = new Bitmap(cursorSize, cursorSize);
    Graphics graphics = Graphics.FromImage(image);
    cursor.Draw(graphics, new Rectangle(0, 0, cursorSize, cursorSize));

    // Extract pixels from the bitmap, and copy into the texture.
    cursorTexture = new Texture2D(GraphicsDevice, cursorSize, cursorSize);
    Microsoft.Xna.Framework.Graphics.Color[] data = new Microsoft.Xna.Framework.Graphics.Color[cursorSize * cursorSize];
    for (int y = 0; y < cursorSize; y++)
    {
        for (int x = 0; x < cursorSize; x++)
        {
            System.Drawing.Color color = image.GetPixel(x, y);
            data[x + y * cursorSize] = new Microsoft.Xna.Framework.Graphics.Color(color.R, color.G, color.B, color.A);
        }
    }
    cursorTexture.SetData<Microsoft.Xna.Framework.Graphics.Color>(data);
}

Keep in mind this is off the top of my head - not guaranteed to work. The basic idea is there, though.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜