@makefully/platypus 4.1.6 → 4.1.8

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.6",
3
+ "version": "4.1.8",
4
4
  "description": "2D tile-based HTML5 game engine with a component-based entity model",
5
5
  "license": "MIT",
6
6
  "contributors": [
@@ -73,7 +73,7 @@
73
73
  "webpack-dev-server": "^5.2.2"
74
74
  },
75
75
  "peerDependencies": {
76
- "@esotericsoftware/spine-pixi-v8": "^4.2.111",
76
+ "@esotericsoftware/spine-pixi-v8": "^4.3.7",
77
77
  "@pixi/sound": "github:Makefully-Studios/sound#feature/media-file",
78
78
  "@tweenjs/tween.js": "^23.1.1",
79
79
  "pako": "^2.1.0",
@@ -376,9 +376,17 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
376
376
  spineAtlas = platypus.assetCache.get(this.atlas),
377
377
  spineJsonParser = new SkeletonJson(new AtlasAttachmentLoader(spineAtlas)),
378
378
  skeletonData = spineJsonParser.readSkeletonData(skeleton),
379
- spine = this.spine = new Spine(skeletonData),
379
+ spine = this.spine = new Spine({skeletonData, autoUpdate: false}),
380
380
  map = createAnimationMap(this.animationMap, skeleton.animations);
381
381
 
382
+ // Spine 4.3 inherits Pixi container world-transform deltas into skeleton physics by default.
383
+ // Platypus pans the camera by moving the world container, which shifts every entity's world
384
+ // transform even when owner.x/y are unchanged — causing unwanted physics on stationary characters.
385
+ // Use the `apply-spine-physics` event for intentional movement-driven physics instead.
386
+ spine.setPhysicsPositionInheritanceFactor(0, 0);
387
+ spine.physicsRotationInheritanceFactor = 0;
388
+ spine.resetPhysicsTransform();
389
+
382
390
  let animation = '';
383
391
 
384
392
  spine.state.addListener({
@@ -414,7 +422,6 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
414
422
  this.owner.triggerEvent('animation-ended', animationName);
415
423
  }
416
424
  });
417
- spine.autoUpdate = false;
418
425
 
419
426
  this.stateBased = map && this.stateBased;
420
427
  this.eventBased = map && this.eventBased;
@@ -621,7 +628,7 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
621
628
  for (x = 0; x < slots.length; x++) {
622
629
  slot = this.spine.skeleton.findSlot(slots[x]);
623
630
  if (slot) {
624
- slot.color.setFromString(color);
631
+ slot.pose.color.setFromString(color);
625
632
  }
626
633
  }
627
634
  },
@@ -660,7 +667,7 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
660
667
  * rotate: {x: 0, y: 0, degrees: 0}
661
668
  * }
662
669
  *
663
- * Has known vibration issues. Until pixi-spine 4.3, recommend 120 FPS on physics constraints on joints.
670
+ * Has known vibration issues at low frame rates. Spine 4.3 improves physics constraint stability.
664
671
  * Potential fixes: https://esotericsoftware.com/forum/d/28093-jittering-when-applying-physicstranslate-pixispine/5
665
672
  *
666
673
  * @event platypus.Entity#apply-spine-physics
@@ -672,7 +679,7 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
672
679
  }
673
680
 
674
681
  if (changes.rotate) {
675
- this.spine.skeleton.physicsTranslate(changes.rotate.x, changes.rotate.y, changes.rotate.degrees);
682
+ this.spine.skeleton.physicsRotate(changes.rotate.x, changes.rotate.y, changes.rotate.degrees);
676
683
  }
677
684
  }
678
685
  },
@@ -698,7 +705,7 @@ export default createComponentClass(/** @lends platypus.components.RenderSpine.p
698
705
  }
699
706
 
700
707
  this.spine.skeleton.setSkin(skin);
701
- this.spine.skeleton.setSlotsToSetupPose();
708
+ this.spine.skeleton.setupPoseSlots();
702
709
  },
703
710
  addToContainer: function () {
704
711
  this.owner.container.cullable = false;
@@ -257,7 +257,43 @@ export default createComponentClass(/** @lends platypus.components.RenderTiles.p
257
257
  * @type Number
258
258
  * @default 0
259
259
  */
260
- left: 0
260
+ left: 0,
261
+
262
+ /**
263
+ * Tiled parallax factor for horizontal scrolling. 1.0 scrolls with the camera; values less than 1.0 scroll slower (background); 0 is fixed to the screen.
264
+ *
265
+ * @property parallaxX
266
+ * @type number
267
+ * @default 1
268
+ */
269
+ parallaxX: 1,
270
+
271
+ /**
272
+ * Tiled parallax factor for vertical scrolling.
273
+ *
274
+ * @property parallaxY
275
+ * @type number
276
+ * @default 1
277
+ */
278
+ parallaxY: 1,
279
+
280
+ /**
281
+ * Map parallax origin X in world coordinates (Tiled `parallaxoriginx`, plus any map offset).
282
+ *
283
+ * @property parallaxOriginX
284
+ * @type number
285
+ * @default 0
286
+ */
287
+ parallaxOriginX: 0,
288
+
289
+ /**
290
+ * Map parallax origin Y in world coordinates (Tiled `parallaxoriginy`, plus any map offset).
291
+ *
292
+ * @property parallaxOriginY
293
+ * @type number
294
+ * @default 0
295
+ */
296
+ parallaxOriginY: 0
261
297
  },
