From cd0d6e29e9a212014ca2ebd2bd2bcd2922f2570d Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Wed, 17 Mar 2021 01:29:51 +0000 Subject: [PATCH] Add chasing functionality to the bat --- AI/HurtBox.gd | 11 +++++++++ AI/PlayerDetectionZone.gd | 15 ++++++++++++ AI/PlayerDetectionZone.tscn | 12 +++++++++ Effects/HitEffect.tscn | 26 ++++++++++++++++++++ Enemies/Bat.gd | 49 +++++++++++++++++++++++++++++++++++++ Enemies/Bat.tscn | 16 +++++++++++- 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 AI/HurtBox.gd create mode 100644 AI/PlayerDetectionZone.gd create mode 100644 AI/PlayerDetectionZone.tscn create mode 100644 Effects/HitEffect.tscn diff --git a/AI/HurtBox.gd b/AI/HurtBox.gd new file mode 100644 index 0000000..7cc1a69 --- /dev/null +++ b/AI/HurtBox.gd @@ -0,0 +1,11 @@ +extends Area2D + +export(bool) var hit_effect = true + +const HitEffect = preload("res://Effects/HitEffect.tscn") + +func _on_HurtBox_area_entered(_hitbox): + if hit_effect: + var effect = HitEffect.instance() + get_tree().current_scene.add_child(effect) + effect.global_position = global_position diff --git a/AI/PlayerDetectionZone.gd b/AI/PlayerDetectionZone.gd new file mode 100644 index 0000000..05a9448 --- /dev/null +++ b/AI/PlayerDetectionZone.gd @@ -0,0 +1,15 @@ +extends Area2D + +var player = null + + +func _on_PlayerDetectionZone_body_entered(body): + player = body + + +func _on_PlayerDetectionZone_body_exited(_body): + player = null + + +func is_player_detected(): + return player != null diff --git a/AI/PlayerDetectionZone.tscn b/AI/PlayerDetectionZone.tscn new file mode 100644 index 0000000..a4d9e57 --- /dev/null +++ b/AI/PlayerDetectionZone.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://AI/PlayerDetectionZone.gd" type="Script" id=1] + +[node name="PlayerDetectionZone" type="Area2D"] +collision_layer = 0 +collision_mask = 2 +script = ExtResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +[connection signal="body_entered" from="." to="." method="_on_PlayerDetectionZone_body_entered"] +[connection signal="body_exited" from="." to="." method="_on_PlayerDetectionZone_body_exited"] diff --git a/Effects/HitEffect.tscn b/Effects/HitEffect.tscn new file mode 100644 index 0000000..d02998b --- /dev/null +++ b/Effects/HitEffect.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://Effects/HitEffect.png" type="Texture" id=1] +[ext_resource path="res://Effects/Effects.gd" type="Script" id=2] + +[sub_resource type="AtlasTexture" id=1] +atlas = ExtResource( 1 ) +region = Rect2( 0, 0, 24, 24 ) + +[sub_resource type="AtlasTexture" id=2] +atlas = ExtResource( 1 ) +region = Rect2( 24, 0, 24, 24 ) + +[sub_resource type="SpriteFrames" id=3] +animations = [ { +"frames": [ SubResource( 1 ), SubResource( 2 ) ], +"loop": false, +"name": "animate", +"speed": 10.0 +} ] + +[node name="HitEffect" type="AnimatedSprite"] +frames = SubResource( 3 ) +animation = "animate" +offset = Vector2( 0, -8 ) +script = ExtResource( 2 ) diff --git a/Enemies/Bat.gd b/Enemies/Bat.gd index 19fcce7..6b2eee6 100644 --- a/Enemies/Bat.gd +++ b/Enemies/Bat.gd @@ -3,12 +3,61 @@ extends KinematicBody2D const DeathEffect = preload("res://Effects/EnemyDeathEffect.tscn") var knockback = Vector2.ZERO +var velocity = Vector2.ZERO + onready var stats = $Stats +onready var player_detector = $PlayerDetectionZone +onready var sprite = $AnimatedSprite +onready var original_position = global_position + +export(int) var acceleration = 300 +export(int) var max_speed = 300 +export(int) var friction = 200 + +enum { + IDLE, + MOVE, + CHASE, + MOVE_BACK +} + +onready var state = IDLE func _physics_process(delta): knockback = knockback.move_toward(Vector2.ZERO, 200 * delta) knockback = move_and_slide(knockback) + match state: + IDLE: + velocity = velocity.move_toward(Vector2.ZERO, friction) + seek_player() + + MOVE_BACK: + # TODO: Navigation here + pass + + MOVE: + pass + CHASE: + var player = player_detector.player + if player != null: + var direction = (player.global_position - global_position).normalized() + velocity = velocity.move_toward(direction * max_speed, acceleration * delta) + sprite.flip_h = velocity.x < 0 + else: + state = IDLE + + velocity = move_and_slide(velocity) + +func around_the_original_position(): + return abs(original_position.x - global_position.x) < 5 and abs(original_position.y - global_position.y) < 5 + + +func seek_player(): + if player_detector.is_player_detected(): + state = CHASE + + func _on_HurtBox_area_entered(area): stats.health -= area.damage knockback = area.knockback_vector * 120 diff --git a/Enemies/Bat.tscn b/Enemies/Bat.tscn index 3063258..6efa453 100644 --- a/Enemies/Bat.tscn +++ b/Enemies/Bat.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=14 format=2] +[gd_scene load_steps=16 format=2] [ext_resource path="res://Shadows/SmallShadow.png" type="Texture" id=1] [ext_resource path="res://Enemies/Bat.png" type="Texture" id=2] [ext_resource path="res://AI/HurtBox.tscn" type="PackedScene" id=3] [ext_resource path="res://Enemies/Bat.gd" type="Script" id=4] [ext_resource path="res://AI/Stats.tscn" type="PackedScene" id=5] +[ext_resource path="res://AI/PlayerDetectionZone.tscn" type="PackedScene" id=6] [sub_resource type="AtlasTexture" id=1] atlas = ExtResource( 2 ) @@ -41,9 +42,14 @@ radius = 3.92309 radius = 5.875 height = 0.75 +[sub_resource type="CircleShape2D" id=9] +radius = 46.4887 + [node name="Bat" type="KinematicBody2D"] collision_layer = 16 script = ExtResource( 4 ) +acceleration = 200 +max_speed = 50 [node name="AnimatedSprite" type="AnimatedSprite" parent="."] frames = SubResource( 6 ) @@ -68,7 +74,15 @@ shape = SubResource( 8 ) [node name="Stats" parent="." instance=ExtResource( 5 )] max_health = 2 + +[node name="PlayerDetectionZone" parent="." instance=ExtResource( 6 )] + +[node name="CollisionShape2D" parent="PlayerDetectionZone" index="0"] +modulate = Color( 0.654902, 0.192157, 0.192157, 0.298039 ) +shape = SubResource( 9 ) [connection signal="area_entered" from="HurtBox" to="." method="_on_HurtBox_area_entered"] [connection signal="no_health" from="Stats" to="." method="_on_Stats_no_health"] [editable path="HurtBox"] + +[editable path="PlayerDetectionZone"]