q5play 4.2.2 → 4.2.3

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 (2) hide show
  1. package/package.json +1 -1
  2. package/q5play.js +212 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q5play",
3
- "version": "4.2.2",
3
+ "version": "4.2.3",
4
4
  "author": "quinton-ashley",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "description": "A beginner friendly, web-based game engine that uses q5.js WebGPU for graphics and Box2D v3 WASM for physics.",
package/q5play.js CHANGED
@@ -702,6 +702,8 @@ async function q5playPreSetup(q) {
702
702
  if (typeof val == 'string') {
703
703
  if (!val.includes('.')) {
704
704
  val = new $.EmojiImage(val, this.w);
705
+ } else if (using_p5) {
706
+ return this._setP5Img(val);
705
707
  } else val = $.loadImage(val);
706
708
  }
707
709
  this._img = this._extendImage(val);
@@ -730,6 +732,13 @@ async function q5playPreSetup(q) {
730
732
  return img;
731
733
  }
732
734
 
735
+ async _setP5Img(val) {
736
+ // for p5 v2 compatibility
737
+ let img = await $.loadImage(val);
738
+ this._img = this._extendImage(img);
739
+ this._hasImagery = true;
740
+ }
741
+
733
742
  addAni() {
734
743
  let args = [...arguments];
735
744
  let ani, name;
@@ -1083,6 +1092,30 @@ async function q5playPreSetup(q) {
1083
1092
  }
1084
1093
  });
1085
1094
 
1095
+ if (using_p5) {
1096
+ this._vel.direction = function () {
1097
+ if (!this._directionCached) {
1098
+ const x = this.x,
1099
+ y = this.y;
1100
+ if (x || y) this._direction = $.atan2(this.y, this.x);
1101
+ else this._direction = 0;
1102
+ this._directionCached = this._useCache;
1103
+ }
1104
+ return this._direction;
1105
+ };
1106
+
1107
+ this._vel.setDirection = function (ang) {
1108
+ let mag = this.mag();
1109
+ if (mag) {
1110
+ this.x = mag * $.cos(ang);
1111
+ this.y = mag * $.sin(ang);
1112
+ }
1113
+ this._direction = ang;
1114
+ this._directionCached = this._useCache;
1115
+ return this;
1116
+ };
1117
+ }
1118
+
1086
1119
  this._heading = 'right';
1087
1120
 
1088
1121
  if (group._layer) this.layer = group._layer;
