diff --git a/assets/images/sprites/Enemies/Entity/Agis.png b/assets/images/sprites/Enemies/Entity/Agis.png new file mode 100644 index 0000000..c63608d Binary files /dev/null and b/assets/images/sprites/Enemies/Entity/Agis.png differ diff --git a/assets/images/sprites/Enemies/Entity/Agis.png.import b/assets/images/sprites/Enemies/Entity/Agis.png.import new file mode 100644 index 0000000..eee4166 --- /dev/null +++ b/assets/images/sprites/Enemies/Entity/Agis.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvgfsm4ocwxsw" +path="res://.godot/imported/Agis.png-e1611e9d4c4f9014531b1d534d2161fd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/images/sprites/Enemies/Entity/Agis.png" +dest_files=["res://.godot/imported/Agis.png-e1611e9d4c4f9014531b1d534d2161fd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/scenes/actors/Creeper.tscn b/scenes/actors/Creeper.tscn new file mode 100644 index 0000000..bce83b9 --- /dev/null +++ b/scenes/actors/Creeper.tscn @@ -0,0 +1,476 @@ +[gd_scene format=3 uid="uid://cr7ibxkl174o1"] + +[ext_resource type="Script" uid="uid://cj5w74n7beula" path="res://scenes/actors/creeper.gd" id="1_683kk"] +[ext_resource type="Texture2D" uid="uid://mta76reo0an0" path="res://assets/images/sprites/Enemies/Monsters/monster.png" id="1_noq3l"] +[ext_resource type="Script" uid="uid://cxsbkcxpnu3t6" path="res://scenes/components/hurt_box.gd" id="2_hurtbox"] +[ext_resource type="Script" uid="uid://ev7uglfcbl02" path="res://scenes/components/health_component.gd" id="3_health"] +[ext_resource type="Script" uid="uid://dw1cot7pm0rp6" path="res://scenes/components/hit_box.gd" id="5_7og3g"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_6gm0u"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_o77sm"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fiwxl"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xxnpd"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hk1d6"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1334s"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_h12pd"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ef3yn"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 144, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bcab8"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_q5rkb"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_53wdg"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qc2f3"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_h6kpp"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vxsoj"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_53fqn"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ib8sr"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 288, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wrhl5"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_o07x0"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4xuc4"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_f4n60"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6fyr1"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_isrvx"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7jb5g"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4snpt"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 336, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0bs3p"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 240, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6er14"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 240, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2ousp"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 240, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_683kk"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7psr3"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_usrw5"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7og3g"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_blets"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_nt051"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mck3s"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ipyt4"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_m1exi"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_u4pvs"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_pdeun"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ajc8e"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4a32r"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0lcgg"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vn5sj"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rw06l"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 48, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_oqjui"] +atlas = ExtResource("1_noq3l") +region = Rect2(0, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_oh0i5"] +atlas = ExtResource("1_noq3l") +region = Rect2(48, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_etdul"] +atlas = ExtResource("1_noq3l") +region = Rect2(96, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_b67jb"] +atlas = ExtResource("1_noq3l") +region = Rect2(144, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_odu4t"] +atlas = ExtResource("1_noq3l") +region = Rect2(192, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_i755r"] +atlas = ExtResource("1_noq3l") +region = Rect2(240, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_p4bqm"] +atlas = ExtResource("1_noq3l") +region = Rect2(288, 96, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_pinoy"] +atlas = ExtResource("1_noq3l") +region = Rect2(336, 96, 48, 48) + +[sub_resource type="SpriteFrames" id="SpriteFrames_uvqlf"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_6gm0u") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_o77sm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_fiwxl") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_xxnpd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_hk1d6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1334s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_h12pd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ef3yn") +}], +"loop": 0, +"name": &"attack", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_bcab8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_q5rkb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_53wdg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qc2f3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_h6kpp") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vxsoj") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_53fqn") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ib8sr") +}], +"loop": 0, +"name": &"death_1", +"speed": 7.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_wrhl5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_o07x0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4xuc4") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_f4n60") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_6fyr1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_isrvx") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7jb5g") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4snpt") +}], +"loop": 0, +"name": &"death_2", +"speed": 7.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_0bs3p") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_6er14") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2ousp") +}], +"loop": 0, +"name": &"hurt", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_683kk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7psr3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_usrw5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7og3g") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_blets") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_nt051") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_mck3s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ipyt4") +}], +"loop": 1, +"name": &"idle", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_m1exi") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_u4pvs") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_pdeun") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ajc8e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4a32r") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_0lcgg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vn5sj") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rw06l") +}], +"loop": 1, +"name": &"walk_1", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_oqjui") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_oh0i5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_etdul") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_b67jb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_odu4t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_i755r") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_p4bqm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_pinoy") +}], +"loop": 1, +"name": &"walk_2", +"speed": 10.0 +}] + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_gy2im"] +radius = 6.0 +height = 18.0 + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_uvqlf"] +radius = 5.0 +height = 16.0 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uvqlf"] +size = Vector2(178.875, 27) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_gy2im"] +size = Vector2(17, 6) + +[node name="Creeper" type="CharacterBody2D" unique_id=1458442942] +collision_layer = 8 +script = ExtResource("1_683kk") + +[node name="HealthComponent" type="Node" parent="." unique_id=391872171] +script = ExtResource("3_health") +max_health = 15 + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1045569955] +position = Vector2(0, -8) +scale = Vector2(1.2, 1.2) +sprite_frames = SubResource("SpriteFrames_uvqlf") +animation = &"idle" +autoplay = "idle" + +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=101852921] +position = Vector2(1, -9) +shape = SubResource("CapsuleShape2D_gy2im") + +[node name="HurtBox" type="Area2D" parent="." unique_id=1950866404] +collision_layer = 4 +collision_mask = 2 +script = ExtResource("2_hurtbox") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="HurtBox" unique_id=1935738172] +position = Vector2(1, -8) +shape = SubResource("CapsuleShape2D_uvqlf") +debug_color = Color(1, 0, 0, 0.41960785) + +[node name="DetectionArea" type="Area2D" parent="." unique_id=2027089166] +collision_layer = 0 +collision_mask = 16 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="DetectionArea" unique_id=1536337340] +position = Vector2(1, -14) +shape = SubResource("RectangleShape2D_uvqlf") +debug_color = Color(0.77266294, 0.44344115, 3.85046e-07, 0.41960785) + +[node name="HitBox" type="Area2D" parent="." unique_id=1279016534] +collision_layer = 2 +collision_mask = 4 +script = ExtResource("5_7og3g") +damage = 1 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox" unique_id=622613801] +position = Vector2(-14.5, -14) +shape = SubResource("RectangleShape2D_gy2im") + +[node name="AttackRangeArea" type="Area2D" parent="." unique_id=-473062739] +collision_layer = 0 +collision_mask = 4 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="AttackRangeArea" unique_id=1058720448] +position = Vector2(-14.5, -14) +shape = SubResource("RectangleShape2D_gy2im") +debug_color = Color(0.9622, 0.6, 0.1, 0.41960785) + +[node name="RayCast2D" type="RayCast2D" parent="." unique_id=562937948] +target_position = Vector2(0, 15) diff --git a/scenes/actors/creeper.gd b/scenes/actors/creeper.gd new file mode 100644 index 0000000..c130fe4 --- /dev/null +++ b/scenes/actors/creeper.gd @@ -0,0 +1,175 @@ +class_name Creeper +extends CharacterBody2D + +@onready var _hurtbox: HurtBox = $HurtBox +@onready var _health: HealthComponent = $HealthComponent +@onready var _sprite: AnimatedSprite2D = $AnimatedSprite2D +@onready var _detection_area: Area2D = $DetectionArea +@onready var _hitbox: HitBox = $HitBox +@onready var _hitbox_collision: CollisionShape2D = $HitBox/CollisionShape2D +@onready var _attack_range_area: Area2D = $AttackRangeArea +@onready var _ledge_detector: RayCast2D = $RayCast2D + +# Creeper Exported Variables +@export_group("Movement") +@export var move_speed: float = 60.0 +@export var patrol_speed: float = 20.0 +@export var ledge_check_offset: float = 10.0 + +@export_group("Combat") +@export var attack_cooldown: float = 1.0 +@export var backoff_min_distance: float = 30.0 +@export var attack_hit_frame_start: int = 4 +@export var attack_hit_frame_end: int = 5 + +# Creeper Runtime Variables +var _player: Node2D = null +var _player_in_attack_range: bool = false +var _is_attacking: bool = false +var _is_hurt: bool = false +var _is_dead: bool = false +var _attack_cooldown_timer: float = 0.0 +var _facing_direction: float = 1.0 +var _patrol_direction: float = 1.0 + +func _ready() -> void: + _hurtbox.hit_received.connect(_on_hurtbox_hit_received) + _health.health_changed.connect(_on_health_changed) + _health.died.connect(_on_died) + _sprite.animation_finished.connect(_on_animation_finished) + _detection_area.body_entered.connect(_on_detection_area_body_entered) + _detection_area.body_exited.connect(_on_detection_area_body_exited) + _attack_range_area.area_entered.connect(_on_hitbox_area_entered) + _attack_range_area.area_exited.connect(_on_hitbox_area_exited) + +func _physics_process(delta: float) -> void: + _apply_gravity(delta) + _update_attack_cooldown(delta) + + if not _is_dead: + _process_ai() + _update_hitbox() + + move_and_slide() + +func _update_hitbox() -> void: + var is_active_hit_frame: bool = _sprite.animation == &"attack" \ + and _sprite.frame >= attack_hit_frame_start \ + and _sprite.frame <= attack_hit_frame_end + _hitbox_collision.disabled = not (_is_attacking and is_active_hit_frame) + +func _apply_gravity(delta: float) -> void: + if not is_on_floor(): + velocity.y += ProjectSettings.get_setting("physics/2d/default_gravity") * delta + +func _update_attack_cooldown(delta: float) -> void: + if _attack_cooldown_timer > 0.0: + _attack_cooldown_timer -= delta + +func _process_ai() -> void: + if _is_hurt: + velocity.x = 0.0 + return + + if _is_attacking: + velocity.x = 0.0 + return + + if _player_in_attack_range and _attack_cooldown_timer <= 0.0: + _start_attack() + return + + if _player_in_attack_range: + _facing_direction = signf(_player.global_position.x - global_position.x) + var distance_to_player: float = absf(_player.global_position.x - global_position.x) + if distance_to_player < backoff_min_distance: + velocity.x = -_facing_direction * move_speed + if _sprite.animation != &"walk_1": + _sprite.play(&"walk_1") + else: + velocity.x = 0.0 + if _sprite.animation != &"idle": + _sprite.play(&"idle") + _sprite.flip_h = _facing_direction > 0.0 + _hitbox.scale.x = -_facing_direction + _attack_range_area.scale.x = -_facing_direction + return + + if _player: + _facing_direction = signf(_player.global_position.x - global_position.x) + if _has_ground_ahead(_facing_direction): + velocity.x = _facing_direction * move_speed + if _sprite.animation != &"walk_1": + _sprite.play(&"walk_1") + else: + velocity.x = 0.0 + if _sprite.animation != &"idle": + _sprite.play(&"idle") + else: + _facing_direction = _patrol_direction + velocity.x = _patrol_direction * patrol_speed + if _sprite.animation != &"walk_2": + _sprite.play(&"walk_2") + + _sprite.flip_h = _facing_direction > 0.0 + _hitbox.scale.x = -_facing_direction + _attack_range_area.scale.x = -_facing_direction + + if not _player: + _update_patrol_direction() + +func _has_ground_ahead(direction: float) -> bool: + _ledge_detector.position.x = ledge_check_offset * direction + _ledge_detector.force_raycast_update() + return _ledge_detector.is_colliding() + +func _update_patrol_direction() -> void: + if is_on_wall() or not _has_ground_ahead(_patrol_direction): + _patrol_direction = -_patrol_direction + +func _start_attack() -> void: + _is_attacking = true + _attack_cooldown_timer = attack_cooldown + velocity.x = 0.0 + _sprite.play(&"attack") + +func _on_detection_area_body_entered(body: Node2D) -> void: + _player = body + +func _on_detection_area_body_exited(body: Node2D) -> void: + if body == _player: + _player = null + +func _on_hitbox_area_entered(area: Area2D) -> void: + if area is HurtBox and area.get_parent() == _player: + _player_in_attack_range = true + +func _on_hitbox_area_exited(area: Area2D) -> void: + if area is HurtBox and area.get_parent() == _player: + _player_in_attack_range = false + +func _on_hurtbox_hit_received(hitbox: HitBox) -> void: + _health.take_damage(hitbox.damage) + +func _on_health_changed(_new_value: int, _max_value: int) -> void: + _is_attacking = false + _is_hurt = true + _sprite.play(&"hurt") + +func _on_died() -> void: + _is_dead = true + velocity = Vector2.ZERO + _hurtbox.set_deferred("monitoring", false) + _hitbox_collision.set_deferred("disabled", true) + +func _on_animation_finished() -> void: + if _sprite.animation == &"hurt": + _is_hurt = false + if _is_dead: + _sprite.play(&"death_1") + else: + _sprite.play(&"idle") + elif _sprite.animation == &"attack": + _is_attacking = false + elif _sprite.animation == &"death_1": + queue_free() diff --git a/scenes/actors/creeper.gd.uid b/scenes/actors/creeper.gd.uid new file mode 100644 index 0000000..a37a237 --- /dev/null +++ b/scenes/actors/creeper.gd.uid @@ -0,0 +1 @@ +uid://cj5w74n7beula diff --git a/scenes/actors/entity.tscn b/scenes/actors/entity.tscn new file mode 100644 index 0000000..fdfed4e --- /dev/null +++ b/scenes/actors/entity.tscn @@ -0,0 +1,123 @@ +[gd_scene format=3 uid="uid://cwq8mu0hub5qd"] + +[ext_resource type="Texture2D" uid="uid://cvgfsm4ocwxsw" path="res://assets/images/sprites/Enemies/Entity/Agis.png" id="1_hfkv4"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_n1j25"] +atlas = ExtResource("1_hfkv4") +region = Rect2(0, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7us7e"] +atlas = ExtResource("1_hfkv4") +region = Rect2(224, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rf7ig"] +atlas = ExtResource("1_hfkv4") +region = Rect2(448, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_078wo"] +atlas = ExtResource("1_hfkv4") +region = Rect2(672, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_21adn"] +atlas = ExtResource("1_hfkv4") +region = Rect2(896, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2x2mf"] +atlas = ExtResource("1_hfkv4") +region = Rect2(1120, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_g1arv"] +atlas = ExtResource("1_hfkv4") +region = Rect2(1344, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_chiue"] +atlas = ExtResource("1_hfkv4") +region = Rect2(1568, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_f3a0o"] +atlas = ExtResource("1_hfkv4") +region = Rect2(1792, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xy100"] +atlas = ExtResource("1_hfkv4") +region = Rect2(2016, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fv5mp"] +atlas = ExtResource("1_hfkv4") +region = Rect2(2240, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wunnd"] +atlas = ExtResource("1_hfkv4") +region = Rect2(2464, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_u15hw"] +atlas = ExtResource("1_hfkv4") +region = Rect2(2688, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ai8gr"] +atlas = ExtResource("1_hfkv4") +region = Rect2(2912, 0, 224, 240) + +[sub_resource type="AtlasTexture" id="AtlasTexture_retyq"] +atlas = ExtResource("1_hfkv4") +region = Rect2(3136, 0, 224, 240) + +[sub_resource type="SpriteFrames" id="SpriteFrames_uvqlf"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_n1j25") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7us7e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rf7ig") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_078wo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_21adn") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2x2mf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_g1arv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_chiue") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_f3a0o") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_xy100") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_fv5mp") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wunnd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_u15hw") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ai8gr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_retyq") +}], +"loop": 1, +"name": &"idle", +"speed": 8.0 +}] + +[node name="Entity" type="AnimatedSprite2D" unique_id=286688007] +scale = Vector2(2, 2) +sprite_frames = SubResource("SpriteFrames_uvqlf") +animation = &"idle" +autoplay = "idle" +frame_progress = 0.9163391 diff --git a/scenes/components/health_component.gd b/scenes/components/health_component.gd new file mode 100644 index 0000000..74875c1 --- /dev/null +++ b/scenes/components/health_component.gd @@ -0,0 +1,28 @@ +class_name HealthComponent +extends Node + +signal health_changed(new_value: int, max_value: int) +signal died + +@export var max_health: int = 1 + +var current_health: int + +func _ready() -> void: + current_health = max_health + +func take_damage(amount: int) -> void: + if current_health <= 0: + return + + current_health = max(current_health - amount, 0) + health_changed.emit(current_health, max_health) + + if current_health == 0: + died.emit() + +func heal(amount: int) -> void: + if current_health <= 0: + return + current_health = min(current_health + amount, max_health) + health_changed.emit(current_health, max_health) diff --git a/scenes/components/health_component.gd.uid b/scenes/components/health_component.gd.uid new file mode 100644 index 0000000..47bcbea --- /dev/null +++ b/scenes/components/health_component.gd.uid @@ -0,0 +1 @@ +uid://ev7uglfcbl02 diff --git a/scenes/components/hit_box.gd b/scenes/components/hit_box.gd new file mode 100644 index 0000000..b3c57e6 --- /dev/null +++ b/scenes/components/hit_box.gd @@ -0,0 +1,4 @@ +class_name HitBox +extends Area2D + +@export var damage: int = 0 diff --git a/scenes/components/hit_box.gd.uid b/scenes/components/hit_box.gd.uid new file mode 100644 index 0000000..6eb4dfd --- /dev/null +++ b/scenes/components/hit_box.gd.uid @@ -0,0 +1 @@ +uid://dw1cot7pm0rp6 diff --git a/scenes/components/hurt_box.gd b/scenes/components/hurt_box.gd new file mode 100644 index 0000000..5d67129 --- /dev/null +++ b/scenes/components/hurt_box.gd @@ -0,0 +1,11 @@ +class_name HurtBox +extends Area2D + +signal hit_received(hitbox: HitBox) + +func _ready() -> void: + area_entered.connect(_on_area_entered) + +func _on_area_entered(area: Area2D) -> void: + if area is HitBox and area.get_parent() != get_parent(): + hit_received.emit(area) diff --git a/scenes/components/hurt_box.gd.uid b/scenes/components/hurt_box.gd.uid new file mode 100644 index 0000000..c480efd --- /dev/null +++ b/scenes/components/hurt_box.gd.uid @@ -0,0 +1 @@ +uid://cxsbkcxpnu3t6 diff --git a/scenes/components/hurt_box.tscn b/scenes/components/hurt_box.tscn new file mode 100644 index 0000000..6d1c11e --- /dev/null +++ b/scenes/components/hurt_box.tscn @@ -0,0 +1,12 @@ +[gd_scene format=3 uid="uid://y8ge2udsupng"] + +[ext_resource type="Script" uid="uid://cxsbkcxpnu3t6" path="res://scenes/components/hurt_box.gd" id="1_eeq1w"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_cg0qn"] + +[node name="HurtBox" type="Area2D" unique_id=208381358] +script = ExtResource("1_eeq1w") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=497117705] +position = Vector2(23, -12) +shape = SubResource("RectangleShape2D_cg0qn")