60 lines
1.5 KiB
C#
60 lines
1.5 KiB
C#
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 = 30f;
|
|
[Export] public float MaxRadius = 90f;
|
|
|
|
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;
|
|
if (offset.Length() < DeadzoneRadius)
|
|
return Vector2.Zero;
|
|
|
|
return offset.Normalized() * Mathf.Min(offset.Length(), MaxRadius);
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|