TUT: Box2d - MOUSEJOINT (DRAG and DROP)

  ... tutorials on how to use AndEngine.

TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby albrandroid » Mon Nov 22, 2010 2:55 pm

Hello Community,

now as promissed my MouseJoint - Tutorial.
If you drag your body with the help of the MouseJoint, it will collide with the other bodys in the world and apply force to them.

Box2d - Manual - http://www.box2d.org/manual.html#_Toc258082974
8.10 Mouse Joint
The mouse joint is used in the testbed to manipulate bodies with the mouse. It attempts to drive a point on a body towards the current position of the cursor. There is no restriction on rotation.

The mouse joint definition has a target point, maximum force, frequency, and damping ratio. The target point initially coincides with the body’s anchor point. The maximum force is used to prevent violent reactions when multiple dynamic bodies interact. You can make this as large as you like. The frequency and damping ratio are used to create a spring/damper effect similar to the distance joint.

Many users have tried to adapt the mouse joint for game play. Users often want to achieve precise positioning and instantaneous response. The mouse joint doesn’t work very well in that context. You may wish to consider using kinematic bodies instead.


So let's start..

1. You have to create your PhysicWorld and at least one body in it. ( Checkout the PhysicExample how to.. )


2. MouseJoint method
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public MouseJoint createMouseJoint(AnimatedSprite box , float x, float y){
  2.                 final Body boxBody = this.mPhysicsWorld.getPhysicsConnectorManager().findBodyByShape(box);
  3.                
  4.                 Vector2 v =boxBody.getWorldPoint(new Vector2(x/pixelToMeteRatio, y/pixelToMeteRatio));
  5.                
  6.                 MouseJointDef mjd = new MouseJointDef();
  7.                 mjd.bodyA                               = groundBody;
  8.                 mjd.bodyB                               = boxBody;
  9.                 mjd.dampingRatio        = 0.2f;
  10.                 mjd.frequencyHz         = 30;
  11.                 mjd.maxForce                    = (float) (200.0f * boxBody.getMass());
  12.                 mjd.collideConnected= true;
  13.                 mjd.target.set(v);
  14.                 return (MouseJoint) this.mPhysicsWorld.createJoint(mjd);
  15.         }
  16.  
Parsed in 0.033 seconds, using GeSHi 1.0.8.4




3. Touching Body
we have to override our onAreaTouched method to create an MouseJoint anchor-point on the touch position.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. MouseJoint mjActive = null;
  3. private float pixelToMeteRatio = PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
  4. @Override
  5. public boolean onAreaTouched(
  6.                 final TouchEvent        pSceneTouchEvent,
  7.                 final ITouchArea        pTouchArea      ,
  8.                 final float             pTouchAreaLocalX,
  9.                 final float             pTouchAreaLocalY )
  10. {
  11.        
  12.         if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
  13.                
  14.                 this.runOnUpdateThread(new Runnable() {
  15.                         @Override
  16.                         public void run() {
  17.                
  18.                         final AnimatedSprite face = (AnimatedSprite)pTouchArea; //The touched body
  19.                         //If we have a active MouseJoint, we are just moving arround don't create an 2nd one.
  20.                         if( mjActive == null)
  21.                         {
  22.                                 Vector2 vector = new Vector2(pTouchAreaLocalX/pixelToMeteRatio,pTouchAreaLocalY/pixelToMeteRatio);
  23.                                 //=====================================
  24.                                 // GROUNDBODY - Used for the MouseJoint
  25.                                 //=====================================
  26.                                 BodyDef groundBodyDef = new BodyDef();
  27.                                 groundBodyDef.position.set(vector);
  28.                                 groundBody      = mPhysicsWorld.createBody(groundBodyDef);
  29.                                 //====================================
  30.                                 // CREATE THE MOUSEJOINT
  31.                                 //====================================
  32.                                 mjActive        = PhysicsJumpExample.this.createMouseJoint(face, pTouchAreaLocalX, pTouchAreaLocalY);
  33.                         }
  34.                 }});
  35.                
  36.                 return true;
  37.         }
  38.        
  39. return false;
  40. }
  41.  
Parsed in 0.034 seconds, using GeSHi 1.0.8.4



4. Moving the body

We are moving our finger over the scene, so we have to move the MouseJoint too.
If we release the finger.. we must destroy the MouseJoint..
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         @Override
  2.         public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
  3.                
  4.                 if(this.mPhysicsWorld != null) {
  5.                
  6.            
  7.                 if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
  8.                        
  9.                         this.runOnUpdateThread(new Runnable() {
  10.                                 @Override
  11.                                 public void run() {
  12.                                        
  13.                                 if( mjActive != null ){ //If the MJ is active move it ..
  14.                                
  15.                                         // =========================================
  16.                                         // MOVE THE MOUSEJOINT WITH THE FINGER..
  17.                                         // =========================================
  18.                                         Vecotr2 vec = new Vector2(pSceneTouchEvent.getX()/pixelToMeteRatio, pSceneTouchEvent.getY()/pixelToMeteRatio);
  19.                                         mjActive.setTarget(vec);
  20.                                        
  21.                                 }
  22.                         }});
  23.                         return true;
  24.                 }
  25.                
  26.                 //===========================================
  27.                 // RELEASE THE FINGER FROM THE SCENE..
  28.                 //===========================================
  29.                 if(     pSceneTouchEvent.getAction() == MotionEvent.ACTION_UP           ||
  30.                                 pSceneTouchEvent.getAction() == MotionEvent.ACTION_CANCEL
  31.                   ) {
  32.                  
  33.                         this.runOnUpdateThread(new Runnable() {
  34.                                 @Override
  35.                                 public void run() {
  36.                        
  37.                                
  38.                                 if( mjActive != null )
  39.                                 {
  40.                                         //======================================
  41.                                         // DESTROY OUR MOUSEJOINT
  42.                                         //======================================
  43.                                         PhysicsJumpExample.this.mPhysicsWorld.destroyJoint(mjActive);
  44.                                         PhysicsJumpExample.this.mPhysicsWorld.destroyBody(groundBody);
  45.                                         mjActive = null;
  46.                                 }
  47.                        
  48.                         }});
  49.                        
  50.                         return true;
  51.                 }
  52.                
  53.                 return false;
  54.         }
  55.  
