• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Image_angle smooth rotation?

R

RATInteractive

Guest
Is the a way to have my player object rotate smoothly to another direction?

Rather than snapping to that direction with the image_angle code

Would rather not have loads of sprites

Thank you
 
N

Nate

Guest
not quite sure what you mean, but if you did a test like this:

if keyboard_check(vk_left)
{
image_angle+=2
}

That should work fine, and look pretty smooth.
 
C

CedSharp

Guest
image_angle is a direction variable. You can set it to any of the 360 degree of a circle.

Instead of "setting the value directly to what you want" maybe you should consider using something like a "target value" and slowly go "toward" that target :p

Regards,
Cedsharp
 
R

RATInteractive

Guest
Roughly:

Code:
image_angle += min(sign(angle_difference(image_angle, target_angle) * rotation_speed), angle_difference(image_angle, target_angle));
That looks confusing

How would I'm implement this for 4 directions Up,Down,Left,Right

Basically I'm hoping for the sprite to smoothly turn to that direction slowly then stop at it correct position
 
Last edited by a moderator:

Yal

🐧 *penguin noises*
GMC Elder
I'd use either something like 0.1*angle_difference (which slows down smoothly but starts up abruptly) or checking the sign of the angle difference and then add small increments with the same sign (which gives uniform movement in any speed or slowness you desire). Up down left and right are the directions 90, 270, 180 and 0 respectively (direction zero is right, and then you rotate counter-clockwise; this is the mathematical standard for measuring direction... just note that GM uses degrees instead of radians to measure direction).

And basically people are understanding what you're asking for, it's just hard to do it without actual code... better get used to stuff looking complicated :p
 
R

RATInteractive

Guest
I'd use either something like 0.1*angle_difference (which slows down smoothly but starts up abruptly) or checking the sign of the angle difference and then add small increments with the same sign (which gives uniform movement in any speed or slowness you desire). Up down left and right are the directions 90, 270, 180 and 0 respectively (direction zero is right, and then you rotate counter-clockwise; this is the mathematical standard for measuring direction... just note that GM uses degrees instead of radians to measure direction).

And basically people are understanding what you're asking for, it's just hard to do it without actual code... better get used to stuff looking complicated :p

The current code is minimal

Code:
if keyboard_check(ord('W')) //Up
{
motion_set(90,4);
image_angle = 90;
}
I tried having a target direction but it ignored it and carried on spinning at the image_angle +=5 that i had chosen

i tried creating a target varible and if it matched that to stop but it didnt stop either.
 
A

Aura

Guest
You can use angle_difference() to get the difference between image_angle and direction (as Yal had suggested). You can use min() to put a limit on the rotation speed.

Code:
var diff = angle_difference(image_angle, direction);
image_angle += min(10 * sign(diff), diff);
 
Last edited by a moderator:
C

CedSharp

Guest
create a new script, call it something nice like "rotate_toward"

Roughly:
Code:
image_angle += min(sign(angle_difference(image_angle, target_angle) * rotation_speed), angle_difference(image_angle, target_angle));
that's a very good piece of code.

you can add it into the script you can create, like this:
Code:
/// rotate_toward( angle, speed )
target_angle = argument[0];
rotation_speed = argument[1];
image_angle += min(sign(angle_difference(image_angle, target_angle) * rotation_speed), angle_difference(image_angle, target_angle));
Now, in your code, replace "image_angle" by this new "rotate_toward" script you just created:
Code:
if( keyboard_check( ord('W') ) // Up
{
    motion_set( 90,4 );
    rotate_toward( 90, 8 ); // change the 8 for rotation speed
}
NOTE
The rotation will stop, even if not facing the right direction, if you release the key before it finishes.
If you want the rotation to complete, you could do something like this:
Code:
if( keyboard_check( ord('W') ) )
{
    // code to go up
}
if( keyboard_check( ord('S') ) )
{
    // code to go down
}
if( keyboard_check( ord('A') ) )
{
    // code to go left
}
if( keyboard_check( ord('D') ) )
{
    // code to go up
}

// If not pressing any of the 4 directions
if( !keyboard_check(ord('W')) and !keyboard_check(ord('A')) and !keyboard_check(ord('S')) and !keyboard_check(ord('D')) )
{
    if( image_angle != target_angle ) // if rotation is not completed
    {
        rotate_toward( target_angle, rotation_speed ); // continue the current rotation
    }
}
-- EDIT --
In the above piece of code, to avoid GameMaker complaining about variables being used before being declared, you should add both 'target_angle=0 and rotation_speed=0' to the create event of your object.

Hopefully this helps you solve your current issue ~

Regards,
CedSharp
 
Last edited:

Bingdom

Googledom
You can use angle_difference() to get the difference between image_angle and direction (as Yal had suggested). You can use min() to put a limit on the rotation speed.

Code:
image_angle += min(10, angle_difference(image_angle, direction));
The problem with using just min is that angle_difference can return a negative value, so it can result in being able to rotate faster than -10. ;)

