创建新工程
This commit is contained in:
99
scripts/VirtualJoystick.gd
Normal file
99
scripts/VirtualJoystick.gd
Normal file
@@ -0,0 +1,99 @@
|
||||
extends Control
|
||||
class_name VirtualJoystick
|
||||
## 虚拟摇杆控件
|
||||
## 用于移动端触摸输入
|
||||
|
||||
# 摇杆参数
|
||||
@export var joystick_radius: float = 50.0
|
||||
@export var stick_radius: float = 20.0
|
||||
@export var dead_zone: float = 0.2
|
||||
|
||||
# 摇杆状态
|
||||
var is_pressed: bool = false
|
||||
var touch_index: int = -1
|
||||
var stick_position: Vector2 = Vector2.ZERO
|
||||
var output_direction: Vector2 = Vector2.ZERO
|
||||
|
||||
# 视觉元素
|
||||
var base_circle: ColorRect
|
||||
var stick_circle: ColorRect
|
||||
|
||||
func _ready():
|
||||
"""初始化虚拟摇杆"""
|
||||
_create_visual_elements()
|
||||
|
||||
# 设置大小
|
||||
custom_minimum_size = Vector2(joystick_radius * 2, joystick_radius * 2)
|
||||
size = custom_minimum_size
|
||||
|
||||
func _create_visual_elements():
|
||||
"""创建摇杆的视觉元素"""
|
||||
# 创建底座
|
||||
base_circle = ColorRect.new()
|
||||
base_circle.color = Color(0.3, 0.3, 0.3, 0.5)
|
||||
base_circle.size = Vector2(joystick_radius * 2, joystick_radius * 2)
|
||||
base_circle.position = Vector2.ZERO
|
||||
add_child(base_circle)
|
||||
|
||||
# 创建摇杆
|
||||
stick_circle = ColorRect.new()
|
||||
stick_circle.color = Color(0.8, 0.8, 0.8, 0.8)
|
||||
stick_circle.size = Vector2(stick_radius * 2, stick_radius * 2)
|
||||
stick_circle.position = Vector2(joystick_radius - stick_radius, joystick_radius - stick_radius)
|
||||
add_child(stick_circle)
|
||||
|
||||
func _gui_input(event: InputEvent):
|
||||
"""处理触摸输入"""
|
||||
if event is InputEventScreenTouch:
|
||||
if event.pressed:
|
||||
# 触摸开始
|
||||
is_pressed = true
|
||||
touch_index = event.index
|
||||
_update_stick_position(event.position)
|
||||
elif event.index == touch_index:
|
||||
# 触摸结束
|
||||
is_pressed = false
|
||||
touch_index = -1
|
||||
_reset_stick()
|
||||
|
||||
elif event is InputEventScreenDrag and event.index == touch_index:
|
||||
# 触摸拖动
|
||||
_update_stick_position(event.position)
|
||||
|
||||
func _update_stick_position(touch_pos: Vector2):
|
||||
"""更新摇杆位置"""
|
||||
var center = Vector2(joystick_radius, joystick_radius)
|
||||
var offset = touch_pos - center
|
||||
|
||||
# 限制在摇杆范围内
|
||||
var max_distance = joystick_radius - stick_radius
|
||||
if offset.length() > max_distance:
|
||||
offset = offset.normalized() * max_distance
|
||||
|
||||
stick_position = offset
|
||||
|
||||
# 更新视觉位置
|
||||
stick_circle.position = center + offset - Vector2(stick_radius, stick_radius)
|
||||
|
||||
# 计算输出方向
|
||||
var normalized_offset = offset / max_distance
|
||||
if normalized_offset.length() < dead_zone:
|
||||
output_direction = Vector2.ZERO
|
||||
else:
|
||||
output_direction = normalized_offset.normalized() * ((normalized_offset.length() - dead_zone) / (1.0 - dead_zone))
|
||||
|
||||
func _reset_stick():
|
||||
"""重置摇杆到中心"""
|
||||
stick_position = Vector2.ZERO
|
||||
output_direction = Vector2.ZERO
|
||||
|
||||
var center = Vector2(joystick_radius, joystick_radius)
|
||||
stick_circle.position = center - Vector2(stick_radius, stick_radius)
|
||||
|
||||
## 获取当前方向
|
||||
func get_direction() -> Vector2:
|
||||
"""
|
||||
获取摇杆当前方向
|
||||
@return: 归一化的方向向量
|
||||
"""
|
||||
return output_direction
|
||||
Reference in New Issue
Block a user