9
\$\begingroup\$

I'm developing a game in which player can use ropes to swing (just like what Spiderman or Bionic Commando did) and I'm having problem implementing this behavior. Can anyone help me how to do this, I mean physics formulas and etc. Till now I've come up with 3 ideas. One is using spring, but it consumes a lot of time and sometimes it is jumpy. The other two are trying to calculate next step (one via calculating potential energy and one via calculating torque) and both of them almost crash whenever the actor is trying to swing.

Here is the code I wrote to calculate torque:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;
\$\endgroup\$
7
  • \$\begingroup\$ Relevant (on making a rope): 2D Rope Collision Detection \$\endgroup\$ Jun 5, 2011 at 23:36
  • \$\begingroup\$ @JonathanHobbs the answer in that question is exactly how I'm trying to implement my rope with one exception, since collision is unwanted in my case I set every rope part as a sensor so they can move freely without geting stuck in each other. \$\endgroup\$
    – Ali1S232
    Jun 6, 2011 at 1:20
  • \$\begingroup\$ What about simple pendulum for rope + some animations which apear ropeish? I do not believe that old games like Bionic Commando had something else than pendulum. \$\endgroup\$
    – user712092
    Oct 5, 2011 at 23:28
  • \$\begingroup\$ @user that pendulum idea should work fine. but in my case either because of player's fast movement or my bad implementation, it didn't give good results. \$\endgroup\$
    – Ali1S232
    Oct 6, 2011 at 5:00
  • \$\begingroup\$ @Gajet try to do some debug drawing until You get it right? This pendulum line might be done as a sufficiently thin box in Box2D to get collisions (and maybe exclude it from physics and move by hand?). \$\endgroup\$
    – user712092
    Oct 6, 2011 at 10:01

5 Answers 5

6
\$\begingroup\$

If you want a rigid-swing, so the distance to the rotation-point is constant, just treat the character as a point on a circle centered at the rotation point. Give him a one-dimensional (along the circle) angular-velocity. Each frame the angular-acceleration should be accelerationDueToGravity * cos(angleOfPlayerOnCircle) (with 0-degrees pointing right).

If you want the rope to get longer/shorter, you could use the above scheme and just vary the radius each frame.

\$\endgroup\$
1
  • \$\begingroup\$ you answer was my second try but it moves with much more speed that it should i'll edit my question and add my code maybe you can spot where the problem is. \$\endgroup\$
    – Ali1S232
    May 31, 2011 at 22:34
3
\$\begingroup\$

after many attempts I went with box2d.

there are generaly two approches to for this simulation or at least I found 2:

  1. one is to use some circle shapes and connect them using distant joints.
  2. and the other one is to rectangles for the chain itself and then attach them using revolute joints

in each senario you have got to have a ancher (which in my case was an static box). it's better if you lower the weight of rope parts (either you use circle shapes or rectangle shapes), for example to have more realistic physics I set their density to 0.1 and for the box connected in the end of rope I used density 10.

another thing you need to worry about how your rope segment react to each other. i just wanted my rope to move freely in scene so I marked all rope fixtures as sensors. you may need diffrent approch.

the next thing you have to worry about is the number of iterations you are pasing to the world update: for low segment of rope( maybe 8 at most) there is no need to use a high iteration value maybe 10/10 which box2d itself suggested is enough but if you increase the number of segment for example i tried 30 segments, with low number of iterations your rope seems to increase it's length more that it should, so you need maybe areoung 40/40 iterations to solve those situations.

after some testing it seems box 2d is designed for scenes with object sizes of 0.1m to 10m and the maximum size suggested for large scenes is somthing about 50mx50m. so basicaly you need to scale your object down to match these parameters. in my case I first tried to pass pixel positions directly to box2d but it seemed like there was some speed limits preventing world to move as fast is it should, so I had to scale my scene around 64 times to have the best results. although i didn't test myself there are some limits in box2d that prevent you from using larger scenes. for example there is a defined value in b2Setting.h file #define b2_maxTranslation 2.0f you can change box2d settings but it seems not recommended.

