GMS 2 rotating sprites with mp_potential, how to avoid flickering

T

Tempus

Guest
Hi

Try to make my enemy movement as fluent as possible.
The enemies are driven by mp_potential functions and follow the player. This works pretty well.
I have 4 directions for the movement animations (up, down, left, right).

At the moment I get the direction which the enemy is pointing to change the animation.

My problem with the mp_potential functions is that sometimes the enemies are rotating at one place to find their way. The rotating is really fast, so they are just flickering.

How can I stop this?

(I have a vague idea of changing the animation based on how many steps (pixels) in one direction the enemy has made. So if the enemy is rotating but not moving a number of pixels (for example 2 pixels) he doesn´t change the animation. Sadly I have no idea how to code this.)
 

GMWolf

aka fel666
Simple solution:
Don't use mp_potential_step functions on their own.
There are really quite bad...

Instead, use mp_potential_grid to build the larger path finding, build a path, and go from point to point using mp_potential_step.
That should greatly reduce the amount of flickering you see.

Another solution is to set the radius of the mp functions to be much greater so your object won't turn as fast.
 
T

Tempus

Guest
Thx for the quick answer.

The grid function would be a bit too much. I have lots of enemies. The pathfinding with mp_potential is good enough and to be honest it would be too complicated for me to use the combination of grid and mp_potential ;-).

The flickering happens mostly if they cluster together. I think this would be also the case with the combination of grid and mp_potential.

I think the other solution with the radius for mp_potential doesn´t avoid clustering as well.

If the enemies are clustered either the grid or the mp_potential would give me a “clean” path without numerous changing directions.
It´s a bit like in reality if two persons can´t decide how they walk past each other.
 
T

Tempus

Guest
Ok here is an other idea to stop the flickering with mp_potential. As i said bevor it is caused, because the sprite rotates to find it´s way.
upload_2017-3-31_12-20-30.png
My code at the moment is
Code:
///chase
if (current_state == states.chase)
{
            if direction >= 45 and direction < 135 {
                sprite_index = spr_enemy_walk_up; image_speed = running_speed*2;}
            if direction >= 135 and direction < 225 {
                sprite_index = spr_enemy_walk_left; image_speed = running_speed*2;}
            if direction >= 225 and direction < 315 {
                sprite_index = spr_enemy_walk_down; image_speed = running_speed*2;}
            if direction >= 315 and direction <= 360 {
                sprite_index = spr_enemy_walk_right; image_speed = running_speed*2;}
            if direction <45 {
                sprite_index = spr_enemy_walk_right; image_speed = running_speed*2;}

        mp_potential_step(obj_player.x, obj_player.y, running_speed, true);
}
upload_2017-3-31_12-22-47.png

The idea is that the object has to be in one direction for a number of steps or seconds to change the sprite
upload_2017-3-31_12-31-31.png
In this example the object must be in one direction for at least 2 steps to change the sprite.

Is this a solution? I guess the animation will lag a bit behind the change of direction.
How can i code this? I think a have to use an alarm?
 
Last edited by a moderator:

GMWolf

aka fel666
That is a pretty neat solution actually.

How to implement it though? Well, there are quite a few different ways to go about it.

You could have tree variables : facing (the true direction its going in), previous_facing, and facing_time.

Then do something like this:
Code:
if (facing == previous_facing) {
   facing_time ++;
   if facing_time >= 3 {
       facing_smooth = facing;
   }
} else {
   facing_time = 0;
}
previous_facing = facing;
 

NightFrost

Member
My solution to the facing jitter has been a counter too, but it builds up each step from how far movement directon is over the sprite change angle, and directions below the angle can take the counter back towards zero. This way, small jitter back and forth across the value (for example 44, 46, 44, 46, 44, 46, 44, 46.... when sprite change angle is 45) will never make the counter go high enough to change the sprite, while a large shift in direction changes it immediately. This was in a project where enemies were mostly just homing on the player, so large repeated back and forth in direction just couldn't happen. I suppose it could come up in automated pathfinding, defeating the code's workings.
 

ph101

Member
I like the cumulative facing solution, but I think I just solved this once (in my early GM days) by only changing the directional sprite according to direction every 10 steps or something (or more if you want less jitter). In fact I simply set an alarm with 10 steps to repeat which makes a variable set to true - this then executes the sprite directional code you posted, but which also sets the jitter var back to false and starts another countdown for 10 steps. This seemed to work. Your cumulative solution may be more accurate in some ways but perhaps it uses more cpu. Perhaps they would visually produce similar results.
 
Top