How to make rope

  ... the Physics Box2D Extension for AndEngine.

How to make rope

Postby kt1 » Sun Feb 26, 2012 8:07 pm

Hi all.
I would be curious to I how to make elastic rope in andengien.
Pleas help me.
(sorry about my bad English)
kt1
 
Posts: 42
Joined: Sun Feb 26, 2012 7:58 pm
Location: Hungary

Re: How to make rope

Postby RealMayo » Sun Feb 26, 2012 8:34 pm

Make many bodies, each connected to each other using RevoluteJoint.
Warning, if each body's density is too large, then the rope will be strectched too much from the weight, and not work very well. So, set the density on each body to a very small value, like 0.01f or 0.1f
Also, you must enableLimit on each RevoluteJoint, or else each link in the rope can spin 360 degrees around the joint, which is not good.

Once you create 2 bodies (chain links in your rope), then use this code (below) to join them. Repeat this code for all of the bodies (chain links) that make up your rope:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. // FIRST CREATE TWO BODIES, THEN USE THIS CODE TO JOIN THEM TOGETHER
  2.         RevoluteJointDef chainLinkDef = new RevoluteJointDef();
  3.         chainLinkDef.collideConnected = false;
  4.         chainLinkDef.initialize(chainLinkBody1, chainLinkBody2, chainLinkBody1.getWorldCenter());
  5. // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF PREVIOUS BODY
  6. // USUALLY EQUALS PREVIOUS BODY LENGTH                         
  7.         chainLinkDef.localAnchorA.set(0.0f,1.0f);
  8. // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF THIS BODY
  9. // USUALLY EQUALS THIS BODY LENGTH
  10.         chainLinkDef.localAnchorB.set(0.0f,-1.0f);
  11.         chainLinkDef.enableMotor = true;
  12.         chainLinkDef.motorSpeed = 0;
  13.         chainLinkDef.enableLimit = true;
  14.         chainLinkDef.lowerAngle = MathUtils.degToRad(45);
  15.         chainLinkDef.upperAngle = MathUtils.degToRad(180);
  16. // NOW THAT WE DEFINED THE JOINT, HERE WE ACTUALLY CREATE THE JOINT
  17.         Joint chainLink1 = this.myActivity.mPhysicsWorld.createJoint(chainLinkDef);                    
  18.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4
User avatar
RealMayo
 
Posts: 1682
Joined: Sat Sep 03, 2011 9:25 pm
Location: Chicago, IL

Re: How to make rope

Postby squeeb » Mon Feb 27, 2012 1:32 am

I have been playing around with the physics revolute joint example and trting to do this! Glad I found this... Will try later. Why do we set motor true? I put mine false and speed torque 0
squeeb
 
Posts: 167
Joined: Mon May 16, 2011 1:24 am

Re: How to make rope

Postby RealMayo » Mon Feb 27, 2012 1:35 am

I think you right, you can probably do enableMotor = false
User avatar
RealMayo
 
Posts: 1682
Joined: Sat Sep 03, 2011 9:25 pm
Location: Chicago, IL

Re: How to make rope

Postby OzLark » Tue Feb 28, 2012 6:10 am

Hi RealMayo, thanks for sharing your rope solution - but I'm having some difficulties getting it to work for me.

Here's my code:

Syntax: [ Download ] [ Hide ]
Using javascript Syntax Highlighting
  1. public Sprite makeRope(int links, float x, float y) {
  2.     final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(0.01f, 0.01f, 0.01f);
  3.  
  4.     Sprite l1 = new Sprite(x, y, mRopeTextureRegion.getWidth(), mRopeTextureRegion.getHeight(), mRopeTextureRegion, this.vertexBufferObjectManager);
  5.  
  6.     final Sprite firstLink = l1;
  7.  
  8.     Body b1 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, l1, BodyType.DynamicBody, objectFixtureDef);
  9.     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(l1, b1, true, true));
  10.     attachChild(l1);  
  11.     final float linkHeight = mRopeTextureRegion.getHeight();
  12.  
  13.     for (int i = 1; i < links; ++i) {
  14.         Sprite l2 = new Sprite(x, y + (i * linkHeight), mRopeTextureRegion.getWidth(), linkHeight, mRopeTextureRegion, this.vertexBufferObjectManager);
  15.         Body b2 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, l2, BodyType.DynamicBody, objectFixtureDef);
  16.         this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(l2, b2, true, true));
  17.         attachChild(l2);
  18.  
  19.         joinRopeBodies(b1, b2);
  20.  
  21.         b1 = b2;
  22.         l1 = l2;
  23.     }
  24.     return firstLink;
  25. }
  26.  
  27. public void joinRopeBodies(Body chainLinkBody1, Body chainLinkBody2) {
  28.     // FIRST CREATE TWO BODIES, THEN USE THIS CODE TO JOIN THEM TOGETHER
  29.     RevoluteJointDef chainLinkDef = new RevoluteJointDef();
  30.     chainLinkDef.collideConnected = false;
  31.     chainLinkDef.initialize(chainLinkBody1, chainLinkBody2, chainLinkBody1.getWorldCenter());
  32.     // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF PREVIOUS BODY
  33.     // USUALLY EQUALS PREVIOUS BODY LENGTH
  34.     chainLinkDef.localAnchorA.set(0.0f, 16.0f / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
  35.     // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF THIS BODY
  36.     // USUALLY EQUALS THIS BODY LENGTH
  37.     chainLinkDef.localAnchorB.set(0.0f, 16.0f / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
  38.     chainLinkDef.enableMotor = false;
  39.     chainLinkDef.motorSpeed = 0;
  40.     chainLinkDef.enableLimit = true;
  41.     chainLinkDef.lowerAngle = MathUtils.degToRad(45);
  42.     chainLinkDef.upperAngle = MathUtils.degToRad(180);
  43.     // NOW THAT WE DEFINED THE JOINT, HERE WE ACTUALLY CREATE THE JOINT
  44.     Joint chainLink1 = mPhysicsWorld.createJoint(chainLinkDef);
  45. }
  46.  
Parsed in 0.008 seconds, using GeSHi 1.0.8.4


Gives me a rope that is bound in a circle (?) - obviously not what I'm after.. This image shows two ropes I created - I have debug draw turned on to help see what's going on...

Image

My image (well someone elses image - this is temp until I make my own) is 8px wide by 16px high and I'm trying to create the rope with segments stacked on each other vertically on Y axis like:

|
|
|
|
|

Any ideas on where I'm going wrong? Do you have a complete example using your code (somewhat like I've tried to create?)

Thanks again for sharing your ideas.

Lark.
Did this post help you? Feel free to return the gesture by downloading Ninja Bees, creating a level (or more) and sharing it to the Ninja Bees website!

Ninja Bees - Our latest Android game, check it out on Google Play (free) or paid with no ads
OzLark
 
Posts: 1130
Joined: Sun Feb 05, 2012 3:19 am

Re: How to make rope

Postby RealMayo » Tue Feb 28, 2012 5:00 pm

Hi Lark,
Since you are doing this:
new Sprite(x, y + (i * linkHeight),....
That means you are creating your rope using a top down approach (your first body is in the sky, and all subsequent bodies get created towards the ground. That is important to keep in mind later when you are doing this:
localAnchorA.set(0.0f, 16.0f......
localAnchorB.set(0.0f, 16.0f......

In this case, you need to make AnchorB negative like this:
localAnchorB.set(0.0f, -16.0f......

For example you have bodyA and bodyB.
bodyA is in the sky, and you place bodyB below bodyA, so....
AnchorA should exist at the bottom of bodyA
AnchorB should exist at the top of bodyB
This is because AnchorA and Anchor B share the same joint

Let me know if that helps :)
User avatar
RealMayo
 
Posts: 1682
Joined: Sat Sep 03, 2011 9:25 pm
Location: Chicago, IL

Re: How to make rope

Postby OzLark » Wed Feb 29, 2012 1:23 pm

RealMayo wrote:In this case, you need to make AnchorB negative like this:
localAnchorB.set(0.0f, -16.0f......


Thanks Mr Mayo!

I needed a few more tweaks to get it nice, but this was the key! Other changes I needed in case others are interested.

Syntax: [ Download ] [ Hide ]
Using javascript Syntax Highlighting
  1. public Sprite makeRope(int links, float x, float y) {
  2.     final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(0.01f, 0.01f, 0.01f);
  3.     Sprite l1 = new Sprite(x, y, mRopeTextureRegion.getWidth(), mRopeTextureRegion.getHeight(), mRopeTextureRegion, this.vertexBufferObjectManager);
  4.  
  5.     final Sprite firstLink = l1;
  6.  
  7.     Body b1 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, l1, BodyType.DynamicBody, objectFixtureDef);
  8.     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(l1, b1, true, true));
  9.     attachChild(l1);
  10.                
  11.     final float linkHeight = mRopeTextureRegion.getHeight();
  12.     for (int i = 1; i < links; ++i) {
  13.         Sprite l2 = new Sprite(x, y + (i * linkHeight), mRopeTextureRegion.getWidth(), linkHeight, mRopeTextureRegion, this.vertexBufferObjectManager);
  14.         Body b2 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, l2, BodyType.DynamicBody, objectFixtureDef);
  15.         this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(l2, b2, true, true));
  16.         attachChild(l2);
  17.  
  18.         joinRopeBodies(b1, b2, linkHeight);
  19.  
  20.         b1 = b2;
  21.         l1 = l2;
  22.     }
  23.     return firstLink;
  24. }
  25.  
  26. public void joinRopeBodies(Body chainLinkBody1, Body chainLinkBody2, float bodyHeight) {
  27.     // FIRST CREATE TWO BODIES, THEN USE THIS CODE TO JOIN THEM TOGETHER
  28.     RevoluteJointDef chainLinkDef = new RevoluteJointDef();
  29.     chainLinkDef.collideConnected = false;
  30.     chainLinkDef.initialize(chainLinkBody1, chainLinkBody2, chainLinkBody1.getWorldCenter());
  31.     // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF PREVIOUS BODY
  32.     // USUALLY EQUALS PREVIOUS BODY LENGTH
  33.     chainLinkDef.localAnchorA.set(0.0f, ((bodyHeight/2) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
  34.     // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF THIS BODY
  35.     // USUALLY EQUALS THIS BODY LENGTH
  36.     chainLinkDef.localAnchorB.set(0.0f, ((bodyHeight/2) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT));
  37.     chainLinkDef.enableMotor = false;
  38.     chainLinkDef.motorSpeed = 0;
  39.     chainLinkDef.enableLimit = true;
  40.     chainLinkDef.lowerAngle = MathUtils.degToRad(45);
  41.     //chainLinkDef.upperAngle = MathUtils.degToRad(180);
  42.     chainLinkDef.upperAngle = MathUtils.degToRad(90);
  43.     // NOW THAT WE DEFINED THE JOINT, HERE WE ACTUALLY CREATE THE JOINT
  44.     Joint chainLink1 = mPhysicsWorld.createJoint(chainLinkDef);
  45. }
Parsed in 0.009 seconds, using GeSHi 1.0.8.4


Changes of interest:

Lines 33 and 36 - I needed to use half the body height in these two lines, I think that makes sense since we're going from centers.

Line 41/42 - I changed the upper angle to 90 instead of 180, this worked better for me..

Thanks again - much appreciated!

PS - RealMayo = Thomy Delikatess
Did this post help you? Feel free to return the gesture by downloading Ninja Bees, creating a level (or more) and sharing it to the Ninja Bees website!

Ninja Bees - Our latest Android game, check it out on Google Play (free) or paid with no ads
OzLark
 
Posts: 1130
Joined: Sun Feb 05, 2012 3:19 am

Re: How to make rope

Postby Mathew » Sun Mar 18, 2012 12:23 am

Thanks for codes attached there, they are helpful for better understanding how to handle it.

I'm trying to create 'suspension bridge' - simply by creating rope, with two static bodies (one on beginning and one on the end + dynamic bodies connected between them) here's little image showing what do I mean:

Image

I have been trying a lot of ways using attached code, but all the time its screwed, any ideas how should I make it properly?

Thanks.
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Re: How to make rope

Postby RealMayo » Sun Mar 18, 2012 4:05 pm

Hi Mathew,
To make a bridge, you'll need to build horizontally, so...
1) when setting the localAnchor you need to set the X value while leaving the Y value at zero
2) the upperLimit and lowerLimit might need to be different. In fact you could try starting out by setting enableLimit false until you've got a basic bridge working.

What problems are you experiencing?
User avatar
RealMayo
 
Posts: 1682
Joined: Sat Sep 03, 2011 9:25 pm
Location: Chicago, IL

Re: How to make rope

Postby Mathew » Mon Mar 19, 2012 3:07 pm

Thanks for answer, thats how does it look (little test) :

Image

(Those 3 boxes, on the left side, near player)

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.                 Sprite b1 = new Sprite(200, 250, 40, 40, boxTextureRegion);
  2.                 Body body1 = PhysicsFactory.createBoxBody(physicsWorld, b1, BodyType.DynamicBody, wallFixtureDef);
  3.                 physicsWorld.registerPhysicsConnector(new PhysicsConnector(b1, body1, true, true));
  4.                
  5.                 Sprite b2 = new Sprite(250, 250, 40, 40, boxTextureRegion);
  6.                 Body body2 = PhysicsFactory.createBoxBody(physicsWorld, b2, BodyType.DynamicBody, wallFixtureDef);
  7.                 physicsWorld.registerPhysicsConnector(new PhysicsConnector(b2, body2, true, true));
  8.                
  9.                 Sprite b3 = new Sprite(300, 250, 40, 40, boxTextureRegion);
  10.                 Body body3 = PhysicsFactory.createBoxBody(physicsWorld, b3, BodyType.DynamicBody, wallFixtureDef);
  11.                 physicsWorld.registerPhysicsConnector(new PhysicsConnector(b3, body3, true, true));            
  12.  
  13.                
  14.                 Utils.joinRopeBodies(body1, body2, 40, physicsWorld);
  15.                 Utils.joinRopeBodies(body2, body3, 40, physicsWorld);
  16.                
  17.                 scene.attachChild(b1);
  18.                 scene.attachChild(b2);
  19.                 scene.attachChild(b3);
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         public static void joinRopeBodies(Body chainLinkBody1, Body chainLinkBody2, float bodyHeight, PhysicsWorld physicsWorld)
  2.         {
  3.             // FIRST CREATE TWO BODIES, THEN USE THIS CODE TO JOIN THEM TOGETHER
  4.             RevoluteJointDef chainLinkDef = new RevoluteJointDef();
  5.             chainLinkDef.collideConnected = false;
  6.             chainLinkDef.initialize(chainLinkBody1, chainLinkBody2, chainLinkBody1.getWorldCenter());
  7.             // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF PREVIOUS BODY
  8.             // USUALLY EQUALS PREVIOUS BODY LENGTH
  9.             chainLinkDef.localAnchorA.set(((bodyHeight/2) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT), 0);
  10.             // NEXT IS DISTANCE OF ANCHOR AWAY FROM CENTER OF THIS BODY
  11.             // USUALLY EQUALS THIS BODY LENGTH
  12.             chainLinkDef.localAnchorB.set(((bodyHeight/2) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT), 0);
  13.             chainLinkDef.enableMotor = false;
  14.             chainLinkDef.motorSpeed = 0;
  15.             chainLinkDef.enableLimit = true;
  16.             chainLinkDef.lowerAngle = MathUtils.degToRad(45);
  17.             //chainLinkDef.upperAngle = MathUtils.degToRad(180);
  18.             chainLinkDef.upperAngle = MathUtils.degToRad(90);
  19.             // NOW THAT WE DEFINED THE JOINT, HERE WE ACTUALLY CREATE THE JOINT
  20.             physicsWorld.createJoint(chainLinkDef);
  21.         }
Parsed in 0.039 seconds, using GeSHi 1.0.8.4
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Next

Return to Physics Box2D

Who is online

Users browsing this forum: No registered users and 8 guests