Parsed in 0.039 seconds, using GeSHi 1.0.8.4



FYI:
To fit your needs, you have to play with this settings ( in the createMouseJoint method )
mjd.dampingRatio = 0.2f;
mjd.frequencyHz = 30;
mjd.maxForce = (float) (200.0f * boxBody.getMass());

hope this will help someone..
Greets,
Alen
Last edited by albrandroid on Tue Nov 23, 2010 9:25 am, edited 1 time in total.
albrandroid
 
Posts: 26
Joined: Thu Aug 12, 2010 9:17 am
Location: Vienna

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby Br0ken » Mon Nov 22, 2010 3:45 pm

Thanks Alen
Br0ken
 
Posts: 265
Joined: Sun Sep 12, 2010 3:57 pm

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby albrandroid » Mon Nov 22, 2010 4:29 pm

...
Last edited by albrandroid on Mon Nov 22, 2010 4:33 pm, edited 1 time in total.
albrandroid
 
Posts: 26
Joined: Thu Aug 12, 2010 9:17 am
Location: Vienna

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby albrandroid » Mon Nov 22, 2010 4:31 pm

Br0ken wrote:Thanks Alen

you are welcome.

i have forgotten the groundBody declaration..
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. private Body groundBody = null;
Parsed in 0.034 seconds, using GeSHi 1.0.8.4
albrandroid
 
Posts: 26
Joined: Thu Aug 12, 2010 9:17 am
Location: Vienna

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby oldskool73 » Tue Nov 23, 2010 3:06 am

nice series of tutorials, keep 'em coming!

one minor thing, the blue you used for the quote is hard to read on the grey :)
oldskool73
 
Posts: 128
Joined: Tue Oct 12, 2010 4:04 pm

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby albrandroid » Tue Nov 23, 2010 9:30 am

oldskool73 wrote:nice series of tutorials, keep 'em coming!

one minor thing, the blue you used for the quote is hard to read on the grey :)


Thx..
changed to white :geek: :)

regards,
Alen
albrandroid
 
Posts: 26
Joined: Thu Aug 12, 2010 9:17 am
Location: Vienna

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby sohippy » Sun Jan 16, 2011 8:05 am

Really thanks.

This tutorial nearly fits a game I am developing. But I face a problem that the body I drag will rotate around my finger. I know this is a joint between my finger body and the drag body, and as they collide each other. Is it possible to prevent from collision between 2 bodies? I saw something that static body will not collide with kinematic body, but I don't know where I should change.

I find something called BodyDef. Should I configure here?

Sorry for my poor English and I hope you understand what I say.

Thanks :D
sohippy
 
Posts: 3
Joined: Sun Jan 16, 2011 7:56 am

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby sohippy » Wed Jan 19, 2011 11:51 am

sohippy wrote:Really thanks.

This tutorial nearly fits a game I am developing. But I face a problem that the body I drag will rotate around my finger. I know this is a joint between my finger body and the drag body, and as they collide each other. Is it possible to prevent from collision between 2 bodies? I saw something that static body will not collide with kinematic body, but I don't know where I should change.

I find something called BodyDef. Should I configure here?

Sorry for my poor English and I hope you understand what I say.

Thanks :D


could anyone help me.. :cry:
sohippy
 
Posts: 3
Joined: Sun Jan 16, 2011 7:56 am

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby vroom » Mon Jan 24, 2011 5:50 am

sohippy wrote:
sohippy wrote:Really thanks.

This tutorial nearly fits a game I am developing. But I face a problem that the body I drag will rotate around my finger. I know this is a joint between my finger body and the drag body, and as they collide each other. Is it possible to prevent from collision between 2 bodies? I saw something that static body will not collide with kinematic body, but I don't know where I should change.

I find something called BodyDef. Should I configure here?

Sorry for my poor English and I hope you understand what I say.

Thanks :D


could anyone help me.. :cry:


I don't understand your problem, because two bodies who are linked with a joint should never collide. anyway, I know 2 ways to avoid collisions. body sensors and group index.

activate the sensor like this (true is the sensor boolean argument):
objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.1f, 0.4f, true);

a sensor registers the contact but it does not make a collision.

group index:
objectFixtureDef.filter.groupIndex = -2;

give 2 bodys the same negative groupindex and they will never collide.
vroom
 
Posts: 74
Joined: Mon Dec 06, 2010 3:33 pm

Re: TUT: Box2d - MOUSEJOINT (DRAG and DROP)

Postby fasteque » Mon Feb 07, 2011 3:16 pm

Hi guys,

I not able to get the mousejoint working in my example. I tried to use the code posted here but I am not sure if I'm doing correct things or the code posted here is not complete (there are some typos, so I wonder if it has been compiled or not).


Does anyone have a working version of the code?


Thanks,
fasteque
fasteque
 
Posts: 7
Joined: Fri Jul 09, 2010 12:50 am

Next

Return to Tutorials

Who is online

Users browsing this forum: Google Feedfetcher and 16 guests