game: add godot project
This commit is contained in:
78
scenes/attacks/attack_sword.gd
Normal file
78
scenes/attacks/attack_sword.gd
Normal file
@@ -0,0 +1,78 @@
|
||||
extends Node2D
|
||||
|
||||
@export var default_attack_time: float = 0.5
|
||||
@export var default_damage: float = 5.0
|
||||
|
||||
@onready var trigger_area: Area2D = $TriggerArea
|
||||
@onready var trigger_collision: CollisionShape2D = $TriggerArea/TriggerCollision
|
||||
@onready var timer: Timer = $Timer
|
||||
@onready var attack_path: Path2D = $AttackPath
|
||||
@onready var path_follow_2d: PathFollow2D = $AttackPath/PathFollow2D
|
||||
@onready var attack_area: Area2D = $AttackPath/PathFollow2D/Sprite2D/AttackArea
|
||||
|
||||
var damage: float
|
||||
var current_target: Node2D = null
|
||||
var current_progress: float = 0.0
|
||||
var damaged_this_attack: Array = []
|
||||
|
||||
func _ready() -> void:
|
||||
attack_path.visible = false
|
||||
damage = default_damage
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if timer.is_stopped():
|
||||
timer.start()
|
||||
if current_progress == 1.0:
|
||||
reset_attack()
|
||||
if current_target and is_instance_valid(current_target) and not current_target.is_queued_for_deletion():
|
||||
track_target(current_target)
|
||||
attack_path.visible = true
|
||||
|
||||
# Do attack animation
|
||||
current_progress += delta / default_attack_time
|
||||
current_progress = clampf(current_progress, 0.0, 1.0)
|
||||
path_follow_2d.progress_ratio = current_progress
|
||||
|
||||
func reset_attack() -> void:
|
||||
current_target = null
|
||||
attack_path.visible = false
|
||||
current_progress = 0.0
|
||||
damaged_this_attack = []
|
||||
position = Vector2.ZERO
|
||||
rotation = 0.0
|
||||
|
||||
func set_target(body: Node2D):
|
||||
current_target = body
|
||||
|
||||
func track_target(body: Node2D):
|
||||
if not current_target or not is_instance_valid(body) or body.is_queued_for_deletion():
|
||||
print_debug("target deleted or queued for deletion")
|
||||
return
|
||||
var mid_distance = attack_path.curve.get_baked_length() / 2
|
||||
var mid_point: Vector2 = attack_path.curve.sample_baked(mid_distance)
|
||||
var offset = body.global_position - to_global(mid_point)
|
||||
var desired_dir = (body.global_position - to_global(mid_point)).normalized()
|
||||
var start_point_global = attack_path.to_global(attack_path.curve.sample_baked(0))
|
||||
var end_point_global = attack_path.to_global(attack_path.curve.sample_baked(attack_path.curve.get_baked_length()))
|
||||
var curve_dir = (start_point_global - end_point_global).normalized()
|
||||
var angle_diff = curve_dir.angle_to(desired_dir)
|
||||
if rotation == 0.0:
|
||||
rotation = curve_dir.angle_to(desired_dir)
|
||||
print_debug("tracked target")
|
||||
position += offset
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
if trigger_area.has_overlapping_bodies():
|
||||
for body in trigger_area.get_overlapping_bodies():
|
||||
if body.is_in_group(GlobalConst.GROUP_ENEMY):
|
||||
set_target(body)
|
||||
|
||||
func _on_attack_area_body_entered(body: Node2D) -> void:
|
||||
if not attack_path.visible:
|
||||
return
|
||||
if body in damaged_this_attack:
|
||||
return
|
||||
if body.is_in_group(GlobalConst.GROUP_ENEMY) and body.is_in_group(GlobalConst.GROUP_DAMAGEABLE):
|
||||
body.take_damage(damage)
|
||||
damaged_this_attack.append(body)
|
1
scenes/attacks/attack_sword.gd.uid
Normal file
1
scenes/attacks/attack_sword.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://db326gu8abue5
|
55
scenes/attacks/attack_sword.tscn
Normal file
55
scenes/attacks/attack_sword.tscn
Normal file
@@ -0,0 +1,55 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://cdojqe2m4kxx1"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dycw7c3484dir" path="res://assets/sprites/sword.png" id="1_3fwwl"]
|
||||
[ext_resource type="Script" uid="uid://db326gu8abue5" path="res://scenes/attacks/attack_sword.gd" id="1_frsqi"]
|
||||
|
||||
[sub_resource type="Curve2D" id="Curve2D_frsqi"]
|
||||
bake_interval = 2.0
|
||||
_data = {
|
||||
"points": PackedVector2Array(0, 0, 0, 0, 0, 0, 0, 0, 25, 10, 150, 0)
|
||||
}
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_frsqi"]
|
||||
size = Vector2(13.9997, 46.999)
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_3fwwl"]
|
||||
radius = 267.002
|
||||
|
||||
[node name="AttackSword" type="Node2D"]
|
||||
script = ExtResource("1_frsqi")
|
||||
|
||||
[node name="AttackPath" type="Path2D" parent="."]
|
||||
curve = SubResource("Curve2D_frsqi")
|
||||
|
||||
[node name="PathFollow2D" type="PathFollow2D" parent="AttackPath"]
|
||||
loop = false
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="AttackPath/PathFollow2D"]
|
||||
position = Vector2(0.322462, -0.946582)
|
||||
rotation = 0.328329
|
||||
scale = Vector2(1, 1)
|
||||
texture = ExtResource("1_3fwwl")
|
||||
|
||||
[node name="AttackArea" type="Area2D" parent="AttackPath/PathFollow2D/Sprite2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
|
||||
[node name="AttackCollision" type="CollisionShape2D" parent="AttackPath/PathFollow2D/Sprite2D/AttackArea"]
|
||||
position = Vector2(-0.0328934, -4.50646)
|
||||
shape = SubResource("RectangleShape2D_frsqi")
|
||||
|
||||
[node name="TriggerArea" type="Area2D" parent="."]
|
||||
visible = false
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
|
||||
[node name="TriggerCollision" type="CollisionShape2D" parent="TriggerArea"]
|
||||
shape = SubResource("CircleShape2D_3fwwl")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
one_shot = true
|
||||
autostart = true
|
||||
|
||||
[connection signal="body_entered" from="AttackPath/PathFollow2D/Sprite2D/AttackArea" to="." method="_on_attack_area_body_entered"]
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
|
Reference in New Issue
Block a user