Trap explosions with damage and health bar depletion.
This commit is contained in:
BIN
audio/sounds/explosion_large_01_n.wav
Normal file
BIN
audio/sounds/explosion_large_01_n.wav
Normal file
Binary file not shown.
24
audio/sounds/explosion_large_01_n.wav.import
Normal file
24
audio/sounds/explosion_large_01_n.wav.import
Normal file
@@ -0,0 +1,24 @@
|
||||
[remap]
|
||||
|
||||
importer="wav"
|
||||
type="AudioStreamWAV"
|
||||
uid="uid://cw0mfvl76lpxq"
|
||||
path="res://.godot/imported/explosion_large_01_n.wav-0f4fe3d8d9d02bb99f06e621d264e4e7.sample"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://audio/sounds/explosion_large_01_n.wav"
|
||||
dest_files=["res://.godot/imported/explosion_large_01_n.wav-0f4fe3d8d9d02bb99f06e621d264e4e7.sample"]
|
||||
|
||||
[params]
|
||||
|
||||
force/8_bit=false
|
||||
force/mono=false
|
||||
force/max_rate=false
|
||||
force/max_rate_hz=44100
|
||||
edit/trim=false
|
||||
edit/normalize=false
|
||||
edit/loop_mode=0
|
||||
edit/loop_begin=0
|
||||
edit/loop_end=-1
|
||||
compress/mode=2
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -47,9 +47,8 @@ var disarming : bool
|
||||
|
||||
var difficulty : int = 1
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
timer_label.text = "%02d.3" % timer.time_left
|
||||
timer_label.text = "%02f.3" % timer.time_left
|
||||
|
||||
func start_disarming() -> void:
|
||||
disarming = true
|
||||
|
||||
15
scripts/healthbar.gd
Normal file
15
scripts/healthbar.gd
Normal file
@@ -0,0 +1,15 @@
|
||||
class_name HealthBar extends TextureProgressBar
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
func _on_health_changed(current : int, max : int) -> void:
|
||||
max_value = max
|
||||
value = current
|
||||
1
scripts/healthbar.gd.uid
Normal file
1
scripts/healthbar.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bolw6n14ocxt3
|
||||
@@ -1,11 +1,12 @@
|
||||
class_name HUD extends Control
|
||||
|
||||
@onready var trap_display : TrapDisplay = %TrapDisplay
|
||||
|
||||
@onready var p1_healthbar : HealthBar = %P1HealthBar
|
||||
func _ready() -> void:
|
||||
Game.hud = self
|
||||
|
||||
func register_player(player : Player) -> void:
|
||||
player.health_changed.connect(p1_healthbar._on_health_changed)
|
||||
trap_display._on_trap_list_changed(player.data.traps, player.data.active_trap)
|
||||
player.trap_cycled.connect(trap_display._on_trap_cycled)
|
||||
player.trap_quantity_changed.connect(trap_display._on_trap_quantity_changed)
|
||||
|
||||
@@ -9,6 +9,8 @@ const disarm_trap_modal = preload("res://templates/disarm_trap_modal.tscn")
|
||||
@onready var data : PlayerData = $Data
|
||||
@onready var trap_sound : AudioStreamPlayer3D = $TrapSound
|
||||
|
||||
var id : int = 1
|
||||
|
||||
var button_actions : Dictionary[int, String]
|
||||
var current_square : Vector3i
|
||||
var detecting : bool = false
|
||||
@@ -22,7 +24,7 @@ var modal = null
|
||||
signal trap_cycled(trap_index)
|
||||
signal trap_quantity_changed(trap_index, quantity)
|
||||
signal trap_list_changed(traps)
|
||||
|
||||
signal health_changed(current : int, max : int)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var dir = Input.get_vector("west", "east", "north", "south")
|
||||
@@ -156,6 +158,9 @@ func show_disarm_trap_modal() -> void:
|
||||
modal = disarm_trap_modal.instantiate()
|
||||
modal.difficulty = Game.level.difficulty
|
||||
modal.square = current_square
|
||||
var trap = Game.level.traps[current_square]
|
||||
trap.disarming = true
|
||||
trap.disarm_id = Multiplayer.id
|
||||
Game.level.add_child(modal)
|
||||
|
||||
func start_detecting() -> void:
|
||||
@@ -216,6 +221,10 @@ func cycle_active_trap(dir) -> void:
|
||||
if prev != data.active_trap:
|
||||
trap_cycled.emit(data.active_trap)
|
||||
|
||||
func hurt(damage : int) -> void:
|
||||
data.life = max(0, data.life - damage)
|
||||
health_changed.emit(data.life, data.max_life)
|
||||
|
||||
func _on_trap_disarmed(type : Trap.Type) -> void:
|
||||
for i in range(len(data.traps)):
|
||||
var d = data.traps[i]
|
||||
|
||||
@@ -59,6 +59,10 @@ func is_valid_trap_square(crd : Vector3i) -> bool:
|
||||
return false
|
||||
return true
|
||||
|
||||
func add_vfx(vfx, crd : Vector3i) -> void:
|
||||
vfx.global_position = Vector3(crd) #+ Vector3(0.5, 0, 0.5)
|
||||
add_child(vfx)
|
||||
|
||||
func activate_trap(crd : Vector3i) -> void:
|
||||
var trap = traps[crd]
|
||||
#if trap:
|
||||
|
||||
@@ -9,6 +9,14 @@ enum Type{
|
||||
PITFALL
|
||||
}
|
||||
|
||||
const range_shapes : Dictionary = {
|
||||
Trap.Type.BOMB : Vector3(5,1,5),
|
||||
Trap.Type.GAS : Vector3(1,1,1),
|
||||
Trap.Type.PITFALL : Vector3(1,1,1),
|
||||
Trap.Type.FORCE_PANEL : Vector3(1,1,1),
|
||||
Trap.Type.SWITCH : Vector3(3,1,3),
|
||||
Trap.Type.MINE : Vector3(5,1,5),
|
||||
}
|
||||
const trap_icons : Dictionary = {
|
||||
Trap.Type.BOMB : preload("res://visuals/images/icons/t-bomb.png"),
|
||||
Trap.Type.GAS : preload("res://visuals/images/icons/t-gas.png"),
|
||||
@@ -18,6 +26,10 @@ const trap_icons : Dictionary = {
|
||||
Trap.Type.MINE : preload("res://visuals/images/icons/t-mine.png"),
|
||||
}
|
||||
|
||||
const explosion_template = preload("res://templates/explosion.tscn")
|
||||
|
||||
@onready var range_area : Area3D = %RangeArea
|
||||
@onready var range_shape : BoxShape3D = %RangeShape.shape
|
||||
@onready var model : MeshInstance3D = %Model
|
||||
@onready var icon : Sprite3D = %Icon
|
||||
@onready var material : StandardMaterial3D = model.get_surface_override_material(0)
|
||||
@@ -25,6 +37,12 @@ const trap_icons : Dictionary = {
|
||||
var type : Type
|
||||
var square : Vector3i
|
||||
var trap_owner : int
|
||||
|
||||
var disarming : bool
|
||||
var disarm_id : int
|
||||
|
||||
var damage : int = 10
|
||||
|
||||
signal disarmed(type : Trap.Type)
|
||||
|
||||
|
||||
@@ -51,4 +69,17 @@ func _ready() -> void:
|
||||
icon.texture = trap_icons[type]
|
||||
model.visible = owns_trap
|
||||
icon.visible = owns_trap
|
||||
range_shape.size = range_shapes[type]
|
||||
material.albedo_color = Color.YELLOW if owns_trap else Color.RED
|
||||
|
||||
func activate() -> void:
|
||||
var exp = explosion_template.instantiate()
|
||||
Game.level.add_vfx(exp, square)
|
||||
for body in range_area.get_overlapping_bodies():
|
||||
body.hurt(damage)
|
||||
#match(type):
|
||||
|
||||
func _on_body_entered(body: Node3D) -> void:
|
||||
if !disarming or body.id != disarm_id:
|
||||
if !body.detecting:
|
||||
activate()
|
||||
|
||||
@@ -9,3 +9,12 @@ func _ready() -> void:
|
||||
func _on_timer_timeout() -> void:
|
||||
print("Done")
|
||||
queue_free()
|
||||
|
||||
func proximal_shake(distance : float) -> void:
|
||||
print(Input.get_connected_joypads())
|
||||
if !Game.player:
|
||||
return
|
||||
var d = global_position.distance_squared_to(Game.player.global_position)
|
||||
if d <= distance * distance:
|
||||
Input.start_joy_vibration(0, 1,1,1000)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=30 format=3 uid="uid://bgocskbofewsr"]
|
||||
[gd_scene load_steps=31 format=3 uid="uid://bgocskbofewsr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bm50jiya4s3ei" path="res://scripts/hud.gd" id="1_jiiqi"]
|
||||
[ext_resource type="Texture2D" uid="uid://dri0a20l6kpbj" path="res://visuals/images/icon.svg" id="1_k5de2"]
|
||||
@@ -11,6 +11,7 @@
|
||||
[ext_resource type="Texture2D" uid="uid://btjn353r1qg1q" path="res://visuals/images/icons/player 2 tag.png" id="3_k0acs"]
|
||||
[ext_resource type="Texture2D" uid="uid://urh11huy67cs" path="res://visuals/materials/health gradient.tres" id="3_vhta5"]
|
||||
[ext_resource type="PackedScene" uid="uid://xk323c0ta2b" path="res://templates/trap_icon.tscn" id="4_aopqe"]
|
||||
[ext_resource type="Script" uid="uid://bolw6n14ocxt3" path="res://scripts/healthbar.gd" id="4_iv5le"]
|
||||
[ext_resource type="Texture2D" uid="uid://bcv3f38cib5xk" path="res://visuals/images/icons/mine.png" id="4_l86lr"]
|
||||
[ext_resource type="Texture2D" uid="uid://cyuylbs0o72xk" path="res://visuals/images/icons/pitfall.png" id="5_aopqe"]
|
||||
[ext_resource type="Texture2D" uid="uid://hiwrcar5fnyk" path="res://visuals/images/icons/switch.png" id="6_e7ody"]
|
||||
@@ -79,12 +80,14 @@ theme_override_constants/separation = 2
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_yda1o")
|
||||
|
||||
[node name="ProgressBar" type="TextureProgressBar" parent="Control/PanelContainer/HBoxContainer/VBoxContainer2/PanelContainer/VBoxContainer"]
|
||||
[node name="P1HealthBar" type="TextureProgressBar" parent="Control/PanelContainer/HBoxContainer/VBoxContainer2/PanelContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 50)
|
||||
layout_mode = 2
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
texture_over = ExtResource("3_vhta5")
|
||||
texture_progress = ExtResource("3_vhta5")
|
||||
script = ExtResource("4_iv5le")
|
||||
|
||||
[node name="PanelContainer2" type="PanelContainer" parent="Control/PanelContainer/HBoxContainer/VBoxContainer2"]
|
||||
custom_minimum_size = Vector2(250, 100)
|
||||
@@ -98,12 +101,12 @@ theme_override_constants/separation = 2
|
||||
layout_mode = 2
|
||||
texture = ExtResource("3_k0acs")
|
||||
|
||||
[node name="ProgressBar" type="TextureProgressBar" parent="Control/PanelContainer/HBoxContainer/VBoxContainer2/PanelContainer2/VBoxContainer"]
|
||||
[node name="P2HealthBar" type="TextureProgressBar" parent="Control/PanelContainer/HBoxContainer/VBoxContainer2/PanelContainer2/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 50)
|
||||
layout_mode = 2
|
||||
value = 100.0
|
||||
nine_patch_stretch = true
|
||||
texture_over = ExtResource("3_vhta5")
|
||||
texture_progress = ExtResource("3_vhta5")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Control/PanelContainer/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(150, 0)
|
||||
|
||||
@@ -157,7 +157,6 @@ size = Vector2(0.25, 1)
|
||||
center_offset = Vector3(0, 0.4, 0)
|
||||
|
||||
[sub_resource type="Animation" id="Animation_d5gho"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
@@ -168,7 +167,7 @@ tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
"values": [true]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
@@ -177,10 +176,10 @@ tracks/1/path = NodePath("StreakFX:emitting")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"times": PackedFloat32Array(0, 0.033333335),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
"values": [false, true]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
@@ -189,10 +188,10 @@ tracks/2/path = NodePath("OmniLight3D:light_energy")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"times": PackedFloat32Array(0, 0.06666667),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [20.0]
|
||||
"values": [20.0, 0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_gf6ds"]
|
||||
@@ -234,6 +233,20 @@ tracks/2/keys = {
|
||||
"update": 0,
|
||||
"values": [20.0, 0.0]
|
||||
}
|
||||
tracks/3/type = "method"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath(".")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"values": [{
|
||||
"args": [3.0],
|
||||
"method": &"proximal_shake"
|
||||
}]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_p88g7"]
|
||||
_data = {
|
||||
@@ -258,7 +271,6 @@ draw_pass_1 = SubResource("SphereMesh_4y8np")
|
||||
[node name="ParticleFX" type="GPUParticles3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.4375714, 0, 0.5602956)
|
||||
material_override = ExtResource("2_l2v4y")
|
||||
emitting = false
|
||||
amount = 10
|
||||
lifetime = 0.6
|
||||
one_shot = true
|
||||
|
||||
@@ -16,6 +16,8 @@ height = 1.0
|
||||
|
||||
[node name="Player" type="CharacterBody3D"]
|
||||
physics_interpolation_mode = 1
|
||||
collision_layer = 2
|
||||
collision_mask = 5
|
||||
floor_constant_speed = true
|
||||
floor_max_angle = 0.93549645
|
||||
floor_snap_length = 1.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://bk3yqawritfnj"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://bk3yqawritfnj"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://yjsgte3x7jjw" path="res://scripts/trap.gd" id="1_6h4aj"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://bih57xe642hrc" path="res://models/trap.obj" id="2_oj6ox"]
|
||||
@@ -14,7 +14,12 @@ albedo_color = Color(1, 1, 0, 1)
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_dw7u0"]
|
||||
size = Vector3(0.8, 1, 0.8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_6h4aj"]
|
||||
resource_local_to_scene = true
|
||||
|
||||
[node name="Trap" type="Area3D"]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
script = ExtResource("1_6h4aj")
|
||||
|
||||
[node name="Model" type="MeshInstance3D" parent="."]
|
||||
@@ -40,4 +45,14 @@ texture = ExtResource("3_mxvh5")
|
||||
[node name="RevealTimer" type="Timer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="RangeArea" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
|
||||
[node name="RangeShape" type="CollisionShape3D" parent="RangeArea"]
|
||||
unique_name_in_owner = true
|
||||
shape = SubResource("BoxShape3D_6h4aj")
|
||||
|
||||
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
||||
[connection signal="timeout" from="RevealTimer" to="." method="_on_reveal_timeout"]
|
||||
|
||||
Reference in New Issue
Block a user