squishjs 0.6.42 → 0.7.2
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 +230 -0
- package/src/ViewableGame.js +60 -0
- package/src/node-types.js +15 -0
- package/src/squish.js +90 -432
- 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/src/terrain/defs.ts +16 -0
- 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 +35 -37
- package/test/utils.js +91 -0
- package/testapp.html +26 -0
- package/testapp.js +988 -0
- package/tsconfig.json +22 -0
- package/license.txt +0 -674
package/src/GameNode.js
CHANGED
|
@@ -1,110 +1,113 @@
|
|
|
1
|
-
const listenable = require("./util/listenable");
|
|
2
|
-
const InternalGameNode = require('./InternalGameNode');
|
|
3
1
|
const Shapes = require('./Shapes');
|
|
2
|
+
const SUBTYPES = require('./subtypes');
|
|
3
|
+
const { gameNode, BaseNode } = require('./BaseNode');
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const shapeTypeToSubtype = {
|
|
6
|
+
[Shapes.CIRCLE]: SUBTYPES.SHAPE_2D_CIRCLE,
|
|
7
|
+
[Shapes.POLYGON]: SUBTYPES.SHAPE_2D_POLYGON,
|
|
8
|
+
[Shapes.LINE]: SUBTYPES.SHAPE_2D_LINE
|
|
8
9
|
};
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.node = gameNode(color, onClick, coordinates2d, border, fill, null, null, playerIds, effects, input);
|
|
17
|
-
this.id = this.node.id;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
addChild(child) {
|
|
21
|
-
this.node.addChild(child);
|
|
22
|
-
}
|
|
11
|
+
const subtypeToShapeType = {
|
|
12
|
+
[SUBTYPES.SHAPE_2D_CIRCLE]: Shapes.CIRCLE,
|
|
13
|
+
[SUBTYPES.SHAPE_2D_POLYGON]: Shapes.POLYGON,
|
|
14
|
+
[SUBTYPES.SHAPE_2D_LINE]: Shapes.LINE
|
|
15
|
+
};
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
class Shape extends BaseNode {
|
|
18
|
+
constructor({ color, onClick, shapeType, coordinates2d, border, fill, playerIds, effects, input, node, id }) {
|
|
19
|
+
if ((!coordinates2d || !shapeType) && !(node)) {
|
|
20
|
+
throw new Error("Shape requires coordinates2d and shapeType");
|
|
27
21
|
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
removeChild(nodeId) {
|
|
31
|
-
this.node.removeChild(nodeId);
|
|
32
|
-
}
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
super({
|
|
24
|
+
color,
|
|
25
|
+
onClick,
|
|
26
|
+
coordinates2d,
|
|
27
|
+
border,
|
|
28
|
+
fill,
|
|
29
|
+
playerIds,
|
|
30
|
+
effects,
|
|
31
|
+
input,
|
|
32
|
+
node,
|
|
33
|
+
subtype: shapeTypeToSubtype[shapeType],
|
|
34
|
+
id
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clone({ handleClick, input, id }) {
|
|
39
|
+
const _id = id || null;
|
|
40
|
+
return new Shape({
|
|
41
|
+
color: this.node.color,
|
|
42
|
+
onClick: handleClick,
|
|
43
|
+
shapeType: subtypeToShapeType[this.node.subType],
|
|
44
|
+
coordinates2d: this.node.coordinates2d,
|
|
45
|
+
border: this.node.border,
|
|
46
|
+
fill: this.node.fill,
|
|
47
|
+
playerIds: this.node.playerIds,
|
|
48
|
+
effects: this.node.effects,
|
|
49
|
+
input,
|
|
50
|
+
id: _id
|
|
51
|
+
});
|
|
36
52
|
}
|
|
37
53
|
|
|
38
|
-
clearChildren(excludedNodeIds) {
|
|
39
|
-
this.node.clearChildren(excludedNodeIds);
|
|
40
|
-
}
|
|
41
54
|
}
|
|
42
55
|
|
|
43
|
-
class Text {
|
|
44
|
-
constructor({ textInfo, playerIds, input }) {
|
|
45
|
-
if (!textInfo) {
|
|
56
|
+
class Text extends BaseNode {
|
|
57
|
+
constructor({ textInfo, playerIds, input, node, id }) {
|
|
58
|
+
if (!textInfo && !node) {
|
|
46
59
|
throw new Error("Text node requires textInfo");
|
|
47
60
|
}
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
addChildren(...nodes) {
|
|
58
|
-
for (let nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
|
|
59
|
-
this.addChild(nodes[nodeIndex]);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
removeChild(nodeId) {
|
|
64
|
-
this.node.removeChild(nodeId);
|
|
62
|
+
super({
|
|
63
|
+
textInfo,
|
|
64
|
+
playerIds,
|
|
65
|
+
input,
|
|
66
|
+
node,
|
|
67
|
+
subtype: SUBTYPES.TEXT,
|
|
68
|
+
id
|
|
69
|
+
});
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
72
|
+
clone({ handleClick, input, id }) {
|
|
73
|
+
const _id = id || null;
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
return new Text({
|
|
76
|
+
textInfo: Object.assign({}, this.node.text),
|
|
77
|
+
playerIds: this.playerIds?.slice(),
|
|
78
|
+
id: _id
|
|
79
|
+
});
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
|
|
76
|
-
class Asset {
|
|
77
|
-
constructor({ assetInfo, onClick, coordinates2d, playerIds, effects }) {
|
|
78
|
-
if (!assetInfo) {
|
|
83
|
+
class Asset extends BaseNode {
|
|
84
|
+
constructor({ assetInfo, onClick, coordinates2d, playerIds, effects, node, id }) {
|
|
85
|
+
if (!assetInfo && !node) {
|
|
79
86
|
throw new Error("Asset node requires assetInfo");
|
|
80
87
|
}
|
|
81
|
-
this.node = gameNode(null, onClick, coordinates2d, null, null, null, assetInfo, playerIds, effects);
|
|
82
|
-
this.id = this.node.id;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
addChild(child) {
|
|
86
|
-
this.node.addChild(child);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
addChildren(...nodes) {
|
|
90
|
-
for (let nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
|
|
91
|
-
this.addChild(nodes[nodeIndex]);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
88
|
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
super({
|
|
90
|
+
assetInfo,
|
|
91
|
+
onClick,
|
|
92
|
+
coordinates2d,
|
|
93
|
+
playerIds,
|
|
94
|
+
effects,
|
|
95
|
+
node,
|
|
96
|
+
subtype: SUBTYPES.ASSET,
|
|
97
|
+
id
|
|
98
|
+
});
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
101
|
+
clone({ handleClick, input, id }) {
|
|
102
|
+
const _id = id || null;
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
return new Asset({
|
|
105
|
+
assetInfo: Object.assign({}, this.node.asset),
|
|
106
|
+
playerIds: this.playerIds?.slice(),
|
|
107
|
+
id: _id
|
|
108
|
+
});
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
const GameNode = {
|
package/src/InternalGameNode.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
let
|
|
1
|
+
let _id = 0;
|
|
2
2
|
|
|
3
3
|
class InternalGameNode {
|
|
4
|
-
constructor(color, onClick, coordinates2d, border, fill, text, asset, playerIds = [], effects = null, input = null) {
|
|
5
|
-
this.id = id++;
|
|
4
|
+
constructor(color, onClick, coordinates2d, border, fill, text, asset, playerIds = [], effects = null, input = null, subType = null, id = null) {
|
|
5
|
+
this.id = id ? Number(id) : _id++;
|
|
6
6
|
this.children = new Array();
|
|
7
7
|
this.color = color;
|
|
8
8
|
this.handleClick = onClick;
|
|
@@ -18,6 +18,7 @@ class InternalGameNode {
|
|
|
18
18
|
playerIds = [playerIds];
|
|
19
19
|
}
|
|
20
20
|
this.playerIds = playerIds || [];
|
|
21
|
+
this.subType = subType;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
addChild(node) {
|
package/src/Squisher.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
const ASSET_TYPE = 1;
|
|
2
|
+
|
|
3
|
+
const { squish, unsquish } = require('./squish');
|
|
4
|
+
|
|
5
|
+
const INVISIBLE_PLAYER_ID = 0;
|
|
6
|
+
const DEFAULT_TICK_RATE = 60;
|
|
7
|
+
|
|
8
|
+
class Squisher {
|
|
9
|
+
constructor({ game, scale, customBottomLayer, customTopLayer }) {
|
|
10
|
+
this.ids = new Set();
|
|
11
|
+
|
|
12
|
+
this.game = game;
|
|
13
|
+
|
|
14
|
+
this.customBottomLayer = customBottomLayer;
|
|
15
|
+
this.customTopLayer = customTopLayer;
|
|
16
|
+
|
|
17
|
+
this.playerFrames = {};
|
|
18
|
+
|
|
19
|
+
this.listeners = new Set();
|
|
20
|
+
this.scale = scale || {x: 1, y: 1};
|
|
21
|
+
this.state = this.squish(this.game.getLayers());
|
|
22
|
+
this.spectatorState = this.game.getSpectatorLayers ? this.squish(this.game.getSpectatorLayers()) : [];
|
|
23
|
+
this.assets = {};
|
|
24
|
+
if (this.game.tick) {
|
|
25
|
+
const tickRate = this.gameMetadata && this.gameMetadata.tickRate ? this.gameMetadata.tickRate : DEFAULT_TICK_RATE;
|
|
26
|
+
setInterval(this.game.tick.bind(this.game), 1000 / tickRate);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
addListener(onEvent) {
|
|
31
|
+
const listener = {
|
|
32
|
+
onEvent,
|
|
33
|
+
remove: () => this.removeListener(listener)
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
this.listeners.add(listener);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
removeListener(listener) {
|
|
40
|
+
this.listeners.remove(listener);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
unsquish(node) {
|
|
44
|
+
return unsquish(node);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
squish(layers, scale = null) {
|
|
48
|
+
|
|
49
|
+
if (!layers) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let layerLength = layers.length;
|
|
54
|
+
|
|
55
|
+
let toSquish = [];
|
|
56
|
+
|
|
57
|
+
const playerMap = {};
|
|
58
|
+
|
|
59
|
+
Object.keys(this.game.players).forEach(playerId => {
|
|
60
|
+
playerMap[Number(playerId)] = [];
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (this.customBottomLayer) {
|
|
64
|
+
const squishedLayer = [];
|
|
65
|
+
this.squishHelper(this.customBottomLayer.root, squishedLayer, this.customBottomLayer.scale, playerMap);
|
|
66
|
+
toSquish.push(squishedLayer);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const layerIndex in layers) {
|
|
70
|
+
const squishedLayer = [];
|
|
71
|
+
const layerInfo = layers[layerIndex];
|
|
72
|
+
|
|
73
|
+
const layerScale = layerInfo.scale ? {
|
|
74
|
+
x: this.scale.x * layerInfo.scale.x,
|
|
75
|
+
y: this.scale.y * layerInfo.scale.y
|
|
76
|
+
} : this.scale;
|
|
77
|
+
|
|
78
|
+
this.squishHelper(layerInfo.root, squishedLayer, scale || layerScale, playerMap);
|
|
79
|
+
toSquish.push(squishedLayer);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if (this.customTopLayer) {
|
|
84
|
+
const squishedLayer = [];
|
|
85
|
+
this.squishHelper(this.customTopLayer.root, squishedLayer, this.customTopLayer.scale, playerMap);
|
|
86
|
+
toSquish.push(squishedLayer);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.playerFrames = playerMap;
|
|
90
|
+
|
|
91
|
+
return toSquish.flat();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getPlayerFrame(playerId) {
|
|
95
|
+
return this.playerFrames[playerId];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
squishHelper(node, squishedNodes, scale = {x: 1, y: 1}, playerMap = {}) {
|
|
99
|
+
if (!node.node.listeners.has(this)) {
|
|
100
|
+
node.addListener(this);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const squished = squish(node, scale);
|
|
104
|
+
squishedNodes.push(squished);
|
|
105
|
+
|
|
106
|
+
if (playerMap) {
|
|
107
|
+
if (node.node.playerIds && node.node.playerIds.length) {
|
|
108
|
+
node.node.playerIds.forEach(playerId => {
|
|
109
|
+
if (playerMap[playerId]) {
|
|
110
|
+
playerMap[playerId].push(squished);
|
|
111
|
+
} else {
|
|
112
|
+
console.warn(`Node references unknown player ID: ${playerId}`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
Object.keys(playerMap).forEach(playerId => {
|
|
117
|
+
playerMap[playerId].push(squished);
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < node.node.children.length; i++) {
|
|
123
|
+
this.squishHelper(node.node.children[i], squishedNodes, scale, playerMap);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getJson() {
|
|
129
|
+
const layers = this.game.layers;
|
|
130
|
+
const jsonLayers = new Array(layers.length);
|
|
131
|
+
for (const layerIndex in layers) {
|
|
132
|
+
const layerInfo = layers[layerIndex];
|
|
133
|
+
const jsonLayer = layerInfo.root;
|
|
134
|
+
jsonLayers[layerIndex] = jsonLayer;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return JSON.stringify(jsonLayers);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
initialize() {
|
|
141
|
+
return new Promise((resolve, reject) => {
|
|
142
|
+
const gameMetadata = this.game.constructor.metadata && this.game.constructor.metadata();
|
|
143
|
+
|
|
144
|
+
const gameAssets = gameMetadata && gameMetadata.assets ? gameMetadata.assets : {};
|
|
145
|
+
|
|
146
|
+
if (this.customBottomLayer && this.customBottomLayer.assets) {
|
|
147
|
+
Object.assign(gameAssets, this.customBottomLayer.assets);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (this.customTopLayer && this.customTopLayer.assets) {
|
|
151
|
+
Object.assign(gameAssets, this.customTopLayer.assets);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (this.game.getAssets && this.game.getAssets()) {
|
|
155
|
+
Object.assign(gameAssets, this.game.getAssets());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const initializeAssetBundle = () => new Promise((resolve, reject) => {
|
|
159
|
+
let assetBundleSize = 0;
|
|
160
|
+
let finishedCount = 0;
|
|
161
|
+
const totalCount = Object.keys(gameAssets).length;
|
|
162
|
+
|
|
163
|
+
for (const key in gameAssets) {
|
|
164
|
+
gameAssets[key].getData().then(buf => {
|
|
165
|
+
const assetKeyLength = 32;
|
|
166
|
+
let keyIndex = 0;
|
|
167
|
+
const assetKeyArray = new Array(32);
|
|
168
|
+
while (keyIndex < assetKeyLength && keyIndex < key.length) {
|
|
169
|
+
assetKeyArray[keyIndex] = key.charCodeAt(keyIndex);
|
|
170
|
+
keyIndex++;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const encodedLength = (buf.length + assetKeyLength).toString(36);
|
|
174
|
+
|
|
175
|
+
const assetType = gameAssets[key].info.type === 'image' ? 1 : 2;
|
|
176
|
+
|
|
177
|
+
const encodedMaxLength = 10;
|
|
178
|
+
let encodedLengthString = '';
|
|
179
|
+
for (let i = 0; i < (encodedMaxLength - encodedLength.length); i++) {
|
|
180
|
+
encodedLengthString += '0';
|
|
181
|
+
}
|
|
182
|
+
for (let j = encodedLength.length; j < encodedMaxLength; j++) {
|
|
183
|
+
encodedLengthString += encodedLength.charAt(j - encodedLength.length);
|
|
184
|
+
}
|
|
185
|
+
const encodedLengthArray = new Array(encodedMaxLength);
|
|
186
|
+
for (let i = 0; i < encodedMaxLength; i++) {
|
|
187
|
+
encodedLengthArray[i] = encodedLength.charCodeAt(i);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.assets[key] = [ASSET_TYPE, assetType, ...encodedLengthArray, ...assetKeyArray, ...buf];
|
|
191
|
+
assetBundleSize += this.assets[key].length;
|
|
192
|
+
finishedCount += 1;
|
|
193
|
+
|
|
194
|
+
if (finishedCount == totalCount) {
|
|
195
|
+
const newAssetBundle = new Array(assetBundleSize);
|
|
196
|
+
for (let index = 0; index < assetBundleSize; index++) {
|
|
197
|
+
for (const key in this.assets) {
|
|
198
|
+
for (let y = 0; y < this.assets[key].length; y++) {
|
|
199
|
+
newAssetBundle[index++] = this.assets[key][y];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
resolve(newAssetBundle);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
initializeAssetBundle().then((newAssetBundle) => {
|
|
210
|
+
this.assetBundle = newAssetBundle;
|
|
211
|
+
resolve();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
handleStateChange(node, layerName) {
|
|
218
|
+
this.state = this.squish(this.game.getLayers());
|
|
219
|
+
this.broadcast();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
broadcast() {
|
|
223
|
+
for (const listener of this.listeners) {
|
|
224
|
+
listener.onEvent(this.state);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
module.exports = Squisher;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const { GameNode } = require('./GameNode');
|
|
2
|
+
const Shapes = require('./Shapes');
|
|
3
|
+
const ShapeUtils = require('./util/shapes');
|
|
4
|
+
const Colors = require('./Colors');
|
|
5
|
+
const Game = require('./Game');
|
|
6
|
+
|
|
7
|
+
const makePlane = (s) => {
|
|
8
|
+
return new GameNode.Shape({
|
|
9
|
+
shapeType: Shapes.POLYGON,
|
|
10
|
+
coordinates2d: ShapeUtils.rectangle(0, 0, s, s)
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
class ViewableGame extends Game {
|
|
15
|
+
#plane;
|
|
16
|
+
#fakeRoot;
|
|
17
|
+
#planeSize;
|
|
18
|
+
constructor(planeSize) {
|
|
19
|
+
super();
|
|
20
|
+
this.#planeSize = planeSize;
|
|
21
|
+
this.#plane = makePlane(this.planeSize);
|
|
22
|
+
|
|
23
|
+
this.#fakeRoot = new GameNode.Shape({
|
|
24
|
+
shapeType: Shapes.POLYGON,
|
|
25
|
+
coordinates2d: ShapeUtils.rectangle(0, 0, 0, 0),
|
|
26
|
+
fill: Colors.COLORS.BLACK,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
this.layers = [
|
|
30
|
+
{
|
|
31
|
+
root: this.#fakeRoot
|
|
32
|
+
}
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
updatePlaneSize(s) {
|
|
37
|
+
this.#planeSize = s;
|
|
38
|
+
this.#plane.node.coordinates2d = ShapeUtils.rectangle(0, 0, s, s);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getLayers() {
|
|
42
|
+
return this.layers;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getPlane() {
|
|
46
|
+
return this.#plane;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getPlaneSize() {
|
|
50
|
+
return this.#planeSize;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getViewRoot() {
|
|
54
|
+
return this.#fakeRoot;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = ViewableGame;
|
|
60
|
+
|