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.
- package/dist/littlejs.d.ts +8 -4
- package/dist/littlejs.esm.js +29 -18
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +29 -18
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +29 -18
- package/package.json +1 -1
- package/plugins/textureSheet.js +28 -17
- package/src/engine.js +1 -1
package/dist/littlejs.release.js
CHANGED
|
@@ -35,7 +35,7 @@ const engineName = 'LittleJS';
|
|
|
35
35
|
* @type {string}
|
|
36
36
|
* @default
|
|
37
37
|
* @memberof Engine */
|
|
38
|
-
const engineVersion = '1.18.
|
|
38
|
+
const engineVersion = '1.18.23';
|
|
39
39
|
|
|
40
40
|
/** Frames per second to update
|
|
41
41
|
* @type {number}
|
|
@@ -14307,13 +14307,19 @@ class TextureSheet
|
|
|
14307
14307
|
* @param {Vector2} imageSize - Size of the source image in pixels
|
|
14308
14308
|
* @param {Vector2} [frameSize] - Size of each frame, or the whole image if not passed
|
|
14309
14309
|
* @param {number} [padding] - How many pixels padding around each frame
|
|
14310
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
|
|
14310
14311
|
* @return {TileInfo} Tile for the packed image, or undefined if the sheet is full */
|
|
14311
|
-
tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding)
|
|
14312
|
+
tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding, sourcePadding=0)
|
|
14312
14313
|
{
|
|
14313
14314
|
ASSERT(isVector2(imageSize) && isVector2(frameSize), 'sizes must be vec2');
|
|
14314
14315
|
ASSERT(frameSize.x > 0 && frameSize.y > 0, 'frame size must be positive');
|
|
14315
|
-
ASSERT(
|
|
14316
|
-
|
|
14316
|
+
ASSERT(isNumber(sourcePadding) && sourcePadding >= 0, 'sourcePadding must be a number >= 0');
|
|
14317
|
+
|
|
14318
|
+
// the source may have its own padding baked in around each frame
|
|
14319
|
+
const sourceCellWidth = frameSize.x + sourcePadding*2;
|
|
14320
|
+
const sourceCellHeight = frameSize.y + sourcePadding*2;
|
|
14321
|
+
ASSERT(imageSize.x % sourceCellWidth === 0 && imageSize.y % sourceCellHeight === 0,
|
|
14322
|
+
'image size must be a multiple of the padded frame size');
|
|
14317
14323
|
|
|
14318
14324
|
const cellWidth = frameSize.x + padding*2;
|
|
14319
14325
|
const cellHeight = frameSize.y + padding*2;
|
|
@@ -14322,8 +14328,8 @@ class TextureSheet
|
|
|
14322
14328
|
|
|
14323
14329
|
// keep the layout of the source image, but narrow it if a row is too wide
|
|
14324
14330
|
// frames wrap down to the next row, which TileInfo.frame handles via columns
|
|
14325
|
-
const sourceColumns = imageSize.x /
|
|
14326
|
-
const frameCount = sourceColumns * (imageSize.y /
|
|
14331
|
+
const sourceColumns = imageSize.x / sourceCellWidth;
|
|
14332
|
+
const frameCount = sourceColumns * (imageSize.y / sourceCellHeight);
|
|
14327
14333
|
const columns = min(sourceColumns, maxColumns);
|
|
14328
14334
|
const blockWidth = columns * cellWidth;
|
|
14329
14335
|
const blockHeight = ceil(frameCount / columns) * cellHeight;
|
|
@@ -14352,23 +14358,26 @@ class TextureSheet
|
|
|
14352
14358
|
/** Draw an image into this sheet at a tile returned by tryAdd
|
|
14353
14359
|
* @param {HTMLImageElement} image - Source image to copy from
|
|
14354
14360
|
* @param {TileInfo} tileInfo - Where to put it, from tryAdd
|
|
14355
|
-
* @param {boolean} [update] - Upload to webgl now, pass false when batching
|
|
14356
|
-
|
|
14361
|
+
* @param {boolean} [update] - Upload to webgl now, pass false when batching
|
|
14362
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image */
|
|
14363
|
+
drawImage(image, tileInfo, update=true, sourcePadding=0)
|
|
14357
14364
|
{
|
|
14358
14365
|
ASSERT(!!this.context, 'texture sheet has no canvas');
|
|
14359
14366
|
|
|
14360
14367
|
// copy frames in order, reading the source left to right, top to bottom
|
|
14361
14368
|
// the destination wraps at tileInfo.columns which may be narrower than the source
|
|
14362
14369
|
const frameSize = tileInfo.size;
|
|
14363
|
-
const
|
|
14364
|
-
const
|
|
14370
|
+
const sourceCellWidth = frameSize.x + sourcePadding*2;
|
|
14371
|
+
const sourceCellHeight = frameSize.y + sourcePadding*2;
|
|
14372
|
+
const sourceColumns = image.width / sourceCellWidth;
|
|
14373
|
+
const frameCount = sourceColumns * (image.height / sourceCellHeight);
|
|
14365
14374
|
const columns = tileInfo.columns || frameCount;
|
|
14366
14375
|
const cellWidth = frameSize.x + tileInfo.padding*2;
|
|
14367
14376
|
const cellHeight = frameSize.y + tileInfo.padding*2;
|
|
14368
14377
|
for (let i = frameCount; i--;)
|
|
14369
14378
|
{
|
|
14370
|
-
const sourceX = (i % sourceColumns) *
|
|
14371
|
-
const sourceY = (i / sourceColumns | 0) *
|
|
14379
|
+
const sourceX = (i % sourceColumns) * sourceCellWidth + sourcePadding;
|
|
14380
|
+
const sourceY = (i / sourceColumns | 0) * sourceCellHeight + sourcePadding;
|
|
14372
14381
|
this.context.drawImage(image,
|
|
14373
14382
|
sourceX, sourceY, frameSize.x, frameSize.y,
|
|
14374
14383
|
tileInfo.pos.x + (i % columns) * cellWidth,
|
|
@@ -14398,15 +14407,17 @@ class TextureSheet
|
|
|
14398
14407
|
* - Nothing is visible until it loads, use spritesReady to wait for it
|
|
14399
14408
|
* - Pass frameSize for animations, then step through them with TileInfo.frame
|
|
14400
14409
|
* - Grid images keep their layout and frames wrap down to the next row
|
|
14410
|
+
* - Pass sourcePadding if the source image has padding baked in around frames
|
|
14401
14411
|
* @param {string} src - Image source path
|
|
14402
14412
|
* @param {Vector2|number} [frameSize] - Size of each animation frame in pixels
|
|
14403
14413
|
* @param {number} [padding] - How many pixels padding around each frame
|
|
14414
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
|
|
14404
14415
|
* @return {TileInfo}
|
|
14405
14416
|
* @example
|
|
14406
14417
|
* const playerTile = loadSprite('player.png'); // a single sprite
|
|
14407
14418
|
* const runTile = loadSprite('run.png', vec2(16)); // a 16x16 frame animation
|
|
14408
14419
|
* @memberof TextureSheets */
|
|
14409
|
-
function loadSprite(src, frameSize, padding=textureSheetPadding)
|
|
14420
|
+
function loadSprite(src, frameSize, padding=textureSheetPadding, sourcePadding=0)
|
|
14410
14421
|
{
|
|
14411
14422
|
ASSERT(isStringLike(src), 'image src must be a string');
|
|
14412
14423
|
ASSERT(!frameSize || isVector2(frameSize) || isNumber(frameSize), 'frameSize must be a vec2 or number');
|
|
@@ -14441,9 +14452,9 @@ function loadSprite(src, frameSize, padding=textureSheetPadding)
|
|
|
14441
14452
|
// pack onto a sheet, then fill in the tile that was already handed out,
|
|
14442
14453
|
// copying every field so nothing is missed if TileInfo gains more of them
|
|
14443
14454
|
const imageSize = vec2(image.width, image.height);
|
|
14444
|
-
const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding);
|
|
14455
|
+
const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding, sourcePadding);
|
|
14445
14456
|
Object.assign(tileInfo, tile);
|
|
14446
|
-
sheet.drawImage(image, tileInfo, false); // upload once per batch below
|
|
14457
|
+
sheet.drawImage(image, tileInfo, false, sourcePadding); // upload once per batch below
|
|
14447
14458
|
}
|
|
14448
14459
|
else
|
|
14449
14460
|
{
|
|
@@ -14644,16 +14655,16 @@ function textureSheetCreate()
|
|
|
14644
14655
|
}
|
|
14645
14656
|
|
|
14646
14657
|
// use the first sheet with enough space, or make a new one
|
|
14647
|
-
function textureSheetAdd(imageSize, frameSize, padding)
|
|
14658
|
+
function textureSheetAdd(imageSize, frameSize, padding, sourcePadding)
|
|
14648
14659
|
{
|
|
14649
14660
|
let sheet, tile;
|
|
14650
14661
|
for (sheet of textureSheets)
|
|
14651
|
-
if (tile = sheet.tryAdd(imageSize, frameSize, padding))
|
|
14662
|
+
if (tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding))
|
|
14652
14663
|
break;
|
|
14653
14664
|
if (!tile)
|
|
14654
14665
|
{
|
|
14655
14666
|
sheet = textureSheetCreate();
|
|
14656
|
-
tile = sheet.tryAdd(imageSize, frameSize, padding);
|
|
14667
|
+
tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding);
|
|
14657
14668
|
ASSERT(!!tile, 'image is too large to fit on a texture sheet');
|
|
14658
14669
|
}
|
|
14659
14670
|
return {sheet, tile};
|
package/package.json
CHANGED
package/plugins/textureSheet.js
CHANGED
|
@@ -73,13 +73,19 @@ class TextureSheet
|
|
|
73
73
|
* @param {Vector2} imageSize - Size of the source image in pixels
|
|
74
74
|
* @param {Vector2} [frameSize] - Size of each frame, or the whole image if not passed
|
|
75
75
|
* @param {number} [padding] - How many pixels padding around each frame
|
|
76
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
|
|
76
77
|
* @return {TileInfo} Tile for the packed image, or undefined if the sheet is full */
|
|
77
|
-
tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding)
|
|
78
|
+
tryAdd(imageSize, frameSize=imageSize, padding=textureSheetPadding, sourcePadding=0)
|
|
78
79
|
{
|
|
79
80
|
ASSERT(isVector2(imageSize) && isVector2(frameSize), 'sizes must be vec2');
|
|
80
81
|
ASSERT(frameSize.x > 0 && frameSize.y > 0, 'frame size must be positive');
|
|
81
|
-
ASSERT(
|
|
82
|
-
|
|
82
|
+
ASSERT(isNumber(sourcePadding) && sourcePadding >= 0, 'sourcePadding must be a number >= 0');
|
|
83
|
+
|
|
84
|
+
// the source may have its own padding baked in around each frame
|
|
85
|
+
const sourceCellWidth = frameSize.x + sourcePadding*2;
|
|
86
|
+
const sourceCellHeight = frameSize.y + sourcePadding*2;
|
|
87
|
+
ASSERT(imageSize.x % sourceCellWidth === 0 && imageSize.y % sourceCellHeight === 0,
|
|
88
|
+
'image size must be a multiple of the padded frame size');
|
|
83
89
|
|
|
84
90
|
const cellWidth = frameSize.x + padding*2;
|
|
85
91
|
const cellHeight = frameSize.y + padding*2;
|
|
@@ -88,8 +94,8 @@ class TextureSheet
|
|
|
88
94
|
|
|
89
95
|
// keep the layout of the source image, but narrow it if a row is too wide
|
|
90
96
|
// frames wrap down to the next row, which TileInfo.frame handles via columns
|
|
91
|
-
const sourceColumns = imageSize.x /
|
|
92
|
-
const frameCount = sourceColumns * (imageSize.y /
|
|
97
|
+
const sourceColumns = imageSize.x / sourceCellWidth;
|
|
98
|
+
const frameCount = sourceColumns * (imageSize.y / sourceCellHeight);
|
|
93
99
|
const columns = min(sourceColumns, maxColumns);
|
|
94
100
|
const blockWidth = columns * cellWidth;
|
|
95
101
|
const blockHeight = ceil(frameCount / columns) * cellHeight;
|
|
@@ -118,23 +124,26 @@ class TextureSheet
|
|
|
118
124
|
/** Draw an image into this sheet at a tile returned by tryAdd
|
|
119
125
|
* @param {HTMLImageElement} image - Source image to copy from
|
|
120
126
|
* @param {TileInfo} tileInfo - Where to put it, from tryAdd
|
|
121
|
-
* @param {boolean} [update] - Upload to webgl now, pass false when batching
|
|
122
|
-
|
|
127
|
+
* @param {boolean} [update] - Upload to webgl now, pass false when batching
|
|
128
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image */
|
|
129
|
+
drawImage(image, tileInfo, update=true, sourcePadding=0)
|
|
123
130
|
{
|
|
124
131
|
ASSERT(!!this.context, 'texture sheet has no canvas');
|
|
125
132
|
|
|
126
133
|
// copy frames in order, reading the source left to right, top to bottom
|
|
127
134
|
// the destination wraps at tileInfo.columns which may be narrower than the source
|
|
128
135
|
const frameSize = tileInfo.size;
|
|
129
|
-
const
|
|
130
|
-
const
|
|
136
|
+
const sourceCellWidth = frameSize.x + sourcePadding*2;
|
|
137
|
+
const sourceCellHeight = frameSize.y + sourcePadding*2;
|
|
138
|
+
const sourceColumns = image.width / sourceCellWidth;
|
|
139
|
+
const frameCount = sourceColumns * (image.height / sourceCellHeight);
|
|
131
140
|
const columns = tileInfo.columns || frameCount;
|
|
132
141
|
const cellWidth = frameSize.x + tileInfo.padding*2;
|
|
133
142
|
const cellHeight = frameSize.y + tileInfo.padding*2;
|
|
134
143
|
for (let i = frameCount; i--;)
|
|
135
144
|
{
|
|
136
|
-
const sourceX = (i % sourceColumns) *
|
|
137
|
-
const sourceY = (i / sourceColumns | 0) *
|
|
145
|
+
const sourceX = (i % sourceColumns) * sourceCellWidth + sourcePadding;
|
|
146
|
+
const sourceY = (i / sourceColumns | 0) * sourceCellHeight + sourcePadding;
|
|
138
147
|
this.context.drawImage(image,
|
|
139
148
|
sourceX, sourceY, frameSize.x, frameSize.y,
|
|
140
149
|
tileInfo.pos.x + (i % columns) * cellWidth,
|
|
@@ -164,15 +173,17 @@ class TextureSheet
|
|
|
164
173
|
* - Nothing is visible until it loads, use spritesReady to wait for it
|
|
165
174
|
* - Pass frameSize for animations, then step through them with TileInfo.frame
|
|
166
175
|
* - Grid images keep their layout and frames wrap down to the next row
|
|
176
|
+
* - Pass sourcePadding if the source image has padding baked in around frames
|
|
167
177
|
* @param {string} src - Image source path
|
|
168
178
|
* @param {Vector2|number} [frameSize] - Size of each animation frame in pixels
|
|
169
179
|
* @param {number} [padding] - How many pixels padding around each frame
|
|
180
|
+
* @param {number} [sourcePadding] - How many pixels padding around each frame in the source image
|
|
170
181
|
* @return {TileInfo}
|
|
171
182
|
* @example
|
|
172
183
|
* const playerTile = loadSprite('player.png'); // a single sprite
|
|
173
184
|
* const runTile = loadSprite('run.png', vec2(16)); // a 16x16 frame animation
|
|
174
185
|
* @memberof TextureSheets */
|
|
175
|
-
function loadSprite(src, frameSize, padding=textureSheetPadding)
|
|
186
|
+
function loadSprite(src, frameSize, padding=textureSheetPadding, sourcePadding=0)
|
|
176
187
|
{
|
|
177
188
|
ASSERT(isStringLike(src), 'image src must be a string');
|
|
178
189
|
ASSERT(!frameSize || isVector2(frameSize) || isNumber(frameSize), 'frameSize must be a vec2 or number');
|
|
@@ -207,9 +218,9 @@ function loadSprite(src, frameSize, padding=textureSheetPadding)
|
|
|
207
218
|
// pack onto a sheet, then fill in the tile that was already handed out,
|
|
208
219
|
// copying every field so nothing is missed if TileInfo gains more of them
|
|
209
220
|
const imageSize = vec2(image.width, image.height);
|
|
210
|
-
const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding);
|
|
221
|
+
const {sheet, tile} = textureSheetAdd(imageSize, frameSize, padding, sourcePadding);
|
|
211
222
|
Object.assign(tileInfo, tile);
|
|
212
|
-
sheet.drawImage(image, tileInfo, false); // upload once per batch below
|
|
223
|
+
sheet.drawImage(image, tileInfo, false, sourcePadding); // upload once per batch below
|
|
213
224
|
}
|
|
214
225
|
else
|
|
215
226
|
{
|
|
@@ -410,16 +421,16 @@ function textureSheetCreate()
|
|
|
410
421
|
}
|
|
411
422
|
|
|
412
423
|
// use the first sheet with enough space, or make a new one
|
|
413
|
-
function textureSheetAdd(imageSize, frameSize, padding)
|
|
424
|
+
function textureSheetAdd(imageSize, frameSize, padding, sourcePadding)
|
|
414
425
|
{
|
|
415
426
|
let sheet, tile;
|
|
416
427
|
for (sheet of textureSheets)
|
|
417
|
-
if (tile = sheet.tryAdd(imageSize, frameSize, padding))
|
|
428
|
+
if (tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding))
|
|
418
429
|
break;
|
|
419
430
|
if (!tile)
|
|
420
431
|
{
|
|
421
432
|
sheet = textureSheetCreate();
|
|
422
|
-
tile = sheet.tryAdd(imageSize, frameSize, padding);
|
|
433
|
+
tile = sheet.tryAdd(imageSize, frameSize, padding, sourcePadding);
|
|
423
434
|
ASSERT(!!tile, 'image is too large to fit on a texture sheet');
|
|
424
435
|
}
|
|
425
436
|
return {sheet, tile};
|