The best way to make Worms like ninja rope using Box2D is using a prismatic joint on a rotating body:
a) With a prismatic joint the body is limited to moving/sliding along an axis and that is exactly what we need.
b) Using the joint's motor we can make the attached body move up/down without breaking the physics simulation and if some object is in the way and blocking the movement it will behave normally (unless we set the motor torque to an insanely huge value).
c) Using a motor with a high torque we can fix the players position on the rope, so the player can "stand" on the rope, just like in Worms games.
The rope will have three parts:
Rope (long thin triangle) - a body which is connected to terrain using a revolute joint, so the whole thing can swing.
Slider (rectangle) - a body connected to the hook using a prismatic joint, so the player can move up/down the rope using the joint's motor.
Rotor (yellow circle) - the player body has a fixed rotation, so it always stays upwards. We can't connect the player directly to the slider, because with fixed rotation it wont allow connected bodies to rotate freely. There needs to be a body between the player and slider connected to both with a revolute joint, so the player can maintain the fixed rotation, but the rope can still freely rotate.
Wrap around terrain
It is important to note that only one segment of ninja rope is fully active at any given moment. Basically the swinging part will work as described above in the method 4, and the rest of the rope are just static points with a line rendered between them.
a) How to detect when a corner is hit and split the rope ?
The rope needs to be very long and thin, make the center of mass closest to the player as possible, and needs to be a bullet body. When bullet bodies collide in Box2D you get the exact point of impact in PreSolve() callback function which you can use to determine where the rope needs to be split.
The rope needs to collide with the terrain, but shouldn't bounce off the terrain, we just need the collision point. So in the PreSolve() callback the contact needs to be disabled with contact->SetEnabled(false).
The rope should not be connected directly on the collision point, because we don't want the tip of the rope/hook to constantly collide around that point while rotating and cause problems. The connection point needs to be a bit outside of the terrain body (see image above).
When existing rope collides all the rope objects are deleted and the rope is recreated in that collision point. Like mentioned previously; only the last part of the rope is active. The previous connection points are still needed to render the entire rope and to know when to reconnect the parts.
When the player is moved all the way up the rope, you have all this extra mass below her (the player in not the center of mass) that can cause unwanted movement.
The solution is to make the rope/hook body very small, so the center of mass is always the player, and use some other method to find out where the rope hits the terrain.
b) How to reconnect it all again ?
If you swing clockwise and hit something and split the rope, you will have to reconnect only when you swing in the opposite direction and past that point. Use the revolute joint's speed to check the direction(negative is clockwise, positive is counter-clockwise), and you can check if you past that point using a cross product formula:
Two last rope points is the line you need to cross, and the point you check is the current player position. If you crossed the line you remove the last rope point and recreate the rope in the last of the remaining collision points. While doing all this splitting and reconnecting you need to keep in mind the total length of the rope, and change the rope/hook body length accordingly.
When using a revolute joint, use a rope joint alongside the revolute joint because the physics engine might break and the revolute joint might extend (the rope joint fixes the extension)
http://antonior-software.blogspot.hr/2016/12/box2d-ninja-rope.html
https://www.youtube.com/watch?v=YNhjAPZNzxI
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/Joint.html
Prismatic and revolute joint method
The best way to make Worms like ninja rope using Box2D is using a prismatic joint on a rotating body: a) With a prismatic joint the body is limited to moving/sliding along an axis and that is exactly what we need. b) Using the joint's motor we can make the attached body move up/down without breaking the physics simulation and if some object is in the way and blocking the movement it will behave normally (unless we set the motor torque to an insanely huge value). c) Using a motor with a high torque we can fix the players position on the rope, so the player can "stand" on the rope, just like in Worms games.
The rope will have three parts:
Wrap around terrain
It is important to note that only one segment of ninja rope is fully active at any given moment. Basically the swinging part will work as described above in the method 4, and the rest of the rope are just static points with a line rendered between them.
a) How to detect when a corner is hit and split the rope ?
The rope needs to be very long and thin, make the center of mass closest to the player as possible, and needs to be a bullet body. When bullet bodies collide in Box2D you get the exact point of impact in PreSolve() callback function which you can use to determine where the rope needs to be split.
When existing rope collides all the rope objects are deleted and the rope is recreated in that collision point. Like mentioned previously; only the last part of the rope is active. The previous connection points are still needed to render the entire rope and to know when to reconnect the parts.
When the player is moved all the way up the rope, you have all this extra mass below her (the player in not the center of mass) that can cause unwanted movement. The solution is to make the rope/hook body very small, so the center of mass is always the player, and use some other method to find out where the rope hits the terrain.
b) How to reconnect it all again ?
If you swing clockwise and hit something and split the rope, you will have to reconnect only when you swing in the opposite direction and past that point. Use the revolute joint's speed to check the direction(negative is clockwise, positive is counter-clockwise), and you can check if you past that point using a cross product formula:
http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line
Two last rope points is the line you need to cross, and the point you check is the current player position. If you crossed the line you remove the last rope point and recreate the rope in the last of the remaining collision points. While doing all this splitting and reconnecting you need to keep in mind the total length of the rope, and change the rope/hook body length accordingly.
When using a revolute joint, use a rope joint alongside the revolute joint because the physics engine might break and the revolute joint might extend (the rope joint fixes the extension)