Skip to content

Commit

Permalink
split projectile + hitbox, fixes for bullets
Browse files Browse the repository at this point in the history
  • Loading branch information
myin142 committed Nov 11, 2023
1 parent f30e412 commit 043c468
Show file tree
Hide file tree
Showing 16 changed files with 142 additions and 85 deletions.
8 changes: 7 additions & 1 deletion godot/src/base-system/combat/HitBox.gd
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class_name HitBox
extends Area2D

signal hit()

@export var damage := 1
@export var damage_value: NumberValue
@export var knockback_force := 0
Expand All @@ -14,4 +16,8 @@ func _ready():
func _do_damage(area: HurtBox):
var dmg = damage_value.get_value() if damage_value else damage
var knockback_dir = global_position.direction_to(area.global_position)
return area.damage(dmg, knockback_dir * knockback_force)

var did_hit = area.damage(dmg, knockback_dir * knockback_force)
if did_hit:
hit.emit()
return did_hit
1 change: 1 addition & 0 deletions godot/src/base-system/combat/Hurtbox.gd
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ func damage(dmg: int, knockback_force: Vector2):
frame_freeze.freeze()

get_tree().create_timer(invincible_time).timeout.connect(func(): invincible = false)
return true
2 changes: 1 addition & 1 deletion godot/src/base-system/spawner/AreaSpawner2D.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ func spawn():
for i in count:
var start = dir.rotated(-spread/2)
var d = start.rotated(i * spread/count)
_create(d * center_offset)
_create(d * center_offset, Vector2.RIGHT.angle_to(d))
4 changes: 2 additions & 2 deletions godot/src/base-system/spawner/DeathSpawner2D.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ extends Node2D

func _ready():
if health:
health.zero_health.connect(func(): _create())
health.zero_health.connect(func(): spawn())

func _should_spawn():
return spawn_chance == null or randf() <= spawn_chance.get_value()

func _create():
func spawn():
if not _should_spawn():
return

Expand Down
4 changes: 2 additions & 2 deletions godot/src/base-system/spawner/Spawner2D.gd
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ func _ready():
func spawn():
return _create()

func _create(offset_dir = offset * Vector2.RIGHT.rotated(global_rotation)):
func _create(offset_dir = offset * Vector2.RIGHT.rotated(global_rotation), rot = global_rotation):
var eff = scene.instantiate()
eff.global_position = global_position + offset_dir
eff.global_rotation = global_rotation
eff.global_rotation = rot
get_tree().current_scene.add_child(eff)
return eff
1 change: 0 additions & 1 deletion godot/src/character/Trident.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ extends Projectile
@onready var player_detect = $PlayerDetect

var target: Node2D
var velocity := Vector2.ZERO
var player: Node2D

func _physics_process(delta):
Expand Down
6 changes: 1 addition & 5 deletions godot/src/character/bomb_bullet.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ extends Projectile
@export var speed: ValueProvider

@onready var hurtbox = $Hurtbox
@onready var death_spawner_2d = $DeathSpawner2D
@onready var health = $Health

func _ready():
ignored.append(hurtbox)
super._ready()

health.zero_health.connect(func(): queue_free())

func _physics_process(delta):
translate(dir * speed.get_value() * delta)
global_rotation = Vector2.RIGHT.angle_to(dir)

func _on_hurtbox_knockback(dir):
death_spawner_2d.global_rotation = Vector2.RIGHT.angle_to(dir)
death_spawner.global_rotation = Vector2.RIGHT.angle_to(dir)
34 changes: 23 additions & 11 deletions godot/src/character/bomb_bullet.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=16 format=3 uid="uid://bjoxmq8nco7tj"]
[gd_scene load_steps=18 format=3 uid="uid://bjoxmq8nco7tj"]

[ext_resource type="Script" path="res://src/character/bomb_bullet.gd" id="1_w8slh"]
[ext_resource type="Script" path="res://src/base-system/combat/DelayedDamage.gd" id="3_f7q0i"]
Expand All @@ -7,6 +7,7 @@
[ext_resource type="Script" path="res://src/base-system/combat/health.gd" id="5_fqps8"]
[ext_resource type="Script" path="res://src/base-system/spawner/DeathSpawner2D.gd" id="6_xn0k5"]
[ext_resource type="PackedScene" uid="uid://demmj5vw7sf6i" path="res://src/props/bomb_bullet_death.tscn" id="7_2qm82"]
[ext_resource type="Script" path="res://src/base-system/combat/HitBox.gd" id="9_i6l0c"]
[ext_resource type="Script" path="res://src/nodes/MirrorValue.gd" id="13_4j2ad"]

