Games MouseJoint Example

Gunther

Active Member
Licensed User
Longtime User
Here is a "MouseJoint"-Example.

You can click on the body anywhere and you can move the body around with the mouse.

The MouseJoint is done by creation of a temporary body which will be used for the anchor point of the revjoint. After releasing the mouse button the joint and the body are destroyed.

So, it not breaks the physics of the touched body that much (e.g. the box spins further).

upload_2018-12-7_16-4-59.png


Sure you need to add a Pane in the Designer, if not already there: name PanelForTouch

In the Class_Globals add:
B4X:
' MouseJoint
' *************************************
Private PanelForTouch As B4XView
Private MovingBody As Boolean
Private TouchedBody As B2Body
Private TouchPointVec As B2Vec2
Private MouseBody As X2BodyWrapper
Private MouseJointDef As B2RevoluteJointDef
Private MouseJoint As B2RevoluteJoint
' ************************************
'

The main part is in the PanelForTouch_Touch Event in the Game.bas:

B4X:
Private Sub PanelForTouch_Touch ( Action As Int, X As Float, Y As Float )
    X = Max( 0, Min( X, PanelForTouch.Width ) )
    Y = Max( 0, Min( Y, PanelForTouch.Height ) )
    Select Action
        Case PanelForTouch.TOUCH_ACTION_DOWN
            Dim p As B2Vec2 = X2.ScreenPointToWorld( X, Y )
            Dim touched As List = X2.GetBodiesIntersectingWithWorldPoint( p )
            If touched.Size > 0 Then
                MovingBody = True
                Dim bw As X2BodyWrapper = touched.Get( 0 )
                TouchedBody = bw.Body
                TouchedBody.GravityScale = 0
                TouchedBody.SleepingAllowed = False
                '
                ' Where is the Body touched
                TouchPointVec = TouchedBody.GetLocalPoint( p )
                '
                Dim circleShape As B2CircleShape
                circleShape.Initialize( .1 )
                Dim fd As B2FixtureDef
                fd.Shape = circleShape
                fd.Density = 1
                fd.Friction = 0
                fd.SetFilterBits(  1 , 0 )
 
                Dim bd As B2BodyDef
                bd.BodyType =  bd.TYPE_KINEMATIC
                bd.Position.Set( p.X , p.Y )
 
                MouseBody = X2.CreateBodyAndWrapper( bd, Null, "MouseBody" )
                MouseBody.Body.CreateFixture( fd )
 
                MouseJointDef.Initialize( MouseBody.Body, TouchedBody, TouchedBody.Position )
                MouseJoint = world.CreateJoint( MouseJointDef )
                '
            Else
                MovingBody = False
            End If
 
        Case PanelForTouch.TOUCH_ACTION_MOVE
            Dim p As B2Vec2 = X2.ScreenPointToWorld( X, Y )
            If MovingBody Then
                MouseBody.Body.SetTransform( p, 0 )
            Else
 
            End If
 
        Case PanelForTouch.TOUCH_ACTION_UP
            If MovingBody = False Then
 
            Else
                TouchedBody.GravityScale = 1
                TouchedBody.SleepingAllowed = True
                world.DestroyJoint( MouseJoint )
                world.DestroyBody( MouseBody.Body )
            End If
    End Select
End Sub
 

Attachments

  • MouseJoint.zip
    29.4 KB · Views: 412
Last edited:

Gunther

Active Member
Licensed User
Longtime User
updated Version (in first post) -> transfered the code into a class in order to make the transportability much more easier. Just copy the MouseJoint.bas into your project.

add to the Game.bas parts (only the relevant code to add):

B4X:
Sub Class_Globals
'
    Private MouseJoint As MouseJoint
    Private PanelForTouch As B4XView
'
End Sub

Public Sub Initialize (Parent As B4XView)
'
    MouseJoint.Initialize(Me)
'
End Sub


Private Sub PanelForTouch_Touch (Action As Int, X As Float, Y As Float)
    X = Max(0, Min(X, PanelForTouch.Width))
    Y = Max(0, Min(Y, PanelForTouch.Height))
    '
    Select Action
        Case PanelForTouch.TOUCH_ACTION_DOWN
            '
            MouseJoint.Create( X,Y )
            '
        Case PanelForTouch.TOUCH_ACTION_MOVE
            '
            MouseJoint.Move( X,Y )
            '
        Case PanelForTouch.TOUCH_ACTION_UP
            '
            MouseJoint.Destroy
            '
    End Select
    '
End Sub

In addition not only dynamic bodies can be moved, also static and kinematic bodies can be dragged and dropped.

upload_2018-12-9_17-19-26.png
 
Last edited:
Top