fuzzyworld

godot-shooter / change-html-template / files / Enemy.gd

Branch change-html-template · default branch · all branches

Enemy.gd

3.0 KB · history · blame

1extends KinematicBody2D
2class_name Enemy
3
4onready var ray_cast_2d: RayCast2D = $RayCast2D
5onready var damage_points = $DamagePoints
6const Utils = preload("res://Utils.gd")
7const Explosion = preload("res://Explosion.tscn")
8const Smoke = preload("res://Smoke.tscn")
9
10export var move_speed = 40
11export var turn_rate = 0.01
12export var health = -1
13export var max_health = 10
14export var is_targeted = false
15export var is_invincible = false
16signal enemy_killed
17
18var velocity = Vector2.ZERO
19var dead = false
20
21func _ready() -> void:
22 $AnimationPlayer.play("fade_in")
23 if health < 0 or health > max_health:
24 health = max_health
25 else:
26 var hurt_points = max_health - health
27 health = max_health
28 for i in hurt_points:
29 hurt()
30
31func _process(_delta: float) -> void:
32 $Graphics/Alive/Container/HealthLabel.text = "%s / %s" % [health, max_health]
33 $Graphics/Alive/Container.global_rotation = 0
34 $Graphics/Alive/Target.visible = is_targeted
35 $Graphics/Alive/Target.global_rotation = 0
36
37func _physics_process(_delta: float) -> void:
38 if dead:
39 return
40
41 velocity = move_and_slide(velocity)
42 global_rotation = velocity.angle() + PI/2.0
43
44 var ray_length = ray_cast_2d.cast_to.length()
45 if ray_cast_2d.is_colliding():
46 var players = get_tree().get_nodes_in_group("player")
47 var player: Player = players[0]
48 var dist_to_player = global_position.distance_to(player.global_position)
49 if ray_cast_2d.get_collider() == player and dist_to_player < (ray_length + 5):
50 player.hurt(2)
51 var explosion = Explosion.instance()
52 explosion.transform = transform
53 get_parent().add_child(explosion)
54 kill()
55
56func turn_towards(pos: Vector2):
57 var to_dir = (pos - global_position).normalized()
58 var curr_dir = velocity.normalized()
59 var dir_diff = to_dir - curr_dir
60 var change = dir_diff.normalized() * turn_rate * move_speed
61 velocity = (velocity + change).normalized() * move_speed
62
63func hurt():
64 if dead || is_invincible:
65 return
66 health -= 1
67 var smoke = Smoke.instance()
68 var smoke_pos = get_damage_point_on_body()
69 smoke.position = smoke_pos
70 add_child(smoke)
71 if health <= 0:
72 kill()
73
74func kill():
75 if dead || is_invincible:
76 return
77 dead = true
78 $Graphics/Alive.hide()
79 $CollisionPolygon2D.set_deferred("disabled", true)
80 var explosion = Explosion.instance()
81 explosion.connect("explosion_done", self, "_on_death_explosion_finished")
82 $Graphics.add_child(explosion)
83 z_index = -1
84 emit_signal("enemy_killed")
85
86func _on_death_explosion_finished():
87 $AnimationPlayer.play("fade_out")
88
89func get_damage_point_on_body() -> Vector2:
90 var child_count = damage_points.get_child_count()
91 var random_index = randi() % child_count
92 var random_child: Position2D = damage_points.get_child(random_index)
93 return random_child.position
94
95func remove_thyself():
96 queue_free()
97
98func _on_Area2D_body_entered(body: Node) -> void:
99 var players = get_tree().get_nodes_in_group("player")
100 var player: Player = players[0]
101 var is_player = body == player
102 if is_player:
103 player.hurt(2)
104 var explosion = Explosion.instance()
105 explosion.transform = transform
106 get_parent().add_child(explosion)
107 kill()
108