original-touch.txt 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. ===== OLD =====
  2. private onMouseDown(event: EventMouse) {
  3. if (this.state !== 'playing') return;
  4. this.unlockAudio();
  5. this.handlePointerStart(-1, event);
  6. }
  7. ===== NEW =====
  8. private onMouseDown(event: EventMouse) {
  9. if (event.getButton() !== EventMouse.BUTTON_LEFT) return;
  10. if (this.state !== 'playing') return;
  11. this.unlockAudio();
  12. this.handlePointerStart(-1, event);
  13. }
  14. ===== OLD =====
  15. private resolveMobileActionFromEvent(event: EventTouch | EventMouse): MobileAction | null {
  16. const point = this.pointerToWorldPoint(event);
  17. if (this.spriteEllipseHit(point.x, point.y, this.touchFireSprite)) return 'fire';
  18. if (this.spriteEllipseHit(point.x, point.y, this.touchSwitchSprite)) return 'switch';
  19. return this.resolveJoystickActionFromEvent(event);
  20. }
  21. private resolveJoystickActionFromEvent(event: EventTouch | EventMouse): Extract<MobileAction, 'left' | 'right' | 'up'> | null {
  22. const point = this.pointerToWorldPoint(event);
  23. const box = this.spriteWorldBox(this.touchJoystickSprite);
  24. if (!box) return null;
  25. const rx = Math.max(1, box.width / 2);
  26. const ry = Math.max(1, box.height / 2);
  27. const nx = (point.x - box.cx) / rx;
  28. const ny = (point.y - box.cy) / ry;
  29. if (nx * nx + ny * ny > 1.12) return null;
  30. if (ny < -0.32 || (Math.abs(nx) < 0.18 && Math.abs(ny) < 0.18)) return null;
  31. if (ny > 0.30 && Math.abs(ny) >= Math.abs(nx) * 0.58) return 'up';
  32. if (nx < -0.18) return 'left';
  33. if (nx > 0.18) return 'right';
  34. return null;
  35. }
  36. private pointerToWorldPoint(event: EventTouch | EventMouse) {
  37. const location = event.getLocation();
  38. const camera = this.cameraNode.getComponent(Camera);
  39. if (!camera) return { x: location.x, y: location.y };
  40. const world = camera.screenToWorld(new Vec3(location.x, location.y, 0));
  41. return { x: world.x, y: world.y };
  42. }
  43. private spriteEllipseHit(x: number, y: number, sprite: Sprite | null) {
  44. const box = this.spriteWorldBox(sprite);
  45. if (!box) return false;
  46. const dx = (x - box.cx) / Math.max(1, box.width / 2);
  47. const dy = (y - box.cy) / Math.max(1, box.height / 2);
  48. return dx * dx + dy * dy <= 1;
  49. }
  50. private spriteWorldBox(sprite: Sprite | null) {
  51. const rect = sprite?.node.getComponent(UITransform)?.getBoundingBoxToWorld();
  52. if (!rect) return null;
  53. return {
  54. x: rect.x,
  55. y: rect.y,
  56. width: rect.width,
  57. height: rect.height,
  58. cx: rect.x + rect.width / 2,
  59. cy: rect.y + rect.height / 2
  60. };
  61. }
  62. ===== NEW =====
  63. private resolveMobileActionFromEvent(event: EventTouch | EventMouse): MobileAction | null {
  64. const point = this.pointerToGamePoint(event);
  65. if (this.controlEllipseHit(point.x, point.y, this.fireButtonCenter(), 118, 118)) return 'fire';
  66. if (this.controlEllipseHit(point.x, point.y, this.switchButtonCenter(), 90, 90)) return 'switch';
  67. return this.resolveJoystickActionAt(point.x, point.y);
  68. }
  69. private resolveJoystickActionFromEvent(event: EventTouch | EventMouse): Extract<MobileAction, 'left' | 'right' | 'up'> | null {
  70. const point = this.pointerToGamePoint(event);
  71. return this.resolveJoystickActionAt(point.x, point.y);
  72. }
  73. private resolveJoystickActionAt(x: number, y: number): Extract<MobileAction, 'left' | 'right' | 'up'> | null {
  74. const center = this.joystickCenter();
  75. const nx = (x - center.x) / 128;
  76. const ny = (y - center.y) / 128;
  77. if (nx * nx + ny * ny > 1.2) return null;
  78. if (ny < -0.28 || (Math.abs(nx) < 0.14 && Math.abs(ny) < 0.14)) return null;
  79. if (ny > 0.24 && Math.abs(ny) >= Math.abs(nx) * 0.5) return 'up';
  80. if (nx < -0.14) return 'left';
  81. if (nx > 0.14) return 'right';
  82. return null;
  83. }
  84. private pointerToGamePoint(event: EventTouch | EventMouse) {
  85. const location = event.getUILocation();
  86. const visible = view.getVisibleSize();
  87. const sourceWidth = Math.max(1, visible.width);
  88. const sourceHeight = Math.max(1, visible.height);
  89. const worldWidth = this.visibleWorldWidth();
  90. return {
  91. x: (location.x / sourceWidth - 0.5) * worldWidth,
  92. y: (location.y / sourceHeight - 0.5) * H
  93. };
  94. }
  95. private controlEllipseHit(x: number, y: number, center: { x: number; y: number }, radiusX: number, radiusY: number) {
  96. const dx = (x - center.x) / Math.max(1, radiusX);
  97. const dy = (y - center.y) / Math.max(1, radiusY);
  98. return dx * dx + dy * dy <= 1;
  99. }