private static void ApplyInput(string[] actions, float[] strengths, float duration = DT) { float frames = FPS * duration; int fullFrames = (int)frames; float lastFrameDuration = duration - fullFrames * DT; for (int i = 0; i < actions.Length; i++) { Input.ActionPress(actions[i], strengths[i]); } for (int i = 0; i < fullFrames; i++) { player._PhysicsProcess(DT); } if (lastFrameDuration > 0) { player._PhysicsProcess(lastFrameDuration); } for (int i = 0; i < actions.Length; i++) { Input.ActionRelease(actions[i]); } }
public override void _Input(InputEvent @event) { if (@event is InputEventScreenTouch || @event is InputEventScreenDrag) { Vector2 position = @event is InputEventScreenTouch ? (@event as InputEventScreenTouch).Position : (@event as InputEventScreenDrag).Position; bool released = @event is InputEventScreenTouch && !(@event as InputEventScreenTouch).Pressed; if (released) { foreach (var p in allRectangles.Zip(actionNames, (a, b) => new { Rect = a, Name = b })) { if (p.Rect.HasPoint(position)) { Input.ActionRelease(p.Name); } } if (leftRect.HasPoint(position)) { Input.ActionRelease("right"); } if (rightRect.HasPoint(position)) { Input.ActionRelease("left"); } } else if (@event is InputEventScreenDrag drag_event) { var speed = drag_event.Speed; var rel = drag_event.Relative; var old_position = drag_event.Position - drag_event.Relative; // Release action if the user lefts the button if ((leftRect.HasPoint(old_position) && !leftRect.HasPoint(position)) || (rightRect.HasPoint(old_position) && !rightRect.HasPoint(position))) { Input.ActionRelease(Input.IsActionPressed("left") ? "left" : "right"); } foreach (var p in allRectangles.Zip(actionNames, (a, b) => new { Rect = a, Name = b })) { if (p.Rect.HasPoint(old_position) && !p.Rect.HasPoint(position)) { Input.ActionRelease(p.Name); } } // If user swipes left/right too fast, left/right action can be pressed in advance if (leftRect.HasPoint(position) || rightRect.HasPoint(position)) { if (speed.x > SPEED_TOO_FAST || rel.x > REL_TOO_FAST) { Input.ActionRelease("left"); Input.ActionPress("right"); } if (speed.x < -SPEED_TOO_FAST || rel.x < -REL_TOO_FAST) { Input.ActionRelease("right"); Input.ActionPress("left"); } } // If user swipes back after this, original direction should be restored // Swiping up/down (too slow on X) should not affect this if (leftRect.HasPoint(position) && !(Input.IsActionPressed("right") && rel.x >= -REL_TOO_SLOW)) { Input.ActionRelease("right"); Input.ActionPress("left"); } if (rightRect.HasPoint(position) && !(Input.IsActionPressed("left") && rel.x <= REL_TOO_SLOW)) { Input.ActionRelease("left"); Input.ActionPress("right"); } if (downRect.HasPoint(position)) { Input.ActionPress("down"); } if (upRect.HasPoint(position)) { Input.ActionPress("up"); } } else { foreach (var p in allRectangles.Zip(actionNames, (a, b) => new { Rect = a, Name = b })) { if (p.Rect.HasPoint(position)) { Input.ActionPress(p.Name); } } } ChangeOpacity(leftUpPanel, Input.IsActionPressed("left") && Input.IsActionPressed("up")); ChangeOpacity(rightUpPanel, Input.IsActionPressed("right") && Input.IsActionPressed("up")); ChangeOpacity(leftPanel, Input.IsActionPressed("left") && !Input.IsActionPressed("up")); ChangeOpacity(rightPanel, Input.IsActionPressed("right") && !Input.IsActionPressed("up")); ChangeOpacity(downPanel, Input.IsActionPressed("down")); foreach (var p in jumpPanels.Zip(jumpActionNames, (a, b) => new { Pan = a, Name = b })) { if (p.Name == "pause") { continue; } ChangeOpacity(p.Pan, Input.IsActionPressed(p.Name)); } } }