rigidbody_controller.gd 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. extends RigidBody2D
  2. var _initial_velocity := Vector2.ZERO
  3. var _constant_velocity := Vector2.ZERO
  4. var _motion_speed := 400.0
  5. var _gravity_force := 50.0
  6. var _jump_force := 1000.0
  7. var _velocity := Vector2.ZERO
  8. var _floor_max_angle := 45.0
  9. var _on_floor := false
  10. var _jumping := false
  11. var _keep_velocity := false
  12. func _ready() -> void:
  13. gravity_scale = 0.0
  14. func _physics_process(_delta: float) -> void:
  15. if _initial_velocity != Vector2.ZERO:
  16. _velocity = _initial_velocity
  17. _initial_velocity = Vector2.ZERO
  18. _keep_velocity = true
  19. elif _constant_velocity != Vector2.ZERO:
  20. _velocity = _constant_velocity
  21. elif not _keep_velocity:
  22. _velocity.x = 0.0
  23. # Handle horizontal controls.
  24. if Input.is_action_pressed(&"character_left"):
  25. if position.x > 0.0:
  26. _velocity.x = -_motion_speed
  27. _keep_velocity = false
  28. _constant_velocity = Vector2.ZERO
  29. elif Input.is_action_pressed(&"character_right"):
  30. if position.x < 1024.0:
  31. _velocity.x = _motion_speed
  32. _keep_velocity = false
  33. _constant_velocity = Vector2.ZERO
  34. # Handle jump controls and gravity.
  35. if is_on_floor():
  36. if not _jumping and Input.is_action_just_pressed(&"character_jump"):
  37. # Start jumping.
  38. _jumping = true
  39. _velocity.y = -_jump_force
  40. elif not _jumping:
  41. # Reset gravity.
  42. _velocity.y = 0.0
  43. else:
  44. _velocity.y += _gravity_force
  45. _jumping = false
  46. linear_velocity = _velocity
  47. func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
  48. _on_floor = false
  49. var contacts := state.get_contact_count()
  50. for i in contacts:
  51. var normal := state.get_contact_local_normal(i)
  52. # Detect floor.
  53. if acos(normal.dot(Vector2.UP)) <= deg_to_rad(_floor_max_angle) + 0.01:
  54. _on_floor = true
  55. # Detect ceiling.
  56. if acos(normal.dot(-Vector2.UP)) <= deg_to_rad(_floor_max_angle) + 0.01:
  57. _jumping = false
  58. _velocity.y = 0.0
  59. func is_on_floor() -> bool:
  60. return _on_floor