lashy's full forme

This commit is contained in:
Haze Weathers 2025-03-09 05:56:20 -04:00
parent aaf9278350
commit 19c8ee9566
5 changed files with 91 additions and 103 deletions

View file

@ -0,0 +1,9 @@
shader_type canvas_item;
uniform float radius = 0.0;
uniform float speed = 0.0;
void vertex() {
VERTEX.x += cos(TIME * speed) * radius;
VERTEX.y += sin(TIME * speed) * radius;
}

View file

@ -0,0 +1 @@
uid://bc8j5jyjynbca

View file

@ -25,7 +25,9 @@ tile_map_data = PackedByteArray("AAAAAAsAAAAAAAAAAAABAAsAAAAAAAAAAAACAAsAAAAAAAA
tile_set = ExtResource("2_dj7w1")
[node name="Lashy" parent="." instance=ExtResource("4_gykx6")]
position = Vector2(264, 72)
position = Vector2(160, 160)
launch_power = 300.0
idle_radius = 6.0
[node name="Player" parent="." instance=ExtResource("5_5v7mr")]
position = Vector2(120, 144)
@ -34,4 +36,4 @@ position = Vector2(120, 144)
position = Vector2(96, 144)
[node name="RotoBoy" parent="." instance=ExtResource("7_j1102")]
position = Vector2(152, 104)
position = Vector2(240, 40)

View file

@ -2,82 +2,59 @@
extends Node2D
enum State {
IDLE,
WINDING_UP,
ATTACK,
RECOVER,
}
@export var launch_power: float
@export var idle_radius: float
@export var draw_back_distance: float
@export var smash_distance: float
@export var idle_distance: float
@export_custom(PROPERTY_HINT_NONE, "radians_as_degrees")
var idle_rotate_speed: float
@export var wind_up_time: float
@export var wind_up_distance: float
@export var attack_time: float
@export var attack_distance: float
@export var recover_time: float
@export_range(0,1,1,"or_greater") var detection_radius: float:
set(value):
detection_radius = value
if not is_inside_tree():
await tree_entered
var shape = detector_shape.shape as CircleShape2D
if shape:
shape.radius = detection_radius
@export_group("Timing", "time_")
@export var time_draw_back: float
@export var time_smash: float
@export var time_recover: float
@export_group("Internal References")
@export var head: Node2D
@export var head_pivot: Node2D
@export var detector_shape: CollisionShape2D
var state: State = State.IDLE
var tween: Tween = null
var tracked_player: Player = null
var idle_angle: float = 0.0
var target_pos: Vector2 = Vector2.ZERO
var progress: float = 0.0
func _process(delta: float) -> void:
if Engine.is_editor_hint():
return
match state:
State.IDLE:
idle_angle = fposmod(idle_angle + idle_rotate_speed * delta, TAU)
head_pivot.rotation = idle_angle
State.WINDING_UP:
target_pos = tracked_player.global_position
var angle = (global_position - target_pos).angle()
progress += delta / wind_up_time
head_pivot.rotation = lerp_angle(head_pivot.rotation, angle, progress)
State.RECOVER:
progress += delta / recover_time
head_pivot.rotation = lerp_angle(head_pivot.rotation, idle_angle, progress)
func _start_attack() -> void:
state = State.WINDING_UP
if tween:
tween.kill()
tween = create_tween().set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
tween.tween_property(head, ^"position:x", wind_up_distance, wind_up_time)
tween.tween_property(self, ^"state", State.ATTACK, 0.0)
tween.tween_property(head, ^"position:x", -attack_distance, attack_time).set_trans(Tween.TRANS_BOUNCE)
tween.tween_property(self, ^"state", State.RECOVER, 0.0)
tween.tween_property(head, ^"position:x", idle_distance, recover_time)
tween.tween_property(self, ^"state", State.IDLE, 0.0)
var _player: Player = null
var _tween: Tween = null
func _on_player_detector_body_entered(body: Node2D) -> void:
if body is Player:
if state == State.IDLE:
tracked_player = body
_player = body
_start_attack()
func _on_head_body_entered(body: Node2D) -> void:
if body is Player:
body.launch(global_position.direction_to(body.global_position) * launch_power)
func _start_attack() -> void:
# do nothing if already doing animation
if _tween and _tween.is_running():
return
_tween = create_tween().set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
# draw back away from player
_tween.tween_property(head.material, ^"shader_parameter/radius", 0.0, 0.1)
_tween.parallel().tween_method(_move_facing_player, 0.0, -draw_back_distance, time_draw_back)\
.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CUBIC)
# smash towards player
_tween.tween_method(_move_facing_player, -draw_back_distance, smash_distance, time_smash)\
.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
# return to center
_tween.tween_method(_move_facing_player, smash_distance, 0.0, time_recover)\
.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BOUNCE)
_tween.tween_property(head.material, ^"shader_parameter/radius", idle_radius, 0.1)
## move head this disatance from (0,0) towards (or away if negative) from player
func _move_facing_player(distance: float) -> void:
if not _player:
return
var dir = global_position.direction_to(_player.global_position)
head.position = dir * distance

