q5play 4.0.1 → 4.0.4

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.
package/LICENSE.md CHANGED
@@ -1,3 +1,5 @@
1
+ SPDX-License-Identifier: LicenseRef-q5play-Creator-License
2
+
1
3
  # q5play Creator License
2
4
 
3
5
  This License Agreement ("Agreement") is made between Quinton Ashley, the sole copyright owner of q5play ("Licensor") and an individual, organization, or company ("Licensee") that is using q5play.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q5play",
3
- "version": "4.0.1",
3
+ "version": "4.0.4",
4
4
  "author": "quinton-ashley",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "description": "A web-based game engine that uses q5.js WebGPU for graphics and Box2D v3 WASM for physics.",
package/q5play.d.ts CHANGED
@@ -41,17 +41,6 @@ declare global {
41
41
  * @default true
42
42
  */
43
43
  friendlyRounding: boolean;
44
- /**
45
- * Snaps sprites to the nearest `q5play.gridSize`
46
- * increment when they are moved.
47
- * @default false
48
- */
49
- snapToGrid: boolean;
50
- /**
51
- * The size of the grid cells that sprites are snapped to.
52
- * @default 0.5
53
- */
54
- gridSize: number;
55
44
  /**
56
45
  * Information about the operating system being used.
57
46
  */
@@ -596,11 +585,6 @@ declare global {
596
585
  */
597
586
  get heading(): string;
598
587
  set heading(val: string);
599
- /**
600
- * True if the sprite is moving.
601
- * @readonly
602
- */
603
- get isMoving(): boolean;
604
588
  /**
605
589
  * Set this to true if the sprite goes really fast to prevent
606
590
  * inaccurate physics simulation.
@@ -2600,6 +2584,18 @@ declare global {
2600
2584
  * @returns true on the first frame that the user releases the input after dragging the mouse
2601
2585
  */
2602
2586
  dragged(inp?: string): boolean;
2587
+ /**
2588
+ * @returns true on the first frame that the user scrolls the mouse wheel
2589
+ */
2590
+ scrolls(): boolean;
2591
+ /**
2592
+ * @returns the amount of frames the user has been scrolling the mouse wheel
2593
+ */
2594
+ scrolling(): number;
2595
+ /**
2596
+ * @returns true on the first frame that the user stops scrolling the mouse wheel
2597
+ */
2598
+ scrolled(): boolean;
2603
2599
  }
2604
2600
 
2605
2601
  class _Pointer extends InputDevice {
package/q5play.js CHANGED
@@ -30,8 +30,9 @@ if (typeof globalThis.Q5 == 'undefined') {
30
30
  let box2dPromise;
31
31
 
32
32
  // called when a new instance of Q5 is created
33
- async function q5playPreSetup($, q) {
34
- const log = console.log;
33
+ async function q5playPreSetup(q) {
34
+ const $ = this,
35
+ log = console.log;
35
36
 
36
37
  if (!box2dPromise) {
37
38
  box2dPromise = (async () => {
@@ -243,8 +244,6 @@ async function q5playPreSetup($, q) {
243
244
  this.spritesDrawn = 0;
244
245
  this.images = {};
245
246
  this.palettes = [];
246
- this.snapToGrid = false;
247
- this.gridSize = 0.5;
248
247
  this.emojiScale = 1;
249
248
  this.os = {};
250
249
  this.context = 'web';
@@ -584,11 +583,18 @@ async function q5playPreSetup($, q) {
584
583
  this.x += this.vx * timeScale;
585
584
  this.y += this.vy * timeScale;
586
585
 
586
+ if (this.tint) $.tint(this.tint);
587
+ if (this.opacity) $.opacity(this.opacity);
588
+
587
589
  if (this.ani) {
588
590
  $.animation(this.ani, this.x, this.y);
589
591
  } else if (this._img) {
590
592
  $.image(this._img, this.x, this.y);
591
593
  }
594
+
595
+ if (this.tint) $.noTint();
596
+ if (this.opacity) $.opacity(1);
597
+
592
598
  this.life -= timeScale;
593
599
  }
594
600
 
@@ -698,24 +704,26 @@ async function q5playPreSetup($, q) {
698
704
  }
699
705
 
700
706
  changeAni(name) {
701
- let ani = this._anis?.[name];
707
+ let ani = this.anis[name];
702
708
  if (!ani) {
703
- for (let g of this.groups || []) {
704
- ani = g._anis?.[name] || g._anis?.[name];
705
- if (ani) {
706
- ani = ani.clone();
707
- break;
709
+ const groups = this.groups;
710
+ if (groups) {
711
+ for (let g of groups) {
712
+ ani = g._anis?.[name];
713
+ if (ani) break;
708
714
  }
715
+ } else {
716
+ let v = this._visuals;
717
+ ani = v._anis?.[name];
709
718
  }
710
- if (!ani) {
711
- console.error('Ani not found: ' + name);
712
- return;
713
- }
719
+ if (ani) ani = ani.clone();
720
+ else return console.error('Ani not found: ' + name);
714
721
  }
715
722
  // reset to frame 0 of that animation
716
723
  if (this.resetAniOnChange) ani._frame = 0;
717
724
  ani.name = name;
718
725
  this.ani = ani;
726
+ this.anis[name] = ani;
719
727
  }
720
728
 
721
729
  playAni(name) {
@@ -1013,18 +1021,17 @@ async function q5playPreSetup($, q) {
1013
1021
  else y = 0;
1014
1022
  }
1015
1023
 
1016
- let rr;
1017
-
1018
1024
  let forcedBoxShape = false;
1019
1025
  if (w === undefined) {
1020
1026
  w = group.w || group.width || group.d || group.diameter;
1021
1027
  if (!h && !group.d && !group.diameter) {
1022
1028
  h = group.h || group.height;
1023
1029
  forcedBoxShape = true;
1024
- rr = group.roundedRadius;
1025
1030
  }
1026
1031
  }
1027
1032
 
1033
+ let rr = group.roundedRadius;
1034
+
1028
1035
  if (typeof x == 'function') x = x(group.length);
1029
1036
  if (typeof y == 'function') y = y(group.length);
1030
1037
  if (typeof w == 'function') w = w(group.length);
@@ -1866,10 +1873,6 @@ async function q5playPreSetup($, q) {
1866
1873
  this.direction = val;
1867
1874
  }
1868
1875
 
1869
- get isMoving() {
1870
- return this.vel.x != 0 || this.vel.y != 0;
1871
- }
1872
-
1873
1876
  get isSuperFast() {
1874
1877
  return b2Body_IsBullet(this.bdID);
1875
1878
  }
@@ -2292,6 +2295,21 @@ async function q5playPreSetup($, q) {
2292
2295
  this.d = val;
2293
2296
  }
2294
2297
 
2298
+ get roundedRadius() {
2299
+ return this._roundedRadius;
2300
+ }
2301
+ set roundedRadius(val) {
2302
+ if (val == this._roundedRadius) return;
2303
+
2304
+ this._roundedRadius = val;
2305
+ if (this.watch) this.mod[37] = true;
2306
+
2307
+ while (this._shapes.length) {
2308
+ this._shapes.at(-1).delete();
2309
+ }
2310
+ this._add(false, 0, 0, this._w, this._h, val);
2311
+ }
2312
+
2295
2313
  /*
2296
2314
  * Validates convexity.
2297
2315
  */
@@ -2329,13 +2347,6 @@ async function q5playPreSetup($, q) {
2329
2347
  this._customUpdate = val;
2330
2348
  }
2331
2349
 
2332
- get postDraw() {
2333
- return this._postDraw;
2334
- }
2335
- set postDraw(val) {
2336
- this._customPostDraw = val;
2337
- }
2338
-
2339
2350
  get vel() {
2340
2351
  return this._vel;
2341
2352
  }
@@ -2610,13 +2621,6 @@ async function q5playPreSetup($, q) {
2610
2621
  }
2611
2622
  }
2612
2623
 
2613
- _postDraw() {
2614
- if (this._customPostDraw) this._customPostDraw();
2615
-
2616
- this.autoDraw ??= true;
2617
- this.autoUpdate ??= true;
2618
- }
2619
-
2620
2624
  _args2Vec(x, y) {
2621
2625
  if (Array.isArray(x)) {
2622
2626
  return { x: x[0], y: x[1] };
@@ -3167,9 +3171,12 @@ async function q5playPreSetup($, q) {
3167
3171
  }
3168
3172
 
3169
3173
  // loading promise
3170
- this.promise = new Promise((resolve) => {
3171
- this._resolve = resolve;
3172
- });
3174
+ if (args.length) {
3175
+ this.promise = new Promise((resolve) => {
3176
+ this._resolve = resolve;
3177
+ });
3178
+ $._loaders.push(this.promise);
3179
+ }
3173
3180
 
3174
3181
  this._frame = 0;
3175
3182
  this._cycles = 0;
@@ -3384,12 +3391,16 @@ async function q5playPreSetup($, q) {
3384
3391
 
3385
3392
  // play by default but a single frame ani doesn't need to play
3386
3393
  this.playing = this.length != 1 && anis.playing != false;
3394
+
3395
+ if (this.length > 0 && !this.spriteSheet) {
3396
+ Promise.all(this.map((img) => img.promise)).then(() => this._resolve(this));
3397
+ }
3387
3398
  }
3388
3399
 
3389
- // make loading Ani objects awaitable
3390
- // then(resolve, reject) {
3391
- // return this.promise.then(resolve, reject);
3392
- // }
3400
+ // use a plain Array constructor for map/filter/etc.
3401
+ static get [Symbol.species]() {
3402
+ return Array;
3403
+ }
3393
3404
 
3394
3405
  get frame() {
3395
3406
  return this._frame;
@@ -3700,6 +3711,7 @@ async function q5playPreSetup($, q) {
3700
3711
  else this.img = _this._img;
3701
3712
  _this.push(this);
3702
3713
  _this.amount++;
3714
+ this._visuals = _this;
3703
3715
  }
3704
3716
  };
3705
3717
  }
@@ -3953,6 +3965,10 @@ async function q5playPreSetup($, q) {
3953
3965
  constructor() {
3954
3966
  super(_this, ...arguments);
3955
3967
  }
3968
+
3969
+ static withSensor() {
3970
+ return new $.Sprite(null, _this, ...arguments);
3971
+ }
3956
3972
  };
3957
3973
 
3958
3974
  this.Group = class extends $.Group {
@@ -4710,12 +4726,6 @@ async function q5playPreSetup($, q) {
4710
4726
 
4711
4727
  $.imageMode(ogImgMode);
4712
4728
  }
4713
-
4714
- postDraw() {
4715
- for (let s of this) {
4716
- s.postDraw();
4717
- }
4718
- }
4719
4729
  };
4720
4730
 
4721
4731
  $.Group.prototype.__step = $.Sprite.prototype.__step;
@@ -5214,6 +5224,26 @@ async function q5playPreSetup($, q) {
5214
5224
  this._calcBoundsY(val);
5215
5225
  }
5216
5226
 
5227
+ get zoom() {
5228
+ return this._zoom;
5229
+ }
5230
+ set zoom(val) {
5231
+ if (val === undefined || isNaN(val)) return;
5232
+ this._zoom = val;
5233
+ let x = -this._pos.x;
5234
+ if ($._c2d) x += $.canvas.hw / val;
5235
+ let y = -this._pos.y;
5236
+ if ($._c2d) y += $.canvas.hh / val;
5237
+ this.__pos.x = x;
5238
+ this.__pos.y = y;
5239
+ if ($.allSprites.pixelPerfect) {
5240
+ this.__pos.rounded.x = Math.round(x);
5241
+ this.__pos.rounded.y = Math.round(y);
5242
+ }
5243
+ this._calcBoundsX(this._pos.x);
5244
+ this._calcBoundsY(this._pos.y);
5245
+ }
5246
+
5217
5247
  moveTo(x, y, speed) {
5218
5248
  if (x === undefined) return;
5219
5249
  if (isNaN(x)) {
@@ -5243,7 +5273,7 @@ async function q5playPreSetup($, q) {
5243
5273
  this.x += velX;
5244
5274
  this.y += velY;
5245
5275
 
5246
- await $.delay(16);
5276
+ await $.delay();
5247
5277
  if (destIdx != this._destIdx) return false;
5248
5278
  }
5249
5279
  this.x = x;
@@ -5252,26 +5282,6 @@ async function q5playPreSetup($, q) {
5252
5282
  })();
5253
5283
  }
5254
5284
 
5255
- get zoom() {
5256
- return this._zoom;
5257
- }
5258
- set zoom(val) {
5259
- if (val === undefined || isNaN(val)) return;
5260
- this._zoom = val;
5261
- let x = -this._pos.x;
5262
- if ($._c2d) x += $.canvas.hw / val;
5263
- let y = -this._pos.y;
5264
- if ($._c2d) y += $.canvas.hh / val;
5265
- this.__pos.x = x;
5266
- this.__pos.y = y;
5267
- if ($.allSprites.pixelPerfect) {
5268
- this.__pos.rounded.x = Math.round(x);
5269
- this.__pos.rounded.y = Math.round(y);
5270
- }
5271
- this._calcBoundsX(this._pos.x);
5272
- this._calcBoundsY(this._pos.y);
5273
- }
5274
-
5275
5285
  zoomTo(target, speed) {
5276
5286
  if (target == this._zoom) return Promise.resolve(true);
5277
5287
  speed ??= 0.1;
@@ -5287,7 +5297,7 @@ async function q5playPreSetup($, q) {
5287
5297
  for (let i = 0; i < frames; i++) {
5288
5298
  if (zoomIdx != this._zoomIdx) return false;
5289
5299
  this.zoom += speed;
5290
- await $.delay(16);
5300
+ await $.delay();
5291
5301
  }
5292
5302
  this.zoom = target;
5293
5303
  return true;
@@ -6106,8 +6116,11 @@ async function q5playPreSetup($, q) {
6106
6116
  }
6107
6117
 
6108
6118
  function isArrowFunction(fn) {
6109
- return !/^(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*(?:(?:(?:async\s(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*)?function|class)(?:\s|(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*)|(?:[_$\w][\w0-9_$]*\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\()|(?:\[\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*(?:(?:['][^']+['])|(?:["][^"]+["]))\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\]\())/.test(
6110
- fn.toString()
6119
+ return (
6120
+ fn.name == 'jsobj' || // brython lambda function check
6121
+ !/^(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*(?:(?:(?:async\s(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*\s*)?function|class)(?:\s|(?:(?:\/\*[^(?:\*\/)]*\*\/\s*)|(?:\/\/[^\r\n]*))*)|(?:[_$\w][\w0-9_$]*\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\()|(?:\[\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*(?:(?:['][^']+['])|(?:["][^"]+["]))\s*(?:\/\*[^(?:\*\/)]*\*\/\s*)*\s*\]\())/.test(
6122
+ fn.toString()
6123
+ )
6111
6124
  );
6112
6125
  }
6113
6126
 
@@ -6224,6 +6237,8 @@ async function q5playPreSetup($, q) {
6224
6237
 
6225
6238
  let img = g.get(left, top, right - left + 1, bottom - top + 1);
6226
6239
  img.src = emoji;
6240
+ img.defaultWidth = img.width;
6241
+ img.defaultHeight = img.height;
6227
6242
 
6228
6243
  g.remove();
6229
6244
 
@@ -6468,6 +6483,7 @@ async function q5playPreSetup($, q) {
6468
6483
  args[0] = window.innerWidth;
6469
6484
  args[1] = window.innerHeight;
6470
6485
  }
6486
+ args[1] ??= args[0];
6471
6487
  args[0] = Math.floor(args[0] / 2) * 2;
6472
6488
  args[1] = Math.floor(args[1] / 2) * 2;
6473
6489
  let rend = _createCanvas.call($, ...args);
@@ -6505,6 +6521,9 @@ async function q5playPreSetup($, q) {
6505
6521
  let sd = $.mouse.scrollDelta;
6506
6522
  sd.x = e.deltaX;
6507
6523
  sd.y = e.deltaY;
6524
+ if (Math.abs(sd.x) > 1 || Math.abs(sd.y) > 1) {
6525
+ $.mouse.scroll++;
6526
+ }
6508
6527
  });
6509
6528
  c.addEventListener('touchstart', (e) => e.preventDefault());
6510
6529
  // this stops the right click menu from appearing
@@ -6794,8 +6813,14 @@ async function q5playPreSetup($, q) {
6794
6813
 
6795
6814
  _update() {
6796
6815
  let cam = $.camera;
6797
- this.x = $.mouseX / cam.zoom + cam.x;
6798
- this.y = $.mouseY / cam.zoom + cam.y;
6816
+ let m = this;
6817
+ m.x = $.mouseX / cam.zoom + cam.x;
6818
+ m.y = $.mouseY / cam.zoom + cam.y;
6819
+
6820
+ if (m.scroll < 0) m.scroll = 0;
6821
+ if (m.scrollDelta.x == 0 && m.scrollDelta.y == 0) {
6822
+ m.scroll = m.scroll == 1 ? -3 : m.scroll > 0 ? -1 : 0;
6823
+ }
6799
6824
  }
6800
6825
 
6801
6826
  get pos() {
@@ -6837,6 +6862,16 @@ async function q5playPreSetup($, q) {
6837
6862
  inp ??= this._default;
6838
6863
  return this.drag[inp] <= -1;
6839
6864
  }
6865
+
6866
+ scrolls() {
6867
+ return this.scroll == 1;
6868
+ }
6869
+ scrolling() {
6870
+ return this.scroll > 0 ? this.scroll : 0;
6871
+ }
6872
+ scrolled() {
6873
+ return this.scroll <= -1;
6874
+ }
6840
6875
  };
6841
6876
 
6842
6877
  $.mouse = new $._Mouse();
@@ -7024,18 +7059,26 @@ async function q5playPreSetup($, q) {
7024
7059
  super();
7025
7060
  this._default = ' ';
7026
7061
 
7027
- this.alt = 0;
7028
- this.arrowUp = 0;
7029
- this.arrowDown = 0;
7030
- this.arrowLeft = 0;
7031
- this.arrowRight = 0;
7032
- this.backspace = 0;
7033
- this.capsLock = 0;
7034
- this.control = 0;
7035
- this.enter = 0;
7036
- this.meta = 0;
7037
- this.shift = 0;
7038
- this.tab = 0;
7062
+ let keys = [
7063
+ ' ',
7064
+ 'alt',
7065
+ 'arrowUp',
7066
+ 'arrowDown',
7067
+ 'arrowLeft',
7068
+ 'arrowRight',
7069
+ 'backspace',
7070
+ 'capsLock',
7071
+ 'control',
7072
+ 'enter',
7073
+ 'meta',
7074
+ 'shift',
7075
+ 'tab'
7076
+ ];
7077
+ keys = keys.concat("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-=[];,./'".split(''));
7078
+ // initializing these props to 0 makes brython happy
7079
+ for (let key of keys) {
7080
+ this[key] = 0;
7081
+ }
7039
7082
 
7040
7083
  let k = (this._simpleKeyControls = {
7041
7084
  arrowUp: 'up',
@@ -7959,6 +8002,8 @@ async function q5playPreSetup($, q) {
7959
8002
  window[p] = $[p];
7960
8003
  }
7961
8004
  }
8005
+
8006
+ if (Q5.applyLang) Q5.applyLang(q, q5playLibLangs, q5playClassLangs);
7962
8007
  }
7963
8008
 
7964
8009
  // called once after setup
@@ -8087,7 +8132,10 @@ function q5playPostDraw() {
8087
8132
 
8088
8133
  if (cam.isActive) cam.off();
8089
8134
 
8090
- $.allSprites.postDraw();
8135
+ for (let s of $.allSprites) {
8136
+ s.autoDraw ??= true;
8137
+ s.autoUpdate ??= true;
8138
+ }
8091
8139
 
8092
8140
  if ($.q5play.renderStats) $.renderStats();
8093
8141
 
@@ -8131,9 +8179,203 @@ function q5playPostDraw() {
8131
8179
  }
8132
8180
 
8133
8181
  function q5playRemove() {
8134
- this.world.delete();
8182
+ this.world?.delete();
8135
8183
  }
8136
8184
 
8185
+ const q5playLibLangs = `
8186
+ allSprites -> es:todosLosSprites
8187
+ world -> es:mundo
8188
+ camera -> es:cámara
8189
+ mouse -> es:ratón
8190
+ kb -> es:tec
8191
+ keyboard -> es:teclado
8192
+ contro -> es:mando
8193
+ controllers -> es:mandos
8194
+ pointer -> es:puntero
8195
+ pointers -> es:punteros
8196
+ spriteArt -> es:arteSprite
8197
+ delay -> es:esperar
8198
+ animation -> es:animación
8199
+ renderStats -> es:estadísticasRenderizado
8200
+ EmojiImage -> es:ImagenEmoji
8201
+ parseTextureAtlas -> es:parsearAtlasTextura
8202
+ DYNAMIC -> es:DINÁMICO
8203
+ STATIC -> es:ESTÁTICO
8204
+ KINEMATIC -> es:CINEMÁTICO
8205
+ Group -> es:Grupo
8206
+ Joint -> es:Articulación
8207
+ `;
8208
+
8209
+ const q5playClassLangs = {
8210
+ Sprite: `
8211
+ rotation -> es:rotación
8212
+ rotationSpeed -> es:velocidadRotación
8213
+ rotationDrag -> es:resistenciaRotación
8214
+ rotationLock -> es:bloqueoRotación
8215
+ speed -> es:velocidad
8216
+ direction -> es:dirección
8217
+ drag -> es:amortiguación
8218
+ mass -> es:masa
8219
+ density -> es:densidad
8220
+ bounciness -> es:elasticidad
8221
+ friction -> es:fricción
8222
+ physicsEnabled -> es:físicaActivada
8223
+ physicsType -> es:tipoFísica
8224
+ physics -> es:física
8225
+ sleeping -> es:durmiendo
8226
+ allowSleeping -> es:permitirDormir
8227
+ layer -> es:capa
8228
+ life -> es:vida
8229
+ scale -> es:escala
8230
+ tint -> es:tinte
8231
+ opacity -> es:opacidad
8232
+ visible -> es:visible
8233
+ debug -> es:depurar
8234
+ deleted -> es:eliminado
8235
+ bearing -> es:rumbo
8236
+ heading -> es:orientación
8237
+ isSuperFast -> es:esUltraRápido
8238
+ pixelPerfect -> es:perfectoEnPíxeles
8239
+ gravityScale -> es:escalaGravedad
8240
+ diameter -> es:diámetro
8241
+ roundedRadius -> es:radioRedondeado
8242
+ centerOfMass -> es:centroMasa
8243
+ previousPosition -> es:posiciónAnterior
8244
+ previousRotation -> es:rotaciónAnterior
8245
+ velocity -> es:vectorVelocidad
8246
+ position -> es:posición
8247
+ canvasPos -> es:posiciónLienzo
8248
+ addCollider -> es:añadirColisionador
8249
+ addSensor -> es:añadirSensor
8250
+ deleteColliders -> es:eliminarColisionadores
8251
+ deleteSensors -> es:eliminarSensores
8252
+ collide -> es:colisionar
8253
+ collides -> es:colisiona
8254
+ colliding -> es:colisionando
8255
+ collided -> es:colisionó
8256
+ overlap -> es:solapar
8257
+ overlaps -> es:solapa
8258
+ overlapping -> es:solapando
8259
+ overlapped -> es:solapó
8260
+ passes -> es:pasa
8261
+ addAni -> es:añadirAni
8262
+ addAnis -> es:añadirAnis
8263
+ changeAni -> es:cambiarAni
8264
+ playAni -> es:reproducirAni
8265
+ playAnis -> es:reproducirAnis
8266
+ moveTowards -> es:moverHacia
8267
+ rotateTowards -> es:rotarHacia
8268
+ applyForce -> es:aplicarFuerza
8269
+ applyForceScaled -> es:aplicarFuerzaEscalada
8270
+ attractTo -> es:atraerA
8271
+ repelFrom -> es:repelerDe
8272
+ applyTorque -> es:aplicarTorque
8273
+ angleTo -> es:ánguloHacia
8274
+ rotationToFace -> es:rotaciónParaMirar
8275
+ angleToFace -> es:ánguloParaMirar
8276
+ setSpeedAndDirection -> es:establecerVelocidadYDirección
8277
+ scaleBy -> es:escalarPor
8278
+ resetMass -> es:reiniciarMasa
8279
+ distanceTo -> es:distanciaA
8280
+ delete -> es:eliminar
8281
+ addDefaultSensors -> es:añadirSensoresDefecto
8282
+ autoDraw -> es:autoDibujar
8283
+ draw -> es:dibujar
8284
+ autoUpdate -> es:autoActualizar
8285
+ update -> es:actualizar
8286
+ `,
8287
+ Group: `
8288
+ Group -> es:Grupo
8289
+ amount -> es:cantidad
8290
+ autoCull -> es:descartarFueraCampo
8291
+ cull -> es:descartar
8292
+ contains -> es:contiene
8293
+ remove -> es:quitar
8294
+ removeAll -> es:quitarTodo
8295
+ delete -> es:eliminar
8296
+ deleteAll -> es:eliminarTodo
8297
+ `,
8298
+ World: `
8299
+ gravity -> es:gravedad
8300
+ timeScale -> es:escalaVelocidad
8301
+ meterSize -> es:tamañoMetro
8302
+ allowSleeping -> es:permitirDormir
8303
+ awakeBodies -> es:cuerposDespiertos
8304
+ bounceThreshold -> es:umbralRebote
8305
+ hitThreshold -> es:umbralGolpe
8306
+ autoStep -> es:pasoAutomático
8307
+ subSteps -> es:subPasos
8308
+ explodeAt -> es:explosionEn
8309
+ delete -> es:eliminar
8310
+ `,
8311
+ Camera: `
8312
+ position -> es:posición
8313
+ zoom ->
8314
+ moveTo -> es:moverA
8315
+ zoomTo -> es:acercarA
8316
+ on -> es:activar
8317
+ off -> es:desactivar
8318
+ `,
8319
+ Ani: `
8320
+ play -> es:reproducir
8321
+ pause -> es:pausar
8322
+ stop -> es:parar
8323
+ loop -> es:bucle
8324
+ noLoop -> es:sinBucle
8325
+ rewind -> es:rebobinar
8326
+ nextFrame -> es:siguienteFotograma
8327
+ previousFrame -> es:fotogramaAnterior
8328
+ goToFrame -> es:irAlFotograma
8329
+ clone -> es:clonar
8330
+ frame -> es:fotograma
8331
+ lastFrame -> es:últimoFotograma
8332
+ frameImage -> es:imagenFotograma
8333
+ playing -> es:reproduciendo
8334
+ looping -> es:enBucle
8335
+ frameDelay -> es:retardoFotograma
8336
+ `,
8337
+ InputDevice: `
8338
+ presses -> es:presiona
8339
+ pressing -> es:presionando
8340
+ holds -> es:mantiene
8341
+ holding -> es:manteniendo
8342
+ held -> es:mantuvo
8343
+ released -> es:soltó
8344
+ releases -> es:suelta
8345
+ holdThreshold -> es:umbralMantener
8346
+ `,
8347
+ _Mouse: `
8348
+ position -> es:posición
8349
+ visible -> es:visible
8350
+ isOnCanvas -> es:estaEnLienzo
8351
+ scroll -> es:desplazamiento
8352
+ drags -> es:arrastra
8353
+ dragging -> es:arrastrando
8354
+ dragged -> es:arrastró
8355
+ scrolls -> es:desplaza
8356
+ scrolling -> es:desplazando
8357
+ scrolled -> es:desplazó
8358
+ `,
8359
+ _Pointer: `
8360
+ prev -> es:previo
8361
+ canvasPos -> es:posEnLienzo
8362
+ type -> es:tipo
8363
+ duration -> es:duración
8364
+ holdThreshold -> es:umbralDeSostenido
8365
+ drags -> es:arrastra
8366
+ dragging -> es:arrastrando
8367
+ dragged -> es:arrastró
8368
+ grabs -> es:agarra
8369
+ grabbing -> es:agarrando
8370
+ grabbed -> es:agarró
8371
+ overlaps -> es:superpone
8372
+ overlapping -> es:superponiendo
8373
+ overlapped -> es:superpuso
8374
+ pressure -> es:presión
8375
+ `
8376
+ };
8377
+ q5playClassLangs.Group += q5playClassLangs.Sprite;
8378
+
8137
8379
  Q5.addHook('presetup', q5playPreSetup);
8138
8380
  Q5.addHook('postsetup', q5playPostSetup);
8139
8381
  Q5.addHook('predraw', q5playPreDraw);