demon.gd 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. extends Area2D
  2. class_name Demon
  3. @onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
  4. @onready var vision: ShapeCast2D = $Vision
  5. @onready var vision_polygon: Polygon2D = $Vision/Polygon2D
  6. @onready var gun_shot_sound: AudioStreamPlayer = $GunShotSound
  7. var ammo: int = 0
  8. enum State {
  9. STATE_IDLE,
  10. STATE_SHOOTING,
  11. STATE_RELOADING,
  12. }
  13. var state: State = State.STATE_IDLE
  14. var is_being_dragged: bool = false
  15. func _ready() -> void:
  16. ammo = Game.max_ammo
  17. func _process(_delta: float) -> void:
  18. vision_polygon.visible = GlobalInput.visible_vision
  19. func _physics_process(_delta: float) -> void:
  20. vision.force_shapecast_update()
  21. if not vision.is_colliding():
  22. return
  23. var foe = vision.get_collider(0)
  24. if foe == null || not (foe is Area2D):
  25. return
  26. shoot_at(foe as Area2D)
  27. func _on_mouse_entered():
  28. if not GlobalInput.is_dragging():
  29. # TODO: add custom cursor image
  30. Input.set_custom_mouse_cursor(null, Input.CURSOR_MOVE)
  31. func _on_mouse_exited():
  32. if not GlobalInput.is_dragging():
  33. # TODO: add custom cursor image
  34. Input.set_custom_mouse_cursor(null, Input.CURSOR_ARROW)
  35. func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int):
  36. if event is InputEventMouseButton:
  37. handle_click(event)
  38. func handle_click(event: InputEventMouseButton):
  39. if event.button_index != MOUSE_BUTTON_LEFT:
  40. return
  41. if event.pressed && not GlobalInput.is_dragging():
  42. is_being_dragged = true
  43. GlobalInput.start_dragging(self)
  44. elif not event.pressed && is_being_dragged:
  45. is_being_dragged = false
  46. GlobalInput.stop_dragging()
  47. func reload() -> void:
  48. state = State.STATE_RELOADING
  49. print("%s: reloading (%.2f seconds)" % [name, Game.reload_time])
  50. await get_tree().create_timer(Game.reload_time).timeout
  51. print(name + ": done reloading")
  52. ammo = Game.max_ammo
  53. state = State.STATE_IDLE
  54. func shoot_at(foe: Area2D) -> void:
  55. if state != State.STATE_IDLE:
  56. return
  57. print("%s: %d/%d" % [name, ammo, Game.max_ammo])
  58. if ammo <= 0:
  59. await reload()
  60. else:
  61. state = State.STATE_SHOOTING
  62. ammo -= 1
  63. gun_shot_sound.play()
  64. sprite.play("shoot")
  65. if foe.has_method("die"):
  66. foe.die()
  67. else:
  68. foe.queue_free()
  69. await sprite.animation_finished
  70. if ammo <= 0:
  71. await reload()
  72. else:
  73. state = State.STATE_IDLE
  74. func _on_animation_finished():
  75. sprite.animation = "idle"
  76. sprite.frame = 0