player.gd 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. extends CharacterBody2D
  2. ## The player's movement speed (in pixels per second).
  3. const MOTION_SPEED = 90.0
  4. ## The delay before which you can place a new bomb (in seconds).
  5. const BOMB_RATE = 0.5
  6. @export var synced_position := Vector2()
  7. @export var stunned := false
  8. var last_bomb_time := BOMB_RATE
  9. var current_anim := ""
  10. @onready var inputs: Node = $Inputs
  11. func _ready() -> void:
  12. stunned = false
  13. position = synced_position
  14. if str(name).is_valid_int():
  15. $"Inputs/InputsSync".set_multiplayer_authority(str(name).to_int())
  16. func _physics_process(delta: float) -> void:
  17. if multiplayer.multiplayer_peer == null or str(multiplayer.get_unique_id()) == str(name):
  18. # The client which this player represent will update the controls state, and notify it to everyone.
  19. inputs.update()
  20. if multiplayer.multiplayer_peer == null or is_multiplayer_authority():
  21. # The server updates the position that will be notified to the clients.
  22. synced_position = position
  23. # And increase the bomb cooldown spawning one if the client wants to.
  24. last_bomb_time += delta
  25. if not stunned and is_multiplayer_authority() and inputs.bombing and last_bomb_time >= BOMB_RATE:
  26. last_bomb_time = 0.0
  27. $"../../BombSpawner".spawn([position, str(name).to_int()])
  28. else:
  29. # The client simply updates the position to the last known one.
  30. position = synced_position
  31. if not stunned:
  32. # Everybody runs physics. i.e. clients try to predict where they will be during the next frame.
  33. velocity = inputs.motion * MOTION_SPEED
  34. move_and_slide()
  35. # Also update the animation based on the last known player input state.
  36. var new_anim := &"standing"
  37. if inputs.motion.y < 0:
  38. new_anim = &"walk_up"
  39. elif inputs.motion.y > 0:
  40. new_anim = &"walk_down"
  41. elif inputs.motion.x < 0:
  42. new_anim = &"walk_left"
  43. elif inputs.motion.x > 0:
  44. new_anim = &"walk_right"
  45. if stunned:
  46. new_anim = &"stunned"
  47. if new_anim != current_anim:
  48. current_anim = new_anim
  49. $anim.play(current_anim)
  50. @rpc("call_local")
  51. func set_player_name(value: String) -> void:
  52. $label.text = value
  53. # Assign a random color to the player based on its name.
  54. $label.modulate = gamestate.get_player_color(value)
  55. $sprite.modulate = Color(0.5, 0.5, 0.5) + gamestate.get_player_color(value)
  56. @rpc("call_local")
  57. func exploded(_by_who: int) -> void:
  58. if stunned:
  59. return
  60. stunned = true
  61. $anim.play("stunned")