Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 KB | None | 0 0
  1. """
  2. NPC starts locked in a cage, then flocks to the player when released.
  3. It'll shoot toward the mouse cursor when the player shoots.
  4.  
  5. It should seek a new position if it's shot is blocked by the player,
  6. but that's not 100% solved yet.
  7.  
  8. """
  9.  
  10.  
  11. extends KinematicBody2D
  12.  
  13. # Declare member variables here. Examples:
  14. enum States { CAPTIVE, FREE }
  15. var State = States.CAPTIVE
  16. var velocity : Vector2 = Vector2.ZERO
  17. var speed = 200.0
  18. var shooting : bool = false
  19. var blocked : bool = false
  20. var leader : KinematicBody2D # probably global.player, but maybe someday we'll have other groups in formations.
  21.  
  22. var formation_position : Vector2
  23.  
  24. export (PackedScene) var bulletScene = load("res://Projectiles/Arrow/Arrow.tscn")
  25.  
  26.  
  27. signal projectile_requested(projectile, vel, pos, rot)
  28. signal follower_acquired(node)
  29.  
  30. # Called when the node enters the scene tree for the first time.
  31. func _ready():
  32. call_deferred("start")
  33.  
  34. func start():
  35. connect("projectile_requested", global.current_level, "_on_projectile_requested")
  36.  
  37.  
  38. # Called every frame. 'delta' is the elapsed time since the previous frame.
  39. func _process(delta):
  40. if State == States.FREE:
  41. velocity = aggregate_vectors()
  42. var collision = move_and_collide(velocity * speed * delta)
  43. if collision:
  44. pass
  45.  
  46.  
  47. func aggregate_vectors():
  48. var returnVec : Vector2 = Vector2.ZERO
  49. var blocked = is_blocked()
  50.  
  51. if blocked:
  52. returnVec += get_formation_vector()
  53. else:
  54. returnVec += get_follow_leader_vector()
  55.  
  56. returnVec += get_avoid_allies_vector()
  57.  
  58. return returnVec.normalized()
  59.  
  60. func get_formation_vector():
  61. # store an array of idealized positions (assuming the leader is facing Vector2.RIGHT)
  62. # find your position, based on your order in parent node
  63. # go toward that position.
  64.  
  65. var returnVec = Vector2.ZERO
  66. var myPos = get_global_position()
  67. var leaderPos = leader.get_global_position()
  68. var mousePos = get_global_mouse_position()
  69. var offset = 45
  70. var formation_positions = [ Vector2(-1, -1)*offset, Vector2(-1, 1)*offset, Vector2(-2, -2)*offset, Vector2(-2, 2)*offset]
  71. var leader_targeting_angle = Vector2.RIGHT.angle_to_point(mousePos - leaderPos)
  72. var my_ideal_position = leaderPos + formation_positions[get_position_in_parent()].rotated(leader_targeting_angle)
  73. formation_position = my_ideal_position
  74. update()
  75.  
  76. returnVec += (my_ideal_position - myPos).normalized()
  77.  
  78. return returnVec
  79.  
  80.  
  81. func _draw():
  82. draw_circle(to_local(formation_position), 15, Color.antiquewhite)
  83.  
  84. func get_follow_leader_vector():
  85. return (leader.get_global_position() - self.get_global_position()).normalized()
  86.  
  87. func get_avoid_allies_vector():
  88. var returnVec = Vector2.ZERO
  89. var avoid_distance = 45.0
  90.  
  91. # do this for the player and each NPC ally following the player.
  92. var myPos = get_global_position()
  93. if myPos.distance_squared_to(leader.get_global_position()) < avoid_distance * avoid_distance:
  94. returnVec += (self.get_global_position() - leader.get_global_position()).normalized()
  95.  
  96. for NPC in get_parent().get_children():
  97. # check for all sibling NPCs
  98. if NPC != self:
  99. if myPos.distance_squared_to(NPC.get_global_position()) < avoid_distance * avoid_distance:
  100. returnVec += (myPos - NPC.get_global_position()).normalized()
  101. if returnVec != Vector2.ZERO:
  102. return returnVec.normalized()
  103. else:
  104. return returnVec
  105.  
  106. func _on_cage_unlocked(rescuer):
  107. State = States.FREE
  108. leader = rescuer # most likely global.player
  109.  
  110. if leader.has_method("_on_NPC_follower_acquired"):
  111. connect("follower_acquired", leader, "_on_NPC_follower_acquired")
  112. emit_signal("follower_acquired", self) # tell the player we're following them
  113.  
  114. func commence_shooting():
  115. shooting = true
  116. shoot()
  117. $ReloadTimer.start()
  118.  
  119. func stop_shooting():
  120. shooting = false
  121. $ReloadTimer.stop()
  122.  
  123. func _on_player_started_shooting():
  124. commence_shooting()
  125.  
  126. func _on_player_stopped_shooting():
  127. stop_shooting()
  128.  
  129. func is_blocked():
  130. var ray = $RayCast2D
  131. var rot = Vector2(1,0).angle_to_point(get_global_position()-get_global_mouse_position())
  132. var bulletVelocity = velocity + Vector2(global.options["arrow_speed"],0).rotated(rot)
  133.  
  134. ray.set_cast_to(bulletVelocity / 5)
  135. if ray.is_colliding() == true:
  136. var obstacle = ray.get_collider()
  137. if obstacle:
  138.  
  139. if obstacle.is_in_group("player") or obstacle.is_in_group("player_allies"):
  140.  
  141. return true
  142. return false
  143.  
  144.  
  145. func shoot():
  146. # check for a clean line of sight. Move if you don't have one. Then shoot.
  147. var rot = Vector2(1,0).angle_to_point(get_global_position()-get_global_mouse_position())
  148. var bulletVelocity = velocity + Vector2(global.options["arrow_speed"],0).rotated(rot)
  149.  
  150. if not is_blocked():
  151. emit_signal("projectile_requested", bulletScene, bulletVelocity, get_global_position(), rad2deg(rot))
  152.  
  153.  
  154.  
  155. func _on_ReloadTimer_timeout():
  156. if shooting == true:
  157. shoot()
  158. $ReloadTimer.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement