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.