GM:S 1.4 Better way of coding oscillating movement

Discussion in 'Programming' started by Matt93, Feb 16, 2017.

Tags:
1. I'm trying to code oscillating movement for my player. Basically, the player has a parachute, and is floating in the air. When he's idle (when there's no keyboard input) I want him to rotate slightly to the right, then back towards the left in an oscillating movement. I've written code that works, but I feel like there's a better way of doing it. I've had to use a variable which triggers to false when I want him to tilt in one direction, then to true when he tilts in the other. Here's my code:

Code:
//Tilt player
if (forth) //counter clockwise
{
image_angle ++;
if (image_angle >= 30)
{
forth = false; //this variable is set to false when player needs to tilt clockwise
}
}

if (!forth) //clockwise
{
image_angle --;
if (image_angle <= -30)
{
forth = true; //true so player tilts counterclockwise
}
}
Is there a less clunky way of doing this without needing an additional variable? Cheers!

2. Tsa05Member

Joined:
Jun 21, 2016
Posts:
557
When the player starts to fall, time=0;

In the draw step:
Code:
rotation = 45*sin(.105*time)
draw_sprite_ext(sprite_index,-1,x,y,1,1,rotation,c_white,1)
time+=1;
This should draw the sprite, oscillating continuously between -45 and 45 degrees over a period of about 60 game steps. You can scale the degrees by changing the 45. You can change the period of swing by changing the .105.

This depends on the variable "time" to compute oscillation. If you want it totally variable-free, create a player sprite with rotating frames and just play it normally.

3. Pixelated_PopeMember

Joined:
Jun 20, 2016
Posts:
784
Yeah, that's a really "hard" oscillation. I have a script that I use for this.

Code:
///sin_oscillate(min,max,position)
return((argument-argument)/2 * dsin(argument) + (argument+argument)/2);
So the way you would use this is like this:

Code:
image_angle = sin_oscillate(-30,30,timer)
timer+=1;
Adjust how the timer increments to increase or decrease the speed. (And of course declare timer as 0 in your create event).

Gyoza_sauce, Anomaly and Matt93 like this.
4. dphswMember

Joined:
Oct 19, 2016
Posts:
82
You could also do this:
Code:
image_angle+=angle_change;
angle_change-=(0.005 * image_angle);

The number 0.005 will need some adjusting - there will be a way to work out the right amount to make it go up to 30 degrees, but it will probably be something to do with integration, which I was never very good at. (You could also put in a multiplier in the top equation.) The disadvantage of this is that you have to work out what number you need, and it will depend on frame rate. The advantage of this approach is that it's much more efficient than an approach using trigonometry (not important for a single sprite, but it would make a difference if it were being used for a particle system or something, especially on mobile) and more flexible - if you later wanted the parachute to be rotated by other factors like being blown around by wind or something, they would just be other factors to add to the equations.

Matt93 likes this.
5. csanykMember

Joined:
Jun 20, 2016
Posts:
821
This article I wrote may not answer your question directly, but it is good reading and may give you some insights into an approach I came up with to do wave-like motion, which you might adapt for your specific problem.

The solution you have is similar to my "cheap wave" solution, where you just increment a variable and then decrement it periodically on a timer. It's not a bad way to do it at all.

Matt93 likes this.
6. Thank you so much for your replies everyone! I'm going to be trying out all of your methods to see what works best for what I'm wanting to do.

7. AnomalyMember

Joined:
Aug 23, 2017
Posts:
244
Marvellous!!
'thanks for sharing that!