Legacy GM rope swinging physics?

G

GPG

Guest
so i'm working on a 2d platformer and i want to add ropes that you can swing on, i have tried a lot but no results! i want the rope to swing left and right along with player input and to jump off you hit space and will jump off on the side of the arrow key you're holding (example if you hold left and jump you will jump off on the left side) any ideas?
 
G

GPG

Guest
What have you tried exactly that wasn't suitable for you?
i have tried things like making a rope with rope physicsa and if the player object colides with it you get attached to the end and can swing, i have tried using paths, and much much more.
 
A

Anomaly

Guest
the only tutorial i've found so far is from wayback in 2014 and it requires the room to be using physics.

that makes my guy's lazer beams from his gun not shoot right. ( i know sounds stupid (looks pretty) but it is a game breaker)
do we have to be ALL physics or can we have just a few physics elements where and when we want them?
 

samspade

Member
so i'm working on a 2d platformer and i want to add ropes that you can swing on, i have tried a lot but no results! i want the rope to swing left and right along with player input and to jump off you hit space and will jump off on the side of the arrow key you're holding (example if you hold left and jump you will jump off on the left side) any ideas?
My guess is what you want is some type of pendulum motion. Basically, you want to use a sine wave on an angle. It sounds complicated, but it isn't too bad. There's lots of stuff about how to apply a sine wave in game maker and what in general a sine wave is. If you apply that same concept to an angle (rather than an x or y axis as it is normally done) you get the motion of a pendulum.


Code:
        angle_accelerration = -.1 * dcos(angle);
      
        angle_velocity += angle_accelerration;
        angle += angle_velocity;
      
        //angle_velocity *= velocity_dampening;
  
        var new_x = anchor_x + lengthdir_x(distance, angle);
        var new_y = anchor_y + lengthdir_y(distance, angle);
  
        hsp = new_x - x;
        vsp = new_y - y;
Essentially, apply a sine wave formula to the angle_accelerration. Then the next two lines are the angle equivalent of hsp += accel; x += hsp. I commented out the velocity dampening line which is essential friction. The next two lines use lengthdir (which is really just an easier to understand form of sin and cos) to translate the angular position into a normal x and y position. This could be all you need. But since my collision system uses hsp and vsp, I go one step further. I compare the new x and y position to the old x and y position and get the difference. This is hsp and vsp. Then I can use hsp and vsp as I normally would for movement.

Though how you get to this point is another matter. I haven't tried putting rope swings in myself. Probably what you would want to do is add some percentage of the player's velocity to the swing object at the moment of contact and then lock the player to the rope and have the rope control the player's movement. But like I said, I haven't tried that before.
 
R

r7465

Guest
Ok, now I have an idea.

Firstly, design a path: From the start of the rope to the maximum right limit. Then, another path, from right-limit of the path to left-limit.

Now for coding.

On the player's "Create" event, make a variable, and make it only tick on the start. Let's call it "swingingintro" and set it to true. The other variable to create is swinging.
The last variable to create will be swingingtwo = false.

Swinging- Checks if you're on the swing
Swingingintro - Checks if you're on the first path
Swingingtwo - Checks if you're on the second path

On the player's "Step" event, check if the sprite_index != (springing sprite) and if that's the case then swingingintro should be true. Now say if swingingintro = true

Now we need to get the player on the rope. Do anything, say in the collision event with the rope (or use collision_rectangle-- if you will) check if keyboard_check(vk_up) and then this MUST make swinging = true.

Then, make a "Path End" event, check if swingingintro = true && sprite_index = (swinging sprite), if so, then turn on the 2nd path we built.

Now the player keeps swinging on. Make sure that when the path ends, it goes on reverse. And also make sure that there is an alarm to make swinging faster second-by-second. I'll get to this in the end.

Now here is the hard-but-made-to-look-easy part. For beginners, paths use directions and speeds. This is incredibly useful, and you will see why now.

