canvasengine 1.3.0 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/package.json +51 -17
  2. package/src/components/Canvas.ts +134 -0
  3. package/src/components/Container.ts +46 -0
  4. package/src/components/DisplayObject.ts +458 -0
  5. package/src/components/DrawMap/index.ts +65 -0
  6. package/src/components/Graphic.ts +147 -0
  7. package/src/components/NineSliceSprite.ts +46 -0
  8. package/src/components/ParticleEmitter.ts +39 -0
  9. package/src/components/Scene.ts +6 -0
  10. package/src/components/Sprite.ts +493 -0
  11. package/src/components/Text.ts +145 -0
  12. package/src/components/Tilemap/Tile.ts +79 -0
  13. package/src/components/Tilemap/TileGroup.ts +207 -0
  14. package/src/components/Tilemap/TileLayer.ts +163 -0
  15. package/src/components/Tilemap/TileSet.ts +41 -0
  16. package/src/components/Tilemap/index.ts +80 -0
  17. package/src/components/TilingSprite.ts +39 -0
  18. package/src/components/Viewport.ts +159 -0
  19. package/src/components/index.ts +13 -0
  20. package/src/components/types/DisplayObject.ts +69 -0
  21. package/src/components/types/MouseEvent.ts +3 -0
  22. package/src/components/types/Spritesheet.ts +389 -0
  23. package/src/components/types/index.ts +4 -0
  24. package/src/directives/Drag.ts +84 -0
  25. package/src/directives/KeyboardControls.ts +922 -0
  26. package/src/directives/Scheduler.ts +101 -0
  27. package/src/directives/Sound.ts +91 -0
  28. package/src/directives/Transition.ts +45 -0
  29. package/src/directives/ViewportCull.ts +40 -0
  30. package/src/directives/ViewportFollow.ts +26 -0
  31. package/src/directives/index.ts +7 -0
  32. package/src/engine/animation.ts +113 -0
  33. package/src/engine/bootstrap.ts +19 -0
  34. package/src/engine/directive.ts +23 -0
  35. package/src/engine/reactive.ts +379 -0
  36. package/src/engine/signal.ts +138 -0
  37. package/src/engine/trigger.ts +40 -0
  38. package/src/engine/utils.ts +135 -0
  39. package/src/hooks/addContext.ts +6 -0
  40. package/src/hooks/useProps.ts +155 -0
  41. package/src/hooks/useRef.ts +21 -0
  42. package/src/index.ts +13 -0
  43. package/src/utils/Ease.ts +33 -0
  44. package/src/utils/RadialGradient.ts +86 -0
  45. package/.gitattributes +0 -22
  46. package/.npmignore +0 -163
  47. package/canvasengine-1.3.0.all.min.js +0 -21
  48. package/canvasengine.js +0 -5802
  49. package/core/DB.js +0 -24
  50. package/core/ModelServer.js +0 -348
  51. package/core/Users.js +0 -190
  52. package/core/engine-common.js +0 -952
  53. package/doc/cocoonjs.md +0 -36
  54. package/doc/doc-lang.yml +0 -43
  55. package/doc/doc-router.yml +0 -14
  56. package/doc/doc-tuto.yml +0 -9
  57. package/doc/doc.yml +0 -39
  58. package/doc/element.md +0 -37
  59. package/doc/entity.md +0 -90
  60. package/doc/extend.md +0 -47
  61. package/doc/get_started.md +0 -19
  62. package/doc/images/entity.png +0 -0
  63. package/doc/multitouch.md +0 -58
  64. package/doc/nodejs.md +0 -142
  65. package/doc/scene.md +0 -44
  66. package/doc/text.md +0 -156
  67. package/examples/server/client.html +0 -31
  68. package/examples/server/server.js +0 -16
  69. package/examples/tiled_server/client.html +0 -52
  70. package/examples/tiled_server/images/tiles_spritesheet.png +0 -0
  71. package/examples/tiled_server/server/map.json +0 -50
  72. package/examples/tiled_server/server/map.tmx +0 -16
  73. package/examples/tiled_server/server/server.js +0 -16
  74. package/extends/Animation.js +0 -910
  75. package/extends/Effect.js +0 -252
  76. package/extends/Gleed2d.js +0 -252
  77. package/extends/Hit.js +0 -1509
  78. package/extends/Input.js +0 -699
  79. package/extends/Marshal.js +0 -716
  80. package/extends/Scrolling.js +0 -388
  81. package/extends/Soundmanager2.js +0 -5466
  82. package/extends/Spritesheet.js +0 -196
  83. package/extends/Text.js +0 -366
  84. package/extends/Tiled.js +0 -403
  85. package/extends/Window.js +0 -575
  86. package/extends/gamepad.js +0 -397
  87. package/extends/socket.io.min.js +0 -2
  88. package/extends/swf/soundmanager2.swf +0 -0
  89. package/extends/swf/soundmanager2_debug.swf +0 -0
  90. package/extends/swf/soundmanager2_flash9.swf +0 -0
  91. package/extends/swf/soundmanager2_flash9_debug.swf +0 -0
  92. package/extends/swf/soundmanager2_flash_xdomain.zip +0 -0
  93. package/extends/workers/transition.js +0 -43
  94. package/index.js +0 -46
  95. package/license.txt +0 -19
  96. package/readme.md +0 -483
