2025-05-13 19:22:01 +08:00

74 lines
1.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Godot;
using System;
public partial class Joystick : Control
{
private Vector2 _startTouchPos = Vector2.Zero;
private Vector2 _currentTouchPos = Vector2.Zero;
private bool _touching = false;
[Export] public float DeadzoneRadius = 40f;
[Export] public float MaxRadius = 100f;
public override void _Ready()
{
// 设置控件最小尺寸Godot 4 使用 CustomMinimumSize
CustomMinimumSize = new Vector2(MaxRadius * 2, MaxRadius * 2);
}
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventScreenTouch touch)
{
if (touch.Pressed)
{
_touching = true;
_startTouchPos = touch.Position;
_currentTouchPos = touch.Position;
}
else
{
_touching = false;
}
}
else if (@event is InputEventScreenDrag drag && _touching)
{
_currentTouchPos = drag.Position;
}
}
public Vector2 GetDirection()
{
if (!_touching) return Vector2.Zero;
Vector2 offset = _currentTouchPos - _startTouchPos;
float distance = offset.Length();
if (distance < DeadzoneRadius) return Vector2.Zero;
float ratio = Mathf.Clamp(
(distance - DeadzoneRadius) / (MaxRadius - DeadzoneRadius),
0, 1
);
return offset.Normalized() * ratio;
}
public override void _Draw()
{
Vector2 center = new Vector2(CustomMinimumSize.X / 2, CustomMinimumSize.Y / 2);
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();
}
}