diff --git a/ManagedDoom.Maui/Game/MauiDoom.cs b/ManagedDoom.Maui/Game/MauiDoom.cs index c453ad8..f154e29 100644 --- a/ManagedDoom.Maui/Game/MauiDoom.cs +++ b/ManagedDoom.Maui/Game/MauiDoom.cs @@ -2,6 +2,7 @@ using DrawnUi.Maui.Game; using Plugin.Maui.Audio; using SKRect = SkiaSharp.SKRect; +using SkiaSharp; namespace ManagedDoom.Maui.Game; @@ -23,6 +24,12 @@ public class MauiDoom : MauiGame protected WeaponsView _uiSelectWeapon; + private const float ButtonSize = 64; // Adjust as needed + private const float ButtonSpacing = 20; + private SKColor ButtonColor = SKColors.LightGray; + private SKColor ButtonTextColor = SKColors.Black; + + public MauiDoom() { try @@ -46,48 +53,33 @@ public MauiDoom() } } - - /// - /// Normally all input goes to doom, but we want to intercept some - /// keys here so show our own UI for selecting weapons etc. - /// Will be invoked by MauiUserInput in that case - /// - /// - /// was consumed bool OnUiCommand(UiCommand command) { switch (command) { - case UiCommand.SelectWeapon: - { - if (!_uiSelectWeapon.IsVisible) - { - _uiSelectWeapon.IsVisible = true; - return true; - } - } - break; - - case UiCommand.Reset: - default: - if (_uiSelectWeapon.IsVisible) - { - _uiSelectWeapon.IsVisible = false; - return true; - } - break; + case UiCommand.SelectWeapon: + { + if (!_uiSelectWeapon.IsVisible) + { + _uiSelectWeapon.IsVisible = true; + return true; + } + } + break; + + case UiCommand.Reset: + default: + if (_uiSelectWeapon.IsVisible) + { + _uiSelectWeapon.IsVisible = false; + return true; + } + break; } return false; } - /// - /// Paint the game, invoked every frame - /// - /// - /// - /// - /// protected override void Paint(SkiaDrawingContext context, SKRect destination, float scale, object arguments) { //base.Paint(ctx, destination, scale, arguments); - will not draw background color/gradient in this case @@ -118,8 +110,59 @@ protected override void Paint(SkiaDrawingContext context, SKRect destination, fl //render custom ui var drawnChildrenCount = DrawViews(context, DrawingRect, scale);//GetDoomScale(DrawingRect, scale)); + + // Draw virtual keys + DrawVirtualKeys(context, destination, scale); + } + + private void DrawVirtualKeys(SkiaDrawingContext context, SKRect destination, float scale) + { + float buttonScale = scale; + float buttonSizeScaled = ButtonSize * buttonScale; + float spacingScaled = ButtonSpacing * buttonScale; + float margin = spacingScaled; + + float buttonRowY = destination.Bottom - buttonSizeScaled - margin; + + float leftButtonX = destination.Left + margin; + float rightButtonX = leftButtonX + buttonSizeScaled + spacingScaled; + float aButtonX = destination.Right - buttonSizeScaled - margin; + float bButtonX = aButtonX - buttonSizeScaled - spacingScaled; + + + DrawButton(context, leftButtonX, buttonRowY, buttonSizeScaled, "<", MauiKey.ArrowLeft, scale); + + DrawButton(context, rightButtonX, buttonRowY, buttonSizeScaled, ">", MauiKey.ArrowRight, scale); + + + DrawButton(context, aButtonX, buttonRowY, buttonSizeScaled, "AltRight", MauiKey.AltRight, scale); // AltRight for shoot + + DrawButton(context, bButtonX, buttonRowY, buttonSizeScaled, "Space", MauiKey.Space, scale); // Space for jump } + private void DrawButton(SkiaDrawingContext context, float x, float y, float size, string text, MauiKey key, float scale) + { + SKRect buttonRect = new SKRect(x, y - size / 2, x + size, y + size / 2); + var paint = new SKPaint + { + Color = ButtonColor, + Style = SKPaintStyle.Fill, + IsAntialias = true, + }; + + context.Canvas.DrawRoundRect(buttonRect, 10 * scale, 10 * scale, paint); + + paint.Color = ButtonTextColor; + paint.TextSize = size * 0.5f; + paint.TextAlign = SKTextAlign.Center; + float textX = buttonRect.MidX; + float textY = buttonRect.MidY + (paint.TextSize / 2) - (paint.FontMetrics.Bottom / 2); // Center vertically + + + context.Canvas.DrawText(text, textX, textY, paint); + + _input.AddVirtualKey(key, buttonRect); + } /// diff --git a/ManagedDoom.Maui/Game/MauiUserInput.cs b/ManagedDoom.Maui/Game/MauiUserInput.cs index 834a883..95c3340 100644 --- a/ManagedDoom.Maui/Game/MauiUserInput.cs +++ b/ManagedDoom.Maui/Game/MauiUserInput.cs @@ -16,6 +16,9 @@ public class MauiUserInput : IUserInput, IDisposable private Dictionary Pressed = new(); private readonly Config _config; + // Virtual button data + private Dictionary _virtualKeys = new(); + /// /// Set the status of a key, Down or Up. /// If it is an event then fire this event to Doom engine, otherwise just set the key status. @@ -32,11 +35,6 @@ public void SetKeyStatus(EventType type, DoomKey doomKey, Doom doom, EventTimest pressed = currentTime; var needTrigger = true; - //if (Pressed.TryGetValue(doomKey, out var set)) - //{ - // if (set.IsEmpty) - // needTrigger = false; - //} Pressed[doomKey] = pressed; @@ -55,132 +53,179 @@ public static DoomKey KeyToDoom(MauiKey silkKey) { switch (silkKey) { - case MauiKey.Space: return DoomKey.Space; - // case MauiKey.Apostrophe: return DoomKey.Apostrophe; - case MauiKey.Comma: return DoomKey.Comma; - case MauiKey.Minus: return DoomKey.Subtract; - case MauiKey.Period: return DoomKey.Period; - case MauiKey.Slash: return DoomKey.Slash; - case MauiKey.Numpad0: return DoomKey.Num0; - // case MauiKey.D0: return DoomKey.D0; - case MauiKey.Numpad1: return DoomKey.Num1; - case MauiKey.Numpad2: return DoomKey.Num2; - case MauiKey.Numpad3: return DoomKey.Num3; - case MauiKey.Numpad4: return DoomKey.Num4; - case MauiKey.Numpad5: return DoomKey.Num5; - case MauiKey.Numpad6: return DoomKey.Num6; - case MauiKey.Numpad7: return DoomKey.Num7; - case MauiKey.Numpad8: return DoomKey.Num8; - case MauiKey.Numpad9: return DoomKey.Num9; - case MauiKey.Semicolon: return DoomKey.Semicolon; - case MauiKey.Equal: return DoomKey.Equal; - case MauiKey.KeyA: return DoomKey.A; - case MauiKey.KeyB: return DoomKey.B; - case MauiKey.KeyC: return DoomKey.C; - case MauiKey.KeyD: return DoomKey.D; - case MauiKey.KeyE: return DoomKey.E; - case MauiKey.KeyF: return DoomKey.F; - case MauiKey.KeyG: return DoomKey.G; - case MauiKey.KeyH: return DoomKey.H; - case MauiKey.KeyI: return DoomKey.I; - case MauiKey.KeyJ: return DoomKey.J; - case MauiKey.KeyK: return DoomKey.K; - case MauiKey.KeyL: return DoomKey.L; - case MauiKey.KeyM: return DoomKey.M; - case MauiKey.KeyN: return DoomKey.N; - case MauiKey.KeyO: return DoomKey.O; - case MauiKey.KeyP: return DoomKey.P; - case MauiKey.KeyQ: return DoomKey.Q; - case MauiKey.KeyR: return DoomKey.R; - case MauiKey.KeyS: return DoomKey.S; - case MauiKey.KeyT: return DoomKey.T; - case MauiKey.KeyU: return DoomKey.U; - case MauiKey.KeyV: return DoomKey.V; - case MauiKey.KeyW: return DoomKey.W; - case MauiKey.KeyX: return DoomKey.X; - case MauiKey.KeyY: return DoomKey.Y; - case MauiKey.KeyZ: return DoomKey.Z; - case MauiKey.BracketLeft: return DoomKey.LBracket; - case MauiKey.Backslash: return DoomKey.Backslash; - case MauiKey.BracketRight: return DoomKey.RBracket; - // case MauiKey.GraveAccent: return DoomKey.GraveAccent; - // case MauiKey.World1: return DoomKey.World1; - // case MauiKey.World2: return DoomKey.World2; - case MauiKey.Escape: return DoomKey.Escape; - case MauiKey.Enter: return DoomKey.Enter; - case MauiKey.Tab: return DoomKey.Tab; - case MauiKey.Backspace: return DoomKey.Backspace; - case MauiKey.Insert: return DoomKey.Insert; - case MauiKey.Delete: return DoomKey.Delete; - case MauiKey.ArrowRight: return DoomKey.Right; - case MauiKey.ArrowLeft: return DoomKey.Left; - case MauiKey.ArrowDown: return DoomKey.Down; - case MauiKey.ArrowUp: return DoomKey.Up; - case MauiKey.PageUp: return DoomKey.PageUp; - case MauiKey.PageDown: return DoomKey.PageDown; - case MauiKey.Home: return DoomKey.Home; - case MauiKey.End: return DoomKey.End; - // case MauiKey.CapsLock: return DoomKey.CapsLock; - // case MauiKey.ScrollLock: return DoomKey.ScrollLock; - // case MauiKey.NumLock: return DoomKey.NumLock; - // case MauiKey.PrintScreen: return DoomKey.PrintScreen; - case MauiKey.Pause: return DoomKey.Pause; - case MauiKey.F1: return DoomKey.F1; - case MauiKey.F2: return DoomKey.F2; - case MauiKey.F3: return DoomKey.F3; - case MauiKey.F4: return DoomKey.F4; - case MauiKey.F5: return DoomKey.F5; - case MauiKey.F6: return DoomKey.F6; - case MauiKey.F7: return DoomKey.F7; - case MauiKey.F8: return DoomKey.F8; - case MauiKey.F9: return DoomKey.F9; - case MauiKey.F10: return DoomKey.F10; - case MauiKey.F11: return DoomKey.F11; - case MauiKey.F12: return DoomKey.F12; - //case MauiKey.F13: return DoomKey.F13; //todo? - //case MauiKey.F14: return DoomKey.F14;//todo? - //case MauiKey.F15: return DoomKey.F15;//todo? - // case MauiKey.F16: return DoomKey.F16; - // case MauiKey.F17: return DoomKey.F17; - // case MauiKey.F18: return DoomKey.F18; - // case MauiKey.F19: return DoomKey.F19; - // case MauiKey.F20: return DoomKey.F20; - // case MauiKey.F21: return DoomKey.F21; - // case MauiKey.F22: return DoomKey.F22; - // case MauiKey.F23: return DoomKey.F23; - // case MauiKey.F24: return DoomKey.F24; - // case MauiKey.F25: return DoomKey.F25; - //case MauiKey.Numpad0: return DoomKey.Numpad0; //todo check keypad insted of numpad? - //case MauiKey.Numpad1: return DoomKey.Numpad1; - //case MauiKey.Numpad2: return DoomKey.Numpad2; - //case MauiKey.Numpad3: return DoomKey.Numpad3; - //case MauiKey.Numpad4: return DoomKey.Numpad4; - //case MauiKey.Numpad5: return DoomKey.Numpad5; - //case MauiKey.Keypad6: return DoomKey.Numpad6; - //case MauiKey.Keypad7: return DoomKey.Numpad7; - //case MauiKey.Keypad8: return DoomKey.Numpad8; - //case MauiKey.Keypad9: return DoomKey.Numpad9; - // case MauiKey.KeypadDecimal: return DoomKey.Decimal; - case MauiKey.NumpadDivide: return DoomKey.Divide; - case MauiKey.NumpadMultiply: return DoomKey.Multiply; - case MauiKey.NumpadSubtract: return DoomKey.Subtract; - case MauiKey.NumpadAdd: return DoomKey.Add; - //case MauiKey.Enter return DoomKey.Enter; - //case MauiKey.Equal: return DoomKey.Equal; - case MauiKey.ShiftLeft: return DoomKey.LShift; - case MauiKey.ControlLeft: return DoomKey.LControl; - case MauiKey.AltLeft: return DoomKey.LAlt; - // case MauiKey.SuperLeft: return DoomKey.SuperLeft; - case MauiKey.ShiftRight: return DoomKey.RShift; - case MauiKey.ControlRight: return DoomKey.RControl; - case MauiKey.AltRight: return DoomKey.RAlt; - // case MauiKey.SuperRight: return DoomKey.SuperRight; - case MauiKey.ContextMenu: return DoomKey.Menu; - default: return DoomKey.Unknown; + case MauiKey.Space: + return DoomKey.Space; + case MauiKey.Comma: + return DoomKey.Comma; + case MauiKey.Minus: + return DoomKey.Subtract; + case MauiKey.Period: + return DoomKey.Period; + case MauiKey.Slash: + return DoomKey.Slash; + case MauiKey.Numpad0: + return DoomKey.Num0; + case MauiKey.Numpad1: + return DoomKey.Num1; + case MauiKey.Numpad2: + return DoomKey.Num2; + case MauiKey.Numpad3: + return DoomKey.Num3; + case MauiKey.Numpad4: + return DoomKey.Num4; + case MauiKey.Numpad5: + return DoomKey.Num5; + case MauiKey.Numpad6: + return DoomKey.Num6; + case MauiKey.Numpad7: + return DoomKey.Num7; + case MauiKey.Numpad8: + return DoomKey.Num8; + case MauiKey.Numpad9: + return DoomKey.Num9; + case MauiKey.Semicolon: + return DoomKey.Semicolon; + case MauiKey.Equal: + return DoomKey.Equal; + case MauiKey.KeyA: + return DoomKey.A; + case MauiKey.KeyB: + return DoomKey.B; + case MauiKey.KeyC: + return DoomKey.C; + case MauiKey.KeyD: + return DoomKey.D; + case MauiKey.KeyE: + return DoomKey.E; + case MauiKey.KeyF: + return DoomKey.F; + case MauiKey.KeyG: + return DoomKey.G; + case MauiKey.KeyH: + return DoomKey.H; + case MauiKey.KeyI: + return DoomKey.I; + case MauiKey.KeyJ: + return DoomKey.J; + case MauiKey.KeyK: + return DoomKey.K; + case MauiKey.KeyL: + return DoomKey.L; + case MauiKey.KeyM: + return DoomKey.M; + case MauiKey.KeyN: + return DoomKey.N; + case MauiKey.KeyO: + return DoomKey.O; + case MauiKey.KeyP: + return DoomKey.P; + case MauiKey.KeyQ: + return DoomKey.Q; + case MauiKey.KeyR: + return DoomKey.R; + case MauiKey.KeyS: + return DoomKey.S; + case MauiKey.KeyT: + return DoomKey.T; + case MauiKey.KeyU: + return DoomKey.U; + case MauiKey.KeyV: + return DoomKey.V; + case MauiKey.KeyW: + return DoomKey.W; + case MauiKey.KeyX: + return DoomKey.X; + case MauiKey.KeyY: + return DoomKey.Y; + case MauiKey.KeyZ: + return DoomKey.Z; + case MauiKey.BracketLeft: + return DoomKey.LBracket; + case MauiKey.Backslash: + return DoomKey.Backslash; + case MauiKey.BracketRight: + return DoomKey.RBracket; + case MauiKey.Escape: + return DoomKey.Escape; + case MauiKey.Enter: + return DoomKey.Enter; + case MauiKey.Tab: + return DoomKey.Tab; + case MauiKey.Backspace: + return DoomKey.Backspace; + case MauiKey.Insert: + return DoomKey.Insert; + case MauiKey.Delete: + return DoomKey.Delete; + case MauiKey.ArrowRight: + return DoomKey.Right; + case MauiKey.ArrowLeft: + return DoomKey.Left; + case MauiKey.ArrowDown: + return DoomKey.Down; + case MauiKey.ArrowUp: + return DoomKey.Up; + case MauiKey.PageUp: + return DoomKey.PageUp; + case MauiKey.PageDown: + return DoomKey.PageDown; + case MauiKey.Home: + return DoomKey.Home; + case MauiKey.End: + return DoomKey.End; + case MauiKey.Pause: + return DoomKey.Pause; + case MauiKey.F1: + return DoomKey.F1; + case MauiKey.F2: + return DoomKey.F2; + case MauiKey.F3: + return DoomKey.F3; + case MauiKey.F4: + return DoomKey.F4; + case MauiKey.F5: + return DoomKey.F5; + case MauiKey.F6: + return DoomKey.F6; + case MauiKey.F7: + return DoomKey.F7; + case MauiKey.F8: + return DoomKey.F8; + case MauiKey.F9: + return DoomKey.F9; + case MauiKey.F10: + return DoomKey.F10; + case MauiKey.F11: + return DoomKey.F11; + case MauiKey.F12: + return DoomKey.F12; + case MauiKey.NumpadDivide: + return DoomKey.Divide; + case MauiKey.NumpadMultiply: + return DoomKey.Multiply; + case MauiKey.NumpadSubtract: + return DoomKey.Subtract; + case MauiKey.NumpadAdd: + return DoomKey.Add; + case MauiKey.ShiftLeft: + return DoomKey.LShift; + case MauiKey.ControlLeft: + return DoomKey.LControl; + case MauiKey.AltLeft: + return DoomKey.LAlt; + case MauiKey.ShiftRight: + return DoomKey.RShift; + case MauiKey.ControlRight: + return DoomKey.RControl; + case MauiKey.AltRight: + return DoomKey.RAlt; + case MauiKey.ContextMenu: + return DoomKey.Menu; + default: + return DoomKey.Unknown; } } - public MauiUserInput(Config config, bool useMouse, Func callbackInputForUi) { _config = config; @@ -193,8 +238,6 @@ public MauiUserInput(Config config, bool useMouse, Func callbac _mouse = new VirtualMouse(); mouseGrabbed = false; - //todo move this to config static: - if (config.video_highresolution) { _doomViewport = new SKRect(0, 0, 400, 640); @@ -203,7 +246,6 @@ public MauiUserInput(Config config, bool useMouse, Func callbac { _doomViewport = new SKRect(0, 0, 200, 320); } - } private bool IsPressed(DoomKey key) @@ -231,8 +273,10 @@ private bool IsPressed(KeyBinding keyBinding) { foreach (var mouseButton in keyBinding.MouseButtons) { - if (mouseButton == DoomMouseButton.Mouse1 && _pressedFire.HasValue) return true; - if (mouseButton == DoomMouseButton.Mouse2 && _pressedUse.HasValue) return true; + if (mouseButton == DoomMouseButton.Mouse1 && _pressedFire.HasValue) + return true; + if (mouseButton == DoomMouseButton.Mouse2 && _pressedUse.HasValue) + return true; } } @@ -515,7 +559,7 @@ public void Dispose() private float mouseDeltaX; private float mouseDeltaY; - //we need to simulate keys to control UI Menu with touch gestures + void SetMoveLeft(bool value, Doom doom, EventTimestamp currentTime) { @@ -584,7 +628,8 @@ public void Update(Doom doom, EventTimestamp timestamp) } if (_pressedUse.Expired(timestamp, 50)) { - _pressedUse = EventTimestamp.Empty; ; //release right mouse button + _pressedUse = EventTimestamp.Empty; + ; //release right mouse button } AutoReleaseKeys(doom, timestamp); @@ -627,8 +672,6 @@ public bool ProcessGestures(SkiaGesturesParameters args, GestureEventProcessingI var velocityX = (float)(args.Event.Distance.Velocity.X / scale); var velocityY = (float)(args.Event.Distance.Velocity.Y / scale); - //Debug.WriteLine($"{args.Type} {args.Event.NumberOfTouches} {args.Event.Location.X}"); - if (args.Type == TouchActionResult.Panning) { if (args.Event.NumberOfTouches > 1) @@ -654,13 +697,11 @@ public bool ProcessGestures(SkiaGesturesParameters args, GestureEventProcessingI if (_doom.IsCapturingMouse) { - //Debug.WriteLine($"PAN ++ {distance.X} {distance.Y}"); _mouse.Position = new Vector2(_mouse.Position.X + distance.X, _mouse.Position.Y + distance.Y); } else { var velocityThreshold = 300; - bool vertical = false; //up/down keys for menu if (velocityY < -velocityThreshold) @@ -700,19 +741,6 @@ public bool ProcessGestures(SkiaGesturesParameters args, GestureEventProcessingI { _panningStartedAt = args.Event.Location; } - - //if (args.Event.NumberOfTouches == 2) // two-finger tap to USE or ESC in MENU - //{ - // if (_doom.IsCapturingMouse) - // { - // _pressedUse = currentTime; - // } - // else - // { - // SetKeyStatus(EventType.KeyDown, DoomKey.Escape, _doom, currentTime); - // } - // return true; - //} } if (args.Type == TouchActionResult.Up) @@ -723,6 +751,12 @@ public bool ProcessGestures(SkiaGesturesParameters args, GestureEventProcessingI { if (currentTime.Timestamp - _lastDownTime < 500) //tap detected { + // Check for virtual key presses + if (HandleVirtualButtonPress(args.Event.Location, currentTime)) + { + return true; // Consume the event + } + if (_doom.Game.World is { AutoMap.Visible: true }) { //close map @@ -807,15 +841,6 @@ bool IsInsideRightTopCorner(PointF point, SKRect rect) _pressedFire = currentTime; } } - //if (!avatarClicked && !weaponClicked) - //{ - // //just clicked bottom UI bar - // if (!_calbackUi.Invoke(UiCommand.Reset)) - // { - // SetKeyStatus(EventType.KeyDown, DoomKey.Escape, _doom, currentTime); - // } - //} - } else { @@ -839,6 +864,117 @@ bool IsInsideRightTopCorner(PointF point, SKRect rect) return true; } + /// + /// Checks if the touch event falls within the bounds of any virtual key and sets the key status accordingly. + /// + /// The location of the touch event. + /// The current timestamp. + /// True if a virtual key was pressed, false otherwise. + private bool HandleVirtualButtonPress(PointF touchLocation, EventTimestamp currentTime) + { + foreach (var kvp in _virtualKeys) + { + var key = kvp.Key; + var rect = kvp.Value; + + if (rect.Contains(touchLocation.X, touchLocation.Y)) + { + // Key pressed + if (key == MauiKey.Space) + { + _mouseButton1Held = true; // Set Mouse1 as Held + // Simulate Mouse1 down (fire) + SetKeyStatus(EventType.KeyDown, KeyToDoom(MauiKey.Space), _doom, currentTime); + return true; // Consume the event + } + else if (key == MauiKey.ControlLeft) + { + SetKeyStatus(EventType.KeyDown, KeyToDoom(key), _doom, currentTime); + return true; // Consume the event + } + else if (key == MauiKey.ArrowLeft) + { + _moveLeftHeld = true; + SetKeyStatus(EventType.KeyDown, KeyToDoom(key), _doom, currentTime); + return true; + } + else if (key == MauiKey.ArrowRight) + { + _moveRightHeld = true; + SetKeyStatus(EventType.KeyDown, KeyToDoom(key), _doom, currentTime); + return true; + } + else if (key == MauiKey.ArrowUp) + { + _moveUpHeld = true; + SetKeyStatus(EventType.KeyDown, KeyToDoom(key), _doom, currentTime); + return true; + } + else if (key == MauiKey.ArrowDown) + { + _moveDownHeld = true; + SetKeyStatus(EventType.KeyDown, KeyToDoom(key), _doom, currentTime); + return true; + } + } + } + + return false; // No virtual key pressed + } + private bool _moveLeftHeld = false; + private bool _moveRightHeld = false; + private bool _moveUpHeld = false; + private bool _moveDownHeld = false; + private void HandleVirtualButtonRelease(PointF touchLocation, EventTimestamp currentTime) + { + foreach (var kvp in _virtualKeys) + { + var key = kvp.Key; + var rect = kvp.Value; + + if (rect.Contains(touchLocation.X, touchLocation.Y)) + { + if (key == MauiKey.Space) + { + // Simulate Mouse1 up (fire) + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + _mouseButton1Held = false; // Reset mouse + return; + } + else if (key == MauiKey.ControlLeft) + { + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + return; + } + else if (key == MauiKey.ArrowLeft) + { + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + _moveLeftHeld = false; + return; + } + else if (key == MauiKey.ArrowRight) + { + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + _moveRightHeld = false; + return; + } + else if (key == MauiKey.ArrowUp) + { + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + _moveUpHeld = false; + return; + } + else if (key == MauiKey.ArrowDown) + { + SetKeyStatus(EventType.KeyUp, KeyToDoom(key), _doom, currentTime); + _moveDownHeld = false; + return; + } + } + } + } + + private bool _mouseButton1Held = false; public void SelectWeapon(int number) { var currentTime = new EventTimestamp(_lastFrame); @@ -870,6 +1006,16 @@ public void SetKeyStatus(EventType type, MauiKey key, Doom doom, EventTimestamp SetKeyStatus(type, KeyToDoom(key), doom, currentTime); } + /// + /// Add a virtual key's rectangle for touch detection. + /// + /// The MauiKey associated with the virtual button. + /// The SKRect representing the button's area. + public void AddVirtualKey(MauiKey key, SKRect rect) + { + _virtualKeys[key] = rect; + } + /// /// Check if we need to simulate release for keys that were pressed by touch. /// @@ -948,5 +1094,4 @@ public class VirtualMouse { public PointF Position { get; set; } } -} - +} \ No newline at end of file