Player.gd 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. extends CharacterBody3D
  2. signal hit
  3. ## How fast the player moves in meters per second.
  4. @export var speed = 14
  5. ## Vertical impulse applied to the character upon jumping in meters per second.
  6. @export var jump_impulse = 20
  7. ## Vertical impulse applied to the character upon bouncing over a mob in meters per second.
  8. @export var bounce_impulse = 16
  9. ## The downward acceleration when in the air, in meters per second.
  10. @export var fall_acceleration = 75
  11. func _physics_process(delta):
  12. var direction = Vector3.ZERO
  13. if Input.is_action_pressed("move_right"):
  14. direction.x += 1
  15. if Input.is_action_pressed("move_left"):
  16. direction.x -= 1
  17. if Input.is_action_pressed("move_back"):
  18. direction.z += 1
  19. if Input.is_action_pressed("move_forward"):
  20. direction.z -= 1
  21. if direction != Vector3.ZERO:
  22. # In the lines below, we turn the character when moving and make the animation play faster.
  23. direction = direction.normalized()
  24. # Setting the basis property will affect the rotation of the node.
  25. $Pivot.basis = Basis.looking_at(direction)
  26. $AnimationPlayer.speed_scale = 4
  27. else:
  28. $AnimationPlayer.speed_scale = 1
  29. velocity.x = direction.x * speed
  30. velocity.z = direction.z * speed
  31. # Jumping.
  32. if is_on_floor() and Input.is_action_just_pressed("jump"):
  33. velocity.y += jump_impulse
  34. # We apply gravity every frame so the character always collides with the ground when moving.
  35. # This is necessary for the is_on_floor() function to work as a body can always detect
  36. # the floor, walls, etc. when a collision happens the same frame.
  37. velocity.y -= fall_acceleration * delta
  38. move_and_slide()
  39. # Here, we check if we landed on top of a mob and if so, we kill it and bounce.
  40. # With move_and_slide(), Godot makes the body move sometimes multiple times in a row to
  41. # smooth out the character's motion. So we have to loop over all collisions that may have
  42. # happened.
  43. # If there are no "slides" this frame, the loop below won't run.
  44. for index in range(get_slide_collision_count()):
  45. var collision = get_slide_collision(index)
  46. if collision.get_collider().is_in_group("mob"):
  47. var mob = collision.get_collider()
  48. if Vector3.UP.dot(collision.get_normal()) > 0.1:
  49. mob.squash()
  50. velocity.y = bounce_impulse
  51. # Prevent this block from running more than once,
  52. # which would award the player more than 1 point for squashing a single mob.
  53. break
  54. # This makes the character follow a nice arc when jumping
  55. $Pivot.rotation.x = PI / 6 * velocity.y / jump_impulse
  56. func die():
  57. emit_signal("hit")
  58. queue_free()
  59. func _on_MobDetector_body_entered(_body):
  60. die()