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").GetDirection(); UpdateDirectionInput(dir); } private void SetButtonTextures() { string basePath = "res://Sprites/Menus/Mobile/"; GetNode("Buttons/ButtonZ").TextureNormal = GD.Load(basePath + "ButtonZ.png"); GetNode("Buttons/ButtonX").TextureNormal = GD.Load(basePath + "ButtonX.png"); GetNode("Buttons/ButtonC").TextureNormal = GD.Load(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(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.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(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]); } } }