Advertisement
Guest User

BeeEnemyManager

a guest
Jun 18th, 2025
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.99 KB | Gaming | 0 0
  1. extends Node2D
  2. class_name BeeSwarmManager
  3.  
  4. @export var bee_texture : Texture
  5. @export var swarm_size : int = 800
  6. @export var spawn_radius : float = 1000.0
  7. @export_range(0, 2000, 10) var steer_force: float = 210.0
  8. @export_range(0.0, 10.0, 0.1) var linear_damping: float = 3.0
  9. @export var follow_target: NodePath
  10. @export_range(0.1, 50, 0.1) var bee_radius: float = 6.0
  11. @export_range(0.05, 2.0, 0.01) var bee_sprite_scale: float = 0.25
  12. @export_range(0.0, 500.0, 1.0) var min_distance_to_target: float = 20.0
  13.  
  14. # separation tuning (fast, sample‐based)
  15. @export_range(1, 10, 1) var sep_samples : int = 3
  16. @export_range(0.0, 100.0, 1.0) var separation_distance: float = 20.0
  17. @export_range(0.0, 5000.0, 10.0) var separation_force: float = 800.0
  18.  
  19. # low-level RIDs
  20. var _space_rid: RID
  21. var _canvas_rid: RID
  22. var _body_rids: Array[RID] = []
  23. var _shape_rids: Array[RID] = []
  24. var _item_rids: Array[RID] = []
  25. const BEE_LAYER_BIT = 0 # all bees get put on layer 1
  26.  
  27. func _ready() -> void:
  28. randomize()
  29. _space_rid = get_world_2d().space
  30. _canvas_rid = get_canvas_item()
  31. for i in swarm_size:
  32. _spawn_enemy()
  33.  
  34.  
  35. func _physics_process(_delta: float) -> void:
  36. var target_node = get_node_or_null(follow_target)
  37. if not target_node:
  38. return
  39. var tpos = target_node.global_position
  40. var count = _body_rids.size()
  41.  
  42. for i in count:
  43. var body_rid = _body_rids[i]
  44.  
  45. # 1) read position
  46. var st = PhysicsServer2D.body_get_state(
  47. body_rid, PhysicsServer2D.BODY_STATE_TRANSFORM
  48. )
  49. var pos = st.origin
  50.  
  51. # 2) steer toward target if outside guard radius
  52. var diff = tpos - pos
  53. var dist = diff.length()
  54. var rot: float
  55. if dist > min_distance_to_target:
  56. var dir = diff / dist
  57. PhysicsServer2D.body_apply_central_force(body_rid, dir * steer_force)
  58. rot = dir.angle()
  59. else:
  60. rot = diff.angle()
  61.  
  62. # 3) approximate separation (O(k⋅N))
  63. if count > 1 and sep_samples > 0:
  64. for s in sep_samples:
  65. var j = randi() % count
  66. if j == i:
  67. continue
  68. var other_st = PhysicsServer2D.body_get_state(
  69. _body_rids[j], PhysicsServer2D.BODY_STATE_TRANSFORM
  70. )
  71. var other_pos = other_st.origin
  72. var delta = pos - other_pos
  73. var d = delta.length()
  74. if d > 0.0 and d < separation_distance:
  75. var push_dir = delta / d
  76. PhysicsServer2D.body_apply_central_force(
  77. body_rid,
  78. push_dir * separation_force
  79. )
  80.  
  81. # 4) update sprite
  82. var ci_rid = _item_rids[i]
  83. var xform = Transform2D().rotated(rot).translated(pos)
  84. RenderingServer.canvas_item_set_transform(ci_rid, xform)
  85.  
  86.  
  87. func _spawn_enemy() -> void:
  88. var body = PhysicsServer2D.body_create()
  89. PhysicsServer2D.body_set_collision_layer(body, BEE_LAYER_BIT)
  90. PhysicsServer2D.body_set_collision_mask(body, BEE_LAYER_BIT)
  91. PhysicsServer2D.body_set_mode(body, PhysicsServer2D.BODY_MODE_RIGID)
  92. PhysicsServer2D.body_set_space(body, _space_rid)
  93. # disable gravity
  94. PhysicsServer2D.body_set_param(
  95. body,
  96. PhysicsServer2D.BODY_PARAM_GRAVITY_SCALE,
  97. 0.0
  98. )
  99. # apply linear damping
  100. PhysicsServer2D.body_set_param(
  101. body,
  102. PhysicsServer2D.BODY_PARAM_LINEAR_DAMP,
  103. linear_damping
  104. )
  105.  
  106. # shape
  107. var shape = PhysicsServer2D.circle_shape_create()
  108. PhysicsServer2D.shape_set_data(shape, bee_radius)
  109. PhysicsServer2D.body_add_shape(body, shape, Transform2D.IDENTITY)
  110. _body_rids .append(body)
  111. _shape_rids.append(shape)
  112.  
  113. # sprite via RenderingServer
  114. var ci = RenderingServer.canvas_item_create()
  115. RenderingServer.canvas_item_set_parent(ci, _canvas_rid)
  116. var tex_sz = bee_texture.get_size() * bee_sprite_scale
  117. var rect = Rect2(-tex_sz / 2, tex_sz)
  118. RenderingServer.canvas_item_add_texture_rect(ci, rect, bee_texture)
  119. _item_rids.append(ci)
  120.  
  121. # random start
  122. var start = Vector2(
  123. randf_range(-spawn_radius, spawn_radius),
  124. randf_range(-spawn_radius, spawn_radius)
  125. )
  126. var xf = Transform2D.IDENTITY.translated(start)
  127. PhysicsServer2D.body_set_state(
  128. body,
  129. PhysicsServer2D.BODY_STATE_TRANSFORM,
  130. xf
  131. )
  132. RenderingServer.canvas_item_set_transform(ci, xf)
  133.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement