From af0261ce8e2f758ca43f57f3c4b32dd0c621b268 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 1 Mar 2025 10:05:13 +0100 Subject: [PATCH] Strafing and crosshair for FSM player --- Scenes/Actors/fsm_player.tscn | 78 ++++++++++++++++++- .../Actors/PlayerCrosshairProvider.cs | 32 ++++++++ .../Actors/PlayerCrosshairProvider.cs.uid | 1 + .../Actors/PlayerHitboxSpriteProvider.cs | 35 +++++++++ .../Actors/PlayerHitboxSpriteProvider.cs.uid | 1 + Scripts/Components/FSM/Player/Active.cs | 56 ++++++------- 6 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 Scripts/Components/Actors/PlayerCrosshairProvider.cs create mode 100644 Scripts/Components/Actors/PlayerCrosshairProvider.cs.uid create mode 100644 Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs create mode 100644 Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs.uid diff --git a/Scenes/Actors/fsm_player.tscn b/Scenes/Actors/fsm_player.tscn index d9632b07..127f016d 100644 --- a/Scenes/Actors/fsm_player.tscn +++ b/Scenes/Actors/fsm_player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://c4pr2707hbeph"] +[gd_scene load_steps=21 format=3 uid="uid://c4pr2707hbeph"] [ext_resource type="Script" uid="uid://bw2hakslndaxm" path="res://Scripts/Components/FSM/PlayerStateMachine.cs" id="1_mpmil"] [ext_resource type="Script" uid="uid://chwqogny2v8t1" path="res://Scripts/Components/FSM/Player/Init.cs" id="2_i6wc8"] @@ -8,9 +8,59 @@ [ext_resource type="PackedScene" uid="uid://crry0rgk7a8sm" path="res://Scenes/Weapons/BaseWeapon.tscn" id="6_8dcio"] [ext_resource type="Script" uid="uid://bo5sgbv1t8ril" path="res://Scripts/Components/Actors/PlayerAnimationProvider.cs" id="7_pmkfo"] [ext_resource type="Script" uid="uid://dq338w2lw5phl" path="res://Scripts/Components/Actors/KeyboardInputProvider.cs" id="8_i6wc8"] +[ext_resource type="Script" uid="uid://d208gvthkstvc" path="res://Scripts/Components/Actors/PlayerCrosshairProvider.cs" id="9_s0ir4"] +[ext_resource type="Texture2D" uid="uid://cfrvb1moh857m" path="res://Sprites/Crosshair.png" id="10_8dcio"] +[ext_resource type="Script" uid="uid://3jxrxcqp3ndr" path="res://Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs" id="10_gp3hw"] +[ext_resource type="Texture2D" uid="uid://bwjrdlnysft15" path="res://Sprites/Actors/Focus_Circle.png" id="12_8dcio"] +[ext_resource type="Texture2D" uid="uid://bf37ce6jskdel" path="res://Sprites/SmallHitbox.png" id="13_pmkfo"] [sub_resource type="CircleShape2D" id="CircleShape2D_b3hxm"] +[sub_resource type="AtlasTexture" id="AtlasTexture_pmkfo"] +atlas = ExtResource("10_8dcio") +region = Rect2(0, 0, 8, 8) + +[sub_resource type="SpriteFrames" id="SpriteFrames_n5ijo"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_pmkfo") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="AtlasTexture" id="AtlasTexture_n5ijo"] +atlas = ExtResource("12_8dcio") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_igu66"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_n5ijo") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="AtlasTexture" id="AtlasTexture_igu66"] +atlas = ExtResource("13_pmkfo") +region = Rect2(0, 0, 4, 4) + +[sub_resource type="SpriteFrames" id="SpriteFrames_5qlss"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_igu66") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + [node name="FSMPlayer" type="CharacterBody2D"] collision_layer = 2 collision_mask = 97 @@ -21,10 +71,12 @@ InitialState = 1 [node name="Init" type="Node2D" parent="."] script = ExtResource("2_i6wc8") -[node name="Active" type="Node2D" parent="." node_paths=PackedStringArray("_weaponProvider", "_animationProvider", "_inputProvider")] +[node name="Active" type="Node2D" parent="." node_paths=PackedStringArray("_weaponProvider", "_animationProvider", "_crosshairProvider", "_hitboxSpriteProvider", "_inputProvider")] script = ExtResource("3_3tuio") _weaponProvider = NodePath("../WeaponProvider") _animationProvider = NodePath("../AnimationProvider") +_crosshairProvider = NodePath("../CrosshairProvider") +_hitboxSpriteProvider = NodePath("../StrafeSpriteProvider") _inputProvider = NodePath("../InputProvider") State = 1 @@ -45,3 +97,25 @@ _animatedSprite = NodePath("../AnimatedSprite2D") [node name="InputProvider" type="Node2D" parent="."] script = ExtResource("8_i6wc8") + +[node name="CrosshairProvider" type="Node2D" parent="." node_paths=PackedStringArray("AnimatedSprite")] +script = ExtResource("9_s0ir4") +AnimatedSprite = NodePath("Crosshair") +CrosshairDistance = 35.0 + +[node name="Crosshair" type="AnimatedSprite2D" parent="CrosshairProvider"] +sprite_frames = SubResource("SpriteFrames_n5ijo") + +[node name="StrafeSpriteProvider" type="Node2D" parent="." node_paths=PackedStringArray("Hitbox", "Circle")] +show_behind_parent = true +script = ExtResource("10_gp3hw") +Hitbox = NodePath("Hitbox") +Circle = NodePath("MagicCircle") + +[node name="MagicCircle" type="AnimatedSprite2D" parent="StrafeSpriteProvider"] +modulate = Color(1, 1, 1, 0.501961) +sprite_frames = SubResource("SpriteFrames_igu66") + +[node name="Hitbox" type="AnimatedSprite2D" parent="StrafeSpriteProvider"] +z_index = 2 +sprite_frames = SubResource("SpriteFrames_5qlss") diff --git a/Scripts/Components/Actors/PlayerCrosshairProvider.cs b/Scripts/Components/Actors/PlayerCrosshairProvider.cs new file mode 100644 index 00000000..8601afc9 --- /dev/null +++ b/Scripts/Components/Actors/PlayerCrosshairProvider.cs @@ -0,0 +1,32 @@ +using Godot; + +namespace Cirno.Scripts.Components.Actors; + +public partial class PlayerCrosshairProvider : Node2D +{ + [Export] + public AnimatedSprite2D AnimatedSprite { get; private set; } + + [Export] + public float CrosshairDistance { get; private set; } + + public void UpdatePosition(Vector2 facingDirection) + { + AnimatedSprite.Position = CalculateCrosshairPosition(facingDirection); + } + + private Vector2 CalculateCrosshairPosition(Vector2 facingDirection) + { + return facingDirection * CrosshairDistance; + } + + public void Show() + { + AnimatedSprite.Show(); + } + + public void Hide() + { + AnimatedSprite.Hide(); + } +} \ No newline at end of file diff --git a/Scripts/Components/Actors/PlayerCrosshairProvider.cs.uid b/Scripts/Components/Actors/PlayerCrosshairProvider.cs.uid new file mode 100644 index 00000000..18d261db --- /dev/null +++ b/Scripts/Components/Actors/PlayerCrosshairProvider.cs.uid @@ -0,0 +1 @@ +uid://d208gvthkstvc diff --git a/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs b/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs new file mode 100644 index 00000000..878d2a62 --- /dev/null +++ b/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs @@ -0,0 +1,35 @@ +using Godot; + +namespace Cirno.Scripts.Components.Actors; + +public partial class PlayerHitboxSpriteProvider : Node2D +{ + [Export] + public AnimatedSprite2D Hitbox { get; private set; } + [Export] + public AnimatedSprite2D Circle { get; private set; } + + public void SetVisibility(bool isVisible) + { + if (isVisible) + { + Show(); + } + else + { + Hide(); + } + } + + public void Show() + { + Hitbox.Show(); + Circle.Show(); + } + + public void Hide() + { + Hitbox.Hide(); + Circle.Hide(); + } +} \ No newline at end of file diff --git a/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs.uid b/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs.uid new file mode 100644 index 00000000..af4909fa --- /dev/null +++ b/Scripts/Components/Actors/PlayerHitboxSpriteProvider.cs.uid @@ -0,0 +1 @@ +uid://3jxrxcqp3ndr diff --git a/Scripts/Components/FSM/Player/Active.cs b/Scripts/Components/FSM/Player/Active.cs index 6efac96d..8fdcb566 100644 --- a/Scripts/Components/FSM/Player/Active.cs +++ b/Scripts/Components/FSM/Player/Active.cs @@ -7,24 +7,29 @@ namespace Cirno.Scripts.Components.FSM.Player; public partial class Active : PlayerFSMState { private Vector2 _movementDirection { get; set; } - private Vector2 _facingDirection { get; set; } - [Export] public Sprite2D HitboxSprite { get; set; } - - [Export] - private PlayerWeaponProvider _weaponProvider; - [Export] - private PlayerAnimationProvider _animationProvider; - - [Export] - private InputProvider _inputProvider; - - private bool _isStrafing { get; set; } - + public Vector2 FacingDirection { get; private set; } + [Export] public int Speed { get; set; } = 45; [Export] public int StrafeSpeed { get; set; } = 35; + + [ExportCategory("Providers")] + [Export] + private PlayerWeaponProvider _weaponProvider; + [Export] + private PlayerAnimationProvider _animationProvider; + [Export] + private PlayerCrosshairProvider _crosshairProvider; + [Export] private PlayerHitboxSpriteProvider _hitboxSpriteProvider; + + [Export] + private InputProvider _inputProvider; + + private bool _isStrafing; + + public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed; @@ -42,12 +47,14 @@ public partial class Active : PlayerFSMState { // enable sprite // enable crosshair - GD.Print(this.State.ToString()); + _crosshairProvider.Show(); } public override void ExitState() { _animationProvider.SetAnimation(Vector2.Zero); + _crosshairProvider.Hide(); + _hitboxSpriteProvider.Hide(); } public override void PhysicsProcessState(double delta) @@ -59,34 +66,31 @@ public partial class Active : PlayerFSMState public override void ProcessState(double delta) { - - - _movementDirection = _inputProvider.GetMovementInput(); + _movementDirection = _inputProvider.GetMovementInput().Normalized(); _isStrafing = _inputProvider.GetStrafePressed(); // Toggle visibility of the hitbox sprite based on strafing - if (HitboxSprite != null) - { - HitboxSprite.Visible = _isStrafing; - } - - var rightStickInput = _inputProvider.GetAimInput(); + _hitboxSpriteProvider.SetVisibility(_isStrafing); + + var rightStickInput = _inputProvider.GetAimInput().Normalized(); // Update Facing Direction if (!_isStrafing) { if (rightStickInput.Length() > 0.1f) // If the right stick is moved { - _facingDirection = rightStickInput.Normalized(); + FacingDirection = rightStickInput.Normalized(); } else if (_movementDirection != Vector2.Zero) // Fall back to movement direction { - _facingDirection = _movementDirection; + FacingDirection = _movementDirection; } } _animationProvider.SetAnimation(_stateMachine.Velocity); + _crosshairProvider.UpdatePosition(FacingDirection); + HandleShoot(); // FindInteractable(); @@ -97,7 +101,7 @@ public partial class Active : PlayerFSMState private void HandleShoot() { if (!_inputProvider.GetShootPressed()) return; - _weaponProvider.Shoot(this._facingDirection); + _weaponProvider.Shoot(this.FacingDirection); }