简体   繁体   中英

C# XNA Draggable UI

I created a GuiWindow class that held a texture, title, and rectangle so I can draw the texture and title. I've been trying to make it draggable, though I am having a bit of trouble. Originally I had the GuiWindow's bounds rectangle just lock onto the mouse positions:

if(bounds.contains(MouseHandle.Update()) && MouseHandle.Pressed()) //checks if the bounds rectangle contains the mouse rectangle and the mouse left button is pressed
{
    bounds.X = MouseHandle.Update().X;
    bounds.Y = MouseHandle.Update().Y;
}

which would allow me to drag, though only in a single direction. I then tried

if(bounds.contains(MouseHandle.Update()) && MouseHandle.Pressed())
{
    int offx = bounds.X - MouseHandle.Update().X;
    int offy = bounds.Y - MouseHandle.Update().Y;
    bounds.X = MouseHandle.Update().X + offx;
    bounds.Y = MouseHandle.Update().Y + offy;
}

this time the window just stayed still when I tried dragging. I'm pretty sure I have the basic concept of dragging down. Am I doing something wrong?

Alright this is some code that I've been using to move objects with the mouse in some of my XNA applications. Hopefully this will help you with your problem.

//Fields
Texture2D object;
Vector2 object_position;
Rectangle collisionRectangle;
MouseState preMouse;
bool moving = false;
Vector2 mouseOffset;


//initialize fields in LoadContent method
protected override void LoadContent()
{
    object = Content.Load<Texture2D>("nameOfYourImage");
    object_position = new Vector2((graphics.PreferredBackBufferWidth - object.Width)/2, graphics.PreferredBackBufferHeight - object.Height - 60);
    collisionRectangle = new Rectangle((int)object_position.X, (int)object_position.Y, (int)object.Width, (int)object.Height);
}


//add code to Update method



public void MouseInput(MouseState mouse)
{
    if (collsionRectangle.Contains(mouse.X, mouse.Y) && //mouse is over the object
        //the user is clicking the left mousebutton
        mouse.LeftButton == ButtonState.Pressed && 
        //in the previous Update() call the left mousebutton was released, 
        //meaning the user has just clicked the object
        preMouse.LeftButton == ButtonState.Released)
    {
        moving = true;

        //stores what the objects position should be offset by so it doesn't
        //snap to the mouse's position every time you click on it
        mouseOffset = new Vector2(Position.X - mouse.X, Position.Y - mouse.Y);
    }

    if (moving)
    {
        //if the player stops holding down the mousebutton i.e stops moving the object
        if (mouse.LeftButton == ButtonState.Released)  
            moving = false;

        //modifies the position
        Position.X = mouse.X + mouseOffset.X;
        Position.Y = mouse.Y + mouseOffset.Y;

        //prevents object from going off the screen and getting lost
        if (Convert.ToInt32(object_position.X) < 0)
            object_position.X = 0;
        if (object_position.X + object.Width > graphics.PreferredBackBufferWidth)
            object_position.X = graphics.PreferredBackBufferWidth - object.Width;
        if (Convert.ToInt32(object_position.Y) < 0)
            object_position.Y = 0;
        if (object_position.Y + object.Height > graphics.PreferredBackBufferHeight)
            object_position.Y = graphics.PreferredBackBufferHeight - object.Height;

        //updates the collision rectangle
        collisionRectangle = new Rectangle(Postion.X, Position.Y, WIDTH, HEIGHT);
    }

    preMouse = mouse; //stores the current mouseState for use in the next Update() call
}

This will make you able to drag the object with the mouse. Now of course this won't be directly copyable to your application, as i don't know how the code of your GuiWindow, but it should be easy to convert to your needs. Hope this helps :)

Here is a section of my window base class that handled moving and resizing in XNA. My appologies for it being in VB.NET, but you should be able to easily convert it. You probably wont be able to use any of it directly, but hopefully it will point you in the right direction.

    Public Overrides Sub OnMouseDown(e As Ui.MouseEventArgs)
        MyBase.OnMouseDown(e)

        Dim localLoc As Point = ScreenToWindow(e.Location)
        'If Movable AndAlso localLoc.Y >= 0 AndAlso localLoc.Y <= mBackground.TopMargin Then
        If Closable AndAlso Me.CloseButtonBounds.Contains(e.Location) Then
            Me.OnCloseButton()
        ElseIf Movable AndAlso Me.DragArea.Contains(e.Location) Then
            mMouseAnchor = localLoc
            mDragType = DragType.Move
            ' ElseIf Resizable AndAlso localLoc.X > Me.Bounds.Width - mBackground.RightMargin AndAlso localLoc.Y > Me.Bounds.Height - mBackground.BottomMargin Then
        ElseIf Resizable AndAlso Me.ResizeArea.Contains(e.Location) Then
            mMouseAnchor = New Point(Me.Bounds.Right - e.Location.X, Me.Bounds.Bottom - e.Location.Y)
            mDragType = DragType.Resize
        End If
    End Sub

    Public Overrides Sub OnMouseUp(e As Ui.MouseEventArgs)
        MyBase.OnMouseUp(e)
        mDragType = DragType.None
    End Sub


    Public Overrides Sub OnMouseMove(e As Ui.MouseEventArgs)
        MyBase.OnMouseMove(e)

        If mDragType = DragType.Move Then
            Dim change As New Vector2((e.Location.X - mMouseAnchor.X) - Me.X, (e.Location.Y - mMouseAnchor.Y) - Me.Y)
            Me.Bounds = New Rectangle(e.Location.X - mMouseAnchor.X,
                                      e.Location.Y - mMouseAnchor.Y,
                                      Me.Bounds.Width,
                                      Me.Bounds.Height)
            UpdateControlLocations(change)
        ElseIf mResizable AndAlso mDragType = DragType.Resize Then
            Me.Bounds = New Rectangle(Me.Bounds.X,
                                      Me.Bounds.Y,
                                      Me.Bounds.Width - (Me.Bounds.Right - e.Location.X) + mMouseAnchor.X,
                                      Me.Bounds.Height - (Me.Bounds.Bottom - e.Location.Y) + mMouseAnchor.Y)
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.SizeNWSE
        ElseIf mDragType = DragType.None Then
            If mResizable AndAlso Me.ResizeArea.Contains(e.Location) Then
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.SizeNWSE
            Else
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
            End If
        End If
    End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM