From 3695fef9693b61ddbce1fca087b6c3cf348dd030 Mon Sep 17 00:00:00 2001 From: Haze Weathers Date: Sat, 1 Mar 2025 22:10:51 -0500 Subject: [PATCH] Lashy's not quite fully baked yet... --- .../textures/enemies/lashy/lashy_anchor.png | Bin 0 -> 708 bytes .../enemies/lashy/lashy_anchor.png.import | 34 +++++++ assets/textures/enemies/lashy/lashy_body.png | Bin 0 -> 675 bytes .../enemies/lashy/lashy_body.png.import | 34 +++++++ assets/textures/enemies/lashy/lashy_head.png | Bin 0 -> 946 bytes .../enemies/lashy/lashy_head.png.import | 34 +++++++ maps/level_z.tscn | 23 ++++- objects/enemies/lashy/lashy.gd | 83 ++++++++++++++++++ objects/enemies/lashy/lashy.tscn | 71 +++++++++++++++ 9 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 assets/textures/enemies/lashy/lashy_anchor.png create mode 100644 assets/textures/enemies/lashy/lashy_anchor.png.import create mode 100644 assets/textures/enemies/lashy/lashy_body.png create mode 100644 assets/textures/enemies/lashy/lashy_body.png.import create mode 100644 assets/textures/enemies/lashy/lashy_head.png create mode 100644 assets/textures/enemies/lashy/lashy_head.png.import create mode 100644 objects/enemies/lashy/lashy.gd create mode 100644 objects/enemies/lashy/lashy.tscn diff --git a/assets/textures/enemies/lashy/lashy_anchor.png b/assets/textures/enemies/lashy/lashy_anchor.png new file mode 100644 index 0000000000000000000000000000000000000000..b5285c624efef96d6c05174d220bc60821a0c3e3 GIT binary patch literal 708 zcmV;#0z3VQP)EX>4Tx04R}tkv&MmP!xqvQ$>-AgGGusWT;NwLJl@B7_Z;544-lGFrdd4+K+|nA zlS+!Y{HoaZiXZ|QK@1U@S;m|srQus&_tZ;u7w1|2eSg-VTCf-p5Q!7aFm2)u;+aj` z;Ji;9W@T9=J|~WubV1@rt}7nDaW1(m@XWB8&CC;riN#VED_zXWrbawX991=)@`aqo zD(5ZETD8vF_v9}O74(&5uG1Pr3X52R1Q81AsGtfPaoTlKEM(|B>Ej=D{Svtpa#g^{ zv49#h$gUs!4}Qq{5Ef^@QiW2|;02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{005jxL_t(I%k7dq3c^4Tg})UKl1e+pO2pa|*jsoQ!J{a8 z3JG4u#)M7c#+|V>yU_@?dF314$NWJr6B_&NM!g7?bBO3$MG=MF;nc_sL%`iy0FIZm z;jfpA)(!@tkribW1~{izZdu+9@FE}Q&5N=d@J*ufA3%TE0Vu24G;$|Nf=Y~tt{|cq qW0;Re*y@3(0!r;Y?pgPb-=Y^-l|L=8c^N4H0000EX>4Tx04R}tkv&MmP!xqvQ$>-AgGGusWT;NwLJl@B7_Z;544-lGFrdd4+K+|nA zlS+!Y{HoaZiXZ|QK@1U@S;m|srQus&_tZ;u7w1|2eSg-VTCf-p5Q!7aFm2)u;+aj` z;Ji;9W@T9=J|~WubV1@rt}7nDaW1(m@XWB8&CC;riN#VED_zXWrbawX991=)@`aqo zD(5ZETD8vF_v9}O74(&5uG1Pr3X52R1Q81AsGtfPaoTlKEM(|B>Ej=D{Svtpa#g^{ zv49#h$gUs!4}QF zoU=(tsZ_AiXxsZ}X#ab7?soV8egFN4iT{iK|C9cTs&M)M0004WQchC z8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b05nNNK~xCWV_-l40RbL% zFwMu!!_Ew1@bhxAF#;J}Je=$-Oh5()J1Ywlh{3?j#K?%G7XT`S0RA`O0`>p^002ov JPDHLkV1i7v84v&f literal 0 HcmV?d00001 diff --git a/assets/textures/enemies/lashy/lashy_body.png.import b/assets/textures/enemies/lashy/lashy_body.png.import new file mode 100644 index 0000000..be4df18 --- /dev/null +++ b/assets/textures/enemies/lashy/lashy_body.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gnkke4rr0wcr" +path="res://.godot/imported/lashy_body.png-5a8d8988a263a55d2f3ee182268a610d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/enemies/lashy/lashy_body.png" +dest_files=["res://.godot/imported/lashy_body.png-5a8d8988a263a55d2f3ee182268a610d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/textures/enemies/lashy/lashy_head.png b/assets/textures/enemies/lashy/lashy_head.png new file mode 100644 index 0000000000000000000000000000000000000000..c306c0b91d4db549904e9e89895ea466322be9ac GIT binary patch literal 946 zcmV;j15NyiP)EX>4Tx04R}tkv&MmP!xqvQ$>-AgGGusWT;NwLJl@B7_Z;544-lGFrdd4+K+|nA zlS+!Y{HoaZiXZ|QK@1U@S;m|srQus&_tZ;u7w1|2eSg-VTCf-p5Q!7aFm2)u;+aj` z;Ji;9W@T9=J|~WubV1@rt}7nDaW1(m@XWB8&CC;riN#VED_zXWrbawX991=)@`aqo zD(5ZETD8vF_v9}O74(&5uG1Pr3X52R1Q81AsGtfPaoTlKEM(|B>Ej=D{Svtpa#g^{ zv49#h$gUs!4}Qq{584dnhoeuy202y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00D|gL_t(I%dL|;OG7af$A67Qs)I_~MR2H45J6DE?@&RZ zj^gGlS3w*cgx=9feBxJd6&2bqpo>t2F3KIMB8t^oE!aZadmL)Q?L!3hEJ;rCf8-<`B#gK@dpt9zg1J}7607tVaHe>q$l>H-(&sei8 zaeKE=Z%cLSUvmw>UAnBYi*m*;=r^noFCYfqmG;Loy zFyC@@d`!Y!T>wU{IpUFsnIC4ezLs8yMW;nGA7-;O?KKqd+h+29Q%&X#t^9BC3A}X8 Ua?6f`1^@s607*qoM6N<$f>F_!*Z=?k literal 0 HcmV?d00001 diff --git a/assets/textures/enemies/lashy/lashy_head.png.import b/assets/textures/enemies/lashy/lashy_head.png.import new file mode 100644 index 0000000..4d6f196 --- /dev/null +++ b/assets/textures/enemies/lashy/lashy_head.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bf0i64q2dw0au" +path="res://.godot/imported/lashy_head.png-877548aaa0421024db625942f78e1401.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/enemies/lashy/lashy_head.png" +dest_files=["res://.godot/imported/lashy_head.png-877548aaa0421024db625942f78e1401.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/maps/level_z.tscn b/maps/level_z.tscn index c674ebd..2848dd4 100644 --- a/maps/level_z.tscn +++ b/maps/level_z.tscn @@ -1,3 +1,24 @@ -[gd_scene format=3 uid="uid://cccb8wltupasj"] +[gd_scene load_steps=5 format=4 uid="uid://cccb8wltupasj"] + +[ext_resource type="Texture2D" uid="uid://b6a7l24y30iht" path="res://assets/textures/backgrounds/chocomint.png" id="1_h5jcm"] +[ext_resource type="TileSet" uid="uid://xwfn24if3pxk" path="res://assets/tilesets/chocomint.tres" id="2_dj7w1"] +[ext_resource type="PackedScene" uid="uid://mh2gfm7iqqsm" path="res://objects/player/player.tscn" id="3_kyrxg"] +[ext_resource type="PackedScene" uid="uid://c8r040r4glui4" path="res://objects/enemies/lashy/lashy.tscn" id="4_gykx6"] [node name="LevelZ" type="Node2D"] + +[node name="Background" type="Sprite2D" parent="."] +modulate = Color(0.996924, 0.421436, 0, 1) +position = Vector2(144, 108) +texture = ExtResource("1_h5jcm") + +[node name="TileMap" type="TileMapLayer" parent="."] +use_parent_material = true +tile_map_data = PackedByteArray("AAAAAAsAAAAAAAAAAAABAAsAAAAAAAAAAAACAAsAAAAAAAAAAAAHAAsAAAAAAAAAAAAIAAsAAAAAAAAAAAAJAAsAAAAAAAAAAAAKAAsAAAAAAAAAAAALAAsAAAAAAAAAAAANAAsAAAAAAAAAAAAOAAsAAAAAAAAAAAAPAAsAAAAAAAAAAAAQAAsAAAAAAAAAAAARAAsAAAAAAAAAAAADAAsAAAAAAAAAAAAEAAsAAAAAAAAAAAAFAAsAAAAAAAAAAAAGAAsAAAAAAAAAAAAMAAsAAAAAAAAAAAAFAAoAAAAAAAAAAAAGAAoAAAAAAAAAAAAGAAkAAAAAAAAAAAAHAAkAAAAAAAAAAAAIAAkAAAAAAAAAAAAJAAkAAAAAAAAAAAAKAAkAAAAAAAAAAAALAAkAAAAAAAAAAAAMAAkAAAAAAAAAAAALAAoAAAAAAAAAAAAKAAoAAAAAAAAAAAAJAAoAAAAAAAAAAAAIAAoAAAAAAAAAAAAHAAoAAAAAAAAAAAAMAAoAAAAAAAAAAAANAAoAAAAAAAAAAAAOAAoAAAAAAAAAAAAPAAoAAAAAAAAAAAAPAAkAAAAAAAAAAAAQAAkAAAAAAAAAAAAQAAgAAAAAAAAAAAAQAAcAAAAAAAAAAAAQAAYAAAAAAAAAAAARAAcAAAAAAAAAAAAQAAoAAAAAAAAAAAARAAkAAAAAAAAAAAARAAgAAAAAAAAAAAARAAoAAAAAAAAAAAARAAYAAAAAAAAAAAARAAUAAAAAAAAAAAARAAQAAAAAAAAAAAAQAAQAAAAAAAAAAAAQAAUAAAAAAAAAAAAFAAkAAAAAAAAAAAAEAAkAAAAAAAAAAAADAAkAAAAAAAAAAAACAAkAAAAAAAAAAAABAAkAAAAAAAAAAAABAAoAAAAAAAAAAAACAAoAAAAAAAAAAAADAAoAAAAAAAAAAAAEAAoAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAkAAAAAAAAAAAA=") +tile_set = ExtResource("2_dj7w1") + +[node name="Player" parent="." instance=ExtResource("3_kyrxg")] +position = Vector2(40, 124) + +[node name="Lashy" parent="." instance=ExtResource("4_gykx6")] +position = Vector2(141, 99) diff --git a/objects/enemies/lashy/lashy.gd b/objects/enemies/lashy/lashy.gd new file mode 100644 index 0000000..4991781 --- /dev/null +++ b/objects/enemies/lashy/lashy.gd @@ -0,0 +1,83 @@ +@tool +extends Node2D + + +enum State { + IDLE, + WINDING_UP, + ATTACK, + RECOVER, +} + + +@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("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) + + +func _on_player_detector_body_entered(body: Node2D) -> void: + if body is Player: + if state == State.IDLE: + tracked_player = body + _start_attack() diff --git a/objects/enemies/lashy/lashy.tscn b/objects/enemies/lashy/lashy.tscn new file mode 100644 index 0000000..0b29199 --- /dev/null +++ b/objects/enemies/lashy/lashy.tscn @@ -0,0 +1,71 @@ +[gd_scene load_steps=8 format=3 uid="uid://c8r040r4glui4"] + +[ext_resource type="Script" 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" path="res://scripts/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"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_woon5"] +resource_local_to_scene = true +radius = 64.0 + +[sub_resource type="CircleShape2D" id="CircleShape2D_g5iss"] +radius = 6.0 + +[node name="Lashy" type="Node2D" node_paths=PackedStringArray("head", "head_pivot", "detector_shape")] +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") + +[node name="PlayerDetector" type="Area2D" parent="."] +collision_layer = 0 +collision_mask = 16 +monitorable = false + +[node name="DetectorShape" type="CollisionShape2D" parent="PlayerDetector"] +shape = SubResource("CircleShape2D_woon5") +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")] +script = ExtResource("3_8edxw") +texture = ExtResource("4_xnkdk") +target = NodePath("../HeadPivot/Head") +segments = 2 +head_segment = false +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) +metadata/_edit_group_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="HeadPivot/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"]