Как я могу получить курсор IBeam в игре XNA?

Мне удалось заставить курсор измениться на IBeam в тривиальной игре XNA с обновлением как:

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);
    }

Мышь меняется на курсор IBeam при нажатии «I», но сразу же меняется обратно на стрелку, когда вы перемещаете мышь. Есть ли способ заставить его оставаться в качестве Windows IBeam по умолчанию, или мне нужно будет создать и отслеживать собственный курсор?

[EDIT] Я также должен отметить, что установка курсора в каждом отдельном кадре заставляет его мерцать при перемещении мыши. Кажется, XNA (или Windows) внутренне сбрасывает курсор на стрелку каждый кадр?


person Harry Wagstaff    schedule 27.06.2010    source источник


Ответы (2)


Похоже, вам придется рисовать его вручную. Это не должно быть слишком сложно — просто нарисуйте спрайт через SpriteBatch в месте расположения курсора.

// 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();
}

А вот код для извлечения изображения курсора. Имейте в виду, что вам понадобится дополнительная ссылка на 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);
}

Имейте в виду, что это не в моей голове - не гарантируется работа. Хотя основная идея есть.

person YellPika    schedule 13.07.2010

Прежде чем прибегать к рисованию вручную, я бы попытался установить свойство Cursor базового System.Windows.Forms.Form:

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

Поскольку у меня сейчас не установлен XNA, я не знаю, сработает ли это или будет ли оно постоянным, но я не понимаю, почему это не сработает.

person Michael Hoffmann    schedule 22.01.2011