[sub_resource type="CircleShape2D" id="CircleShape2D_58gh8"]
Expand Down Expand Up @@ -51,21 +52,21 @@ animations = [{
[sub_resource type="CircleShape2D" id="CircleShape2D_uma4k"]
radius = 9.0

[node name="BombBullet" type="Area2D" node_paths=PackedStringArray("speed", "collision_shape", "hurt_collision", "raycast")]
[sub_resource type="CircleShape2D" id="CircleShape2D_rbo4n"]
radius = 8.0

[node name="BombBullet" type="Area2D" node_paths=PackedStringArray("speed", "collision_shape", "hurt_collision", "raycast", "death_spawner", "hit_box", "health")]
collision_layer = 0
collision_mask = 56
collision_mask = 32
script = ExtResource("1_w8slh")
speed = NodePath("SpeedValue")
max_reflections = 2
collision_shape = NodePath("CollisionShape2D")
hurt_collision = NodePath("Hurtbox/CollisionShape2D")
raycast = NodePath("RayCast2D")
damage = 2
knockback_force = 200

[node name="DamageValue" type="Node" parent="."]
script = ExtResource("13_4j2ad")
mirror_value = 4.0
death_spawner = NodePath("DeathSpawner2D")
hit_box = NodePath("HitBox")
health = NodePath("Health")

[node name="SpeedValue" type="Node" parent="."]
script = ExtResource("13_4j2ad")
Expand All @@ -90,9 +91,8 @@ frame_progress = 0.485157
[node name="Health" type="Node" parent="."]
script = ExtResource("5_fqps8")

[node name="DeathSpawner2D" type="Node2D" parent="." node_paths=PackedStringArray("health")]
[node name="DeathSpawner2D" type="Node2D" parent="."]
script = ExtResource("6_xn0k5")
health = NodePath("../Health")
scene = ExtResource("7_2qm82")

[node name="Hurtbox" type="Area2D" parent="." node_paths=PackedStringArray("health")]
Expand All @@ -111,4 +111,16 @@ collision_mask = 32
collide_with_areas = true
collide_with_bodies = false

[node name="HitBox" type="Area2D" parent="." node_paths=PackedStringArray("damage_value")]
script = ExtResource("9_i6l0c")
damage_value = NodePath("DamageValue")
knockback_force = 200

[node name="DamageValue" type="Node" parent="HitBox"]
script = ExtResource("13_4j2ad")
mirror_value = 4.0

[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"]
shape = SubResource("CircleShape2D_rbo4n")

[connection signal="knockback" from="Hurtbox" to="." method="_on_hurtbox_knockback"]
6 changes: 5 additions & 1 deletion godot/src/character/bomb_enemy.tscn
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=3 uid="uid://c0mbhp0aqksh1"]
[gd_scene load_steps=5 format=3 uid="uid://c0mbhp0aqksh1"]

[ext_resource type="PackedScene" uid="uid://mt5fy2ohtmg5" path="res://src/character/enemy.tscn" id="1_v1rsa"]
[ext_resource type="Texture2D" uid="uid://b2qgqsafbeyaq" path="res://assets/Enemy__Jellyfish_Normal.png" id="2_euxkn"]
[ext_resource type="Texture2D" uid="uid://dy31gsft2yhng" path="res://assets/Enemy__Jellyfish_Mirror.png" id="3_leutj"]
[ext_resource type="PackedScene" uid="uid://bjoxmq8nco7tj" path="res://src/character/bomb_bullet.tscn" id="4_o3ox8"]

[node name="BombEnemy" instance=ExtResource("1_v1rsa")]
value = 3
Expand All @@ -24,3 +25,6 @@ value = 2.0
[node name="MirrorValue" parent="FireRateTimer" index="0"]
mirror_value = 3.5
value = 5.0

[node name="BulletSpawner" parent="." index="14"]
scene = ExtResource("4_o3ox8")
5 changes: 2 additions & 3 deletions godot/src/character/enemy_bullet.gd
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
extends Projectile

@export var speed: ValueProvider

@onready var hurtbox = $Hurtbox
@onready var health = $Health
@onready var death_spawner_2d = $DeathSpawner2D

func _ready():
ignored.append(hurtbox)
super._ready()

health.zero_health.connect(func(): queue_free())

func _physics_process(delta):
translate(dir * speed.get_value() * delta)
Expand Down
36 changes: 26 additions & 10 deletions godot/src/character/enemy_bullet.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3 uid="uid://ddfl18bx24sfj"]
[gd_scene load_steps=12 format=3 uid="uid://ddfl18bx24sfj"]

[ext_resource type="Script" path="res://src/character/enemy_bullet.gd" id="1_m5cyv"]
[ext_resource type="Texture2D" uid="uid://d8ap1t3wascc" path="res://assets/Bubble.png" id="2_lmg1q"]
Expand All @@ -7,27 +7,29 @@
[ext_resource type="Script" path="res://src/base-system/spawner/DeathSpawner2D.gd" id="3_y2eun"]
[ext_resource type="PackedScene" uid="uid://cnk6fkkr62eva" path="res://src/props/enemy_bullet_death.tscn" id="5_jy5q3"]
[ext_resource type="Script" path="res://src/nodes/MirrorValue.gd" id="7_jof7a"]
[ext_resource type="Script" path="res://src/base-system/combat/HitBox.gd" id="8_w36so"]

[sub_resource type="CircleShape2D" id="CircleShape2D_5521j"]
radius = 6.0

[sub_resource type="CircleShape2D" id="CircleShape2D_k5472"]
radius = 4.12311

[node name="EnemyBullet" type="Area2D" node_paths=PackedStringArray("speed", "collision_shape", "hurt_collision", "raycast")]
[sub_resource type="CircleShape2D" id="CircleShape2D_mqd7s"]
radius = 5.0

[node name="EnemyBullet" type="Area2D" node_paths=PackedStringArray("speed", "collision_shape", "hurt_collision", "raycast", "death_spawner", "hit_box", "health")]
collision_layer = 0
collision_mask = 56
collision_mask = 32
script = ExtResource("1_m5cyv")
speed = NodePath("SpeedValue")
max_reflections = 2
collision_shape = NodePath("CollisionShape2D")
hurt_collision = NodePath("Hurtbox/CollisionShape2D")
raycast = NodePath("RayCast2D")
knockback_force = 100

[node name="DamageValue" type="Node" parent="."]
script = ExtResource("7_jof7a")
mirror_value = 2.0
death_spawner = NodePath("DeathSpawner2D")
hit_box = NodePath("HitBox")
health = NodePath("Health")

[node name="SpeedValue" type="Node" parent="."]
script = ExtResource("7_jof7a")
Expand All @@ -37,9 +39,8 @@ value = 80.0
[node name="Health" type="Node" parent="."]
script = ExtResource("2_ppbv3")

[node name="DeathSpawner2D" type="Marker2D" parent="." node_paths=PackedStringArray("health")]
[node name="DeathSpawner2D" type="Marker2D" parent="."]
script = ExtResource("3_y2eun")
health = NodePath("../Health")
scene = ExtResource("5_jy5q3")

[node name="Sprite2D" type="Sprite2D" parent="."]
Expand All @@ -65,3 +66,18 @@ target_position = Vector2(20, 0)
collision_mask = 32
collide_with_areas = true
collide_with_bodies = false

[node name="HitBox" type="Area2D" parent="." node_paths=PackedStringArray("damage_value")]
collision_layer = 0
collision_mask = 24
script = ExtResource("8_w36so")
damage_value = NodePath("DamageValue")
knockback_force = 100

[node name="DamageValue" type="Node" parent="HitBox"]
script = ExtResource("7_jof7a")
mirror_value = 2.0
value = 1.0

[node name="CollisionShape2D" type="CollisionShape2D" parent="HitBox"]
shape = SubResource("CircleShape2D_mqd7s")
61 changes: 32 additions & 29 deletions godot/src/character/projectile.gd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class_name Projectile
extends HitBox
extends Area2D

signal reflect(dir)

Expand All @@ -11,48 +11,51 @@ signal reflect(dir)
@export var hurt_collision: CollisionShape2D
@export var raycast: RayCast2D

const MIRROR_LAYER = 1 << 5
@export var death_spawner: DeathSpawner2D
@export var hit_box: HitBox
@export var health: Health

var reflected := 0
var ignored = []

func _ready():
if disable_initial_hit:
_temp_disable_collision()
# if disable_initial_hit:
# _temp_disable_collision()

if hit_box:
hit_box.hit.connect(_remove)
if health:
health.zero_health.connect(_remove)

dir = dir.rotated(global_rotation)
area_entered.connect(func(area):
if area in ignored: return

if area is Mirror:
if reflected > max_reflections and max_reflections >= 0:
_remove()
else:
if raycast and raycast.is_colliding():
set_physics_process(false)
hide()
var effect_pos = await area.create_mirror_effect(raycast.get_collision_point(), dir)
global_position = effect_pos
set_physics_process(true)
show()

dir = dir.bounce(area.get_normal())
global_rotation = Vector2.RIGHT.angle_to(dir)
reflected += 1
reflect.emit(dir)
elif area is HurtBox:
if _do_damage(area):
_remove()
else:
if reflected > max_reflections and max_reflections >= 0:
_remove()
else:
if raycast and raycast.is_colliding():
set_physics_process(false)
hide()
var effect_pos = await area.create_mirror_effect(raycast.get_collision_point(), dir)
global_position = effect_pos
set_physics_process(true)
show()

dir = dir.bounce(area.get_normal())
global_rotation = Vector2.RIGHT.angle_to(dir)
reflected += 1
reflect.emit(dir)
)

func _temp_disable_collision():
_disable_hit()
get_tree().create_timer(0.1).timeout.connect(func(): collision_shape.disabled = false) # prevent player from hitting himself
#func _temp_disable_collision():
# _disable_hit()
# get_tree().create_timer(0.1).timeout.connect(func(): collision_shape.disabled = false) # prevent player from hitting himself

func _disable_hit():
collision_shape.set_deferred("disabled", true)
#func _disable_hit():
# collision_shape.set_deferred("disabled", true)

func _remove():
if death_spawner:
death_spawner.spawn()
queue_free()
Loading

0 comments on commit 043c468

Please sign in to comment.