118 lines
3.1 KiB
C#
118 lines
3.1 KiB
C#
using Godot;
|
||
using System;
|
||
|
||
public partial class TouchControls : CanvasLayer
|
||
{
|
||
public override void _Ready()
|
||
{
|
||
//if (OS.GetName() != "Android")
|
||
//{
|
||
// QueueFree();
|
||
// return;
|
||
//}
|
||
SetButtonTextures();
|
||
SetupButtonBindings();
|
||
UpdateButtonPositions();
|
||
}
|
||
|
||
public override void _Process(double delta)
|
||
{
|
||
Vector2 dir = GetNode<Joystick>("Joystick").GetDirection();
|
||
UpdateDirectionInput(dir);
|
||
}
|
||
|
||
private void SetButtonTextures()
|
||
{
|
||
string basePath = "res://Sprites/Menus/Mobile/";
|
||
GetNode<TextureButton>("Buttons/ButtonZ").TextureNormal = GD.Load<Texture2D>(basePath + "ButtonZ.png");
|
||
GetNode<TextureButton>("Buttons/ButtonX").TextureNormal = GD.Load<Texture2D>(basePath + "ButtonX.png");
|
||
GetNode<TextureButton>("Buttons/ButtonC").TextureNormal = GD.Load<Texture2D>(basePath + "ButtonC.png");
|
||
}
|
||
|
||
private void SetupButtonBindings()
|
||
{
|
||
BindButton("Buttons/ButtonZ", "Confirm");
|
||
BindButton("Buttons/ButtonX", "Cancel");
|
||
BindButton("Buttons/ButtonC", "Menu");
|
||
}
|
||
|
||
private void BindButton(string path, string actionName)
|
||
{
|
||
var button = GetNode<TextureButton>(path);
|
||
button.SelfModulate = new Color(1, 1, 1, 0.5f); // 使用 SelfModulate 替代 Modulate,适配所有主题
|
||
|
||
button.Connect("pressed", Callable.From(() =>
|
||
{
|
||
Input.ActionPress(actionName);
|
||
button.SelfModulate = new Color(1.3f, 1.3f, 1.3f, 1f); // 加亮并全不透明
|
||
}));
|
||
|
||
button.Connect("button_up", Callable.From(() =>
|
||
{
|
||
Input.ActionRelease(actionName);
|
||
button.SelfModulate = new Color(1, 1, 1, 0.5f); // 半透明恢复
|
||
}));
|
||
}
|
||
|
||
|
||
private void UpdateButtonPositions()
|
||
{
|
||
Vector2 viewportSize = GetViewport().GetVisibleRect().Size;
|
||
|
||
SetButtonPosition("Buttons/ButtonZ", viewportSize, new Vector2(0.35f, 0.20f));
|
||
SetButtonPosition("Buttons/ButtonX", viewportSize, new Vector2(0.25f, 0.35f));
|
||
SetButtonPosition("Buttons/ButtonC", viewportSize, new Vector2(0.15f, 0.50f));
|
||
|
||
var joystick = GetNode<Joystick>("Joystick");
|
||
joystick.AnchorLeft = 0.0f;
|
||
joystick.AnchorRight = 0.0f;
|
||
joystick.AnchorTop = 1.0f;
|
||
joystick.AnchorBottom = 1.0f;
|
||
joystick.Position = new Vector2(0, 280); // 向右和向上偏移一些像素
|
||
|
||
}
|
||
|
||
private void SetButtonPosition(string path, Vector2 viewportSize, Vector2 offsetPercent)
|
||
{
|
||
var button = GetNode<TextureButton>(path);
|
||
Vector2 finalPosition = new Vector2(
|
||
viewportSize.X * (1 - offsetPercent.X),
|
||
viewportSize.Y * (1 - offsetPercent.Y)
|
||
);
|
||
|
||
button.AnchorRight = 1;
|
||
button.AnchorBottom = 1;
|
||
button.AnchorLeft = 1;
|
||
button.AnchorTop = 1;
|
||
button.Position = finalPosition;
|
||
}
|
||
|
||
private void UpdateDirectionInput(Vector2 dir)
|
||
{
|
||
string[] actions = { "Left", "Right", "Up", "Down" };
|
||
Vector2[] vectors = { Vector2.Left, Vector2.Right, Vector2.Up, Vector2.Down };
|
||
const float thresholdDot = 0.7f;
|
||
|
||
int selectedIndex = -1;
|
||
float maxDot = -Mathf.Inf;
|
||
|
||
for (int i = 0; i < actions.Length; i++)
|
||
{
|
||
float dot = dir.Dot(vectors[i]);
|
||
if (dot > maxDot && dot > thresholdDot)
|
||
{
|
||
maxDot = dot;
|
||
selectedIndex = i;
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < actions.Length; i++)
|
||
{
|
||
if (i == selectedIndex)
|
||
Input.ActionPress(actions[i]);
|
||
else
|
||
Input.ActionRelease(actions[i]);
|
||
}
|
||
}
|
||
}
|