MainCamera.gd 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. extends Camera2D
  2. # Handle zoom and move for player tracking
  3. export var zoom_border = 100
  4. var zoom_rate:float
  5. var dist_max_x:float
  6. var dist_max_y:float
  7. var view:Viewport
  8. func _ready():
  9. view = get_tree().root
  10. view.connect("size_changed", self, "_on_size_changed")
  11. update_zoom_reference()
  12. func _process(_d):
  13. move()
  14. func move():
  15. if !get_tree().has_group("players"):
  16. return
  17. var running
  18. if get_tree().has_group("running"):
  19. running = get_tree().get_nodes_in_group("running")
  20. if !running or running.size() == 0:
  21. # Show every players
  22. var players = get_tree().get_nodes_in_group("players")
  23. center_on(players)
  24. else:
  25. # Show remaining players only
  26. center_on(running)
  27. func center_on(players):
  28. var position_accumulator = Vector2(0.0, 0.0)
  29. for p in players:
  30. position_accumulator += p.position
  31. position = position_accumulator / players.size()
  32. # Compute axis aligned distances
  33. var dist_x = 0
  34. var dist_y = 0
  35. for i in range(players.size() - 1):
  36. for j in range(i + 1, players.size()):
  37. dist_x = max(dist_x, abs(players[i].position.x - players[j].position.x))
  38. dist_y = max(dist_y, abs(players[i].position.y - players[j].position.y))
  39. # Extend camera zoom if liners are far from each other
  40. var new_zoom = 1.0
  41. if dist_x > dist_max_x:
  42. new_zoom += (dist_x - dist_max_x) * zoom_rate
  43. if dist_y > dist_max_y:
  44. new_zoom = max(new_zoom, 1.0 + (dist_y - dist_max_y) * zoom_rate)
  45. zoom = Vector2(new_zoom, new_zoom)
  46. func update_zoom_reference():
  47. dist_max_x = view.size.x - 2 * zoom_border
  48. dist_max_y = view.size.y - 2 * zoom_border
  49. zoom_rate = 1.0 / min(dist_max_x, dist_max_y)
  50. func _on_size_changed():
  51. update_zoom_reference()