From a2974d8dd35706f5325d50599d7ce292207ff1a6 Mon Sep 17 00:00:00 2001 From: Hazel Snider Date: Thu, 19 Jan 2023 18:26:50 -0500 Subject: [PATCH] the damage system refactor! killing is now done based on groups, the same way enemies already killed the player. these groups go on the entity's hitbox, not the entity itself. enemies' hitboxes have all been put in "enemy_hitbox" the arrow_projectile has a variable for the target group, so it could easily be simply set to "player" for arrows shot by enemies blocking is also done with groups. any hitbox with "blocks_arrow" will block arrows, same with "blocks_sword" and "blocks_squash" --- objects/enemy/bat.tscn | 7 ++--- objects/enemy/enemy.gd | 41 +++++++++---------------- objects/enemy/enemy_speedup_in_range.gd | 2 +- objects/enemy/rolling_fiend.tscn | 4 +-- objects/enemy/slime.tscn | 6 ++-- objects/enemy/snail.tscn | 8 ++--- objects/enemy/snake.tscn | 7 ++--- objects/enemy/tentacle.tscn | 7 +++-- objects/environment/rock/rock.gd | 7 +++++ objects/environment/rock/rock.tscn | 6 ++-- objects/player/arrow_projectile.gd | 36 +++++++++++++++++----- objects/player/arrow_projectile.tscn | 13 +++----- objects/player/player.gd | 23 ++++++++++++-- objects/player/player.tscn | 1 + 14 files changed, 102 insertions(+), 66 deletions(-) diff --git a/objects/enemy/bat.tscn b/objects/enemy/bat.tscn index fa74a07..2a7bdec 100644 --- a/objects/enemy/bat.tscn +++ b/objects/enemy/bat.tscn @@ -30,7 +30,6 @@ extents = Vector2( 4, 4 ) [node name="Bat" type="Node2D" groups=["enemy"]] script = ExtResource( 3 ) -can_be_killed_by_sword = false score_for_killing = 25 speed = 40 move_direction = 1 @@ -42,9 +41,9 @@ frames = SubResource( 4 ) frame = 1 playing = true -[node name="Area2D" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["blocks_sword", "enemy_hitbox"]] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] shape = SubResource( 5 ) -[connection signal="area_entered" from="Area2D" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/enemy/enemy.gd b/objects/enemy/enemy.gd index 9c1c463..77684b3 100644 --- a/objects/enemy/enemy.gd +++ b/objects/enemy/enemy.gd @@ -1,38 +1,27 @@ extends Node2D +### +### IMPORTANT: enemy's hitbox must be in the group "enemy_hitbox" to be killed +### it should also be named "Hitbox" for easier (2 click) signal connection +### as the reciever function has been renamed with that in mind +### + const DeathParticles = preload("res://objects/enemy/death_particles.tscn") -export var can_be_killed_by_sword = true -export var can_be_killed_by_arrow = true -export var can_be_squashed = true +### these variables have been replaced with groups to put on the hitbox +### - "blocks_arrow" +### - "blocks_sword" +### if an enemy's hitbox is not in those groups, it will be killed by them +#export var can_be_killed_by_sword = true +#export var can_be_killed_by_arrow = true +#export var can_be_squashed = true + export var score_for_killing = 0 -func _on_Area2D_area_entered(area): +func _on_Hitbox_area_entered(area): #Kill player if area.is_in_group("player"): area.get_parent().die() - #Die from sword - if area.is_in_group("sword"): - if can_be_killed_by_sword: - die() - else: - #Block text - Game.instance_node(Game.block_text,global_position.x,global_position.y,get_parent()) - #Die from arrow - if area.is_in_group("arrow"): - if can_be_killed_by_arrow: - Game.arrows -= 1 - area.get_parent().queue_free() - die() - else: - #Block text - Game.instance_node(Game.block_text,global_position.x,global_position.y,get_parent()) - #Die from rock/ get squashed - if area.is_in_group("squash"): - Debug.print("squash") - var squasher = area.get_parent() - if squasher.global_position.y < global_position.y && squasher.velocity.y > 0: - die() func die(): var death_particles = DeathParticles.instance() diff --git a/objects/enemy/enemy_speedup_in_range.gd b/objects/enemy/enemy_speedup_in_range.gd index 7df60c4..4eb24f6 100644 --- a/objects/enemy/enemy_speedup_in_range.gd +++ b/objects/enemy/enemy_speedup_in_range.gd @@ -13,7 +13,7 @@ export var flip_sprite = true #Onreadys onready var startpos = position onready var sprite = $AnimatedSprite -onready var raycast = $Area2D/RayCast2D +onready var raycast = $Hitbox/RayCast2D onready var timer = $Timer var speed = 50 diff --git a/objects/enemy/rolling_fiend.tscn b/objects/enemy/rolling_fiend.tscn index d85ff47..366d513 100644 --- a/objects/enemy/rolling_fiend.tscn +++ b/objects/enemy/rolling_fiend.tscn @@ -47,10 +47,10 @@ playing = true position = Vector2( 4, 4 ) shape = SubResource( 8 ) -[node name="Hitbox" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox"]] position = Vector2( 4, 4 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] shape = SubResource( 4 ) -[connection signal="area_entered" from="Hitbox" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/enemy/slime.tscn b/objects/enemy/slime.tscn index f194b79..3600715 100644 --- a/objects/enemy/slime.tscn +++ b/objects/enemy/slime.tscn @@ -40,11 +40,11 @@ position = Vector2( 1, 3 ) frames = SubResource( 4 ) playing = true -[node name="Area2D" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox"]] position = Vector2( -4, 0 ) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( 4.5, 3.5 ) shape = SubResource( 5 ) -[connection signal="area_entered" from="Area2D" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/enemy/snail.tscn b/objects/enemy/snail.tscn index a6a17c2..5ff0998 100644 --- a/objects/enemy/snail.tscn +++ b/objects/enemy/snail.tscn @@ -41,13 +41,13 @@ frames = SubResource( 4 ) frame = 1 playing = true -[node name="Area2D" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox"]] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( 4, 4 ) shape = SubResource( 5 ) -[node name="RayCast2D" type="RayCast2D" parent="Area2D"] +[node name="RayCast2D" type="RayCast2D" parent="Hitbox"] position = Vector2( 0, 4 ) enabled = true cast_to = Vector2( 32, 0 ) @@ -58,5 +58,5 @@ collide_with_areas = true wait_time = 0.5 one_shot = true -[connection signal="area_entered" from="Area2D" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"] diff --git a/objects/enemy/snake.tscn b/objects/enemy/snake.tscn index a81b511..5e6505f 100644 --- a/objects/enemy/snake.tscn +++ b/objects/enemy/snake.tscn @@ -35,13 +35,12 @@ score_for_killing = 15 [node name="AnimatedSprite" type="AnimatedSprite" parent="."] material = SubResource( 1 ) frames = SubResource( 4 ) -frame = 1 playing = true -[node name="Area2D" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox"]] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( 0, 4 ) shape = SubResource( 5 ) -[connection signal="area_entered" from="Area2D" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/enemy/tentacle.tscn b/objects/enemy/tentacle.tscn index 555f05e..d3e685e 100644 --- a/objects/enemy/tentacle.tscn +++ b/objects/enemy/tentacle.tscn @@ -28,12 +28,13 @@ script = ExtResource( 1 ) [node name="AnimatedSprite" type="AnimatedSprite" parent="."] position = Vector2( 4, 12 ) frames = SubResource( 3 ) +frame = 1 playing = true -[node name="Area2D" type="Area2D" parent="."] +[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox"]] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( 4, 12 ) shape = SubResource( 4 ) -[connection signal="area_entered" from="Area2D" to="." method="_on_Area2D_area_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/environment/rock/rock.gd b/objects/environment/rock/rock.gd index 5d3db7e..d7f33ae 100644 --- a/objects/environment/rock/rock.gd +++ b/objects/environment/rock/rock.gd @@ -14,3 +14,10 @@ func _physics_process(delta): func push(direction): velocity -= direction * 32 + +func _on_Hitbox_area_entered(area): + # do not squish if in "blocks_squash" group + if area.is_in_group("enemy_hitbox") && !area.is_in_group("blocks_squash"): + var enemy = area.get_parent() + if enemy.global_position.y > global_position.y && velocity.y > 0: + enemy.die() diff --git a/objects/environment/rock/rock.tscn b/objects/environment/rock/rock.tscn index ef3186b..3609eca 100644 --- a/objects/environment/rock/rock.tscn +++ b/objects/environment/rock/rock.tscn @@ -29,12 +29,14 @@ centered = false position = Vector2( 4, 4 ) shape = SubResource( 2 ) -[node name="Area2D" type="Area2D" parent="." groups=["squash"]] +[node name="Hitbox" type="Area2D" parent="." groups=["squash"]] position = Vector2( -1, 0 ) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( 5, 4 ) shape = SubResource( 3 ) [node name="Bottom" type="Position2D" parent="."] position = Vector2( 4, 8 ) + +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] diff --git a/objects/player/arrow_projectile.gd b/objects/player/arrow_projectile.gd index de7a5bf..2023ce0 100644 --- a/objects/player/arrow_projectile.gd +++ b/objects/player/arrow_projectile.gd @@ -1,16 +1,24 @@ extends Node2D -onready var cull_edge = Vector2(5 * scale.x,0) #Edge to check culling, if this edge is offscreen, delete the arrow +export var speed = 240.0 + +# group to kill +var target_group = "enemy_hitbox" +# direction to fly +var direction = 1.0 + +#Edge to check culling, if this edge is offscreen, delete the arrow +onready var cull_edge = Vector2(5 * direction,0) onready var player = get_parent().get_node("Player") onready var initial_sector = Game.get_sector(player.global_position) func _ready(): - #Flip depending on player facing - scale.x = player.sprite.scale.x + #Flip depending on direction + scale.x = direction func _physics_process(delta): - #Move in flip direction - position.x += 4 * scale.x + #Move in right direction + position.x += speed * direction * delta #Delete when offscreen if Game.get_sector(global_position + cull_edge) != initial_sector: queue_free() @@ -22,10 +30,24 @@ func _exit_tree(): particles.global_position = global_position particles.emitting = false get_parent().add_child(particles) - particles.get_node("DeathTimer").start() + get_tree().create_timer(particles.lifetime, false).connect("timeout", particles, "queue_free") #Wall Collision -func _on_Area2D_body_entered(body): +func _on_Hitbox_body_entered(body): if body is TileMap or body is StaticBody2D: queue_free() +# kill entity if in target group +func _on_Hitbox_area_entered(area): + # block if collided area is in "blocks_arrow" group + if area.is_in_group(target_group): + var target = area.get_parent() + # create block text and return if blocked + if area.is_in_group("blocks_arrow"): + var pos = target.global_position + Game.instance_node(Game.block_text, pos.x, pos.y, target.get_parent()) + else: + # kill targeted node + target.die() + Game.arrows = max(0, Game.arrows - 1) # clamp arrows above 0 + queue_free() diff --git a/objects/player/arrow_projectile.tscn b/objects/player/arrow_projectile.tscn index 7617a13..694be18 100644 --- a/objects/player/arrow_projectile.tscn +++ b/objects/player/arrow_projectile.tscn @@ -52,15 +52,12 @@ local_coords = false process_material = SubResource( 5 ) texture = ExtResource( 4 ) -[node name="DeathTimer" type="Timer" parent="DustParticles"] -one_shot = true +[node name="Hitbox" type="Area2D" parent="." groups=["arrow"]] +collision_layer = 0 -[node name="Area2D" type="Area2D" parent="." groups=["arrow"]] -visible = false - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] position = Vector2( -0.5, -0.5 ) shape = SubResource( 2 ) -[connection signal="timeout" from="DustParticles/DeathTimer" to="DustParticles" method="queue_free"] -[connection signal="body_entered" from="Area2D" to="." method="_on_Area2D_body_entered"] +[connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] +[connection signal="body_entered" from="Hitbox" to="." method="_on_Hitbox_body_entered"] diff --git a/objects/player/player.gd b/objects/player/player.gd index 066c0b9..707adf2 100644 --- a/objects/player/player.gd +++ b/objects/player/player.gd @@ -1,5 +1,7 @@ extends KinematicBody2D +const ArrowProjectile = preload("res://objects/player/arrow_projectile.tscn") + ##CLEAN UP CODE LATER ##Children onready var sprite = $Sprite @@ -30,7 +32,6 @@ var can_move_in_air = false #Positions var arrowpos = Vector2(5,3) ##Preload -var pre_arrow = preload("res://objects/player/arrow_projectile.tscn") #Set initial respawn point func _ready(): @@ -187,7 +188,13 @@ func _process_shoot(): func spawn_arrow(): Game.play_sound(Game.a_shoot,Game.ac_jump) - Game.instance_node(pre_arrow,global_position.x+(arrowpos.x*sprite.scale.x),global_position.y+arrowpos.y,map) + var arrow = ArrowProjectile.instance() + arrow.global_position = Vector2( + global_position.x + arrowpos.x * sprite.scale.x, + global_position.y + arrowpos.y + ) + arrow.direction = sprite.scale.x + map.add_child(arrow) func check_jump(): if Input.is_action_just_pressed("jump"): @@ -291,3 +298,15 @@ func _on_AnimationPlayer_animation_finished(anim_name): else: current_state = State.FALL return + + +func _on_SwordArea_area_entered(area): + if area.is_in_group("enemy_hitbox"): + var target = area.get_parent() + # create block text and return if blocked + if area.is_in_group("blocks_sword"): + var pos = target.global_position + Game.instance_node(Game.block_text, pos.x, pos.y, target.get_parent()) + return + else: + target.die() diff --git a/objects/player/player.tscn b/objects/player/player.tscn index a49d418..ada6f7b 100644 --- a/objects/player/player.tscn +++ b/objects/player/player.tscn @@ -731,3 +731,4 @@ process_material = SubResource( 45 ) texture = ExtResource( 16 ) [connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_AnimationPlayer_animation_finished"] +[connection signal="area_entered" from="SwordArea" to="." method="_on_SwordArea_area_entered"]