Now check if swinging = true && keyboard_check_pressed(vk_space) [FOR EXAMPLE, you can use any button you want as long as you know it's ID]. Open a bracket, and put the following code: path_end(); direction *= 1.2; speed *=1.2. Close the bracket now, and I think that's all.

I might have missed something, reply if you have a glitch because I did not test this, but it just came out on my brain. Chances that it works are very high though.

As much as paths look like they're the top layer on Game Maker's motion, they're not stronger than Hspeed/Vspeed & are built on direction & speed.
 
G

GPG

Guest
thanks guys, but i think i might just work with more simple things for right now. thanks again :D
 
A

Anomaly

Guest
My guess is what you want is some type of pendulum motion. Basically, you want to use a sine wave on an angle. It sounds complicated, but it isn't too bad. There's lots of stuff about how to apply a sine wave in game maker and what in general a sine wave is. If you apply that same concept to an angle (rather than an x or y axis as it is normally done) you get the motion of a pendulum.


Code:
        angle_accelerration = -.1 * dcos(angle);
    
        angle_velocity += angle_accelerration;
        angle += angle_velocity;
    
        //angle_velocity *= velocity_dampening;
 
        var new_x = anchor_x + lengthdir_x(distance, angle);
        var new_y = anchor_y + lengthdir_y(distance, angle);
 
        hsp = new_x - x;
        vsp = new_y - y;
Essentially, apply a sine wave formula to the angle_accelerration. Then the next two lines are the angle equivalent of hsp += accel; x += hsp. I commented out the velocity dampening line which is essential friction. The next two lines use lengthdir (which is really just an easier to understand form of sin and cos) to translate the angular position into a normal x and y position. This could be all you need. But since my collision system uses hsp and vsp, I go one step further. I compare the new x and y position to the old x and y position and get the difference. This is hsp and vsp. Then I can use hsp and vsp as I normally would for movement.

Though how you get to this point is another matter. I haven't tried putting rope swings in myself. Probably what you would want to do is add some percentage of the player's velocity to the swing object at the moment of contact and then lock the player to the rope and have the rope control the player's movement. But like I said, I haven't tried that before.

sam, thanks for making this available for people to dissect.
i'm working on this very thing to implement ropes in a simple "Pitfall" type way.
is there any way you could rephrase your code above with mock variables instead of the ones you've used? i'm guessing here..

like show an actual implementation .. ie: which event it should be placed in etc.. where those variables come from initially etc...

thanks,
and thanks r7465 also.

p.s. i'm using GMS : 2 btw.
 

samspade

Member
sam, thanks for making this available for people to dissect.
i'm working on this very thing to implement ropes in a simple "Pitfall" type way.
is there any way you could rephrase your code above with mock variables instead of the ones you've used? i'm guessing here..

like show an actual implementation .. ie: which event it should be placed in etc.. where those variables come from initially etc...

thanks,
and thanks r7465 also.

p.s. i'm using GMS : 2 btw.
From another post (pendulum motion):

Code:
///create event
angle_accelerration = 0;
angle_velocity = 0;
angle = 0;
distance = 50;
velocity_dampening = 0.99;

anchor_x = room_width/2;
anchor_y = room_height/2;

///step event
angle_accelerration = -.1 * dcos(angle);
    
angle_velocity += angle_accelerration;
angle += angle_velocity;
    
//angle_velocity *= velocity_dampening;

var new_x = anchor_x + lengthdir_x(distance, angle);
var new_y = anchor_y + lengthdir_y(distance, angle);

hsp = new_x - x;
vsp = new_y - y;

x += hsp;
y += vsp;

///draw event
draw_set_color(c_red);
draw_line(anchor_x, anchor_y, x, y);
draw_circle(x, y, 15, true);
I'm doing this from memory, but placing this object in the room should create a pendulum hanging in the center of a room.
 
A

Anomaly

Guest
Sam, this code isn't working for me.

I've taken out the draw, and applied it to an object with a sprite
 
A

Anomaly

Guest
It's a 16 wide 32 tall oval
Origin is 2 pixels center from top
Mask is oval

Starting at 0 degrees k (270)
 

samspade

Member
It's a 16 wide 32 tall oval
Origin is 2 pixels center from top
Mask is oval

Starting at 0 degrees k (270)
Starting at 270 (straight down) will give you no movement just as a pendulum at rest (straight down) won't move. Note that in my example, 0 degrees is horizontal, as if you were holding the pendulum up and then letting go.
 
A

Anomaly

Guest
I want one link spawning another for 7 links where each does what the latest one does,
 

moonfall

Member
Hey @samspade - this code is fantastic, and I'm using it in my game :)

Just wondering whether you could help me with one thing. When the rope reaches the left and right side of the arc, it becomes a straight line - that is, it stops and reverses direction at 0 and 180 degrees. Is there a way to make it not swing so wide, say to about 30 and 150?

Sorry if this is poorly worded - hope it makes sense!
 

samspade

Member
Hey @samspade - this code is fantastic, and I'm using it in my game :)

Just wondering whether you could help me with one thing. When the rope reaches the left and right side of the arc, it becomes a straight line - that is, it stops and reverses direction at 0 and 180 degrees. Is there a way to make it not swing so wide, say to about 30 and 150?

Sorry if this is poorly worded - hope it makes sense!
It's been awhile, but I think if you uncomment the velocity dampening line and mess with some of the other values, you should be able to limit it like that.
 
Top