How do I swing on a rope like a pendulum?

Not favoritedFavorited Favorited 0 favourites
  • 2 posts
From the Asset Store
Step onto the fairway and master every swing in Swing Masters
  • I'm trying to add a rope that the player can swing around on in my platformer game.

    I chose not to use the physics system for this, because I wanted to figure out how it worked and I wasn't using the physics system anywhere else. For this, I'm mostly trying to emulate Umihara Kawase, a SNES game where the main action is in throwing a springy grappling hook to change your momentum--so I want it to move between swinging and platforming. from my research the physics of a simple pendulum seemed relatively straightforward, and I thought I could apply the acceleration by making two acceleration vectors every frame and applying them to her platform vectorX and vectorY

    the tension vector being (v^2)/r

    the gravity vector being gsinA.

    here's the code. it's under an else that first checks if the rope becomes slack, which moves her back to regular platforming mode (it actually doesn't really do anything right now though, which you can kind of see in the video)

    before we get here, she gets put into a movement state that removes all of her construct-platform behavior values; so she has no accel/decel/gravity and her max speed and fall speed are set to 2000 px/s. right now it also just kills her momentum rather than converting it into an initial vector, so she should behave as if the pendulum's bob was held up and dropped.

    the main problem is that she's actually accelerating even with no other inputs happening on her. i'm not sure why--as far as I can tell, the physics are right; I validated the trig is correct by duplicating it into desmos and seeing that the x/y components add up correctly, and this is all just the actual newtonian physics I got from reading about pendulums (and from my 20 years past physics classes). but maybe i'm missing something?

    here's a video showing this behavior:

    https://bsky.app/profile/did:plc:ym7kmpznqveevleoktwrxahc/post/3mdo7j4amcc27

    and here's a video where i removed the vertical component as well as the effect from tension, and then put a wall next to her. you can see that even in one swoop she accelerates further to the opposite side than the constraint on the wall-side:

    https://bsky.app/profile/sibylcybil.bsky.social/post/3mdoghtiqvc2b

    the second problem which i'm hoping will go away when I figure out what's wrong here is that it seems like the tension force isn't strong enough to actually maintain the exact length of the rope, so over time she'll be lowered down. I tried adding 1 accel to the tension for each width of rope over the max, but it made her retract too quickly. My guess is that the gravity accel is also too high for the y component.

    here's some thoughts i had but either were unrevealing or afaict dead ends:

    - the problem is i'm not measuring her accel infinitesimally, so i tried averaging 10 and 100 points between the previous and current radii of the rope and got the same result

    - thought maybe it was a result of her going around the corner of the block she's attached to, which changes the radius--which would in the real world change the rotational speed--but it happens even if she's attached directly and not rounding a corner

    - thought maybe it was a dt thing where the time was processing strangely but it's consistently 1/60 a second...

    - maybe it's a floating point thing but i can't investigate that directly and i would assume that would resolve out over multiple swings instead of getting consecutively faster

    - maybe it's a physics thing where i don't have a "simple" pendulum for some reason

    - there's also a disconnect between her position and the exact angle the rope is going to, but since it's fixed to an image point that isn't moving around i would think that probably isn't a factor? so i put it on her image point 0 and it still behaved this way (and also caused a bunch of other problems, that was an annoying test.)

    - thought maybe it's because the tension line isn't directly identical to the rope, since this happens before the rope is updated, but moving it to be after the rope update makes her sink downwards. actually i can't figure that one out really, so it might be revealing in some way

    Anyway, what am I missing here? I've been pulling my hair out over it for two days at this point but haven't changed the code at all (without reverting what I've done, anyway.) It really does seem like the physics should be correct, but maybe it's not? Maybe I'm missing something obvious, like using cos instead of sin somewhere? I just want more eyes on it at this point because I'm totally spinning my wheels.

    Tagged:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • A quick possible fix could be to scale down the acceleration a bit until it’s not adding energy to the swing.

    A likely difference between textbook physics and game physics is game physics is what you call discreet. Aka stuff is done in steps instead of continuously, which depending on the integration method can add or remove energy from the system over time.

    Anyways, I can’t spot offhand what’s amiss with your method.

    Here’s on strategy to do pendulum motion. Basically just let the player move as normal with gravity and whatnot, but once the distance is greater than the rope length it will correct the velocity and position of the player. The velocity correction is done by canceling the part of the velocity going away from the anchor, and the position correction moves it back toward the anchor till it’s at exactly the rope length.

    vars dist, ang, relvel
    Set dist to distance(anchor.x, anchor.y, player.x, player.y)
    Set ang to angle(anchor.x, anchor.y, player.x, player.y)
    
    Compare: dist>rope.length
    — set relvel to player.vx*cos(ang)+player.vy*sin(ang)
    — player: set vx to self.vx-relvel*cos(ang)
    — player: set vy to self.vy-relvel*sin(ang)
    — player: move rope.length-dist pixels at angle ang

    Just an idea at least. That rope will have a hard length limit to it.

    Instead of just canceling any velocity that would make the rope longer, you could do the acceleration idea with a spring, but I’m not sure it would come out to what you had.

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)