diff --git a/objects/brick_player.tscn b/objects/brick_player.tscn index 520720d..c368772 100644 --- a/objects/brick_player.tscn +++ b/objects/brick_player.tscn @@ -10,7 +10,7 @@ [ext_resource type="Script" path="res://scripts/components/player_death.gd" id="8_1v23d"] [ext_resource type="Script" path="res://scripts/components/knockback.gd" id="9_rjyu4"] [ext_resource type="Script" path="res://scripts/components/brick_throw.gd" id="10_u0v3b"] -[ext_resource type="PackedScene" uid="uid://bymro4t7angv5" path="res://objects/brick.tscn" id="11_qutq2"] +[ext_resource type="PackedScene" uid="uid://bcmx07k12gcsc" path="res://objects/ice_brick.tscn" id="11_ktjj0"] [ext_resource type="Script" path="res://scripts/components/stomp_damage_component.gd" id="12_payr4"] [ext_resource type="Script" path="res://scripts/components/flashing_component.gd" id="13_hrtyn"] [ext_resource type="Script" path="res://scripts/components/invulnerability_component.gd" id="14_jopig"] @@ -84,7 +84,7 @@ knockback_force = 1500.0 [node name="BrickThrowComponent" type="Node" parent="." node_paths=PackedStringArray("player_controller", "timer")] script = ExtResource("10_u0v3b") -brick_scene = ExtResource("11_qutq2") +brick_scene = ExtResource("11_ktjj0") fire_rate = 0.3 player_controller = NodePath("..") timer = NodePath("../ThrowTimer") diff --git a/objects/enemy.tscn b/objects/enemy.tscn index b648aba..33fa00a 100644 --- a/objects/enemy.tscn +++ b/objects/enemy.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=13 format=3 uid="uid://bwdlmualj6xbw"] +[gd_scene load_steps=15 format=3 uid="uid://bwdlmualj6xbw"] [ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="1_ep4yr"] [ext_resource type="Texture2D" uid="uid://xes6mt2dd5gu" path="res://sprites/robot_cutout.png" id="1_uh38l"] @@ -9,6 +9,8 @@ [ext_resource type="Script" path="res://scripts/components/enemy_death.gd" id="6_6p3gr"] [ext_resource type="Script" path="res://scripts/components/flashing_component.gd" id="7_xsaiy"] [ext_resource type="Script" path="res://scripts/components/hit_component.gd" id="9_0qjr4"] +[ext_resource type="Script" path="res://scripts/components/fire_effect_component.gd" id="10_ej8vg"] +[ext_resource type="Script" path="res://scripts/components/ice_effect_component.gd" id="11_pq0k7"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_pwwji"] size = Vector2(18, 27) @@ -86,3 +88,16 @@ health_component = NodePath("../HealthComponent") script = ExtResource("9_0qjr4") sprite = NodePath("../Sprite2D") health_component = NodePath("../HealthComponent") + +[node name="FireEffectComponent" type="Node" parent="." node_paths=PackedStringArray("health_component", "root")] +script = ExtResource("10_ej8vg") +duration = 5.0 +damage_per_second = 0.1 +health_component = NodePath("../HealthComponent") +root = NodePath("..") + +[node name="IceEffectComponent" type="Node" parent="." node_paths=PackedStringArray("side_to_side_movement", "periodic_shooting")] +script = ExtResource("11_pq0k7") +duration = 3.0 +side_to_side_movement = NodePath("../SideToSideMovement") +periodic_shooting = NodePath("../PeriodicShootingComponent") diff --git a/objects/fire_brick.tscn b/objects/fire_brick.tscn new file mode 100644 index 0000000..5c60441 --- /dev/null +++ b/objects/fire_brick.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=5 format=3 uid="uid://daau4j5hbklk0"] + +[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_52l28"] +[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_hjcob"] +[ext_resource type="Script" path="res://scripts/components/damage.gd" id="3_3ylb6"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"] +size = Vector2(16, 10) + +[node name="Brick" type="Area2D"] +collision_layer = 16 +collision_mask = 9 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_ar0xf") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_52l28") +hframes = 12 +vframes = 12 +frame = 80 + +[node name="BulletComponent" type="Node" parent="." node_paths=PackedStringArray("root", "area2d", "visibility_notifier", "timer")] +script = ExtResource("2_hjcob") +root = NodePath("..") +speed = 120.0 +area2d = NodePath("..") +visibility_notifier = NodePath("../VisibleOnScreenNotifier2D") +life_time = 2.0 +timer = NodePath("../Timer") + +[node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="."] +position = Vector2(0, 2.38419e-07) +scale = Vector2(0.8, 0.5) + +[node name="Timer" type="Timer" parent="."] + +[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("area2d")] +script = ExtResource("3_3ylb6") +area2d = NodePath("..") +is_fire_brick = true diff --git a/objects/ice_brick.tscn b/objects/ice_brick.tscn new file mode 100644 index 0000000..bdb4877 --- /dev/null +++ b/objects/ice_brick.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=5 format=3 uid="uid://bcmx07k12gcsc"] + +[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_xusxl"] +[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_ilnf5"] +[ext_resource type="Script" path="res://scripts/components/damage.gd" id="3_htddx"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"] +size = Vector2(16, 10) + +[node name="Brick" type="Area2D"] +collision_layer = 16 +collision_mask = 9 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_ar0xf") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_xusxl") +hframes = 12 +vframes = 12 +frame = 80 + +[node name="BulletComponent" type="Node" parent="." node_paths=PackedStringArray("root", "area2d", "visibility_notifier", "timer")] +script = ExtResource("2_ilnf5") +root = NodePath("..") +speed = 120.0 +area2d = NodePath("..") +visibility_notifier = NodePath("../VisibleOnScreenNotifier2D") +life_time = 2.0 +timer = NodePath("../Timer") + +[node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="."] +position = Vector2(0, 2.38419e-07) +scale = Vector2(0.8, 0.5) + +[node name="Timer" type="Timer" parent="."] + +[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("area2d")] +script = ExtResource("3_htddx") +area2d = NodePath("..") +is_ice_brick = true diff --git a/scripts/components/damage.gd b/scripts/components/damage.gd index 198b0f5..1d7ae1c 100644 --- a/scripts/components/damage.gd +++ b/scripts/components/damage.gd @@ -3,6 +3,8 @@ extends Node @export var damage: float = 0.25 @export var area2d: Area2D +@export var is_fire_brick: bool = false +@export var is_ice_brick: bool = false func _ready() -> void: @@ -21,10 +23,20 @@ func on_area2d_body_entered(body: Node2D) -> void: if body.has_node("HealthComponent"): var health_component: HealthComponent = body.get_node("HealthComponent") var invulnerability_component: InvulnerabilityComponent = body.get_node_or_null("InvulnerabilityComponent") + var fire_effect_component: FireEffectComponent = body.get_node_or_null("FireEffectComponent") + var ice_effect_component: IceEffectComponent = body.get_node_or_null("IceEffectComponent") if invulnerability_component and invulnerability_component.is_invulnerable(): return + if fire_effect_component and is_fire_brick: + fire_effect_component.activate() + return + + if ice_effect_component and is_ice_brick: + ice_effect_component.activate() + return + deal_damage(health_component) if invulnerability_component: diff --git a/scripts/components/fire_effect_component.gd b/scripts/components/fire_effect_component.gd new file mode 100644 index 0000000..ba41093 --- /dev/null +++ b/scripts/components/fire_effect_component.gd @@ -0,0 +1,56 @@ +class_name FireEffectComponent +extends Node + +@export var duration: float = 1.0 +@export var damage_per_second: float = 1.0 +@export var health_component: HealthComponent +@export var root: Node2D + +var timer: Timer +var should_deal_damage: bool = false +var time_elapsed: float = 0.0 + + +func _ready() -> void: + if not health_component: + health_component = root.get_node("HealthComponent") + + if not health_component: + printerr("No HealthComponent assigned!") + return + + timer = Timer.new() + timer.timeout.connect(on_timer_timeout) + prepare_timer() + add_child(timer) + + +func _process(delta: float) -> void: + if not should_deal_damage or not health_component: + return + + time_elapsed += delta + if time_elapsed >= 1.0: + health_component.decrease_health(damage_per_second) + time_elapsed = 0.0 + + +func on_timer_timeout() -> void: + deactivate() + + +func activate() -> void: + should_deal_damage = true + timer.start() + + +func deactivate() -> void: + should_deal_damage = false + timer.stop() + + +func prepare_timer() -> void: + timer.set_wait_time(duration) + timer.set_one_shot(true) + timer.stop() + time_elapsed = 0.0 diff --git a/scripts/components/ice_effect_component.gd b/scripts/components/ice_effect_component.gd new file mode 100644 index 0000000..4a72bda --- /dev/null +++ b/scripts/components/ice_effect_component.gd @@ -0,0 +1,52 @@ +class_name IceEffectComponent +extends Node + +@export var duration: float = 1.0 +@export var side_to_side_movement: SideToSideMovement +@export var periodic_shooting: PeriodicShootingComponent + +var timer: Timer +var is_frozen: bool = false +var movement_speed: float = 0.0 + + +func _ready() -> void: + timer = Timer.new() + timer.timeout.connect(on_timer_timeout) + prepare_timer() + add_child(timer) + + if side_to_side_movement: + movement_speed = side_to_side_movement.speed + + +func _process(_delta: float) -> void: + if not side_to_side_movement or not periodic_shooting: + return + + if is_frozen: + side_to_side_movement.process_mode = PROCESS_MODE_DISABLED + periodic_shooting.process_mode = PROCESS_MODE_DISABLED + else: + side_to_side_movement.process_mode = PROCESS_MODE_ALWAYS + periodic_shooting.process_mode = PROCESS_MODE_ALWAYS + + +func on_timer_timeout() -> void: + deactivate() + + +func activate() -> void: + is_frozen = true + timer.start() + + +func deactivate() -> void: + is_frozen = false + timer.stop() + + +func prepare_timer() -> void: + timer.set_wait_time(duration) + timer.set_one_shot(true) + timer.stop()