\$\endgroup\$
5
  • \$\begingroup\$ why's wrong with box2d to earn me a downvote?? \$\endgroup\$
    – Ali1S232
    Jun 6, 2011 at 16:46
  • \$\begingroup\$ This doesn't answer the question. At least write how you made it work using Box2D. \$\endgroup\$
    – bummzack
    Jun 7, 2011 at 15:19
  • \$\begingroup\$ @bummzack: ok i'll add that to my answer \$\endgroup\$
    – Ali1S232
    Jun 7, 2011 at 18:40
  • \$\begingroup\$ If you accept this as your answer, your question if flawed. Segmented rope physics is much different than what you described. \$\endgroup\$ Jun 7, 2011 at 20:55
  • \$\begingroup\$ @attackingHobo: the quesiton was correct at that time but when i transformed my code to box2d, i figured out there without much effort I can implement segmented rope physics. and it's not much diffrent, think of my question as only one segment of a segmented rope. and almost all my solutions were ways to implement circle style rope without box2d. \$\endgroup\$
    – Ali1S232
    Jun 7, 2011 at 21:27
2
\$\begingroup\$

Have you considered slowing down the speed of the swing movement based on how far the rope is from the plumb line (the centre)?

\$\endgroup\$
3
  • \$\begingroup\$ for all 3 approches length of the rope is one of parameters I've used to calculate swinging speed. But I can't guaranty that I've used it correctly. I've just made some physical calculations and applied their solved version to game. \$\endgroup\$
    – Ali1S232
    May 31, 2011 at 20:32
  • \$\begingroup\$ The further away from the centre, the longer the delay before the next movement of the rope swing. You can also multiply the ABSolute value of the delay by something like 0.28 (you'll have to experiment with this). \$\endgroup\$ May 31, 2011 at 20:41
  • \$\begingroup\$ I can't get what you are trying to say, when I'm calculating next step I have some constant value for delta_time, and use all the parameters I have (like previus speed, previes position, rope length, etc.) to calculate new velocity, and then add this velocity multiplied by delta_time to the last position to generate new position. if you mean anything else please provide full details in your answer. \$\endgroup\$
    – Ali1S232
    May 31, 2011 at 21:41
1
\$\begingroup\$

When the player is further than the length of the rope, the player will be immediately pushed back with a force equal to the distance that he has passed it. This should work without feeling springy, and should feel intuitive to the player. You may have to tweak your physics to get the best results for your game though.

When the rope is attached. Save a maxLength value.

Each update, check the distance between the player, and the attachPoint

If the distance is less than the maxLength update normally, no effects from rope.

If the distance is greater than the maxLength, find the normal from the attachPoint to the player. Get the difference between the distance and maxLength. Add to the playerVelocity, normal multiplied by the difference.

Pseudo Code:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;
\$\endgroup\$
3
  • \$\begingroup\$ so is the code i edited into your answer (sorry about that but i didn't find any place better to add it) the one you are suggesting? \$\endgroup\$
    – Ali1S232
    Jun 1, 2011 at 19:42
  • \$\begingroup\$ I approved the edit, and yes I think that should be it. Although I used rope physics before and used a much more convoluted way to do the same thing, because of that I am not entirely sure this code will work properly, but I think it should, and even if it does not, it gets you 95% of the way there. \$\endgroup\$ Jun 1, 2011 at 20:38
  • \$\begingroup\$ after some tries i guess i'll go trying box2d for this issue and by the way you have to change that code so that you have dx = player.x - attachpoint.x and dy = player.y - attachpoint.y. \$\endgroup\$
    – Ali1S232
    Jun 1, 2011 at 22:27
1
\$\begingroup\$

If you look at http://www.cocos2d-iphone.org/archives/1112 there is a implementation of a rope with a rigid body attached to the end of the rope. It uses Box2D for the physics engine. If you look at the source code, I'm sure you can implement it in any language you like.

Also, the above link to the Rope question is mine and this demo(link provided) above really helped.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .