littlejsengine 1.18.22 → 1.18.23

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.
@@ -5841,13 +5841,15 @@ declare module "littlejsengine" {
5841
5841
  * @param {Vector2} imageSize - Size of the source image in pixels
5842
5842
  * @param {Vector2} [frameSize] - Size of each frame, or the whole image if not passed
5843
5843
  * @param {number} [padding] - How many pixels padding around each frame
5844
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
5844
5845
  * @return {TileInfo} Tile for the packed image, or undefined if the sheet is full */
5845
- tryAdd(imageSize: Vector2, frameSize?: Vector2, padding?: number): TileInfo;
5846
+ tryAdd(imageSize: Vector2, frameSize?: Vector2, padding?: number, sourcePadding?: number): TileInfo;
5846
5847
  /** Draw an image into this sheet at a tile returned by tryAdd
5847
5848
  * @param {HTMLImageElement} image - Source image to copy from
5848
5849
  * @param {TileInfo} tileInfo - Where to put it, from tryAdd
5849
- * @param {boolean} [update] - Upload to webgl now, pass false when batching */
5850
- drawImage(image: HTMLImageElement, tileInfo: TileInfo, update?: boolean): void;
5850
+ * @param {boolean} [update] - Upload to webgl now, pass false when batching
5851
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image */
5852
+ drawImage(image: HTMLImageElement, tileInfo: TileInfo, update?: boolean, sourcePadding?: number): void;
5851
5853
  /** Upload the canvas to webgl if it has changed since the last upload
5852
5854
  * Only needed after batching, drawImage uploads automatically by default */
5853
5855
  updateTexture(): void;
@@ -5857,15 +5859,17 @@ declare module "littlejsengine" {
5857
5859
  * - Nothing is visible until it loads, use spritesReady to wait for it
5858
5860
  * - Pass frameSize for animations, then step through them with TileInfo.frame
5859
5861
  * - Grid images keep their layout and frames wrap down to the next row
5862
+ * - Pass sourcePadding if the source image has padding baked in around frames
5860
5863
  * @param {string} src - Image source path
5861
5864
  * @param {Vector2|number} [frameSize] - Size of each animation frame in pixels
5862
5865
  * @param {number} [padding] - How many pixels padding around each frame
5866
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
5863
5867
  * @return {TileInfo}
5864
5868
  * @example
5865
5869
  * const playerTile = loadSprite('player.png'); // a single sprite
5866
5870
  * const runTile = loadSprite('run.png', vec2(16)); // a 16x16 frame animation
5867
5871
  * @memberof TextureSheets */
5868
- export function loadSprite(src: string, frameSize?: Vector2 | number, padding?: number): TileInfo;
5872
+ export function loadSprite(src: string, frameSize?: Vector2 | number, padding?: number, sourcePadding?: number): TileInfo;
5869
5873
  /** Load a pre-packed texture atlas and repack it onto texture sheets
5870
5874
  * - Supports TexturePacker json (hash and array) and Aseprite json
5871
5875
  * - Returns an empty object which is filled with TileInfos when loaded
@@ -35,7 +35,7 @@ const engineName = 'LittleJS';
35
35
  * @type {string}
36
36
  * @default
37
37
  * @memberof Engine */
38
- const engineVersion = '1.18.22';
38
+ const engineVersion = '1.18.23';
39
39
 
40
40
  /** Frames per second to update
41
41
  * @type {number}
@@ -14998,13 +14998,19 @@ class TextureSheet
14998
14998
  * @param {Vector2} imageSize - Size of the source image in pixels
14999
14999
  * @param {Vector2} [frameSize] - Size of each frame, or the whole image if not passed
15000
15000
  * @param {number} [padding] - How many pixels padding around each frame
15001
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
15001
15002
  * @return {TileInfo} Tile for the packed image, or undefined if the sheet is full */
15002
- tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding)
15003
+ tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding, sourcePadding=0)
15003
15004
  {
15004
15005
  ASSERT(isVector2(imageSize) && isVector2(frameSize), 'sizes must be vec2');
15005
15006
  ASSERT(frameSize.x > 0 && frameSize.y > 0, 'frame size must be positive');
15006
- ASSERT(imageSize.x % frameSize.x === 0 && imageSize.y % frameSize.y === 0,
15007
- 'image size must be a multiple of the frame size');
15007
+ ASSERT(isNumber(sourcePadding) && sourcePadding >= 0, 'sourcePadding must be a number >= 0');
15008
+
15009
+ // the source may have its own padding baked in around each frame
15010
+ const sourceCellWidth = frameSize.x + sourcePadding*2;
15011
+ const sourceCellHeight = frameSize.y + sourcePadding*2;
15012
+ ASSERT(imageSize.x % sourceCellWidth === 0 && imageSize.y % sourceCellHeight === 0,
15013
+ 'image size must be a multiple of the padded frame size');
15008
15014
 
15009
15015
  const cellWidth = frameSize.x + padding*2;
15010
15016
  const cellHeight = frameSize.y + padding*2;
@@ -15013,8 +15019,8 @@ class TextureSheet
15013
15019
 
15014
15020
  // keep the layout of the source image, but narrow it if a row is too wide
15015
15021
  // frames wrap down to the next row, which TileInfo.frame handles via columns
15016
- const sourceColumns = imageSize.x / frameSize.x;
15017
- const frameCount = sourceColumns * (imageSize.y / frameSize.y);
15022
+ const sourceColumns = imageSize.x / sourceCellWidth;
15023
+ const frameCount = sourceColumns * (imageSize.y / sourceCellHeight);
15018
15024
  const columns = min(sourceColumns, maxColumns);
15019
15025
  const blockWidth = columns * cellWidth;
15020
15026
  const blockHeight = ceil(frameCount / columns) * cellHeight;
@@ -15043,23 +15049,26 @@ class TextureSheet
15043
15049
  /** Draw an image into this sheet at a tile returned by tryAdd
15044
15050
  * @param {HTMLImageElement} image - Source image to copy from
15045
15051
  * @param {TileInfo} tileInfo - Where to put it, from tryAdd
15046
- * @param {boolean} [update] - Upload to webgl now, pass false when batching */
15047
- drawImage(image, tileInfo, update=true)
15052
+ * @param {boolean} [update] - Upload to webgl now, pass false when batching
15053
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image */
15054
+ drawImage(image, tileInfo, update=true, sourcePadding=0)
15048
15055
  {
15049
15056
  ASSERT(!!this.context, 'texture sheet has no canvas');
15050
15057
 
15051
15058
  // copy frames in order, reading the source left to right, top to bottom
15052
15059
  // the destination wraps at tileInfo.columns which may be narrower than the source
15053
15060
  const frameSize = tileInfo.size;
15054
- const sourceColumns = image.width / frameSize.x;
15055
- const frameCount = sourceColumns * (image.height / frameSize.y);
15061
+ const sourceCellWidth = frameSize.x + sourcePadding*2;
15062
+ const sourceCellHeight = frameSize.y + sourcePadding*2;
15063
+ const sourceColumns = image.width / sourceCellWidth;
15064
+ const frameCount = sourceColumns * (image.height / sourceCellHeight);
15056
15065
  const columns = tileInfo.columns || frameCount;
15057
15066
  const cellWidth = frameSize.x + tileInfo.padding*2;
15058
15067
  const cellHeight = frameSize.y + tileInfo.padding*2;
15059
15068
  for (let i = frameCount; i--;)
15060
15069
  {
15061
- const sourceX = (i % sourceColumns) * frameSize.x;
15062
- const sourceY = (i / sourceColumns | 0) * frameSize.y;
15070
+ const sourceX = (i % sourceColumns) * sourceCellWidth + sourcePadding;
15071
+ const sourceY = (i / sourceColumns | 0) * sourceCellHeight + sourcePadding;
15063
15072
  this.context.drawImage(image,
15064
15073
  sourceX, sourceY, frameSize.x, frameSize.y,
15065
15074
  tileInfo.pos.x + (i % columns) * cellWidth,
@@ -15089,15 +15098,17 @@ class TextureSheet
15089
15098
  * - Nothing is visible until it loads, use spritesReady to wait for it
15090
15099
  * - Pass frameSize for animations, then step through them with TileInfo.frame
15091
15100
  * - Grid images keep their layout and frames wrap down to the next row
15101
+ * - Pass sourcePadding if the source image has padding baked in around frames
15092
15102
  * @param {string} src - Image source path
15093
15103
  * @param {Vector2|number} [frameSize] - Size of each animation frame in pixels
15094
15104
  * @param {number} [padding] - How many pixels padding around each frame
15105
+ * @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
15095
15106
  * @return {TileInfo}
15096
15107
  * @example
15097
15108
  * const playerTile = loadSprite('player.png'); // a single sprite
15098
15109
  * const runTile = loadSprite('run.png', vec2(16)); // a 16x16 frame animation
15099
15110
  * @memberof TextureSheets */
15100
- function loadSprite(src, frameSize, padding=textureSheetPadding)
15111
+ function loadSprite(src, frameSize, padding=textureSheetPadding, sourcePadding=0)
15101
15112
  {
15102
15113
  ASSERT(isStringLike(src), 'image src must be a string');
15103
15114
  ASSERT(!frameSize || isVector2(frameSize) || isNumber(frameSize), 'frameSize must be a vec2 or number');
@@ -15132,9 +15143,9 @@ function loadSprite(src, frameSize, padding=textureSheetPadding)
15132
15143
  // pack onto a sheet, then fill in the tile that was already handed out,
15133
15144
  // copying every field so nothing is missed if TileInfo gains more of them
15134
15145
  const imageSize = vec2(image.width, image.height);
15135
- const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding);
15146
+ const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding, sourcePadding);
15136
15147
  Object.assign(tileInfo, tile);
15137
- sheet.drawImage(image, tileInfo, false); // upload once per batch below
15148
+ sheet.drawImage(image, tileInfo, false, sourcePadding); // upload once per batch below
15138
15149
  }
15139
15150
  else
15140
15151
  {
@@ -15335,16 +15346,16 @@ function textureSheetCreate()
15335
15346
  }
15336
15347
 
15337
15348
  // use the first sheet with enough space, or make a new one
15338
- function textureSheetAdd(imageSize, frameSize, padding)
15349
+ function textureSheetAdd(imageSize, frameSize, padding, sourcePadding)
15339
15350
  {
15340
15351
  let sheet, tile;
15341
15352
  for (sheet of textureSheets)
15342
- if (tile = sheet.tryAdd(imageSize, frameSize, padding))
15353
+ if (tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding))
15343
15354
  break;
15344
15355
  if (!tile)
15345
15356
  {
15346
15357
  sheet = textureSheetCreate();
15347
- tile = sheet.tryAdd(imageSize, frameSize, padding);
15358
+ tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding);
15348
15359
  ASSERT(!!tile, 'image is too large to fit on a texture sheet');
15349
15360
  }
15350
15361
  return {sheet, tile};