@makefully/platypus 4.1.23 → 4.1.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/platypus",
3
- "version": "4.1.23",
3
+ "version": "4.1.24",
4
4
  "description": "2D tile-based HTML5 game engine with a component-based entity model",
5
5
  "license": "MIT",
6
6
  "contributors": [
package/src/Game.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* global document, platypus, window */
2
2
  import {Application} from 'springroll';
3
- import {CullerPlugin, Application as PixiApplication, Rectangle, Ticker, extensions} from 'pixi.js';
3
+ import {CullerPlugin, Application as PixiApplication, RenderTexture, Ticker, extensions} from 'pixi.js';
4
4
  import {arrayCache, greenSlice, greenSplice, union} from './utils/array.js';
5
5
  import Data from './Data.js';
6
6
  import Entity from './Entity.js';
@@ -828,15 +828,14 @@ class Game extends Messenger {
828
828
  * Captures a screenshot of the currently visible game viewport (the canvas /
829
829
  * camera view), not the full stage or world bounds.
830
830
  *
831
- * Uses the same crop approach as Paco's ScreenShooter: after camera
832
- * transforms, the visible area is stage space (0, 0, screenWidth, screenHeight).
833
- * Extracting only that frame avoids pulling in off-screen world content and
834
- * avoids GPU texture-size failures when a full level's stage bounds are huge.
831
+ * Renders the stage into a screen-sized render texture (same space as the
832
+ * backbuffer), then extracts that texture. Never extracts the full stage —
833
+ * large levels exceed GPU max texture / renderbuffer size.
835
834
  *
836
835
  * @param {Object} [options]
837
836
  * @param {string} [options.format='png'] Image format for data URLs (`png`, `jpg`/`jpeg`, `webp`).
838
837
  * @param {number} [options.quality] Encoder quality for lossy formats (0–1).
839
- * @param {boolean} [options.render=true] Render the stage before capturing.
838
+ * @param {boolean} [options.render=true] Unused; kept for API compatibility (always renders to the capture target).
840
839
  * @param {string} [options.as='dataURL'] Return type: `dataURL` or `canvas`.
841
840
  * @return {Promise<string|HTMLCanvasElement|null>} Screenshot, or null if unavailable.
842
841
  **/
@@ -845,7 +844,6 @@ class Game extends Messenger {
845
844
  {
846
845
  format = 'png',
847
846
  quality,
848
- render = true,
849
847
  as = 'dataURL'
850
848
  } = options,
851
849
  {renderer, stage} = this;
@@ -854,77 +852,52 @@ class Game extends Messenger {
854
852
  return null;
855
853
  }
856
854
 
857
- if (render) {
858
- renderer.render(stage);
859
- }
860
-
861
855
  const
862
856
  width = Math.max(1, renderer.screen.width | 0),
863
857
  height = Math.max(1, renderer.screen.height | 0),
864
858
  resolution = renderer.resolution || 1,
865
859
  backgroundColor = this.options?.display?.backgroundColor,
866
860
  hasBackground = typeof backgroundColor === 'number' && backgroundColor >= 0,
867
- // Opaque clear — transparent extracts read as a black shot in Notefully.
861
+ // Opaque clear — transparent captures read as a black shot in Notefully.
868
862
  clearColor = hasBackground ? backgroundColor : 0x000000,
869
863
  mime = format === 'jpg' || format === 'jpeg'
870
864
  ? 'image/jpeg'
871
865
  : format === 'webp'
872
866
  ? 'image/webp'
873
- : 'image/png',
874
- toOutput = (canvas) => {
875
- if (as === 'canvas') {
876
- return canvas;
877
- }
867
+ : 'image/png';
878
868
 
879
- return typeof quality === 'number'
880
- ? canvas.toDataURL(mime, quality)
881
- : canvas.toDataURL(mime);
882
- };
869
+ let target = null;
883
870
 
884
871
  try {
885
- // Screen-sized framed extract (viewport only).
886
- return toOutput(renderer.extract.canvas({
887
- target: stage,
888
- frame: new Rectangle(0, 0, width, height),
889
- resolution,
890
- clearColor
891
- }));
892
- } catch (err) {
893
- platypus.debug.warn('Game.captureViewport framed extract failed; trying bounds crop.', err);
894
- }
872
+ target = RenderTexture.create({
873
+ width,
874
+ height,
875
+ resolution
876
+ });
895
877
 
896
- // Paco ScreenShooter fallback: full extract, then crop the screen origin.
897
- try {
898
- const
899
- bounds = stage.getBounds(),
900
- full = renderer.extract.canvas(stage),
901
- dest = document.createElement('canvas'),
902
- ctx = dest.getContext('2d');
878
+ renderer.render({
879
+ container: stage,
880
+ target,
881
+ clear: true,
882
+ clearColor
883
+ });
903
884
 
904
- dest.width = width;
905
- dest.height = height;
885
+ const canvas = renderer.extract.canvas(target);
906
886
 
907
- if (hasBackground) {
908
- ctx.fillStyle = `#${backgroundColor.toString(16).padStart(6, '0')}`;
909
- ctx.fillRect(0, 0, width, height);
887
+ if (as === 'canvas') {
888
+ return canvas;
910
889
  }
911
890
 
912
- ctx.drawImage(
913
- full,
914
- -bounds.x,
915
- -bounds.y,
916
- width,
917
- height,
918
- 0,
919
- 0,
920
- width,
921
- height
922
- );
923
-
924
- return toOutput(dest);
891
+ return typeof quality === 'number'
892
+ ? canvas.toDataURL(mime, quality)
893
+ : canvas.toDataURL(mime);
925
894
  } catch (err) {
926
895
  platypus.debug.warn('Game.captureViewport failed.', err);
927
896
  return null;
897
+ } finally {
898
+ if (target) {
899
+ target.destroy(true);
900
+ }
928
901
  }
929
902
  }
930
903