From cae917d469c7f70fa8b3c6817a000ddb2332b5d7 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Tue, 4 Mar 2025 02:14:43 +0100 Subject: [PATCH] Exploding brick --- objects/brick.tscn | 2 +- objects/brick_player.tscn | 4 +- objects/cannon.tscn | 20 ++++++- objects/exploding_brick.tscn | 59 +++++++++++++++++++ scripts/components/destroyable_component.gd | 23 ++++++++ scripts/components/explosive_component.gd | 63 +++++++++++++++++++++ 6 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 objects/exploding_brick.tscn create mode 100644 scripts/components/destroyable_component.gd create mode 100644 scripts/components/explosive_component.gd diff --git a/objects/brick.tscn b/objects/brick.tscn index 792c036..3d98812 100644 --- a/objects/brick.tscn +++ b/objects/brick.tscn @@ -2,7 +2,7 @@ [ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_1c3jb"] [ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_i6t5k"] -[ext_resource type="Script" path="res://scripts/components/damage.gd" id="3_8xipx"] +[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_8xipx"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"] size = Vector2(16, 10) diff --git a/objects/brick_player.tscn b/objects/brick_player.tscn index 2b75b9b..7f9fedb 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://bcmx07k12gcsc" path="res://objects/ice_brick.tscn" id="11_thd7o"] +[ext_resource type="PackedScene" uid="uid://5surx230gfw3" path="res://objects/exploding_brick.tscn" id="11_nd7nl"] [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_thd7o") +brick_scene = ExtResource("11_nd7nl") fire_rate = 0.3 player_controller = NodePath("..") timer = NodePath("../ThrowTimer") diff --git a/objects/cannon.tscn b/objects/cannon.tscn index 02e3e37..6674b3b 100644 --- a/objects/cannon.tscn +++ b/objects/cannon.tscn @@ -1,11 +1,27 @@ -[gd_scene load_steps=2 format=3 uid="uid://dstko446qydsc"] +[gd_scene load_steps=5 format=3 uid="uid://dstko446qydsc"] [ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_6gptm"] +[ext_resource type="Script" path="res://scripts/components/destroyable_component.gd" id="2_2tib2"] +[ext_resource type="Script" path="res://scripts/components/health.gd" id="3_vevhj"] -[node name="Cannon" type="Node2D"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"] +size = Vector2(16, 16) + +[node name="Cannon" type="StaticBody2D"] [node name="Sprite2D" type="Sprite2D" parent="."] texture = ExtResource("1_6gptm") hframes = 12 vframes = 12 frame = 42 + +[node name="DestroyableComponent" type="Node" parent="." node_paths=PackedStringArray("root", "health_component")] +script = ExtResource("2_2tib2") +root = NodePath("..") +health_component = NodePath("../HealthComponent") + +[node name="HealthComponent" type="Node" parent="."] +script = ExtResource("3_vevhj") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_j5sus") diff --git a/objects/exploding_brick.tscn b/objects/exploding_brick.tscn new file mode 100644 index 0000000..7e07589 --- /dev/null +++ b/objects/exploding_brick.tscn @@ -0,0 +1,59 @@ +[gd_scene load_steps=7 format=3 uid="uid://5surx230gfw3"] + +[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_rcgxf"] +[ext_resource type="Script" path="res://scripts/components/bullet.gd" id="2_1i2y5"] +[ext_resource type="Script" path="res://scripts/components/damage_component.gd" id="3_y0uai"] +[ext_resource type="Script" path="res://scripts/components/explosive_component.gd" id="4_8lw0n"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ar0xf"] +size = Vector2(16, 10) + +[sub_resource type="CircleShape2D" id="CircleShape2D_e6vaq"] +radius = 32.0 + +[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_rcgxf") +hframes = 12 +vframes = 12 +frame = 80 + +[node name="BulletComponent" type="Node" parent="." node_paths=PackedStringArray("root", "area2d", "visibility_notifier", "timer")] +script = ExtResource("2_1i2y5") +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_y0uai") +damage = 5.0 +area2d = NodePath("..") + +[node name="ExplosiveComponent" type="Node" parent="." node_paths=PackedStringArray("root", "damage", "area2d", "explosion_area2d")] +script = ExtResource("4_8lw0n") +root = NodePath("..") +damage = NodePath("../DamageComponent") +area2d = NodePath("..") +explosion_area2d = NodePath("../Explosion area") + +[node name="Explosion area" type="Area2D" parent="."] +collision_layer = 0 +collision_mask = 9 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Explosion area"] +shape = SubResource("CircleShape2D_e6vaq") diff --git a/scripts/components/destroyable_component.gd b/scripts/components/destroyable_component.gd new file mode 100644 index 0000000..02dfa7d --- /dev/null +++ b/scripts/components/destroyable_component.gd @@ -0,0 +1,23 @@ +class_name DestroyableComponent +extends Node + +@export var root: Node +@export var health_component: HealthComponent +@export var destroy_effect: PackedScene + + +func _ready() -> void: + if not health_component: + printerr("No health component assigned!") + return + + health_component.on_death.connect(on_health_component_death) + + +func on_health_component_death() -> void: + if destroy_effect: + var effect: Node2D = destroy_effect.instantiate() + health_component.get_parent().add_child(effect) + effect.global_position = health_component.global_position + + root.queue_free() diff --git a/scripts/components/explosive_component.gd b/scripts/components/explosive_component.gd new file mode 100644 index 0000000..9a411b5 --- /dev/null +++ b/scripts/components/explosive_component.gd @@ -0,0 +1,63 @@ +class_name ExplosiveComponent +extends Node + +@export var root: Node2D +@export var damage: DamageComponent +@export var area2d: Area2D +@export var explosion_area2d: Area2D +@export var explosion_effect: PackedScene +@export var time_to_explode: float = 9.0 +signal on_explosion(body: Node2D) +var timer: Timer + + +func _ready() -> void: + if not damage: + printerr("No damage component assigned!") + return + + if not explosion_area2d: + printerr("No area2d assigned!") + return + + area2d.body_entered.connect(on_area2d_body_entered) + area2d.area_entered.connect(on_area2d_area_entered) + + prepare_timer() + + +func prepare_timer() -> void: + timer = Timer.new() + timer.set_wait_time(time_to_explode) + timer.set_one_shot(true) + timer.autostart = true + timer.timeout.connect(explode) + add_child(timer) + + +func explode() -> void: + timer.stop() + + if explosion_effect: + var effect: Node2D = explosion_effect.instantiate() + root.get_parent().add_child(effect) + effect.global_position = root.global_position + + var bodies: Array = explosion_area2d.get_overlapping_bodies() + for body in bodies: + var health_component: HealthComponent = body.get_node_or_null("HealthComponent") + + if damage and health_component: + damage.deal_damage(health_component) + + on_explosion.emit(body) + + root.queue_free() + + +func on_area2d_body_entered(_body: Node2D) -> void: + explode() + + +func on_area2d_area_entered(_area: Area2D) -> void: + explode()