# _physics_process(delta) speed * delta with 60fps and speed = 200 gives inconsistent motion effect 2D

Attention Topic was automatically imported from the old Question2Answer platform.

Hello,

I was moving my 2D code motion to grid movement, in order to ensure a fixed range position. I took some Example I got from Godot 3.2: Godot-Grid-Movement

Based, the code changed brings me some inconsistent 2D motion effect.
The code use _physics_process(delta): and a default speed of 200.
at 60fps default the delta = 0,016666666666667 * 200 = 3,33333333333333

Here is the screen recording:
screencast inconsistent 2D motion effect

The code

``````func _physics_process(delta):
if not initialized:
return

# MOVEMENT
# increase, the player travels from grid step
var vel =  speed * delta
if not float_velocity:
vel = ceil(vel)
var p = position
velocity = want_dir * vel
p += velocity
# if we've moved further than one space
if p.distance_to(last_position) >= grid_size - vel:
p = target_position # snap the player to the intended position
if p != position:
position = p
#print("p: %10s vel %10s targer %10s" % [p, vel, target_position])

if position == target_position:
# IDLE on grid position
get_input()
# get new target (also shift to moving state)
var new_target = target_position + want_dir * grid_size
if new_target != position and is_inside_grid(new_target):
target_position = new_target
# record the player's current idle position
last_position = position
speed = our_max_speed
``````

This seems to be due to the specific value computed here: 3,33333333333333
As the increment velocity. If I switch to integer velocity, I don’t get any motion inconsistency, nor for more float value not 3.3333. Speed 201 or 199 don’t generate any motion inconsistency in float.

I was first seeking about the overlapping element on the screen as the “slow” part of the motion seemed be over the silhouette, but no. This is definitely related to float computation.

Did you ever noticed that?
How did you fixed it?

Regards,
Sylvain.

I found.

because of the grid_size of 10 and the sapping to a grid offset:

``````if p.distance_to(last_position) >= grid_size - vel:
p = target_position # snap the player to the intended position
``````

So I suppose that a velocity of 3.3333335 (float32) as exactly at one third of 10 and the floating point accumulated errors, at some part of the addition (with some specific floating number or int may be) then the offset we get has some nasty effect of being snapped to the grid more often that other.

So the motion inconsistency at this specific value, which disappears when we change the velocity to not have a specific relation with he grid size.

I made a python script to simulate this:

``````import numpy as np

speed = 200
grid_size = 10
delta = np.float32(1.0 / 60)
vel = np.float32(speed * delta)
print(vel)

x = np.float32(0)
last_position = 0
target_position = 0
want_move = False
while x < 350:
if x != target_position:
x += vel
if (x - last_position) >= grid_size - vel:
print("%6s %s -> %s" % ("SNAP", x, target_position))
# snap the player to the intended position
x = np.float32(target_position)
else:
print("%6s %s" % ("move", x))
else:
new_target = target_position + grid_size
if new_target != x:
target_position = new_target
# record the player's current idle position
last_position = x
print("%s %s %s" % ("TARGET", last_position, target_position))
``````

Which displays some interesting rounding effect on the float32 precision and the boundary.

Also a better snapping grid condition when we are near the grid point from both side:

``````if (x - last_position) >= grid_size or (target_position - x) < np.float32(0.02)
``````

This avoid the nasty visual effect of slow down when multiple loop of _physics_process are needed to reach a point or to skip a point of the grid.

Hope that helps.
Regards,
Sylvain.