Add this script to your rigid body, it would be even simplier but addcentralforce() behaves in an unusual manner and previous forces need clearing on the next frame. This acts like the damper (I just came across) but in your own script you could tweak the friction depending on what your object is on top of:
extends RigidBody2D
export(float) var mu_static = 0.8 # friction coefficients
export(float) var mu_moving = 0.5 # pushing something moving is easier
# mu depends on what material the object is on, so use area detectors and change
# this values depending on ice or mud
export(float) var move_strength = 50
var applied_forces: Vector2 = Vector2(0, 0)
func add_force_for_frame(force: Vector2):
# add_force adds a permanent force, for a temporary one we need to wipe it
# by undo the force next frame, just keep track of forces applied
applied_forces += force
self.add_central_force(force)
func _ready() -> void:
# no world gravity pushing the object down (in the +y) direction
# we are top down so gravity is acting into the screen (in +z) but the
# "ground" normal force is canceling it out
self.gravity_scale = 0
func _physics_process(delta: float) -> void:
add_force_for_frame(-applied_forces) # wipe out previous forces
# arrows keys apply force to move it
# could equally have a different body which pushes it
if Input.is_action_pressed("ui_right"):
self.add_force_for_frame(move_strength * Vector2(1, 0))
if Input.is_action_pressed("ui_left"):
self.add_force_for_frame(move_strength * Vector2(-1, 0))
if Input.is_action_pressed("ui_up"):
self.add_force_for_frame(move_strength * Vector2(0, -1))
if Input.is_action_pressed("ui_down"):
self.add_force_for_frame(move_strength * Vector2(0, 1))
# this bit applies the damping force
# minus is there because friction resists the direction of motion
# friction depends on the m * g of the object (in this case the weight)
if self.linear_velocity.length() == 0:
self.add_force_for_frame(- self.weight * mu_static * self.linear_velocity.normalized())
else:
self.add_force_for_frame(- self.weight * mu_moving * self.linear_velocity.normalized())
# no worries about collisions as they add their own forces in opposition to these ones