This commit is contained in:
WS-3917 2025-05-03 22:31:20 +08:00
parent e86575e80b
commit ee29207d71
4 changed files with 192 additions and 156 deletions

35
Objects/UI/Joystick.tscn Normal file
View File

@ -0,0 +1,35 @@
[gd_scene load_steps=3 format=3 uid="uid://joystick"]
[ext_resource type="Texture2D" path="res://Sprites/Menus/Mobile/JoystickBase.png" id=1]
[ext_resource type="Texture2D" path="res://Sprites/Menus/Mobile/JoystickHandle.png" id=2]
[node name="Joystick" type="Control" script="res://Scripts/UI/Joystick.cs"]
anchor_right = 0
anchor_bottom = 0
offset_right = 200
offset_bottom = 200
mouse_filter = 2 # Ignore mouse input
[node name="BaseCircle" type="TextureRect" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -100
offset_top = -100
offset_right = 100
offset_bottom = 100
texture = ExtResource(1)
stretch_mode = 6 # Keep aspect centered
[node name="HandleCircle" type="TextureRect" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -40
offset_top = -40
offset_right = 40
offset_bottom = 40
texture = ExtResource(2)
stretch_mode = 6 # Keep aspect centered

View File

@ -6,28 +6,6 @@
[node name="TouchControls" type="CanvasLayer"]
script = ExtResource("1_42104")
[node name="Joystick" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("2_fufkg")
[node name="OuterCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="DeadzoneCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="HandleCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="Buttons" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
@ -48,3 +26,26 @@ offset_bottom = 40.0
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="Joystick" type="Control" parent="."]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("2_fufkg")
[node name="OuterCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_top = -1.0
offset_right = 40.0
offset_bottom = 39.0
[node name="DeadzoneCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="HandleCircle" type="TextureRect" parent="Joystick"]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0

View File

@ -3,57 +3,57 @@ using System;
public partial class Joystick : Control
{
private Vector2 touchStartPos = Vector2.Zero;
private Vector2 currentPos = Vector2.Zero;
private int fingerId = -1;
private Vector2 _startTouchPos = Vector2.Zero;
private Vector2 _currentTouchPos = Vector2.Zero;
private bool _touching = false;
[Export] public float DeadzoneRadius = 40f;
[Export] public float MaxRadius = 120f;
[Export] public float DeadzoneRadius = 30f;
[Export] public float MaxRadius = 90f;
public override void _Input(InputEvent @event)
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventScreenTouch touch)
{
if (touch.Pressed && fingerId == -1 && GetGlobalRect().HasPoint(touch.Position))
if (touch.Pressed)
{
fingerId = touch.Index;
touchStartPos = touch.Position;
currentPos = touch.Position;
_touching = true;
_startTouchPos = touch.Position;
_currentTouchPos = touch.Position;
}
else if (!touch.Pressed && touch.Index == fingerId)
else
{
fingerId = -1;
currentPos = touchStartPos;
_touching = false;
}
}
else if (@event is InputEventScreenDrag drag && drag.Index == fingerId)
else if (@event is InputEventScreenDrag drag && _touching)
{
currentPos = drag.Position;
_currentTouchPos = drag.Position;
}
}
public override void _Process(double delta)
{
Vector2 localOffset = currentPos - touchStartPos;
if (localOffset.Length() > MaxRadius)
localOffset = localOffset.Normalized() * MaxRadius;
// 更新手柄图形位置
var handle = GetNode<TextureRect>("HandleCircle");
handle.Position = localOffset;
QueueRedraw();
}
public Vector2 GetDirection()
{
if (fingerId == -1)
if (!_touching) return Vector2.Zero;
Vector2 offset = _currentTouchPos - _startTouchPos;
if (offset.Length() < DeadzoneRadius)
return Vector2.Zero;
Vector2 delta = currentPos - touchStartPos;
if (delta.Length() < DeadzoneRadius)
return Vector2.Zero;
return offset.Normalized() * Mathf.Min(offset.Length(), MaxRadius);
}
return delta.Normalized();
public override void _Draw()
{
Vector2 center = new Vector2(0, 0);
Vector2 handleOffset = _touching ? (_currentTouchPos - _startTouchPos).Normalized() * Mathf.Min((_currentTouchPos - _startTouchPos).Length(), MaxRadius) : Vector2.Zero;
DrawCircle(center, MaxRadius, new Color(1, 1, 1, 1), false);
DrawCircle(center, DeadzoneRadius, new Color(1, 1, 0, 1), false);
DrawCircle(center + handleOffset, DeadzoneRadius, new Color(1, 1, 1, 0.3f), false); // 当前触点
}
public override void _Process(double delta)
{
QueueRedraw();
}
}

View File

@ -1,16 +1,16 @@
using Godot;
using System;
using Godot;
using System;
public partial class TouchControls : CanvasLayer
{
public partial class TouchControls : CanvasLayer
{
public override void _Ready()
{
// 仅在 Android 平台启用
//if (OS.GetName() != "Android")
//{
//QueueFree();
//return;
//}
if (OS.GetName() != "Android")
{
QueueFree();
return;
}
SetButtonTextures();
SetupButtonBindings();
UpdateButtonPositions(); // 设置初始位置
@ -65,8 +65,8 @@ public partial class TouchControls : CanvasLayer
var joystick = GetNode<Joystick>("Joystick");
Vector2 joyPos = new Vector2(
viewportSize.X * 0.05f, // 距左5%
viewportSize.Y * 0.85f // 距底15%
viewportSize.X * 0.20f,
viewportSize.Y * 0.75f
);
joystick.AnchorLeft = 0;
@ -107,4 +107,4 @@ public partial class TouchControls : CanvasLayer
Input.ActionRelease(actions[i]);
}
}
}
}