@@ -3611,6 +3644,12 @@ async function q5playPreSetup(q) {
3611
3644
 
3612
3645
  // image sequence format
3613
3646
  if (args.length == 2 && typeof args[0] == 'string' && typeof args[1] == 'string' && !args[1].includes('.')) {
3647
+ if (using_p5) {
3648
+ throw new Error(
3649
+ 'p5.js v2 does not support preloading or lazy loading images. Convert the image sequence to a sprite sheet.'
3650
+ );
3651
+ }
3652
+
3614
3653
  let file = args[0],
3615
3654
  extIndex = file.lastIndexOf('.'),
3616
3655
  digits = 0;
@@ -3765,7 +3804,9 @@ async function q5playPreSetup(q) {
3765
3804
  if (typeof sheet == 'string') {
3766
3805
  sheet = $.loadImage(sheet);
3767
3806
  }
3768
- sheet.promise.then(() => {
3807
+ let promise = !using_p5 ? sheet.promise : sheet;
3808
+ promise.then((img) => {
3809
+ if (using_p5) this.spriteSheet = sheet = img;
3769
3810
  if (!this.length) findFrames();
3770
3811
 
3771
3812
  if (this._clones) {
@@ -3787,7 +3828,11 @@ async function q5playPreSetup(q) {
3787
3828
  else {
3788
3829
  for (let i = 0; i < args.length; i++) {
3789
3830
  if (args[i] instanceof Q5.Image) this.push(args[i]);
3790
- else this.push($.loadImage(args[i]));
3831
+ else if (using_p5) {
3832
+ throw new Error(
3833
+ 'p5.js v2 does not support preloading or lazy loading images. You need to use `await load(url)`.'
3834
+ );
3835
+ } else this.push($.loadImage(args[i]));
3791
3836
  }
3792
3837
  }
3793
3838
 
@@ -4156,6 +4201,8 @@ async function q5playPreSetup(q) {
4156
4201
  if (typeof val == 'string') {
4157
4202
  if (!val.includes('.')) {
4158
4203
  val = new $.EmojiImage(val, this.w || this.width || this.d || this.diameter);
4204
+ } else if (using_p5) {
4205
+ return $.Visual.prototype._setP5Img(val);
4159
4206
  } else val = $.loadImage(val);
4160
4207
  }
4161
4208
  this._img = $.Visual.prototype._extendImage(val);
@@ -7239,11 +7286,18 @@ async function q5playPreSetup(q) {
7239
7286
  let rend = _createCanvas.call($, ...args);
7240
7287
  $.ctx = $.drawingContext;
7241
7288
  let c = rend.canvas || rend;
7242
- if (using_p5) window.canvas = c;
7243
- if (rend.GL) {
7244
- c.renderer = 'webgl';
7245
- $._webgl = true;
7246
- } else if (!$._webgpu) $._c2d = true;
7289
+ if (using_p5) {
7290
+ window.canvas = c;
7291
+ if (rend.GPU) {
7292
+ c.renderer = 'webgpu';
7293
+ $._webgpu = true;
7294
+ } else if (rend.GL) {
7295
+ c.renderer = 'webgl';
7296
+ $._webgl = true;
7297
+ } else {
7298
+ $._webgpu = $._webgpuFallback = true;
7299
+ }
7300
+ }
7247
7301
  c.tabIndex = 0;
7248
7302
  c.w = args[0];
7249
7303
  c.h = args[1];
@@ -8497,21 +8551,21 @@ async function q5playPreSetup(q) {
8497
8551
  shapeStack = [];
8498
8552
 
8499
8553
  const colorMax = $._colorFormat,
8500
- debugGreen = $._q5 ? $.color(0, colorMax, 0, colorMax * 0.9) : 'lime',
8501
- debugGreenFill = $._q5 ? $.color(0, colorMax, 0, colorMax * 0.1) : 'lime',
8502
- debugYellow = $._q5 ? $.color(colorMax, colorMax, 0, colorMax * 0.9) : 'yellow',
8503
- debugYellowFill = $._q5 ? $.color(colorMax, colorMax, 0, colorMax * 0.1) : 'yellow';
8554
+ debugGreen = $._q5 ? $.color(0, colorMax, 0, colorMax * 0.9) : '#0f0e',
8555
+ debugGreenFill = $._q5 ? $.color(0, colorMax, 0, colorMax * 0.1) : '#0f02',
8556
+ debugYellow = $._q5 ? $.color(colorMax, colorMax, 0, colorMax * 0.9) : '#ff0e',
8557
+ debugYellowFill = $._q5 ? $.color(colorMax, colorMax, 0, colorMax * 0.1) : '#ff02';
8504
8558
 
8505
8559
  if (using_p5) {
8506
8560
  $._getFillIdx = () => $._renderer.states.fillColor;
8507
- $._setFillIdx = (v) => $.fill(v);
8561
+ $._setFillIdx = (v) => ($._renderer.states.fillColor = v);
8508
8562
  $._getStrokeIdx = () => $._renderer.states.strokeColor;
8509
- $._setStrokeIdx = (v) => {
8510
- if ($._renderer.states.strokeSet) $.stroke(v);
8511
- };
8563
+ $._setStrokeIdx = (v) => ($._renderer.states.strokeColor = v);
8512
8564
  $._getStrokeWeight = () => [$._renderer.states.strokeWeight];
8513
8565
  $._setStrokeWeight = (v) => $.strokeWeight(...v);
8514
8566
  $._getImageMode = () => $._renderer.states.imageMode;
8567
+ $._doFill = () => {};
8568
+ $._doStroke = () => {};
8515
8569
  } else if ($.canvas.c2d) {
8516
8570
  // polyfill for q5 WebGPU high efficiency functions
8517
8571
  $._getFillIdx = () => $._fill;
@@ -8613,7 +8667,7 @@ async function q5playPreSetup(q) {
8613
8667
  transformPoint(xf, v);
8614
8668
  $.vertex(v.x, v.y);
8615
8669
  }
8616
- $.endShape(true);
8670
+ $.endShape($.CLOSE);
8617
8671
  if (rr > 0) {
8618
8672
  $._setStrokeWeight(swData);
8619
8673
  $._setStrokeIdx(ogStroke);
@@ -8659,7 +8713,7 @@ async function q5playPreSetup(q) {
8659
8713
  transformPoint(xf, v);
8660
8714
  $.vertex(v.x, v.y);
8661
8715
  }
8662
- $.endShape(true);
8716
+ $.endShape($.CLOSE);
8663
8717
  } else {
8664
8718
  let x = (cmd.data[0] + cmd.data[2]) / 2,
8665
8719
  y = (cmd.data[1] + cmd.data[3]) / 2;
@@ -8698,7 +8752,7 @@ async function q5playPreSetup(q) {
8698
8752
  };
8699
8753
 
8700
8754
  // prettier-ignore
8701
- let q5playGlobals = ['q5play','Box2D','DYN','DYNAMIC','STA','STATIC','KIN','KINEMATIC','Sprite','Group','allSprites','Ani','Anis','Visual','Visuals','Joint','GlueJoint','DistanceJoint','WheelJoint','HingeJoint','SliderJoint','GrabberJoint','world','kb','keyboard','mouse','contro','contros','controllers','pointer','pointers','spriteArt','EmojiImage','getFPS','animation','parseTextureAtlas','delay'];
8755
+ let q5playGlobals = ['q5play','Box2D','DYN','DYNAMIC','STA','STATIC','KIN','KINEMATIC','Sprite','Group','allSprites','Ani','Anis','Visual','Visuals','Joint','GlueJoint','DistanceJoint','WheelJoint','HingeJoint','SliderJoint','GrabberJoint','world','camera','kb','keyboard','mouse','contro','contros','controllers','pointer','pointers','spriteArt','EmojiImage','getFPS','animation','parseTextureAtlas','delay'];
8702
8756
 
8703
8757
  // manually propagate q5play stuff to the global window object
8704
8758
  if ($._isGlobal) {
@@ -8723,26 +8777,19 @@ function q5playPostSetup() {
8723
8777
 
8724
8778
  if (using_p5) {
8725
8779
  // p5 won't run the draw loop without a draw function defined
8726
- window.draw = () => {};
8780
+ window.draw ??= () => {};
8727
8781
 
8728
8782
  $.loge = $.log;
8729
8783
  $.log = console.log;
8730
8784
  $.camera = $._camera;
8731
8785
 
8732
8786
  if ($._isGlobal) {
8733
- Object.defineProperty(window, 'log', {
8734
- value: console.log
8735
- });
8736
- Object.defineProperty(window, 'loge', {
8737
- value: $.loge
8738
- });
8739
8787
  $.camera3D = window.camera;
8740
- Object.defineProperty(window, 'camera3D', {
8741
- value: $.camera3D
8742
- });
8743
- Object.defineProperty(window, 'camera', {
8744
- value: $.camera
8745
- });
8788
+ for (let prop of ['log', 'loge', 'camera', 'camera3D']) {
8789
+ Object.defineProperty(window, prop, {
8790
+ value: $[prop]
8791
+ });
8792
+ }
8746
8793
  }
8747
8794
  }
8748
8795
 
@@ -9112,7 +9159,8 @@ pressure -> es:presión
9112
9159
  q5playClassLangs.Group += q5playClassLangs.Sprite;
9113
9160
 
9114
9161
  if (typeof globalThis.Q5 == 'undefined') {
9115
- console.warn('p5.js v2 is not fully compatible with q5play. Consider using q5 instead: https://q5js.org');
9162
+ let upgrade = ' Consider upgrading to q5: https://q5js.org';
9163
+ console.warn('p5.js v2 is not fully compatible with q5play.' + upgrade);
9116
9164
 
9117
9165
  p5.addHook = (hook, fn) => {
9118
9166
  p5.registerAddon((p5, proto, lifecycles) => {
@@ -9125,34 +9173,155 @@ if (typeof globalThis.Q5 == 'undefined') {
9125
9173
  return new Promise((resolve) => {
9126
9174
  window.setup = async function () {
9127
9175
  const $ = p5.instance;
9128
- $._webgpu = $._webgpuFallback = true;
9129
9176
 
9130
9177
  $.Canvas(...args);
9131
9178
 
9132
9179
  // q5play defaults
9133
- colorMode(RGB, 1);
9134
- imageMode(CENTER);
9180
+ $.angleMode($.DEGREES);
9181
+ $.colorMode($.RGB, 1);
9182
+ $.imageMode($.CENTER);
9135
9183
 
9136
9184
  $.halfWidth = width / 2;
9137
9185
  $.halfHeight = height / 2;
9186
+ $.jit = (v) => $.random(-v, v);
9187
+
9188
+ $._loaders = [];
9189
+ $._colorFormat = 1;
9190
+
9191
+ const imgRegex = /(jpe?g|png|gif|webp|avif|svg)/i,
9192
+ fontRegex = /(ttf|otf|woff2?|eot|json)/i,
9193
+ fontCategoryRegex = /(serif|sans-serif|monospace|cursive|fantasy)/i,
9194
+ audioRegex = /(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/i;
9138
9195
 
9139
- let _resetMatrix = $.resetMatrix;
9196
+ $.load = function (...urls) {
9197
+ if (Array.isArray(urls[0])) urls = urls[0];
9140
9198
 
9141
- $.resetMatrix = () => {
9142
- _resetMatrix.call($);
9143
- $.translate($.halfWidth, $.halfHeight);
9199
+ let promises = [];
9200
+
9201
+ for (let url of urls) {
9202
+ let ext = url.split('.').pop().toLowerCase();
9203
+
9204
+ let obj;
9205
+ if (ext == 'json') {
9206
+ if (url.includes('-msdf.')) {
9207
+ throw new Error('p5.js v2 can not load MSDF fonts.' + upgrade);
9208
+ }
9209
+ obj = $.loadJSON(url);
9210
+ } else if (ext == 'csv') {
9211
+ obj = $.loadCSV(url);
9212
+ } else if (imgRegex.test(ext)) {
9213
+ obj = $.loadImage(url);
9214
+ } else if (fontRegex.test(ext) || fontCategoryRegex.test(url)) {
9215
+ obj = $.loadFont(url);
9216
+ } else if (audioRegex.test(ext)) {
9217
+ obj = $.loadSound(url);
9218
+ } else if (ext == 'xml') {
9219
+ obj = $.loadXML(url);
9220
+ } else {
9221
+ obj = $.loadText(url);
9222
+ }
9223
+ promises.push(obj);
9224
+ }
9225
+
9226
+ if (urls.length == 1) return promises[0];
9227
+ return Promise.all(promises);
9144
9228
  };
9145
9229
 
9146
- Object.defineProperty(p5, 'update', {
9147
- set(fn) {
9148
- $.update = fn;
9230
+ if ($._webgpuFallback) {
9231
+ $.opacity = function (v) {
9232
+ $.ctx.globalAlpha = v;
9233
+ };
9234
+ }
9235
+
9236
+ $.pushMatrix = $.push;
9237
+ $.popMatrix = $.pop;
9238
+
9239
+ $.loadAll = function () {
9240
+ console.error('p5.js v2 does not have loadAll().' + upgrade);
9241
+ };
9242
+
9243
+ $.displayMode = () => {
9244
+ console.error('p5.js v2 does not have displayMode().' + upgrade);
9245
+ };
9246
+
9247
+ $.MAXED = 'maxed';
9248
+ $.SMOOTH = 'smooth';
9249
+ $.PIXELATED = 'pixelated';
9250
+
9251
+ if ($._isGlobal) {
9252
+ let props = [
9253
+ 'halfWidth',
9254
+ 'halfHeight',
9255
+ 'jit',
9256
+ 'load',
9257
+ 'opacity',
9258
+ 'pushMatrix',
9259
+ 'popMatrix',
9260
+ 'loadAll',
9261
+ 'displayMode',
9262
+ 'MAXED',
9263
+ 'PIXELATED'
9264
+ ];
9265
+ for (let p of props) {
9266
+ window[p] = $[p];
9267
+ }
9268
+ }
9269
+
9270
+ if ($._webgpuFallback) {
9271
+ const _resetMatrix = $.resetMatrix;
9272
+ $.resetMatrix = () => {
9273
+ _resetMatrix.call($);
9274
+ // sets origin to the center of the canvas
9275
+ $.translate($.halfWidth, $.halfHeight);
9276
+ };
9277
+ }
9278
+
9279
+ Object.defineProperty(p5, 'lang', {
9280
+ set() {
9281
+ console.error('p5.js v2 does not support changing language.' + upgrade);
9149
9282
  },
9150
9283
  get() {
9151
- return $.update;
9284
+ return 'en';
9152
9285
  },
9153
9286
  configurable: true
9154
9287
  });
9155
9288
 
9289
+ const entryPoints = [
9290
+ 'setup',
9291
+ 'update',
9292
+ 'draw',
9293
+ 'deviceMoved',
9294
+ 'deviceTurned',
9295
+ 'deviceShaken',
9296
+ 'doubleClicked',
9297
+ 'mousePressed',
9298
+ 'mouseReleased',
9299
+ 'mouseMoved',
9300
+ 'mouseDragged',
9301
+ 'mouseClicked',
9302
+ 'mouseWheel',
9303
+ 'touchStarted',
9304
+ 'touchMoved',
9305
+ 'touchEnded',
9306
+ 'keyPressed',
9307
+ 'keyReleased',
9308
+ 'keyTyped',
9309
+ 'windowResized'
9310
+ ];
9311
+
9312
+ for (let ep of entryPoints) {
9313
+ Object.defineProperty(p5, ep, {
9314
+ set(fn) {
9315
+ $[ep] = fn;
9316
+ if ($._isGlobal) window[ep] = fn;
9317
+ },
9318
+ get() {
9319
+ return $[ep];
9320
+ },
9321
+ configurable: true
9322
+ });
9323
+ }
9324
+
9156
9325
  resolve();
9157
9326
  };
9158
9327
  });