View file

@ -1,31 +1,35 @@
[gd_scene load_steps=8 format=3 uid="uid://c8r040r4glui4"]
[gd_scene load_steps=10 format=3 uid="uid://c8r040r4glui4"]
[ext_resource type="Script" uid="uid://lxppe1op1240" path="res://objects/enemies/lashy/lashy.gd" id="1_34o54"]
[ext_resource type="Texture2D" uid="uid://cm4cantqbhkwx" path="res://assets/textures/enemies/lashy/lashy_anchor.png" id="2_8ls3k"]
[ext_resource type="Script" uid="uid://bt4bdjyekgh53" path="res://scripts/ball_snake/ball_snake.gd" id="3_8edxw"]
[ext_resource type="Texture2D" uid="uid://gnkke4rr0wcr" path="res://assets/textures/enemies/lashy/lashy_body.png" id="4_xnkdk"]
[ext_resource type="Texture2D" uid="uid://bf0i64q2dw0au" path="res://assets/textures/enemies/lashy/lashy_head.png" id="5_b5g1y"]
[ext_resource type="Shader" uid="uid://bc8j5jyjynbca" path="res://assets/shaders/orbit.gdshader" id="5_dkkk6"]
[sub_resource type="CircleShape2D" id="CircleShape2D_woon5"]
resource_local_to_scene = true
radius = 64.0
radius = 32.0
[sub_resource type="ShaderMaterial" id="ShaderMaterial_42oum"]
resource_local_to_scene = true
shader = ExtResource("5_dkkk6")
shader_parameter/radius = 6.0
shader_parameter/speed = 3.142
[sub_resource type="CircleShape2D" id="CircleShape2D_g5iss"]
radius = 6.0
[node name="Lashy" type="Node2D" node_paths=PackedStringArray("head", "head_pivot", "detector_shape")]
[node name="Lashy" type="Node2D" node_paths=PackedStringArray("head")]
script = ExtResource("1_34o54")
idle_distance = 16.0
idle_rotate_speed = 1.5708
wind_up_time = 2.0
wind_up_distance = 32.0
attack_time = 0.5
attack_distance = 64.0
recover_time = 2.0
detection_radius = 64.0
head = NodePath("HeadPivot/Head")
head_pivot = NodePath("HeadPivot")
detector_shape = NodePath("PlayerDetector/DetectorShape")
launch_power = 240.0
idle_radius = 4.0
draw_back_distance = 24.0
smash_distance = 32.0
time_draw_back = 0.2
time_smash = 0.2
time_recover = 0.1
head = NodePath("Head")
[node name="PlayerDetector" type="Area2D" parent="."]
collision_layer = 0
@ -39,34 +43,29 @@ debug_color = Color(0.752941, 0.196078, 1, 0.25098)
[node name="Anchor" type="Sprite2D" parent="."]
texture = ExtResource("2_8ls3k")
[node name="BallSnake" type="Node2D" parent="." node_paths=PackedStringArray("target")]
[node name="BallSnake" type="Node2D" parent="Anchor" node_paths=PackedStringArray("target")]
script = ExtResource("3_8edxw")
texture = ExtResource("4_xnkdk")
target = NodePath("../HeadPivot/Head")
segments = 2
target = NodePath("../../Head")
segments = -1
head_segment = false
tail_segment = true
auto_density = true
pixels_per_segment = 5.0
[node name="HeadSprite" type="Sprite2D" parent="."]
position = Vector2(-5.79198e-05, -16)
texture = ExtResource("5_b5g1y")
[node name="HeadPivot" type="Node2D" parent="."]
rotation = -1.5708
[node name="Head" type="Area2D" parent="HeadPivot"]
position = Vector2(16, 0)
[node name="Head" type="Area2D" parent="."]
material = SubResource("ShaderMaterial_42oum")
collision_layer = 0
collision_mask = 16
monitorable = false
metadata/_edit_group_ = true
[node name="CollisionShape2D" type="CollisionShape2D" parent="HeadPivot/Head"]
[node name="HeadSprite" type="Sprite2D" parent="Head"]
use_parent_material = true
texture = ExtResource("5_b5g1y")
[node name="CollisionShape2D" type="CollisionShape2D" parent="Head"]
shape = SubResource("CircleShape2D_g5iss")
debug_color = Color(1, 0, 0, 0.419608)
[node name="RemoteTransform2D" type="RemoteTransform2D" parent="HeadPivot/Head"]
remote_path = NodePath("../../../HeadSprite")
update_rotation = false
update_scale = false
[connection signal="body_entered" from="PlayerDetector" to="." method="_on_player_detector_body_entered"]
[connection signal="body_entered" from="Head" to="." method="_on_head_body_entered"]