input.ts 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { Button } from '../shared/input';
  2. // KeyboardEvent.code is layout-independent: KeyA/KeyW are Q/Z on AZERTY.
  3. const KEYMAP: Record<string, number> = {
  4. KeyA: Button.Left,
  5. ArrowLeft: Button.Left,
  6. KeyD: Button.Right,
  7. ArrowRight: Button.Right,
  8. KeyW: Button.Jump,
  9. ArrowUp: Button.Jump,
  10. Space: Button.Jump,
  11. KeyS: Button.Down,
  12. ArrowDown: Button.Down,
  13. KeyE: Button.Special,
  14. KeyF: Button.Use,
  15. };
  16. /** Tracks keyboard/mouse state as a button bitmask plus the mouse position in screen pixels. */
  17. export class InputTracker {
  18. buttons = 0;
  19. mouseX = 0;
  20. mouseY = 0;
  21. constructor(target: HTMLElement) {
  22. window.addEventListener('keydown', (e) => {
  23. const b = KEYMAP[e.code];
  24. if (b) {
  25. this.buttons |= b;
  26. e.preventDefault();
  27. }
  28. });
  29. window.addEventListener('keyup', (e) => {
  30. const b = KEYMAP[e.code];
  31. if (b) this.buttons &= ~b;
  32. });
  33. window.addEventListener('blur', () => (this.buttons = 0));
  34. target.addEventListener('pointermove', (e) => {
  35. this.mouseX = e.clientX;
  36. this.mouseY = e.clientY;
  37. });
  38. target.addEventListener('pointerdown', (e) => {
  39. if (e.button === 0) this.buttons |= Button.Attack;
  40. if (e.button === 2) this.buttons |= Button.Special;
  41. });
  42. window.addEventListener('pointerup', (e) => {
  43. if (e.button === 0) this.buttons &= ~Button.Attack;
  44. if (e.button === 2) this.buttons &= ~Button.Special;
  45. });
  46. target.addEventListener('contextmenu', (e) => e.preventDefault());
  47. }
  48. }