262
298
 
263
299
  /**
@@ -873,6 +909,10 @@ export default createComponentClass(/** @lends platypus.components.RenderTiles.p
873
909
  * its world travel, laxCam is at the start of the layer's travel, and
874
910
  * likewise at the end.
875
911
  *
912
+ * Tiled `parallaxx` / `parallaxy` factors are then applied relative to the
913
+ * map's parallax origin so the layer's effective render position is:
914
+ * `layerPos - (camera - parallaxOrigin) * (1 - parallaxFactor)`.
915
+ *
876
916
  * IMPORTANT: laxCam is resized to the *actual viewport dimensions* (not
877
917
  * viewport + refreshBuffer). Its purpose is solely to compute the parallax
878
918
  * offset for sprite positioning (vp.left - laxCam.left). Inflating it with
@@ -885,7 +925,8 @@ export default createComponentClass(/** @lends platypus.components.RenderTiles.p
885
925
  worldPosX = worldWidth - camera.width,
886
926
  worldHeight = this.worldHeight / this.scaleY,
887
927
  worldPosY = worldHeight - camera.height,
888
- laxCam = this.laxCam;
928
+ laxCam = this.laxCam,
929
+ {parallaxOriginX, parallaxOriginY, parallaxX, parallaxY} = this;
889
930
 
890
931
  if ((worldWidth === this.layerWidth) || !worldPosX) {
891
932
  laxCam.moveX(camera.x);
@@ -899,6 +940,14 @@ export default createComponentClass(/** @lends platypus.components.RenderTiles.p
899
940
  laxCam.moveY((camera.top - this.top) * (this.layerHeight - camera.height) / worldPosY + camera.halfHeight + this.top);
900
941
  }
901
942
 
943
+ if (parallaxX !== 1) {
944
+ laxCam.moveX(laxCam.x + (camera.x - parallaxOriginX) * (1 - parallaxX));
945
+ }
946
+
947
+ if (parallaxY !== 1) {
948
+ laxCam.moveY(laxCam.y + (camera.y - parallaxOriginY) * (1 - parallaxY));
949
+ }
950
+
902
951
  // FIX: resize laxCam to the actual viewport size only — never camera + refreshBuffer.
903
952
  if (camera.width !== laxCam.width || camera.height !== laxCam.height) {
904
953
  laxCam.resize(camera.width, camera.height);
@@ -699,7 +699,7 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
699
699
  },
700
700
 
701
701
  methods: {
702
- createLayer: function (entityKind, rawLayer, offsetX, offsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker) {
702
+ createLayer: function (entityKind, rawLayer, offsetX, offsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker, parallaxOriginX, parallaxOriginY) {
703
703
  const
704
704
  //This builds in parallaxing support by allowing the addition of width and height properties into Tiled layers so they pan at a separate rate than other layers.
705
705
  checkParallax = ({data, height, properties, width}) => {
@@ -730,6 +730,8 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
730
730
  },
731
731
 
732
732
  layer = decodeLayer(rawLayer),
733
+ parallaxX = layer.parallaxx ?? 1,
734
+ parallaxY = layer.parallaxy ?? 1,
733
735
  {
734
736
  offsetx: layerOffsetX = 0,
735
737
  offsety: layerOffsetY = 0,
@@ -835,6 +837,10 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
835
837
  layerDefinitionProperties.left = layerDefinitionProperties.x || mapOffsetX;
836
838
  layerDefinitionProperties.top = layerDefinitionProperties.y || mapOffsetY;
837
839
  layerDefinitionProperties.z = layerDefinitionProperties.z || this.layerZ;
840
+ layerDefinitionProperties.parallaxX = parallaxX;
841
+ layerDefinitionProperties.parallaxY = parallaxY;
842
+ layerDefinitionProperties.parallaxOriginX = parallaxOriginX;
843
+ layerDefinitionProperties.parallaxOriginY = parallaxOriginY;
838
844
 
839
845
  if (tilesets.length) {
840
846
  let imageIndex = 0;
@@ -910,7 +916,7 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
910
916
  }
911
917
  }
912
918
 
913
- if ((!this.separateTiles) && (combineRenderLayer?.tileHeight === tHeight) && (combineRenderLayer?.tileWidth === tWidth) && (combineRenderLayer?.columns === width) && (combineRenderLayer?.rows === height)) {
919
+ if ((!this.separateTiles) && (combineRenderLayer?.parallaxX ?? 1) === parallaxX && (combineRenderLayer?.parallaxY ?? 1) === parallaxY && (combineRenderLayer?.tileHeight === tHeight) && (combineRenderLayer?.tileWidth === tWidth) && (combineRenderLayer?.columns === width) && (combineRenderLayer?.rows === height)) {
914
920
  combineRenderLayer.triggerEvent('add-tiles', renderTiles);
915
921
  combineRenderLayer.triggerEvent('add-collision-tiles', collisionTiles);
916
922
 
@@ -998,7 +1004,9 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
998
1004
  height = level.height * tileHeight,
999
1005
  width = level.width * tileWidth,
1000
1006
  x = offsetMap ? getPowerOfTen(width) : 0,
1001
- y = offsetMap ? getPowerOfTen(height) : 0;
1007
+ y = offsetMap ? getPowerOfTen(height) : 0,
1008
+ parallaxOriginX = (level.parallaxoriginx ?? 0) + x,
1009
+ parallaxOriginY = (level.parallaxoriginy ?? 0) + y;
1002
1010
  let layer = null;
1003
1011
 
1004
1012
  createTilesetObjectGroupReference(tileSetTileData, tilesets);
@@ -1130,7 +1138,7 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
1130
1138
  switch (layerDefinition.type) {
1131
1139
  case 'imagelayer':
1132
1140
  layer = this.convertImageLayer(layerDefinition);
1133
- layer = this.createLayer(getProperty(layer.properties, 'entity') || 'image-layer', layer, x, y, layer.tilewidth, layer.tileheight, [layer.tileset], null, images, layer, progress, entityLinker);
1141
+ layer = this.createLayer(getProperty(layer.properties, 'entity') || 'image-layer', layer, x, y, layer.tilewidth, layer.tileheight, [layer.tileset], null, images, layer, progress, entityLinker, parallaxOriginX, parallaxOriginY);
1134
1142
  break;
1135
1143
  case 'objectgroup':
1136
1144
  this.setUpEntities(layerDefinition.objects.map((object) => getObjectCentered(object)), layerDefinition, x, y, tilesets, progress, entityLinker);
@@ -1138,7 +1146,7 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
1138
1146
  this.updateLoadingProgress(progress);
1139
1147
  break;
1140
1148
  case 'tilelayer':
1141
- layer = this.setupLayer(layerDefinition, layer, x, y, tileWidth, tileHeight, tilesets, tileSetTileData, images, progress, entityLinker);
1149
+ layer = this.setupLayer(layerDefinition, layer, x, y, tileWidth, tileHeight, tilesets, tileSetTileData, images, progress, entityLinker, parallaxOriginX, parallaxOriginY);
1142
1150
  break;
1143
1151
  default:
1144
1152
  platypus.debug.warn('Component TiledLoader: Platypus does not support Tiled layers of type "' + layerDefinition.type + '". This layer will not be loaded.');
@@ -1374,7 +1382,7 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
1374
1382
  };
1375
1383
  }()),
1376
1384
 
1377
- setupLayer: function (layer, combineRenderLayer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, progress, entityLinker) {
1385
+ setupLayer: function (layer, combineRenderLayer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, progress, entityLinker, parallaxOriginX, parallaxOriginY) {
1378
1386
  const
1379
1387
  entity = getProperty(layer.properties, 'entity') ?? 'render-layer', // default
1380
1388
  entityDefinition = platypus.game.settings.entities[entity] ?? standardEntityLayers[entity];
@@ -1393,9 +1401,9 @@ export default createComponentClass(/** @lends platypus.components.TiledLoader.p
1393
1401
  }
1394
1402
 
1395
1403
  if (canCombine) {
1396
- return this.createLayer(entity, layer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker);
1404
+ return this.createLayer(entity, layer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker, parallaxOriginX, parallaxOriginY);
1397
1405
  } else {
1398
- this.createLayer(entity, layer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker);
1406
+ this.createLayer(entity, layer, mapOffsetX, mapOffsetY, tileWidth, tileHeight, tilesets, tileSetTileData, images, combineRenderLayer, progress, entityLinker, parallaxOriginX, parallaxOriginY);
1399
1407
  return null;
1400
1408
  }
1401
1409
  },