However, the error will accumulate unless it is a constant motion.

There is a constant friction force in your case a= 20; (from your code: velocity -= 20 * dt;)

The velocity is changing between time t to t+dt (it is not the same between time t and time t+dt).

However, because it is in a constant acceleration mode. so the velocity change linearly.

You should use the average velocity to calculate the displacement (i.e. use Midpoint method instead of Euler's method).

Your problem is mainly due to how you calculate the change in velocity.

dx = vx / velocity;

dy = vy / velocity;

velocity -= 20 * dt;

I know you were trying to calculate the component, but the ratio of vx,vy will be different before and after you change the velocity. That is the reason why the moving direction was changed.

Because it is a constant force acting on the particle. So both vx and vy will change the same amount,

Just use vx-=a*dt; vy-=a*dt; will be fine.

To make the calculation more accurate.

define vxs,vys before the above change:

i.e.

//save the previous velocity value

vxs=vx;

vys=vy;

//calculate the new velocity

vx-= a*dt;

vy-=a*dt;

// calculate the displacement

x+= (vxs+vx)*dt/2;

y+= (vys+vy)*dt/2;

The above method is also called as "Midpoint Method".