I would recommend doing this

Code:
diff = angle_difference(image_angle,direction); // The difference between the direction and the player's current angle
//Slow Rotation
image_angle+=clamp(diff,-spd,spd);
 

Yambam

Member
Just a little modification on Bingdom's piece of code, this will make sure the starting torque is not more than spd and it will slow down based on how much of the extra angle is still needed:
Code:
diff = angle_difference(direction,image_angle); // The difference between the direction and the player's current angle
//Slow Rotation
image_angle+=clamp(.7*diff,-spd,spd); //<-- The 0.7*diff part (short: .7*diff) makes it leave 3 tenths of the angle difference for the next "step" of the game
EDIT: Also, I think the order of arguments is (direction, image_angle), since you need to do image_angle += direction - image_angle; to the exact rotation needed in one step. Of course the angle_difference function takes into account "wrapping" the 360 degrees so it won't turn all the way round to get it to rotate to say 315 degrees from 10 degrees, instead it will return a negative value. :)
 

Yal

🐧 *penguin noises*
GMC Elder
I tried having a target direction but it ignored it and carried on spinning at the image_angle +=5 that i had chosen

i tried creating a target varible and if it matched that to stop but it didnt stop either.
Both those things should work in theory, so it sounds more like a problem with the implementation. How does the code for that look?
 
Personally I use
Code:
image_angle= alpha * image_angle + (1-alpha)*desired_angle
With alpha usually between 0.5 and 1 (try 0.8)
Smoothest transitions ever!
Works with all values!
 

Bingdom

Googledom
Personally I use
Code:
image_angle= alpha * image_angle + (1-alpha)*desired_angle
With alpha usually between 0.5 and 1 (try 0.8)
Smoothest transitions ever!
Works with all values!
Tried it, it's neat but there is 1 problem. It seems to do a reflex angle when you pass the 0 degrees mark.
 
Tried it, it's neat but there is 1 problem. It seems to do a reflex angle when you pass the 0 degrees mark.
In that case:

Code:
diffangle=(desired_angle-image_angle) mod 360;
if diffangle>180 diffangle-=360;
if diffangle<-180 diffangle+=360;

image_angle+=alpha*diffangle;
try that! same value for alpha.
 
A

Aura

Guest
The problem with using just min is that angle_difference can return a negative value, so it can result in being able to rotate faster than -10. ;)
Fixed the code 4 minutes before you posted that. ^^"
 
R

RATInteractive

Guest
Regards,
CedSharp

Getting this error with your code sent, do you know what the fix could be

Variable object113.target_angle(100002, -2147483648) not set before reading it.
at gml_Object_object113_StepNormalEvent_1 (line 24) - if( image_angle != target_angle ) // if rotation is not completed
 
C

Cuvette

Guest
Just out of interest. Where are you pulling this rotate_toward function from?
 
C

CedSharp

Guest
The piece of code I provided assumes you've at least ran "rotate_toward" once.
If you want to use the code before using "rotate_toward" then you should define both
'target_angle = 0' and 'rotation_speed = 0' in the create event, so that GameMaker
doesn't complain that those variables don't exists :p

I've updated my reply above to mention this.

Hopefully that should do the trick.
 
Last edited:
C

CedSharp

Guest
Just out of interest. Where are you pulling this rotate_toward function from?
It's the script I created for him.
If your interested in the code, its in one of my replies ( a big one ) above.

Regards,
CedSharp
 
R

RATInteractive

Guest
It's the script I created for him.
If your interested in the code, its in one of my replies ( a big one ) above.

Regards,
CedSharp

Tried this script and it ran without errors although the movement didn't work as it should sadly.
 
Top