squishjs 0.6.43 → 0.7.1
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/.github/workflows/node.js.yml +1 -1
- package/LICENSE.md +21 -0
- package/README.md +116 -42
- package/index.js +11 -1
- package/oldsvgexport.js +89 -0
- package/package.json +1 -1
- package/render-tester.js +120 -0
- package/src/BaseNode.js +101 -0
- package/src/Game.js +15 -3
- package/src/GameNode.js +82 -79
- package/src/InternalGameNode.js +4 -3
- package/src/Squisher.js +224 -0
- package/src/ViewableGame.js +60 -0
- package/src/node-types.js +15 -0
- package/src/squish.js +90 -349
- package/src/squishHelpers/asset.js +63 -0
- package/src/squishHelpers/border.js +16 -0
- package/src/squishHelpers/color.js +16 -0
- package/src/squishHelpers/coordinates2d.js +98 -0
- package/src/squishHelpers/effect.js +55 -0
- package/src/squishHelpers/fill.js +16 -0
- package/src/squishHelpers/handleClick.js +16 -0
- package/src/squishHelpers/id.js +16 -0
- package/src/squishHelpers/input.js +22 -0
- package/src/squishHelpers/playerIds.js +12 -0
- package/src/squishHelpers/pos.js +23 -0
- package/src/squishHelpers/size.js +23 -0
- package/src/squishHelpers/subType.js +16 -0
- package/src/squishHelpers/text.js +154 -0
- package/src/subtype-mappings.js +10 -0
- package/src/subtypes.js +7 -0
- package/{dist/terrain/defs.d.ts → src/terrain/defs.ts} +7 -6
- package/src/terrain/index.ts +156 -0
- package/src/terrain/terrainFunctions.ts +142 -0
- package/src/util/geometry.js +45 -0
- package/src/util/index.ts +6 -0
- package/src/util/listenable.ts +20 -0
- package/src/util/shapes.ts +18 -0
- package/src/util/views.js +108 -0
- package/test/Layers.test.js +63 -0
- package/test/Scale.test.js +235 -0
- package/test/Squisher.test.js +49 -0
- package/test/StateUpdates.js +10 -0
- package/test/Terrain.test.js +0 -1
- package/test/main.test.js +55 -35
- package/test/utils.js +91 -0
- package/testapp.html +26 -0
- package/testapp.js +988 -0
- package/tsconfig.json +22 -0
- package/dist/Colors.d.ts +0 -7
- package/dist/Colors.js +0 -124
- package/dist/Game.d.ts +0 -20
- package/dist/Game.js +0 -48
- package/dist/GameNode.d.ts +0 -66
- package/dist/GameNode.js +0 -148
- package/dist/InternalGameNode.d.ts +0 -20
- package/dist/InternalGameNode.js +0 -32
- package/dist/Shapes.d.ts +0 -6
- package/dist/Shapes.js +0 -8
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -18
- package/dist/sharedDefs.d.ts +0 -72
- package/dist/sharedDefs.js +0 -13
- package/dist/squish.d.ts +0 -8
- package/dist/squish.js +0 -336
- package/dist/terrain/defs.js +0 -5
- package/dist/terrain/index.d.ts +0 -2
- package/dist/terrain/index.js +0 -151
- package/dist/terrain/terrainFunctions.d.ts +0 -6
- package/dist/terrain/terrainFunctions.js +0 -152
- package/dist/util/index.d.ts +0 -2
- package/dist/util/index.js +0 -11
- package/dist/util/listenable.d.ts +0 -3
- package/dist/util/listenable.js +0 -21
- package/dist/util/shapes.d.ts +0 -2
- package/dist/util/shapes.js +0 -23
- package/license.txt +0 -674
package/src/squish.js
CHANGED
|
@@ -1,384 +1,125 @@
|
|
|
1
|
-
const InternalGameNode = require("./InternalGameNode");
|
|
2
|
-
const Colors = require('./Colors');
|
|
3
|
-
|
|
4
1
|
const assert = require('assert');
|
|
5
2
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const {
|
|
3
|
+
const InternalGameNode = require("./InternalGameNode");
|
|
4
|
+
const { CONSTRUCTOR_TO_TYPE, TYPE_TO_CONSTRUCTOR } = require('./node-types');
|
|
5
|
+
const SUBTYPE_MAPPINGS = require('./subtype-mappings');
|
|
6
|
+
|
|
7
|
+
const { squishId } = require('./squishHelpers/id');
|
|
8
|
+
const { squishColor } = require('./squishHelpers/color');
|
|
9
|
+
const { squishPlayerIds } = require('./squishHelpers/playerIds');
|
|
10
|
+
const { squishPos } = require('./squishHelpers/pos');
|
|
11
|
+
const { squishFill } = require('./squishHelpers/fill');
|
|
12
|
+
const { squishSize } = require('./squishHelpers/size');
|
|
13
|
+
const { squishHandleClick } = require('./squishHelpers/handleClick');
|
|
14
|
+
const { squishBorder } = require('./squishHelpers/border');
|
|
15
|
+
const { squishSubType } = require('./squishHelpers/subType');
|
|
16
|
+
const { squishInput } = require('./squishHelpers/input');
|
|
17
|
+
const { squishCoordinates2d } = require('./squishHelpers/coordinates2d');
|
|
18
|
+
const { squishEffect } = require('./squishHelpers/effect');
|
|
19
|
+
const { squishText } = require('./squishHelpers/text');
|
|
20
|
+
const { squishAsset } = require('./squishHelpers/asset');
|
|
23
21
|
|
|
24
22
|
const squishSpec = {
|
|
25
|
-
id:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return [squished[0], squished[1], squished[2], squished[3]];
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
playerIds: {
|
|
44
|
-
type: PLAYER_ID_SUBTYPE,
|
|
45
|
-
squish: (i) => i,
|
|
46
|
-
unsquish: (squished) => squished
|
|
47
|
-
},
|
|
48
|
-
pos: {
|
|
49
|
-
type: POS_SUBTYPE,
|
|
50
|
-
squish: (p) => {
|
|
51
|
-
return [Math.floor(p.x), Math.round(100 * (p.x - Math.floor(p.x))), Math.floor(p.y), Math.round(100 * (p.y - Math.floor(p.y)))]
|
|
52
|
-
},
|
|
53
|
-
unsquish: (squished) => {
|
|
54
|
-
return {
|
|
55
|
-
x: squished[0] + squished[1] / 100,
|
|
56
|
-
y: squished[2] + squished[3] / 100
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
coordinates2d: {
|
|
61
|
-
type: COORDINATES_2D_SUBTYPE,
|
|
62
|
-
squish: (p, scale) => {
|
|
63
|
-
const originalCoords = p.flat();
|
|
64
|
-
const squished = new Array(originalCoords.length * 2);
|
|
65
|
-
|
|
66
|
-
for (const i in originalCoords) {
|
|
67
|
-
if (scale) {
|
|
68
|
-
const isX = i % 2 == 0;
|
|
69
|
-
const scaleValue = isX ? scale.x : scale.y;
|
|
70
|
-
const scaled = scaleValue * originalCoords[i];
|
|
71
|
-
|
|
72
|
-
const removedSpace = Math.round(100 * (1 - scaleValue));
|
|
73
|
-
|
|
74
|
-
const shifted = scaled + (removedSpace / 2);
|
|
75
|
-
|
|
76
|
-
squished[2 * i] = shifted;
|
|
77
|
-
squished[(2 * i) + 1] = getFractional(shifted);
|
|
78
|
-
|
|
79
|
-
} else {
|
|
80
|
-
squished[2 * i] = Math.floor(originalCoords[i]);
|
|
81
|
-
squished[(2 * i) + 1] = Math.round(100 * (originalCoords[i] - Math.floor(originalCoords[i])));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return squished;
|
|
86
|
-
},
|
|
87
|
-
unsquish: (squished) => {
|
|
88
|
-
const unsquished = new Array(squished.length / 2);
|
|
89
|
-
for (let i = 0; i < squished.length; i += 2) {
|
|
90
|
-
const value = squished[i] + (squished[i + 1] / 100);
|
|
91
|
-
unsquished[i / 2] = value;
|
|
92
|
-
}
|
|
93
|
-
return unsquished;
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
fill: {
|
|
97
|
-
type: FILL_SUBTYPE,
|
|
98
|
-
squish: (c) => {
|
|
99
|
-
return [c[0], c[1], c[2], c[3]];
|
|
100
|
-
},
|
|
101
|
-
unsquish: (squished) => {
|
|
102
|
-
return [squished[0], squished[1], squished[2], squished[3]];
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
size: {
|
|
106
|
-
type: SIZE_SUBTYPE,
|
|
107
|
-
squish: (s) => {
|
|
108
|
-
return [Math.floor(s.x), Math.round(100 * (s.x - Math.floor(s.x))), Math.floor(s.y), Math.round(100 * (s.y - Math.floor(s.y)))]
|
|
109
|
-
},
|
|
110
|
-
unsquish: (squished) => {
|
|
111
|
-
return {
|
|
112
|
-
x: squished[0] + squished[1] / 100,
|
|
113
|
-
y: squished[2] + squished[3] / 100
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
text: {
|
|
118
|
-
type: TEXT_SUBTYPE,
|
|
119
|
-
squish: (t, scale) => {
|
|
120
|
-
const textX = scale ? (t.x * scale.x) + Math.round(100 * (1 - scale.x)) / 2 : t.x;
|
|
121
|
-
const textY = scale ? (t.y * scale.y) + Math.round(100 * (1 - scale.y)) / 2 : t.y;
|
|
122
|
-
|
|
123
|
-
const align = t.align || 'left';
|
|
124
|
-
const squishedText = new Array(t.text.length + 10 + align.length);
|
|
125
|
-
|
|
126
|
-
squishedText[0] = Math.floor(textX);
|
|
127
|
-
squishedText[1] = Math.round(100 * (textX - Math.floor(textX)));
|
|
128
|
-
|
|
129
|
-
squishedText[2] = Math.floor(textY);
|
|
130
|
-
squishedText[3] = Math.round(100 * (textY - Math.floor(textY)));
|
|
131
|
-
|
|
132
|
-
const textSize = t.size || 1;
|
|
133
|
-
const scaledTextSize = scale ? textSize * hypLength(scale.x, scale.y) : textSize;
|
|
134
|
-
|
|
135
|
-
squishedText[4] = Math.floor(scaledTextSize);
|
|
136
|
-
squishedText[5] = Math.round(100 * (scaledTextSize - Math.floor(scaledTextSize)));
|
|
137
|
-
|
|
138
|
-
const textColor = t.color || Colors.BLACK;
|
|
139
|
-
const squishedTextColor = squishSpec.color.squish(textColor);
|
|
140
|
-
|
|
141
|
-
for (let i = 0; i < squishedTextColor.length; i++) {
|
|
142
|
-
squishedText[6 + i] = squishedTextColor[i];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
squishedText[6 + squishedTextColor.length] = align.length;
|
|
146
|
-
|
|
147
|
-
for (let i = 0; i < align.length; i++) {
|
|
148
|
-
squishedText[6 + squishedTextColor.length + 1 + i] = align.codePointAt(i);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
for (let i = 0; i < t.text.length; i++) {
|
|
152
|
-
squishedText[6 + squishedTextColor.length + align.length + 1 + i] = t.text.codePointAt(i);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return squishedText;
|
|
156
|
-
},
|
|
157
|
-
unsquish: (squished) => {
|
|
158
|
-
const textPosX = squished[0] + squished[1] / 100;
|
|
159
|
-
const textPosY = squished[2] + squished[3] / 100;
|
|
160
|
-
const textSize = squished[4] + squished[5] / 100;
|
|
161
|
-
const textColor = squished.slice(6, 10);
|
|
162
|
-
const textAlignLength = squished[10];
|
|
163
|
-
const align = String.fromCodePoint.apply(null, squished.slice(11, 11 + textAlignLength));
|
|
164
|
-
|
|
165
|
-
const text = String.fromCodePoint.apply(null, squished.slice(11 + textAlignLength));
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
x: textPosX,
|
|
169
|
-
y: textPosY,
|
|
170
|
-
text: text,
|
|
171
|
-
size: textSize,
|
|
172
|
-
color: textColor,
|
|
173
|
-
align
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
asset: {
|
|
178
|
-
type: ASSET_SUBTYPE,
|
|
179
|
-
squish: (a, scale) => {
|
|
180
|
-
const assetKey = Object.keys(a)[0];
|
|
181
|
-
const squishedAssets = new Array(8 + assetKey.length);
|
|
182
|
-
|
|
183
|
-
const asset = a[assetKey];
|
|
184
|
-
|
|
185
|
-
const posX = scale ? ((scale.x * asset.pos.x) + Math.round(100 * (1 - scale.x)) / 2) : asset.pos.x;
|
|
186
|
-
const posY = scale ? ((scale.y * asset.pos.y) + Math.round(100 * (1 - scale.y)) / 2) : asset.pos.y;
|
|
187
|
-
|
|
188
|
-
const sizeX = scale ? scale.x * asset.size.x : asset.size.x;
|
|
189
|
-
const sizeY = scale ? scale.y * asset.size.y : asset.size.y;
|
|
23
|
+
id: squishId,
|
|
24
|
+
color: squishColor,
|
|
25
|
+
playerIds: squishPlayerIds,
|
|
26
|
+
pos: squishPos,
|
|
27
|
+
coordinates2d: squishCoordinates2d,
|
|
28
|
+
fill: squishFill,
|
|
29
|
+
size: squishSize,
|
|
30
|
+
text: squishText,
|
|
31
|
+
asset: squishAsset,
|
|
32
|
+
effects: squishEffect,
|
|
33
|
+
handleClick:squishHandleClick,
|
|
34
|
+
border: squishBorder,
|
|
35
|
+
subType: squishSubType,
|
|
36
|
+
input: squishInput
|
|
37
|
+
};
|
|
190
38
|
|
|
191
|
-
|
|
192
|
-
squishedAssets[1] = getFractional(posX);
|
|
39
|
+
const typeToSquishMap = {};
|
|
193
40
|
|
|
194
|
-
|
|
195
|
-
|
|
41
|
+
for (const key in squishSpec) {
|
|
42
|
+
typeToSquishMap[Number(squishSpec[key]['type'])] = key;
|
|
43
|
+
}
|
|
196
44
|
|
|
197
|
-
|
|
198
|
-
|
|
45
|
+
const unsquish = (squished) => {
|
|
46
|
+
assert(squished[0] == 3);
|
|
199
47
|
|
|
200
|
-
|
|
201
|
-
squishedAssets[7] = getFractional(sizeY);
|
|
48
|
+
assert(squished.length === squished[1]);
|
|
202
49
|
|
|
203
|
-
|
|
204
|
-
squishedAssets[8 + i] = assetKey.codePointAt(i);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return squishedAssets;
|
|
208
|
-
},
|
|
209
|
-
unsquish: (squished) => {
|
|
210
|
-
const assetPosX = squished[0] + squished[1] / 100;
|
|
211
|
-
const assetPosY = squished[2] + squished[3] / 100;
|
|
50
|
+
let squishedIndex = 3;
|
|
212
51
|
|
|
213
|
-
|
|
214
|
-
const assetSizeY = squished[6] + squished[7] / 100;
|
|
52
|
+
let constructedInternalNode = new InternalGameNode();
|
|
215
53
|
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
[assetKey]: {
|
|
219
|
-
pos: {
|
|
220
|
-
x: assetPosX,
|
|
221
|
-
y: assetPosY
|
|
222
|
-
},
|
|
223
|
-
size: {
|
|
224
|
-
x: assetSizeX,
|
|
225
|
-
y: assetSizeY
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
effects: {
|
|
232
|
-
type: EFFECTS_SUBTYPE,
|
|
233
|
-
squish: (a) => {
|
|
234
|
-
if (a['shadow']) {
|
|
235
|
-
const assetKey = 'shadow';
|
|
236
|
-
let squishedLength = assetKey.length + 4; // + 4 for color
|
|
237
|
-
if (a['shadow'].blur) {
|
|
238
|
-
squishedLength += 2;
|
|
239
|
-
}
|
|
240
|
-
const squishedEffects = new Array(squishedLength);
|
|
241
|
-
for (let i = 0; i < assetKey.length; i++) {
|
|
242
|
-
squishedEffects[i] = assetKey.codePointAt(i);
|
|
243
|
-
}
|
|
244
|
-
squishedEffects[assetKey.length] = a.shadow.color[0];
|
|
245
|
-
squishedEffects[assetKey.length + 1] = a.shadow.color[1];
|
|
246
|
-
squishedEffects[assetKey.length + 2] = a.shadow.color[2];
|
|
247
|
-
squishedEffects[assetKey.length + 3] = a.shadow.color[3];
|
|
54
|
+
while(squishedIndex < squished.length) {
|
|
248
55
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
56
|
+
const subFrameType = squished[squishedIndex];
|
|
57
|
+
const subFrameLength = squished[squishedIndex + 1];
|
|
58
|
+
const subFrame = squished.slice(squishedIndex + 2, squishedIndex + subFrameLength);
|
|
253
59
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const unsquished = {
|
|
267
|
-
[assetKey]: {
|
|
268
|
-
color
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
if (blur) {
|
|
273
|
-
unsquished[assetKey].blur = blur;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return unsquished;
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
handleClick: {
|
|
280
|
-
type: ONCLICK_SUBTYPE,
|
|
281
|
-
squish: (a) => {
|
|
282
|
-
return a ? [1] : [0];
|
|
283
|
-
},
|
|
284
|
-
unsquish: (a) => {
|
|
285
|
-
return a[0] === 1;
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
border: {
|
|
289
|
-
type: BORDER_SUBTYPE,
|
|
290
|
-
squish: (a) => {
|
|
291
|
-
return [a];
|
|
292
|
-
},
|
|
293
|
-
unsquish: (s) => {
|
|
294
|
-
return s[0];
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
input: {
|
|
298
|
-
type: INPUT_SUBTYPE,
|
|
299
|
-
squish: (a) => {
|
|
300
|
-
const squished = new Array(a.type.length);
|
|
301
|
-
for (let i = 0; i < a.type.length; i++) {
|
|
302
|
-
squished[i] = a.type.codePointAt(i);
|
|
303
|
-
}
|
|
304
|
-
return squished;
|
|
305
|
-
},
|
|
306
|
-
unsquish: (squished) => {
|
|
307
|
-
return {
|
|
308
|
-
type: String.fromCodePoint.apply(null, squished)
|
|
309
|
-
}
|
|
60
|
+
if (!typeToSquishMap[subFrameType]) {
|
|
61
|
+
console.warn("Unknown sub frame type " + subFrameType);
|
|
62
|
+
break;
|
|
63
|
+
} else {
|
|
64
|
+
const objField = typeToSquishMap[subFrameType];
|
|
65
|
+
const unsquishFun = squishSpec[objField]['unsquish'];
|
|
66
|
+
// anything that was declared as a dependency of this property will be available when
|
|
67
|
+
// calling this property's unsquish function
|
|
68
|
+
const dependencyReference = Object.assign({}, constructedInternalNode);
|
|
69
|
+
const unsquishedVal = unsquishFun(subFrame, dependencyReference);
|
|
70
|
+
constructedInternalNode[objField] = unsquishedVal;
|
|
310
71
|
}
|
|
72
|
+
squishedIndex += subFrameLength;
|
|
311
73
|
}
|
|
312
|
-
};
|
|
313
74
|
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
'playerIds',
|
|
318
|
-
'coordinates2d',
|
|
319
|
-
'fill',
|
|
320
|
-
'pos',
|
|
321
|
-
'size',
|
|
322
|
-
'text',
|
|
323
|
-
'asset',
|
|
324
|
-
'effects',
|
|
325
|
-
'border',
|
|
326
|
-
'handleClick',
|
|
327
|
-
'input'
|
|
328
|
-
];
|
|
75
|
+
const constructor = TYPE_TO_CONSTRUCTOR[squished[2]];
|
|
76
|
+
return new constructor({ node: constructedInternalNode });
|
|
77
|
+
}
|
|
329
78
|
|
|
330
|
-
|
|
79
|
+
// When squishing, we need to make sure that properties that other properties depend on are inserted first.
|
|
80
|
+
// This is because when unsquishing, we need to guarantee that the dependee is available to the function responsible
|
|
81
|
+
// for creating the dependant
|
|
82
|
+
const sortSpecKeys = () => {
|
|
83
|
+
const keysWithDeps = Object.keys(squishSpec).filter(key => {
|
|
84
|
+
return squishSpec[key].dependsOn && squishSpec[key].dependsOn.length > 0;
|
|
85
|
+
});
|
|
331
86
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
87
|
+
const keysWithoutDeps = Object.keys(squishSpec).filter(key => {
|
|
88
|
+
return !squishSpec[key].dependsOn || squishSpec[key].dependsOn.length === 0;
|
|
89
|
+
});
|
|
335
90
|
|
|
336
|
-
|
|
337
|
-
assert(squished[0] == 3);
|
|
338
|
-
|
|
339
|
-
assert(squished.length === squished[1]);
|
|
91
|
+
// todo: recursively find circular deps
|
|
340
92
|
|
|
341
|
-
|
|
93
|
+
return [keysWithoutDeps, keysWithDeps].flat();
|
|
94
|
+
}
|
|
342
95
|
|
|
343
|
-
|
|
96
|
+
const squish = (entity, scale = null) => {
|
|
97
|
+
let squishedPieces = [];
|
|
344
98
|
|
|
345
|
-
|
|
99
|
+
const internalNode = entity.node;
|
|
346
100
|
|
|
347
|
-
|
|
348
|
-
const subFrameLength = squished[squishedIndex + 1];
|
|
349
|
-
const subFrame = squished.slice(squishedIndex + 2, squishedIndex + subFrameLength);
|
|
101
|
+
const sortedSpecKeys = sortSpecKeys();
|
|
350
102
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
constructedGameNode[objField] = unsquishedVal;
|
|
103
|
+
for (const keyIndex in sortedSpecKeys) {
|
|
104
|
+
const key = sortedSpecKeys[keyIndex];
|
|
105
|
+
if (key in internalNode) {
|
|
106
|
+
const attr = internalNode[key];
|
|
107
|
+
if (attr !== undefined && attr !== null) {
|
|
108
|
+
const squished = squishSpec[key].squish(attr, scale, internalNode);
|
|
109
|
+
squishedPieces.push([squishSpec[key]['type'], squished.length + 2, ...squished]);
|
|
359
110
|
}
|
|
360
|
-
squishedIndex += subFrameLength;
|
|
361
111
|
}
|
|
362
|
-
|
|
363
|
-
return constructedGameNode;
|
|
364
112
|
}
|
|
365
113
|
|
|
366
|
-
|
|
367
|
-
let squishedPieces = [];
|
|
114
|
+
let nodeClassCode = CONSTRUCTOR_TO_TYPE[entity.constructor.name];
|
|
368
115
|
|
|
369
|
-
for (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const attr = entity[key];
|
|
373
|
-
if (attr !== undefined && attr !== null) {
|
|
374
|
-
const squished = squishSpec[key].squish(attr, scale);
|
|
375
|
-
squishedPieces.push([squishSpec[key]['type'], squished.length + 2, ...squished]);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
116
|
+
// implemented for json support (infer from subtype instead of custom json property)
|
|
117
|
+
if (!nodeClassCode) {
|
|
118
|
+
nodeClassCode = CONSTRUCTOR_TO_TYPE[SUBTYPE_MAPPINGS[internalNode.subType]];
|
|
378
119
|
}
|
|
379
120
|
|
|
380
121
|
const squished = squishedPieces.flat();
|
|
381
|
-
return [3, squished.length +
|
|
122
|
+
return [3, squished.length + 3, nodeClassCode, ...squished];
|
|
382
123
|
|
|
383
124
|
}
|
|
384
125
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const { getFractional } = require('../util')
|
|
2
|
+
|
|
3
|
+
const ASSET_SUBTYPE = 48;
|
|
4
|
+
|
|
5
|
+
const squishAsset = {
|
|
6
|
+
type: ASSET_SUBTYPE,
|
|
7
|
+
squish: (a, scale) => {
|
|
8
|
+
const assetKey = Object.keys(a)[0];
|
|
9
|
+
const squishedAssets = new Array(8 + assetKey.length);
|
|
10
|
+
|
|
11
|
+
const asset = a[assetKey];
|
|
12
|
+
|
|
13
|
+
const posX = scale ? ((scale.x * asset.pos.x) + Math.round(100 * (1 - scale.x)) / 2) : asset.pos.x;
|
|
14
|
+
const posY = scale ? ((scale.y * asset.pos.y) + Math.round(100 * (1 - scale.y)) / 2) : asset.pos.y;
|
|
15
|
+
|
|
16
|
+
const sizeX = scale ? scale.x * asset.size.x : asset.size.x;
|
|
17
|
+
const sizeY = scale ? scale.y * asset.size.y : asset.size.y;
|
|
18
|
+
|
|
19
|
+
squishedAssets[0] = Math.floor(posX);
|
|
20
|
+
squishedAssets[1] = getFractional(posX);
|
|
21
|
+
|
|
22
|
+
squishedAssets[2] = Math.floor(posY);
|
|
23
|
+
squishedAssets[3] = getFractional(posY);
|
|
24
|
+
|
|
25
|
+
squishedAssets[4] = Math.floor(sizeX);
|
|
26
|
+
squishedAssets[5] = getFractional(sizeX);
|
|
27
|
+
|
|
28
|
+
squishedAssets[6] = Math.floor(sizeY);
|
|
29
|
+
squishedAssets[7] = getFractional(sizeY);
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < assetKey.length; i++) {
|
|
32
|
+
squishedAssets[8 + i] = assetKey.codePointAt(i);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return squishedAssets;
|
|
36
|
+
},
|
|
37
|
+
unsquish: (squished) => {
|
|
38
|
+
const assetPosX = squished[0] + squished[1] / 100;
|
|
39
|
+
const assetPosY = squished[2] + squished[3] / 100;
|
|
40
|
+
|
|
41
|
+
const assetSizeX = squished[4] + squished[5] / 100;
|
|
42
|
+
const assetSizeY = squished[6] + squished[7] / 100;
|
|
43
|
+
|
|
44
|
+
const assetKey = String.fromCodePoint.apply(null, squished.slice(8));
|
|
45
|
+
return {
|
|
46
|
+
[assetKey]: {
|
|
47
|
+
pos: {
|
|
48
|
+
x: assetPosX,
|
|
49
|
+
y: assetPosY
|
|
50
|
+
},
|
|
51
|
+
size: {
|
|
52
|
+
x: assetSizeX,
|
|
53
|
+
y: assetSizeY
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
ASSET_SUBTYPE,
|
|
62
|
+
squishAsset
|
|
63
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const COLOR_SUBTYPE = 42;
|
|
2
|
+
|
|
3
|
+
const squishColor = {
|
|
4
|
+
type: COLOR_SUBTYPE,
|
|
5
|
+
squish: (c) => {
|
|
6
|
+
return [c[0], c[1], c[2], c[3]];
|
|
7
|
+
},
|
|
8
|
+
unsquish: (squished) => {
|
|
9
|
+
return [squished[0], squished[1], squished[2], squished[3]];
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
COLOR_SUBTYPE,
|
|
15
|
+
squishColor
|
|
16
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const { getFractional } = require('../util');
|
|
2
|
+
const subtypes = require('../subtypes');
|
|
3
|
+
|
|
4
|
+
const COORDINATES_2D_SUBTYPE = 52;
|
|
5
|
+
|
|
6
|
+
const squishHelper = (scale, coord) => {
|
|
7
|
+
const scaledCenter = scale * coord;
|
|
8
|
+
const removedSpaceCenter = Math.round(100 * (1 - scale));
|
|
9
|
+
return scaledCenter + (removedSpaceCenter / 2);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const squishCoordinates2d = {
|
|
13
|
+
type: COORDINATES_2D_SUBTYPE,
|
|
14
|
+
squish: (p, scale, node) => {
|
|
15
|
+
const originalCoords = p.flat();
|
|
16
|
+
const squished = new Array(originalCoords.length * 2);
|
|
17
|
+
|
|
18
|
+
if (node.subType == subtypes.SHAPE_2D_CIRCLE) {
|
|
19
|
+
if (scale) {
|
|
20
|
+
const shiftedCenterX = squishHelper(scale.x, originalCoords[0])
|
|
21
|
+
squished[0] = shiftedCenterX;
|
|
22
|
+
squished[1] = getFractional(shiftedCenterX);
|
|
23
|
+
|
|
24
|
+
const shiftedCenterY = squishHelper(scale.y, originalCoords[1])
|
|
25
|
+
squished[2] = shiftedCenterY;
|
|
26
|
+
squished[3] = getFractional(shiftedCenterY);
|
|
27
|
+
|
|
28
|
+
let diagonal;
|
|
29
|
+
if (scale.x === scale.y) {
|
|
30
|
+
diagonal = scale.x * originalCoords[2];
|
|
31
|
+
} else {
|
|
32
|
+
// probably broken
|
|
33
|
+
diagonal = Math.sqrt( Math.pow(100 * scale.x, 2) + Math.pow(100 * scale.y, 2)) * (originalCoords[2] / 100);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
squished[4] = Math.floor(diagonal);
|
|
37
|
+
squished[5] = getFractional(diagonal);
|
|
38
|
+
} else {
|
|
39
|
+
const centerX = originalCoords[0];
|
|
40
|
+
squished[0] = Math.floor(centerX);
|
|
41
|
+
squished[1] = getFractional(centerX);
|
|
42
|
+
|
|
43
|
+
const centerY = originalCoords[1];
|
|
44
|
+
squished[2] = Math.floor(centerY);
|
|
45
|
+
squished[3] = getFractional(centerY);
|
|
46
|
+
|
|
47
|
+
const radius = originalCoords[2];
|
|
48
|
+
squished[4] = Math.round(radius);
|
|
49
|
+
squished[5] = getFractional(radius);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
for (const i in originalCoords) {
|
|
53
|
+
if (scale) {
|
|
54
|
+
const isX = i % 2 == 0;
|
|
55
|
+
const scaleValue = isX ? scale.x : scale.y;
|
|
56
|
+
const scaled = scaleValue * originalCoords[i];
|
|
57
|
+
|
|
58
|
+
const removedSpace = Math.round(100 * (1 - scaleValue));
|
|
59
|
+
|
|
60
|
+
const shifted = scaled + (removedSpace / 2);
|
|
61
|
+
|
|
62
|
+
squished[2 * i] = shifted;
|
|
63
|
+
squished[(2 * i) + 1] = getFractional(shifted);
|
|
64
|
+
|
|
65
|
+
} else {
|
|
66
|
+
squished[2 * i] = Math.floor(originalCoords[i]);
|
|
67
|
+
squished[(2 * i) + 1] = Math.round(100 * (originalCoords[i] - Math.floor(originalCoords[i])));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return squished;
|
|
73
|
+
},
|
|
74
|
+
dependsOn: ['subType'],
|
|
75
|
+
unsquish: (squished, { subType }) => {
|
|
76
|
+
const unsquished = new Array(squished.length / 2);
|
|
77
|
+
for (let i = 0; i < squished.length; i += 2) {
|
|
78
|
+
const value = squished[i] + (squished[i + 1] / 100);
|
|
79
|
+
unsquished[i / 2] = value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (subType === subtypes.SHAPE_2D_POLYGON || subType === subtypes.SHAPE_2D_LINE) {
|
|
83
|
+
const coordPairs = new Array(unsquished.length / 2);
|
|
84
|
+
for (let i = 0; i < unsquished.length; i += 2) {
|
|
85
|
+
coordPairs[i / 2] = [unsquished[i], unsquished[i + 1]];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return coordPairs;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return unsquished;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = {
|
|
96
|
+
COORDINATES_2D_SUBTYPE,
|
|
97
|
+
squishCoordinates2d
|
|
98
|
+
};
|