@@ -0,0 +1,922 @@
1
+ import { Directive, registerDirective } from "../engine/directive";
2
+ import { Element } from "../engine/reactive";
3
+ import { fps2ms } from "../engine/utils";
4
+
5
+ export enum Input {
6
+ Break = 'break',
7
+ Backspace = 'backspace',
8
+ Tab = 'tab',
9
+ Clear = 'clear',
10
+ Enter = 'enter',
11
+ Shift = 'shift',
12
+ Ctrl = 'ctrl',
13
+ Alt = 'alt',
14
+ Pause = 'pause/break',
15
+ CapsLock = 'caps lock',
16
+ Escape = 'escape',
17
+ Conversion = 'conversion',
18
+ NonConversion = 'non-conversion',
19
+ Space = 'space',
20
+ PageUp = 'page up',
21
+ PageDown = 'page down',
22
+ End = 'end',
23
+ Home = 'home',
24
+ Left = 4,
25
+ Up = 1,
26
+ Right = 2,
27
+ Down = 3,
28
+ Select = 'select',
29
+ Print = 'print',
30
+ Execute = 'execute',
31
+ PrintScreen = 'Print Screen',
32
+ Insert = 'insert',
33
+ Delete = 'delete',
34
+ Zero = '0',
35
+ One = '1',
36
+ Two = '2',
37
+ Three = '3',
38
+ Four = '4',
39
+ Five = '5',
40
+ Six = '6',
41
+ Seven = '7',
42
+ Height = '8',
43
+ Nine = '9',
44
+ Equal = '=',
45
+ Semicolon = 'semicolon (firefox), equals',
46
+ LessThan = '<',
47
+ Equals = 'equals (firefox)',
48
+ Beta = 'ß',
49
+ At = '@',
50
+ A = 'a',
51
+ B = 'b',
52
+ C = 'c',
53
+ D = 'd',
54
+ E = 'e',
55
+ F = 'f',
56
+ G = 'g',
57
+ H = 'h',
58
+ I = 'i',
59
+ J = 'j',
60
+ K = 'k',
61
+ L = 'l',
62
+ M = 'm',
63
+ N = 'n',
64
+ O = 'o',
65
+ P = 'p',
66
+ Q = 'q',
67
+ R = 'r',
68
+ S = 's',
69
+ T = 't',
70
+ U = 'u',
71
+ V = 'v',
72
+ W = 'w',
73
+ X = 'x',
74
+ Y = 'y',
75
+ Z = 'z',
76
+ SearchKey = 'Windows Key / Left ⌘ / Chromebook Search key',
77
+ NumPad0 = 'numpad 0',
78
+ NumPad1 = 'numpad 1',
79
+ NumPad2 = 'numpad 2',
80
+ NumPad3 = 'numpad 3',
81
+ NumPad4 = 'numpad 4',
82
+ NumPad5 = 'numpad 5',
83
+ NumPad6 = 'numpad 6',
84
+ NumPad7 = 'numpad 7',
85
+ NumPad8 = 'numpad 8',
86
+ NumPad9 = 'numpad 9',
87
+ Multiply = 'multiply',
88
+ Add = 'add',
89
+ Subtract = 'subtract',
90
+ DecimalPoint = 'decimal point',
91
+ Divide = 'divide',
92
+ F1 = 'f1',
93
+ F2 = 'f2',
94
+ F3 = 'f3',
95
+ F4 = 'f4',
96
+ F5 = 'f5',
97
+ F6 = 'f6',
98
+ F7 = 'f7',
99
+ F8 = 'f8',
100
+ F9 = 'f9',
101
+ F10 = 'f10',
102
+ F11 = 'f11',
103
+ F12 = 'f12',
104
+ F13 = 'f13',
105
+ F14 = 'f14',
106
+ F15 = 'f15',
107
+ F16 = 'f16',
108
+ F17 = 'f17',
109
+ F18 = 'f18',
110
+ F19 = 'f19',
111
+ F20 = 'f20',
112
+ F21 = 'f21',
113
+ F22 = 'f22',
114
+ F23 = 'f23',
115
+ F24 = 'f24',
116
+ NumLock = 'num lock',
117
+ ScrollLock = 'scroll lock',
118
+ CircumflexAccent = '^',
119
+ ExclamationMark = '!',
120
+ Hash = '#',
121
+ Dollar = '$',
122
+ AccentU = 'ù',
123
+ PageBackward = 'page backward',
124
+ PageForWard = 'page forward',
125
+ Star = '*',
126
+ DecreaseVolume = 'decrease volume level',
127
+ IncreaseVolume = 'increase volume level',
128
+ Next = 'next',
129
+ Previous = 'previous',
130
+ Stop = 'stop',
131
+ PlayPause = 'play/pause',
132
+ Email = 'e-mail',
133
+ SemiColon = 'semi-colon / ñ',
134
+ EqualSign = 'equal sign',
135
+ Comma = 'comma',
136
+ Dash = 'dash',
137
+ FowardSlach = 'forward slash / ç',
138
+ GraveAccent = 'grave accent / ñ / æ',
139
+ OpenBracket = 'open bracket',
140
+ BackSlach = 'back slash',
141
+ CloseBracket = 'close bracket / å',
142
+ SingleQuote = 'single quote / ø',
143
+ BackQuote = '`',
144
+ Altgr = 'altgr'
145
+ }
146
+
147
+ export interface ControlOptions {
148
+ repeat?: boolean;
149
+ bind: string | string[];
150
+ keyUp?: Function;
151
+ keyDown?: Function;
152
+ delay?: number | {
153
+ duration: number;
154
+ otherControls?: (string)[];
155
+ };
156
+ }
157
+ export interface Controls {
158
+ [controlName: string]: ControlOptions;
159
+ }
160
+
161
+ // keyboard handling
162
+ const keyCodeTable = {
163
+ 3: 'break',
164
+ 8: 'backspace', // backspace / delete
165
+ 9: 'tab',
166
+ 12: 'clear',
167
+ 13: 'enter',
168
+ 16: 'shift',
169
+ 17: 'ctrl',
170
+ 18: 'alt',
171
+ 19: 'pause/break',
172
+ 20: 'caps lock',
173
+ 27: 'escape',
174
+ 28: 'conversion',
175
+ 29: 'non-conversion',
176
+ 32: 'space',
177
+ 33: 'page up',
178
+ 34: 'page down',
179
+ 35: 'end',
180
+ 36: 'home',
181
+ 37: 'left',
182
+ 38: 'up',
183
+ 39: 'right',
184
+ 40: 'down',
185
+ 41: 'select',
186
+ 42: 'print',
187
+ 43: 'execute',
188
+ 44: 'Print Screen',
189
+ 45: 'insert',
190
+ 46: 'delete',
191
+ 48: 'n0',
192
+ 49: 'n1',
193
+ 50: 'n2',
194
+ 51: 'n3',
195
+ 52: 'n4',
196
+ 53: 'n5',
197
+ 54: 'n6',
198
+ 55: 'n7',
199
+ 56: 'n8',
200
+ 57: 'n9',
201
+ 58: ':',
202
+ 59: 'semicolon (firefox), equals',
203
+ 60: '<',
204
+ 61: 'equals (firefox)',
205
+ 63: 'ß',
206
+ 64: '@',
207
+ 65: 'a',
208
+ 66: 'b',
209
+ 67: 'c',
210
+ 68: 'd',
211
+ 69: 'e',
212
+ 70: 'f',
213
+ 71: 'g',
214
+ 72: 'h',
215
+ 73: 'i',
216
+ 74: 'j',
217
+ 75: 'k',
218
+ 76: 'l',
219
+ 77: 'm',
220
+ 78: 'n',
221
+ 79: 'o',
222
+ 80: 'p',
223
+ 81: 'q',
224
+ 82: 'r',
225
+ 83: 's',
226
+ 84: 't',
227
+ 85: 'u',
228
+ 86: 'v',
229
+ 87: 'w',
230
+ 88: 'x',
231
+ 89: 'y',
232
+ 90: 'z',
233
+ 91: 'Windows Key / Left ⌘ / Chromebook Search key',
234
+ 92: 'right window key',
235
+ 93: 'Windows Menu / Right ⌘',
236
+ 96: 'numpad 0',
237
+ 97: 'numpad 1',
238
+ 98: 'numpad 2',
239
+ 99: 'numpad 3',
240
+ 100: 'numpad 4',
241
+ 101: 'numpad 5',
242
+ 102: 'numpad 6',
243
+ 103: 'numpad 7',
244
+ 104: 'numpad 8',
245
+ 105: 'numpad 9',
246
+ 106: 'multiply',
247
+ 107: 'add',
248
+ 108: 'numpad period (firefox)',
249
+ 109: 'subtract',
250
+ 110: 'decimal point',
251
+ 111: 'divide',
252
+ 112: 'f1',
253
+ 113: 'f2',
254
+ 114: 'f3',
255
+ 115: 'f4',
256
+ 116: 'f5',
257
+ 117: 'f6',
258
+ 118: 'f7',
259
+ 119: 'f8',
260
+ 120: 'f9',
261
+ 121: 'f10',
262
+ 122: 'f11',
263
+ 123: 'f12',
264
+ 124: 'f13',
265
+ 125: 'f14',
266
+ 126: 'f15',
267
+ 127: 'f16',
268
+ 128: 'f17',
269
+ 129: 'f18',
270
+ 130: 'f19',
271
+ 131: 'f20',
272
+ 132: 'f21',
273
+ 133: 'f22',
274
+ 134: 'f23',
275
+ 135: 'f24',
276
+ 144: 'num lock',
277
+ 145: 'scroll lock',
278
+ 160: '^',
279
+ 161: '!',
280
+ 163: '#',
281
+ 164: '$',
282
+ 165: 'ù',
283
+ 166: 'page backward',
284
+ 167: 'page forward',
285
+ 169: 'closing paren (AZERTY)',
286
+ 170: '*',
287
+ 171: '~ + * key',
288
+ 173: 'minus (firefox), mute/unmute',
289
+ 174: 'decrease volume level',
290
+ 175: 'increase volume level',
291
+ 176: 'next',
292
+ 177: 'previous',
293
+ 178: 'stop',
294
+ 179: 'play/pause',
295
+ 180: 'e-mail',
296
+ 181: 'mute/unmute (firefox)',
297
+ 182: 'decrease volume level (firefox)',
298
+ 183: 'increase volume level (firefox)',
299
+ 186: 'semi-colon / ñ',
300
+ 187: 'equal sign',
301
+ 188: 'comma',
302
+ 189: 'dash',
303
+ 190: 'period',
304
+ 191: 'forward slash / ç',
305
+ 192: 'grave accent / ñ / æ',
306
+ 193: '?, / or °',
307
+ 194: 'numpad period (chrome)',
308
+ 219: 'open bracket',
309
+ 220: 'back slash',
310
+ 221: 'close bracket / å',
311
+ 222: 'single quote / ø',
312
+ 223: '`',
313
+ 224: 'left or right ⌘ key (firefox)',
314
+ 225: 'altgr',
315
+ 226: '< /git >',
316
+ 230: 'GNOME Compose Key',
317
+ 231: 'ç',
318
+ 233: 'XF86Forward',
319
+ 234: 'XF86Back',
320
+ 240: 'alphanumeric',
321
+ 242: 'hiragana/katakana',
322
+ 243: 'half-width/full-width',
323
+ 244: 'kanji',
324
+ 255: 'toggle touchpad'
325
+ };
326
+
327
+ const inverse = (obj) => {
328
+ const newObj = {}
329
+ for (let key in obj) {
330
+ const val = obj[key]
331
+ newObj[val] = key
332
+ }
333
+ return newObj
334
+ }
335
+
336
+ const inverseKeyCodeTable = inverse(keyCodeTable)
337
+
338
+ type BoundKey = { actionName: string, options: ControlOptions, parameters?: any }
339
+
340
+ export class KeyboardControls extends Directive {
341
+ private keyState: {
342
+ [keyName: string]: {
343
+ isDown: boolean,
344
+ count: number
345
+ } | null
346
+ } = {}
347
+ private boundKeys: {
348
+ [keyName: string]: BoundKey
349
+ } = {}
350
+ private stop: boolean = false
351
+ private lastKeyPressed: number | null = null
352
+ private _controlsOptions: Controls = {}
353
+ private interval: any
354
+ // TODO: This should be dynamic
355
+ private serverFps: number = 60
356
+ private directionState: {
357
+ up: boolean,
358
+ down: boolean,
359
+ left: boolean,
360
+ right: boolean
361
+ } = {
362
+ up: false,
363
+ down: false,
364
+ left: false,
365
+ right: false
366
+ };
367
+
368
+ onInit(element: Element) {
369
+ this.setupListeners();
370
+ this.setInputs(element.props.controls.value)
371
+ // The processing is outside the rendering loop because if the FPS are lower (or higher) then the sending to the server would be slower or faster. Here it is constant
372
+ this.interval = setInterval(() => {
373
+ this.preStep()
374
+ }, fps2ms(this.serverFps ?? 60))
375
+ }
376
+
377
+ onMount(element: Element) {}
378
+
379
+ onUpdate(props) {
380
+ this.setInputs(props)
381
+ }
382
+
383
+ onDestroy() {
384
+ clearInterval(this.interval)
385
+ document.removeEventListener('keydown', (e) => { this.onKeyChange(e, true); });
386
+ document.removeEventListener('keyup', (e) => { this.onKeyChange(e, false); });
387
+ }
388
+
389
+ /** @internal */
390
+ preStep() {
391
+ if (this.stop) return;
392
+
393
+ const direction = this.getDirection();
394
+ if (direction !== 'none') {
395
+ // Trigger only the composite direction
396
+ const directionControl = this.boundKeys[direction];
397
+ if (directionControl) {
398
+ const { keyDown } = directionControl.options;
399
+ if (keyDown ) {
400
+ this.applyInput(direction);
401
+ }
402
+ }
403
+ } else {
404
+ // Process other controls as before
405
+ const boundKeys = Object.keys(this.boundKeys);
406
+ for (let keyName of boundKeys) {
407
+ this.applyInput(keyName);
408
+ }
409
+ }
410
+ }
411
+
412
+ private applyInput(keyName: string) {
413
+ const keyState = this.keyState[keyName];
414
+ if (!keyState) return;
415
+ const { isDown, count } = keyState;
416
+ if (isDown) {
417
+ const { repeat, keyDown } = this.boundKeys[keyName].options;
418
+ if ((repeat || count == 0)) {
419
+ let parameters = this.boundKeys[keyName].parameters;
420
+ if (typeof parameters === "function") {
421
+ parameters = parameters();
422
+ }
423
+ if (keyDown) {
424
+ keyDown(this.boundKeys[keyName]);
425
+ }
426
+ this.keyState[keyName]!.count++;
427
+ }
428
+ }
429
+ }
430
+
431
+ private setupListeners() {
432
+ document.addEventListener('keydown', (e) => { this.onKeyChange(e, true); });
433
+ document.addEventListener('keyup', (e) => { this.onKeyChange(e, false); });
434
+ }
435
+
436
+ private bindKey(keys: Input | Input[], actionName: string, options: ControlOptions, parameters?: object) {
437
+ if (!Array.isArray(keys)) keys = [keys] as Input[]
438
+ const keyOptions = Object.assign({
439
+ repeat: false
440
+ }, options);
441
+ (keys as Input[]).forEach(keyName => {
442
+ this.boundKeys[keyName] = { actionName, options: keyOptions, parameters }
443
+ })
444
+ }
445
+
446
+ private applyKeyDown(name: string) {
447
+ const code = inverseKeyCodeTable[name]
448
+ const e: any = new Event('keydown')
449
+ e.keyCode = code
450
+ this.onKeyChange(e, true)
451
+ }
452
+
453
+ private applyKeyUp(name: string) {
454
+ const code = inverseKeyCodeTable[name]
455
+ const e: any = new Event('keyup')
456
+ e.keyCode = code
457
+ this.onKeyChange(e, false)
458
+ }
459
+
460
+ private applyKeyPress(name: string): Promise<void> {
461
+ return new Promise((resolve: any) => {
462
+ this.applyKeyDown(name)
463
+ setTimeout(() => {
464
+ this.applyKeyUp(name)
465
+ resolve()
466
+ }, 200)
467
+ })
468
+ }
469
+
470
+ private onKeyChange(e: KeyboardEvent, isDown: boolean) {
471
+ e = (e || window.event) as KeyboardEvent;
472
+
473
+ const keyName: string = keyCodeTable[e.keyCode];
474
+
475
+ if (keyName && this.boundKeys[keyName]) {
476
+ if (this.keyState[keyName] == null) {
477
+ this.keyState[keyName] = {
478
+ count: 0,
479
+ isDown: true
480
+ };
481
+ }
482
+ this.keyState[keyName]!.isDown = isDown;
483
+
484
+ // key up, reset press count
485
+ if (!isDown) {
486
+ this.keyState[keyName]!.count = 0
487
+ const { keyUp } = this.boundKeys[keyName].options
488
+ if (keyUp) {
489
+ keyUp(this.boundKeys[keyName]);
490
+ }
491
+ }
492
+
493
+ // keep reference to the last key pressed to avoid duplicates
494
+ this.lastKeyPressed = isDown ? e.keyCode : null;
495
+ }
496
+
497
+ if (keyName) {
498
+ this.updateDirectionState(keyName, isDown);
499
+ }
500
+ }
501
+
502
+ private updateDirectionState(keyName: string, isDown: boolean) {
503
+ switch (keyName) {
504
+ case 'up':
505
+ this.directionState.up = isDown;
506
+ break;
507
+ case 'down':
508
+ this.directionState.down = isDown;
509
+ break;
510
+ case 'left':
511
+ this.directionState.left = isDown;
512
+ break;
513
+ case 'right':
514
+ this.directionState.right = isDown;
515
+ break;
516
+ }
517
+ }
518
+
519
+ private getDirection(): string {
520
+ const { up, down, left, right } = this.directionState;
521
+
522
+ if (up && left) return 'up_left';
523
+ if (up && right) return 'up_right';
524
+ if (down && left) return 'down_left';
525
+ if (down && right) return 'down_right';
526
+ if (up) return 'up';
527
+ if (down) return 'down';
528
+ if (left) return 'left';
529
+ if (right) return 'right';
530
+
531
+ return 'none';
532
+ }
533
+
534
+ /**
535
+ * From the name of the entry, we retrieve the control information
536
+ *
537
+ * ```ts
538
+ * import { Input, inject, KeyboardControls } from '@rpgjs/client'
539
+ *
540
+ * const controls = inject(KeyboardControls)
541
+ * controls.getControl(Input.Enter)
542
+
543
+ * if (control) {
544
+ * console.log(control.actionName) // action
545
+ * }
546
+ * ```
547
+ * @title Get Control
548
+ * @method getControl(inputName)
549
+ * @param {string} inputName
550
+ * @returns { { actionName: string, options: any } | undefined }
551
+ * @memberof KeyboardControls
552
+ */
553
+ getControl(inputName: string): BoundKey | undefined {
554
+ return this.boundKeys[inputName]
555
+ }
556
+
557
+ /**
558
+ * Returns all controls
559
+ *
560
+ * @method getControls()
561
+ * @since 4.2.0
562
+ * @returns { { [key: string]: BoundKey } }
563
+ * @memberof KeyboardControls
564
+ */
565
+ getControls(): { [key: string]: BoundKey } {
566
+ return this.boundKeys
567
+ }
568
+
569
+ /**
570
+ * Triggers an input according to the name of the control
571
+ *
572
+ * ```ts
573
+ * import { Control, inject, KeyboardControls } from '@rpgjs/client'
574
+ *
575
+ * const controls = inject(KeyboardControls)
576
+ * controls.applyControl(Control.Action)
577
+ * ```
578
+ *
579
+ * You can put a second parameter or indicate on whether the key is pressed or released
580
+ *
581
+ * ```ts
582
+ * import { Control, inject, KeyboardControls } from '@rpgjs/client'
583
+ *
584
+ * const controls = inject(KeyboardControls)
585
+ * controls.applyControl(Control.Up, true) // keydown
586
+ * controls.applyControl(Control.Up, false) // keyup
587
+ * ```
588
+ * @title Apply Control
589
+ * @method applyControl(controlName,isDown)
590
+ * @param {string} controlName
591
+ * @param {boolean} [isDown]
592
+ * @returns {Promise<void>}
593
+ * @memberof KeyboardControls
594
+ */
595
+ async applyControl(controlName: string | number, isDown?: boolean | undefined): Promise<void> {
596
+ const control = this._controlsOptions[controlName]
597
+ if (control) {
598
+ const input = Array.isArray(control.bind) ? control.bind[0] : control.bind
599
+ if (isDown === undefined) {
600
+ await this.applyKeyPress(input as string)
601
+ }
602
+ else if (isDown) {
603
+ this.applyKeyDown(input as string)
604
+ }
605
+ else {
606
+ this.applyKeyUp(input as string)
607
+ }
608
+ }
609
+ }
610
+
611
+ /**
612
+ * Stop listening to the inputs. Pressing a key won't do anything
613
+ *
614
+ * @title Stop Inputs
615
+ * @method stopInputs()
616
+ * @returns {void}
617
+ * @memberof KeyboardControls
618
+ */
619
+ stopInputs() {
620
+ this.stop = true
621
+ }
622
+
623
+ /**
624
+ * Listen to the inputs again
625
+ *
626
+ * @title Listen Inputs
627
+ * @method listenInputs()
628
+ * @returns {void}
629
+ * @memberof KeyboardControls
630
+ */
631
+ listenInputs() {
632
+ this.stop = false
633
+ this.keyState = {}
634
+ }
635
+
636
+ /**
637
+ * Assign custom inputs to the scene
638
+ *
639
+ * The object is the following:
640
+ *
641
+ * * the key of the object is the name of the control. Either it is existing controls (Up, Dow, Left, Right, Action, Back) or customized controls
642
+ * * The value is an object representing control information:
643
+ * * repeat {boolean} The key can be held down to repeat the action. (false by default)
644
+ * * bind {string | string[]} To which key is linked the control
645
+ * * method {Function} Function to be triggered. If you do not set this property, the name of the control is sent directly to the server.
646
+ * * delay {object|number} (since v3.2.0) Indicates how long (in milliseconds) the player can press the key again to perform the action
647
+ * * delay.duration
648
+ * * delay.otherControls {string | string[]} Indicates the other controls that will also have the delay at the same time
649
+ *
650
+ * ```ts
651
+ * import { Control, Input, inject, KeyboardControls } from '@rpgjs/client'
652
+ *
653
+ * const controls = inject(KeyboardControls)
654
+ * controls.setInputs({
655
+ [Control.Up]: {
656
+ repeat: true,
657
+ bind: Input.Up
658
+ },
659
+ [Control.Down]: {
660
+ repeat: true,
661
+ bind: Input.Down
662
+ },
663
+ [Control.Right]: {
664
+ repeat: true,
665
+ bind: Input.Right
666
+ },
667
+ [Control.Left]: {
668
+ repeat: true,
669
+ bind: Input.Left
670
+ },
671
+ [Control.Action]: {
672
+ bind: [Input.Space, Input.Enter]
673
+ },
674
+ [Control.Back]: {
675
+ bind: Input.Escape
676
+ },
677
+
678
+ // The myscustom1 control is sent to the server when the A key is pressed.
679
+ mycustom1: {
680
+ bind: Input.A
681
+ },
682
+
683
+ // the myAction method is executed when the B key is pressed
684
+ mycustom2: {
685
+ bind: Input.B,
686
+ method({ actionName }) {
687
+ console.log('cool', actionName)
688
+ }
689
+ },
690
+
691
+ // The player can redo the action after 400ms
692
+ mycustom3: {
693
+ bind: Input.C,
694
+ delay: 400 // ms
695
+ },
696
+
697
+ // The player can redo the action (mycustom4) and the directions after 400ms
698
+ mycustom4: {
699
+ bind: Input.C,
700
+ delay: {
701
+ duration: 400,
702
+ otherControls: [Control.Up, Control.Down, Control.Left, Control.Right]
703
+ }
704
+ }
705
+ })
706
+ *
707
+ * ```
708
+ * @enum {string} Control
709
+ *
710
+ * Control.Up | up
711
+ * Control.Down | down
712
+ * Control.Left | left
713
+ * Control.Right | right
714
+ * Control.Action | action
715
+ * Control.Back | back
716
+ *
717
+ * @enum {string} Mouse Event
718
+ *
719
+ * click | Click
720
+ * dblclick | Double Click
721
+ * mousedown | Mouse Down
722
+ * mouseup | Mouse Up
723
+ * mouseover | Mouse Over
724
+ * mousemove | Mouse Move
725
+ * mouseout | Mouse Out
726
+ * contextmenu | Context Menu
727
+ *
728
+ *
729
+ * @enum {string} Input
730
+ *
731
+ * break | Pause
732
+ * backspace | Backspace / Delete
733
+ * tab | Tab
734
+ * clear | Clear
735
+ * enter | Enter
736
+ * shift | Shift
737
+ * ctrl | Control
738
+ * alt | Alt
739
+ * pause/break | Pause / Break
740
+ * caps lock | Caps Lock
741
+ * escape | Escape
742
+ * conversion | Conversion
743
+ * non-conversion | Non-conversion
744
+ * space | Space
745
+ * page up | Page Up
746
+ * page down | Page Down
747
+ * end | End
748
+ * home | Home
749
+ * left | Left Arrow
750
+ * up | Up Arrow
751
+ * right | Right Arrow
752
+ * down | Down Arrow
753
+ * select | Select
754
+ * print | Print
755
+ * execute | Execute
756
+ * Print Screen | Print Screen
757
+ * insert | Insert
758
+ * delete | Delete
759
+ * n0 | 0
760
+ * n1 | 1
761
+ * n2 | 2
762
+ * n3 | 3
763
+ * n4 | 4
764
+ * n5 | 5
765
+ * n6 | 6
766
+ * n7 | 7
767
+ * n8 | 8
768
+ * n9 | 9
769
+ * : | Colon
770
+ * semicolon (firefox), equals | Semicolon (Firefox), Equals
771
+ * < | Less Than
772
+ * equals (firefox) | Equals (Firefox)
773
+ * ß | Eszett
774
+ * @ | At
775
+ * a | A
776
+ * b | B
777
+ * c | C
778
+ * d | D
779
+ * e | E
780
+ * f | F
781
+ * g | G
782
+ * h | H
783
+ * i | I
784
+ * j | J
785
+ * k | K
786
+ * l | L
787
+ * m | M
788
+ * n | N
789
+ * o | O
790
+ * p | P
791
+ * q | Q
792
+ * r | R
793
+ * s | S
794
+ * t | T
795
+ * u | U
796
+ * v | V
797
+ * w | W
798
+ * x | X
799
+ * y | Y
800
+ * z | Z
801
+ * Windows Key / Left ⌘ / Chromebook Search key | Windows Key / Left Command ⌘ / Chromebook Search Key
802
+ * right window key | Right Windows Key
803
+ * Windows Menu / Right ⌘ | Windows Menu / Right Command ⌘
804
+ * numpad 0 | Numpad 0
805
+ * numpad 1 | Numpad 1
806
+ * numpad 2 | Numpad 2
807
+ * numpad 3 | Numpad 3
808
+ * numpad 4 | Numpad 4
809
+ * numpad 5 | Numpad 5
810
+ * numpad 6 | Numpad 6
811
+ * numpad 7 | Numpad 7
812
+ * numpad 8 | Numpad 8
813
+ * numpad 9 | Numpad 9
814
+ * multiply | Multiply
815
+ * add | Add
816
+ * numpad period (firefox) | Numpad Period (Firefox)
817
+ * subtract | Subtract
818
+ * decimal point | Decimal Point
819
+ * divide | Divide
820
+ * f1 | F1
821
+ * f2 | F2
822
+ * f3 | F3
823
+ * f4 | F4
824
+ * f5 | F5
825
+ * f6 | F6
826
+ * f7 | F7
827
+ * f8 | F8
828
+ * f9 | F9
829
+ * f10 | F10
830
+ * f11 | F11
831
+ * f12 | F12
832
+ * f13 | F13
833
+ * f14 | F14
834
+ * f15 | F15
835
+ * f16 | F16
836
+ * f17 | F17
837
+ * f18 | F18
838
+ * f19 | F19
839
+ * f20 | F20
840
+ * f21 | F21
841
+ * f22 | F22
842
+ * f23 | F23
843
+ * f24 | F24
844
+ * num lock | Num Lock
845
+ * scroll lock | Scroll Lock
846
+ * ^ | Caret
847
+ * ! | Exclamation Point
848
+ * # | Hash
849
+ * $ | Dollar Sign
850
+ * ù | Grave Accent U
851
+ * page backward | Page Backward
852
+ * page forward | Page Forward
853
+ * closing paren (AZERTY) | Closing Parenthesis (AZERTY)
854
+ * * | Asterisk
855
+ * ~ + * key | Tilde + Asterisk Key
856
+ * minus (firefox), mute/unmute | Minus (Firefox), Mute/Unmute
857
+ * decrease volume level | Decrease Volume Level
858
+ * increase volume level | Increase Volume Level
859
+ * next | Next
860
+ * previous | Previous
861
+ * stop | Stop
862
+ * play/pause | Play/Pause
863
+ * e-mail | Email
864
+ * mute/unmute (firefox) | Mute/Unmute (Firefox)
865
+ * decrease volume level (firefox) | Decrease Volume Level (Firefox)
866
+ * increase volume level (firefox) | Increase Volume Level (Firefox)
867
+ * semi-colon / ñ | Semicolon / ñ
868
+ * equal sign | Equal Sign
869
+ * comma | Comma
870
+ * dash | Dash
871
+ * period | Period
872
+ * forward slash / ç | Forward Slash / ç
873
+ * grave accent / ñ / æ | Grave Accent / ñ / æ
874
+ * ?, / or ° | ?, / or °
875
+ * numpad period (chrome) | Numpad Period (Chrome)
876
+ * open bracket | Open Bracket
877
+ * back slash | Backslash
878
+ * close bracket / å | Close Bracket / å
879
+ * single quote / ø | Single Quote / ø
880
+ * \` | Backtick
881
+ * left or right ⌘ key (firefox) | Left or Right Command Key (Firefox)
882
+ * altgr | AltGr
883
+ * < /git > | < /git >
884
+ * GNOME Compose Key | GNOME Compose Key
885
+ * ç | ç
886
+ * XF86Forward | XF86Forward
887
+ * XF86Back | XF86Back
888
+ * alphanumeric | Alphanumeric
889
+ * hiragana/katakana | Hiragana/Katakana
890
+ * half-width/full-width | Half-Width/Full-Width
891
+ * kanji | Kanji
892
+ * toggle touchpad | Toggle Touchpad
893
+ *
894
+ * @title Set Inputs
895
+ * @method setInputs(inputs)
896
+ * @param {object} inputs
897
+ * @memberof KeyboardControls
898
+ */
899
+ setInputs(inputs: Controls) {
900
+ if (!inputs) return
901
+ this.boundKeys = {}
902
+ let inputsTransformed: any = {}
903
+ for (let control in inputs) {
904
+ const option = inputs[control]
905
+ const { bind } = option
906
+ let inputsKey: any = bind
907
+ if (!Array.isArray(inputsKey)) {
908
+ inputsKey = [bind]
909
+ }
910
+ for (let input of inputsKey) {
911
+ this.bindKey(input, control, option)
912
+ }
913
+ }
914
+ this._controlsOptions = inputs
915
+ }
916
+
917
+ get options(): Controls {
918
+ return this._controlsOptions
919
+ }
920
+ }
921
+
922
+ registerDirective('controls', KeyboardControls)