@nanoforge-dev/schematics 2.2.1-beta.88f48da → 2.3.0
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/CHANGELOG.md +472 -0
- package/README.md +12 -15
- package/dist/collection.json +8 -23
- package/dist/index.cjs +21 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +19 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/libs/component/component.factory.d.ts +1 -3
- package/dist/libs/component/component.factory.d.ts.map +1 -1
- package/dist/libs/component/component.factory.js +2 -1
- package/dist/libs/component/component.factory.js.map +1 -1
- package/dist/libs/project/files/js/.dockerignore +5 -0
- package/dist/libs/project/files/js/Dockerfile +36 -0
- package/dist/libs/project/files/js/README.md +53 -0
- package/dist/libs/project/files/js/assets/__dot__gitkeep +0 -0
- package/dist/libs/project/files/js/jsconfig.json +36 -0
- package/dist/libs/project/files/js/nanoforge.config.js +10 -0
- package/dist/libs/project/files/js/package.json.template +24 -0
- package/dist/libs/project/files/js/pnpm-workspace.yaml.template +3 -0
- package/dist/libs/project/files/js/src/components/drawable-circle-2d.component.js +404 -0
- package/dist/libs/project/files/js/src/components/position-2d.component.js +42 -0
- package/dist/libs/project/files/js/src/main.js +43 -0
- package/dist/libs/project/files/js/src/systems/draw-2d.system.js +33 -0
- package/dist/libs/project/files/js/src/systems/move-2d.system.js +34 -0
- package/dist/libs/project/files/js/src/systems/position-sync.system.js +35 -0
- package/dist/libs/project/files/ts/.dockerignore +5 -0
- package/dist/libs/project/files/ts/Dockerfile +36 -0
- package/dist/libs/project/files/ts/README.md +53 -0
- package/dist/libs/project/files/ts/assets/__dot__gitkeep +0 -0
- package/dist/libs/project/files/ts/nanoforge.config.ts +5 -0
- package/dist/libs/project/files/ts/package.json.template +24 -0
- package/dist/libs/project/files/ts/pnpm-workspace.yaml.template +3 -0
- package/dist/libs/project/files/ts/src/components/drawable-circle-2d.component.ts +367 -0
- package/dist/libs/project/files/ts/src/components/position-2d.component.ts +35 -0
- package/dist/libs/project/files/ts/src/main.ts +39 -0
- package/dist/libs/project/files/ts/src/systems/draw-2d.system.ts +25 -0
- package/dist/libs/project/files/ts/src/systems/move-2d.system.ts +26 -0
- package/dist/libs/project/files/ts/src/systems/position-sync.system.ts +27 -0
- package/dist/libs/project/files/ts/tsconfig.json +42 -0
- package/dist/libs/project/project.factory.d.ts +64 -0
- package/dist/libs/project/project.factory.d.ts.map +1 -0
- package/dist/libs/project/project.factory.js +122 -0
- package/dist/libs/project/project.factory.js.map +1 -0
- package/dist/libs/project/schema.json +83 -0
- package/dist/libs/system/system.factory.d.ts +1 -3
- package/dist/libs/system/system.factory.d.ts.map +1 -1
- package/dist/libs/system/system.factory.js +2 -1
- package/dist/libs/system/system.factory.js.map +1 -1
- package/dist/libs/workspace/files/js/.dockerignore +5 -0
- package/dist/libs/workspace/files/js/Dockerfile +36 -0
- package/dist/libs/workspace/files/js/README.md +51 -0
- package/dist/libs/workspace/files/js/__dot__gitignore +137 -0
- package/dist/libs/{application → workspace}/files/js/jsconfig.json +1 -2
- package/dist/libs/workspace/files/js/nanoforge.config.js +6 -0
- package/dist/libs/workspace/files/js/package.json.template +19 -0
- package/dist/libs/workspace/files/js/pnpm-workspace.yaml.template +6 -0
- package/dist/libs/workspace/files/ts/.dockerignore +5 -0
- package/dist/libs/workspace/files/ts/Dockerfile +36 -0
- package/dist/libs/workspace/files/ts/README.md +51 -0
- package/dist/libs/workspace/files/ts/__dot__gitignore +134 -0
- package/dist/libs/workspace/files/ts/nanoforge.config.ts +6 -0
- package/dist/libs/workspace/files/ts/package.json.template +20 -0
- package/dist/libs/workspace/files/ts/pnpm-workspace.yaml.template +6 -0
- package/dist/libs/{application → workspace}/files/ts/tsconfig.json +1 -2
- package/dist/libs/workspace/schema.json +45 -0
- package/dist/libs/workspace/workspace.factory.d.ts +42 -0
- package/dist/libs/workspace/workspace.factory.d.ts.map +1 -0
- package/dist/libs/workspace/workspace.factory.js +116 -0
- package/dist/libs/workspace/workspace.factory.js.map +1 -0
- package/package.json +23 -21
- package/dist/libs/application/application.factory.d.ts +0 -59
- package/dist/libs/application/application.factory.d.ts.map +0 -1
- package/dist/libs/application/application.factory.js +0 -57
- package/dist/libs/application/application.factory.js.map +0 -1
- package/dist/libs/application/files/js/.prettierignore +0 -8
- package/dist/libs/application/files/js/README.md +0 -166
- package/dist/libs/application/files/js/eslint.config.js +0 -11
- package/dist/libs/application/files/js/package.json.template +0 -48
- package/dist/libs/application/files/js/pnpm-workspace.yaml.template +0 -3
- package/dist/libs/application/files/js/prettier.config.js +0 -6
- package/dist/libs/application/files/ts/.prettierignore +0 -8
- package/dist/libs/application/files/ts/README.md +0 -166
- package/dist/libs/application/files/ts/eslint.config.js +0 -15
- package/dist/libs/application/files/ts/package.json.template +0 -52
- package/dist/libs/application/files/ts/pnpm-workspace.yaml.template +0 -3
- package/dist/libs/application/files/ts/prettier.config.js +0 -6
- package/dist/libs/application/schema.json +0 -70
- package/dist/libs/configuration/configuration.factory.d.ts +0 -31
- package/dist/libs/configuration/configuration.factory.d.ts.map +0 -1
- package/dist/libs/configuration/configuration.factory.js +0 -97
- package/dist/libs/configuration/configuration.factory.js.map +0 -1
- package/dist/libs/configuration/files/nanoforge.config.json +0 -1
- package/dist/libs/configuration/schema.json +0 -34
- package/dist/libs/docker/docker.factory.d.ts +0 -19
- package/dist/libs/docker/docker.factory.d.ts.map +0 -1
- package/dist/libs/docker/docker.factory.js +0 -20
- package/dist/libs/docker/docker.factory.js.map +0 -1
- package/dist/libs/docker/files/.dockerignore +0 -1
- package/dist/libs/docker/files/Dockerfile +0 -25
- package/dist/libs/docker/schema.json +0 -19
- package/dist/libs/part-base/files/js/__nanoforgeFolder__/client.save.json +0 -77
- package/dist/libs/part-base/files/js/__nanoforgeFolder__/server.save.json +0 -49
- package/dist/libs/part-base/files/js/__part__/components/example.component.js +0 -72
- package/dist/libs/part-base/files/js/__part__/init/after-init.js +0 -12
- package/dist/libs/part-base/files/js/__part__/init/after-registry-init.js +0 -14
- package/dist/libs/part-base/files/js/__part__/init/after-run.js +0 -12
- package/dist/libs/part-base/files/js/__part__/init/before-init.js +0 -13
- package/dist/libs/part-base/files/js/__part__/init/before-registry-init.js +0 -14
- package/dist/libs/part-base/files/js/__part__/init/before-run.js +0 -12
- package/dist/libs/part-base/files/js/__part__/systems/example.system.js +0 -44
- package/dist/libs/part-base/files/ts/__nanoforgeFolder__/client.save.json +0 -77
- package/dist/libs/part-base/files/ts/__nanoforgeFolder__/server.save.json +0 -49
- package/dist/libs/part-base/files/ts/__part__/components/example.component.ts +0 -55
- package/dist/libs/part-base/files/ts/__part__/init/after-init.ts +0 -5
- package/dist/libs/part-base/files/ts/__part__/init/after-registry-init.ts +0 -6
- package/dist/libs/part-base/files/ts/__part__/init/after-run.ts +0 -5
- package/dist/libs/part-base/files/ts/__part__/init/before-init.ts +0 -5
- package/dist/libs/part-base/files/ts/__part__/init/before-registry-init.ts +0 -6
- package/dist/libs/part-base/files/ts/__part__/init/before-run.ts +0 -5
- package/dist/libs/part-base/files/ts/__part__/systems/example.system.ts +0 -31
- package/dist/libs/part-base/part-base.factory.d.ts +0 -31
- package/dist/libs/part-base/part-base.factory.d.ts.map +0 -1
- package/dist/libs/part-base/part-base.factory.js +0 -33
- package/dist/libs/part-base/part-base.factory.js.map +0 -1
- package/dist/libs/part-base/schema.json +0 -35
- package/dist/libs/part-main/part-main.factory.d.ts +0 -39
- package/dist/libs/part-main/part-main.factory.d.ts.map +0 -1
- package/dist/libs/part-main/part-main.factory.js +0 -252
- package/dist/libs/part-main/part-main.factory.js.map +0 -1
- package/dist/libs/part-main/schema.json +0 -43
- /package/dist/libs/{application → project}/files/js/__dot__gitignore +0 -0
- /package/dist/libs/{application → project}/files/ts/__dot__gitignore +0 -0
- /package/dist/libs/{application → workspace}/files/js/__dot__env +0 -0
- /package/dist/libs/{application → workspace}/files/ts/__dot__env +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "<%= packageName %>",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "nf dev",
|
|
6
|
+
"build": "nf build",
|
|
7
|
+
"start": "nf start"
|
|
8
|
+
},<% if (part === "server") { %>
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@nanoforge-dev/network": "<%= networkVersion %>"
|
|
11
|
+
},<% } %>
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@nanoforge-dev/ecs": "<%= ecsVersion %>",<% if (part === "client") { %>
|
|
14
|
+
"@nanoforge-dev/graphics-2d": "<%= graphics2dVersion %>",
|
|
15
|
+
"@nanoforge-dev/input": "<%= inputVersion %>",
|
|
16
|
+
"@nanoforge-dev/network": "<%= networkVersion %>",<% } %>
|
|
17
|
+
"nanoforge": "<%= nanoforgeVersion %>"
|
|
18
|
+
},<% if (packageManager === "npm" && allowBuilds.length > 0) { %>
|
|
19
|
+
"allowScripts": {<% allowBuilds.forEach(function (pkg, i) { %>
|
|
20
|
+
"<%= pkg %>": true<% if (i < allowBuilds.length - 1) { %>,<% } %><% }); %>
|
|
21
|
+
},<% } %><% if (packageManager === "bun" && allowBuilds.length > 0) { %>
|
|
22
|
+
"trustedDependencies": [<% allowBuilds.forEach(function (pkg, i) { %>"<%= pkg %>"<% if (i < allowBuilds.length - 1) { %>, <% } %><% }); %>],<% } %>
|
|
23
|
+
"private": true
|
|
24
|
+
}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import type { EditorComponentManifest } from "@nanoforge-dev/ecs";
|
|
2
|
+
import { Circle, type Layer } from "@nanoforge-dev/graphics-2d";
|
|
3
|
+
import type { NfFile } from "nanoforge";
|
|
4
|
+
|
|
5
|
+
export class DrawableCircle2D {
|
|
6
|
+
public readonly name: string = this.constructor.name;
|
|
7
|
+
shape: Circle;
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
radius?: number,
|
|
11
|
+
visible?: boolean,
|
|
12
|
+
id?: string,
|
|
13
|
+
opacity?: number,
|
|
14
|
+
scaleX?: number,
|
|
15
|
+
scaleY?: number,
|
|
16
|
+
skewX?: number,
|
|
17
|
+
skewY?: number,
|
|
18
|
+
rotation?: number,
|
|
19
|
+
offsetX?: number,
|
|
20
|
+
offsetY?: number,
|
|
21
|
+
fillColor?: string,
|
|
22
|
+
private _fillPatternImage?: NfFile,
|
|
23
|
+
fillPatternX?: number,
|
|
24
|
+
fillPatternY?: number,
|
|
25
|
+
fillPatternOffsetX?: number,
|
|
26
|
+
fillPatternOffsetY?: number,
|
|
27
|
+
fillPatternScaleX?: number,
|
|
28
|
+
fillPatternScaleY?: number,
|
|
29
|
+
fillPatternRotation?: number,
|
|
30
|
+
fillPatternRepeat?: string,
|
|
31
|
+
) {
|
|
32
|
+
this.shape = new Circle({
|
|
33
|
+
radius,
|
|
34
|
+
visible,
|
|
35
|
+
id,
|
|
36
|
+
opacity,
|
|
37
|
+
scaleX,
|
|
38
|
+
scaleY,
|
|
39
|
+
skewX,
|
|
40
|
+
skewY,
|
|
41
|
+
rotation,
|
|
42
|
+
offsetX,
|
|
43
|
+
offsetY,
|
|
44
|
+
fill: fillColor,
|
|
45
|
+
fillPatternImage: _fillPatternImage
|
|
46
|
+
? Object.assign(new Image(), { src: _fillPatternImage.path })
|
|
47
|
+
: undefined,
|
|
48
|
+
fillPatternX,
|
|
49
|
+
fillPatternY,
|
|
50
|
+
fillPatternOffsetX,
|
|
51
|
+
fillPatternOffsetY,
|
|
52
|
+
fillPatternScaleX,
|
|
53
|
+
fillPatternScaleY,
|
|
54
|
+
fillPatternRotation,
|
|
55
|
+
fillPatternRepeat,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get radius() {
|
|
60
|
+
return this.shape.radius();
|
|
61
|
+
}
|
|
62
|
+
set radius(v: number) {
|
|
63
|
+
this.shape.radius(v);
|
|
64
|
+
this.redraw();
|
|
65
|
+
}
|
|
66
|
+
get visible() {
|
|
67
|
+
return this.shape.visible();
|
|
68
|
+
}
|
|
69
|
+
set visible(v: boolean) {
|
|
70
|
+
this.shape.visible(v);
|
|
71
|
+
this.redraw();
|
|
72
|
+
}
|
|
73
|
+
get id() {
|
|
74
|
+
return this.shape.id();
|
|
75
|
+
}
|
|
76
|
+
set id(v: string) {
|
|
77
|
+
this.shape.id(v);
|
|
78
|
+
this.redraw();
|
|
79
|
+
}
|
|
80
|
+
get opacity() {
|
|
81
|
+
return this.shape.opacity();
|
|
82
|
+
}
|
|
83
|
+
set opacity(v: number) {
|
|
84
|
+
this.shape.opacity(v);
|
|
85
|
+
this.redraw();
|
|
86
|
+
}
|
|
87
|
+
get scaleX() {
|
|
88
|
+
return this.shape.scaleX();
|
|
89
|
+
}
|
|
90
|
+
set scaleX(v: number) {
|
|
91
|
+
this.shape.scaleX(v);
|
|
92
|
+
this.redraw();
|
|
93
|
+
}
|
|
94
|
+
get scaleY() {
|
|
95
|
+
return this.shape.scaleY();
|
|
96
|
+
}
|
|
97
|
+
set scaleY(v: number) {
|
|
98
|
+
this.shape.scaleY(v);
|
|
99
|
+
this.redraw();
|
|
100
|
+
}
|
|
101
|
+
get skewX() {
|
|
102
|
+
return this.shape.skewX();
|
|
103
|
+
}
|
|
104
|
+
set skewX(v: number) {
|
|
105
|
+
this.shape.skewX(v);
|
|
106
|
+
this.redraw();
|
|
107
|
+
}
|
|
108
|
+
get skewY() {
|
|
109
|
+
return this.shape.skewY();
|
|
110
|
+
}
|
|
111
|
+
set skewY(v: number) {
|
|
112
|
+
this.shape.skewY(v);
|
|
113
|
+
this.redraw();
|
|
114
|
+
}
|
|
115
|
+
get rotation() {
|
|
116
|
+
return this.shape.rotation();
|
|
117
|
+
}
|
|
118
|
+
set rotation(v: number) {
|
|
119
|
+
this.shape.rotation(v);
|
|
120
|
+
this.redraw();
|
|
121
|
+
}
|
|
122
|
+
get offsetX() {
|
|
123
|
+
return this.shape.offsetX();
|
|
124
|
+
}
|
|
125
|
+
set offsetX(v: number) {
|
|
126
|
+
this.shape.offsetX(v);
|
|
127
|
+
this.redraw();
|
|
128
|
+
}
|
|
129
|
+
get offsetY() {
|
|
130
|
+
return this.shape.offsetY();
|
|
131
|
+
}
|
|
132
|
+
set offsetY(v: number) {
|
|
133
|
+
this.shape.offsetY(v);
|
|
134
|
+
this.redraw();
|
|
135
|
+
}
|
|
136
|
+
get fillColor() {
|
|
137
|
+
return this.shape.fill().toString();
|
|
138
|
+
}
|
|
139
|
+
set fillColor(v: string) {
|
|
140
|
+
this.shape.fill(v);
|
|
141
|
+
this.redraw();
|
|
142
|
+
}
|
|
143
|
+
get fillPatternImage(): NfFile | undefined {
|
|
144
|
+
return this._fillPatternImage;
|
|
145
|
+
}
|
|
146
|
+
set fillPatternImage(v: NfFile) {
|
|
147
|
+
this.shape.fillPatternImage(v ? Object.assign(new Image(), { src: v.path }) : undefined);
|
|
148
|
+
this.redraw();
|
|
149
|
+
}
|
|
150
|
+
get fillPatternX() {
|
|
151
|
+
return this.shape.fillPatternX();
|
|
152
|
+
}
|
|
153
|
+
set fillPatternX(v: number) {
|
|
154
|
+
this.shape.fillPatternX(v);
|
|
155
|
+
this.redraw();
|
|
156
|
+
}
|
|
157
|
+
get fillPatternY() {
|
|
158
|
+
return this.shape.fillPatternY();
|
|
159
|
+
}
|
|
160
|
+
set fillPatternY(v: number) {
|
|
161
|
+
this.shape.fillPatternY(v);
|
|
162
|
+
this.redraw();
|
|
163
|
+
}
|
|
164
|
+
get fillPatternOffsetX() {
|
|
165
|
+
return this.shape.fillPatternOffsetX();
|
|
166
|
+
}
|
|
167
|
+
set fillPatternOffsetX(v: number) {
|
|
168
|
+
this.shape.fillPatternOffsetX(v);
|
|
169
|
+
this.redraw();
|
|
170
|
+
}
|
|
171
|
+
get fillPatternOffsetY() {
|
|
172
|
+
return this.shape.fillPatternOffsetY();
|
|
173
|
+
}
|
|
174
|
+
set fillPatternOffsetY(v: number) {
|
|
175
|
+
this.shape.fillPatternOffsetY(v);
|
|
176
|
+
this.redraw();
|
|
177
|
+
}
|
|
178
|
+
get fillPatternScaleX() {
|
|
179
|
+
return this.shape.fillPatternScaleX();
|
|
180
|
+
}
|
|
181
|
+
set fillPatternScaleX(v: number) {
|
|
182
|
+
this.shape.fillPatternScaleX(v);
|
|
183
|
+
this.redraw();
|
|
184
|
+
}
|
|
185
|
+
get fillPatternScaleY() {
|
|
186
|
+
return this.shape.fillPatternScaleY();
|
|
187
|
+
}
|
|
188
|
+
set fillPatternScaleY(v: number) {
|
|
189
|
+
this.shape.fillPatternScaleY(v);
|
|
190
|
+
this.redraw();
|
|
191
|
+
}
|
|
192
|
+
get fillPatternRotation() {
|
|
193
|
+
return this.shape.fillPatternRotation();
|
|
194
|
+
}
|
|
195
|
+
set fillPatternRotation(v: number) {
|
|
196
|
+
this.shape.fillPatternRotation(v);
|
|
197
|
+
this.redraw();
|
|
198
|
+
}
|
|
199
|
+
get fillPatternRepeat() {
|
|
200
|
+
return this.shape.fillPatternRepeat();
|
|
201
|
+
}
|
|
202
|
+
set fillPatternRepeat(v: string) {
|
|
203
|
+
this.shape.fillPatternRepeat(v);
|
|
204
|
+
this.redraw();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public addToLayer(layer: Layer): void {
|
|
208
|
+
if (this.shape.getParent() !== layer) layer.add(this.shape);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private redraw() {
|
|
212
|
+
this.shape.getLayer()?.batchDraw();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// * Required to generate code
|
|
216
|
+
export default DrawableCircle2D.name;
|
|
217
|
+
|
|
218
|
+
// * Required for the editor to display the component and generate code
|
|
219
|
+
export const EDITOR_COMPONENT_MANIFEST: EditorComponentManifest = {
|
|
220
|
+
name: "DrawableCircle2D",
|
|
221
|
+
description: "Graphically drawable circle 2D",
|
|
222
|
+
params: [
|
|
223
|
+
{
|
|
224
|
+
name: "radius",
|
|
225
|
+
type: "number",
|
|
226
|
+
description: "Radius of the circle in pixels",
|
|
227
|
+
default: 10,
|
|
228
|
+
optional: false,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: "visible",
|
|
232
|
+
type: "boolean",
|
|
233
|
+
description: "Controls whether the node is rendered",
|
|
234
|
+
default: true,
|
|
235
|
+
optional: false,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: "id",
|
|
239
|
+
type: "string",
|
|
240
|
+
description: "Unique identifier for the node, used with stage.findOne('#id')",
|
|
241
|
+
optional: true,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: "opacity",
|
|
245
|
+
type: "number",
|
|
246
|
+
description: "Opacity from 0 (transparent) to 1 (fully opaque)",
|
|
247
|
+
default: 1,
|
|
248
|
+
optional: true,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: "scaleX",
|
|
252
|
+
type: "number",
|
|
253
|
+
description: "Horizontal scale factor",
|
|
254
|
+
default: 1,
|
|
255
|
+
optional: true,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: "scaleY",
|
|
259
|
+
type: "number",
|
|
260
|
+
description: "Vertical scale factor",
|
|
261
|
+
default: 1,
|
|
262
|
+
optional: true,
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: "skewX",
|
|
266
|
+
type: "number",
|
|
267
|
+
default: 0,
|
|
268
|
+
description: "Horizontal skew in radians, shears along the X axis",
|
|
269
|
+
optional: true,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "skewY",
|
|
273
|
+
type: "number",
|
|
274
|
+
default: 0,
|
|
275
|
+
description: "Vertical skew in radians, shears along the Y axis",
|
|
276
|
+
optional: true,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "rotation",
|
|
280
|
+
type: "number",
|
|
281
|
+
description:
|
|
282
|
+
"Rotation angle in degrees applied around the offset point (positive values rotate clockwise)",
|
|
283
|
+
default: 0,
|
|
284
|
+
optional: true,
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "offsetX",
|
|
288
|
+
type: "number",
|
|
289
|
+
description: "Horizontal offset for the transform origin",
|
|
290
|
+
default: 0,
|
|
291
|
+
optional: true,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "offsetY",
|
|
295
|
+
type: "number",
|
|
296
|
+
description: "Vertical offset for the transform origin",
|
|
297
|
+
default: 0,
|
|
298
|
+
optional: true,
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
name: "fillColor",
|
|
302
|
+
type: "string",
|
|
303
|
+
description:
|
|
304
|
+
'Solid fill color as a CSS color string (e.g. "red", "#ff0000", "rgba(255,0,0,0.5)"), or a pre-built CanvasGradient object',
|
|
305
|
+
default: "red",
|
|
306
|
+
example: "rgb(255,255,255)",
|
|
307
|
+
optional: true,
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "fillPatternImage",
|
|
311
|
+
type: "asset",
|
|
312
|
+
description: "Image element to use as a tiling pattern fill",
|
|
313
|
+
optional: true,
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "fillPatternX",
|
|
317
|
+
type: "number",
|
|
318
|
+
description:
|
|
319
|
+
"Horizontal offset of the pattern origin relative to the shape's top-left corner, in pixels",
|
|
320
|
+
optional: true,
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: "fillPatternY",
|
|
324
|
+
type: "number",
|
|
325
|
+
description:
|
|
326
|
+
"Vertical offset of the pattern origin relative to the shape's top-left corner, in pixels",
|
|
327
|
+
optional: true,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "fillPatternOffsetX",
|
|
331
|
+
type: "number",
|
|
332
|
+
description: "Horizontally shifts the pattern image within the tile before repeating",
|
|
333
|
+
optional: true,
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
name: "fillPatternOffsetY",
|
|
337
|
+
type: "number",
|
|
338
|
+
description: "Vertically shifts the pattern image within the tile before repeating",
|
|
339
|
+
optional: true,
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
name: "fillPatternScaleX",
|
|
343
|
+
type: "number",
|
|
344
|
+
description: "Horizontal scale factor for the pattern tile",
|
|
345
|
+
optional: true,
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: "fillPatternScaleY",
|
|
349
|
+
type: "number",
|
|
350
|
+
description: "Vertical scale factor for the pattern tile",
|
|
351
|
+
optional: true,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "fillPatternRotation",
|
|
355
|
+
type: "number",
|
|
356
|
+
description: "Rotation of the pattern tile in degrees",
|
|
357
|
+
optional: true,
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: "fillPatternRepeat",
|
|
361
|
+
type: "string",
|
|
362
|
+
description:
|
|
363
|
+
'Repeat mode for the pattern. One of "repeat" (default), "repeat-x", "repeat-y", or "no-repeat"',
|
|
364
|
+
optional: true,
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { EditorComponentManifest } from "@nanoforge-dev/ecs";
|
|
2
|
+
|
|
3
|
+
export class Position2D {
|
|
4
|
+
name = this.constructor.name;
|
|
5
|
+
|
|
6
|
+
constructor(
|
|
7
|
+
public x: number,
|
|
8
|
+
public y: number,
|
|
9
|
+
) {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// * Required to generate code
|
|
13
|
+
export default Position2D.name;
|
|
14
|
+
|
|
15
|
+
// * Required for the editor to display the component and generate code
|
|
16
|
+
export const EDITOR_COMPONENT_MANIFEST: EditorComponentManifest = {
|
|
17
|
+
name: "Position2D",
|
|
18
|
+
description: "Position of an entity in a 2 dimensional space in pixel",
|
|
19
|
+
params: [
|
|
20
|
+
{
|
|
21
|
+
type: "number",
|
|
22
|
+
name: "x",
|
|
23
|
+
description: "Horizontal position in pixel",
|
|
24
|
+
example: 4.2,
|
|
25
|
+
default: 0,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: "number",
|
|
29
|
+
name: "y",
|
|
30
|
+
description: "Vertical position in pixel",
|
|
31
|
+
example: 67,
|
|
32
|
+
default: 0,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { NanoforgeFactory, type <%= part === "client" ? "ClientRunOptions" : "ServerRunOptions" %> } from "nanoforge";
|
|
2
|
+
import { EcsLibrary } from "@nanoforge-dev/ecs/<%= part %>";<% if (part === "client") { %>
|
|
3
|
+
import { Graphics2DLibrary } from "@nanoforge-dev/graphics-2d";
|
|
4
|
+
import { InputLibrary } from "@nanoforge-dev/input";<% } %>
|
|
5
|
+
import { <%= part === "client" ? "NetworkClientLibrary" : "NetworkServerLibrary" %> } from "@nanoforge-dev/network/<%= part %>";
|
|
6
|
+
<% if (part === "client") { %>
|
|
7
|
+
import { DrawableCircle2D } from "./components/drawable-circle-2d.component";<% } %>
|
|
8
|
+
import { Position2D } from "./components/position-2d.component";<% if (part === "client") { %>
|
|
9
|
+
import { draw2D } from "./systems/draw-2d.system";<% if (hasServer) { %>
|
|
10
|
+
import { positionSync } from "./systems/position-sync.system";<% } %><% } else { %>
|
|
11
|
+
import { move2D } from "./systems/move-2d.system";<% } %>
|
|
12
|
+
|
|
13
|
+
export const main = async (options: <%= part === "client" ? "ClientRunOptions" : "ServerRunOptions" %>): Promise<void> => {
|
|
14
|
+
const app = NanoforgeFactory.<%= part === "client" ? "createClient" : "createServer" %>({ tickRate: 60 });
|
|
15
|
+
|
|
16
|
+
const ecs = new EcsLibrary();
|
|
17
|
+
app.use(ecs);<% if (part === "client") { %>
|
|
18
|
+
app.use(new Graphics2DLibrary());
|
|
19
|
+
app.use(new InputLibrary());<% } %>
|
|
20
|
+
app.use(new <%= part === "client" ? "NetworkClientLibrary" : "NetworkServerLibrary" %>());
|
|
21
|
+
|
|
22
|
+
await app.init(options);
|
|
23
|
+
|
|
24
|
+
const registry = ecs.registry;
|
|
25
|
+
<% if (part === "client") { %>
|
|
26
|
+
const circle = registry.spawnEntity();
|
|
27
|
+
registry.addComponent(circle, new Position2D(500, 500));
|
|
28
|
+
registry.addComponent(circle, new DrawableCircle2D(75, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "red"));
|
|
29
|
+
|
|
30
|
+
registry.addSystem(draw2D);<% if (hasServer) { %>
|
|
31
|
+
registry.addSystem(positionSync);<% } %>
|
|
32
|
+
<% } else { %>
|
|
33
|
+
const entity = registry.spawnEntity();
|
|
34
|
+
registry.addComponent(entity, new Position2D(500, 500));
|
|
35
|
+
|
|
36
|
+
registry.addSystem(move2D);
|
|
37
|
+
<% } %>
|
|
38
|
+
await app.run();
|
|
39
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EditorSystemManifest, Registry } from "@nanoforge-dev/ecs";
|
|
2
|
+
import { type Context } from "nanoforge";
|
|
3
|
+
|
|
4
|
+
import { DrawableCircle2D } from "../components/drawable-circle-2d.component";
|
|
5
|
+
import { Position2D } from "../components/position-2d.component";
|
|
6
|
+
|
|
7
|
+
export function draw2D(registry: Registry, ctx: Context) {
|
|
8
|
+
const graphic2d = ctx.graphics;
|
|
9
|
+
|
|
10
|
+
const entities = registry.getZipper([Position2D, DrawableCircle2D]);
|
|
11
|
+
|
|
12
|
+
entities.forEach(({ Position2D, DrawableCircle2D }) => {
|
|
13
|
+
DrawableCircle2D.addToLayer(graphic2d.baseLayer);
|
|
14
|
+
DrawableCircle2D.shape.setPosition(Position2D);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
// * Required to generate code
|
|
18
|
+
export default draw2D.name;
|
|
19
|
+
|
|
20
|
+
// * Required for the editor to display the system and generate code
|
|
21
|
+
export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = {
|
|
22
|
+
name: "draw2D",
|
|
23
|
+
description: "Draw every drawable component",
|
|
24
|
+
dependencies: ["Position2D", "DrawableCircle2D"],
|
|
25
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { EditorSystemManifest, Registry } from "@nanoforge-dev/ecs";
|
|
2
|
+
import { type Context } from "nanoforge";
|
|
3
|
+
|
|
4
|
+
import { Position2D } from "../components/position-2d.component";
|
|
5
|
+
|
|
6
|
+
export function move2D(registry: Registry, ctx: Context) {
|
|
7
|
+
const network = ctx.network;
|
|
8
|
+
const entities = registry.getZipper([Position2D]);
|
|
9
|
+
|
|
10
|
+
entities.forEach(({ Position2D }) => {
|
|
11
|
+
Position2D.x += 1;
|
|
12
|
+
|
|
13
|
+
network.tcp.sendToEverybody(
|
|
14
|
+
new TextEncoder().encode(JSON.stringify({ x: Position2D.x, y: Position2D.y })),
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
// * Required to generate code
|
|
19
|
+
export default move2D.name;
|
|
20
|
+
|
|
21
|
+
// * Required for the editor to display the system and generate code
|
|
22
|
+
export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = {
|
|
23
|
+
name: "move2D",
|
|
24
|
+
description: "Moves the entity and broadcasts its position to every connected client",
|
|
25
|
+
dependencies: ["Position2D"],
|
|
26
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { EditorSystemManifest, Registry } from "@nanoforge-dev/ecs";
|
|
2
|
+
import { type Context } from "nanoforge";
|
|
3
|
+
|
|
4
|
+
import { Position2D } from "../components/position-2d.component";
|
|
5
|
+
|
|
6
|
+
export function positionSync(registry: Registry, ctx: Context) {
|
|
7
|
+
const network = ctx.network;
|
|
8
|
+
const packets = network.tcp
|
|
9
|
+
.getReceivedPackets()
|
|
10
|
+
.map((packet) => JSON.parse(new TextDecoder().decode(packet)) as { x: number; y: number });
|
|
11
|
+
|
|
12
|
+
const [entity] = registry.getZipper([Position2D]);
|
|
13
|
+
|
|
14
|
+
packets.forEach((packet) => {
|
|
15
|
+
entity.Position2D.x = packet.x;
|
|
16
|
+
entity.Position2D.y = packet.y;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// * Required to generate code
|
|
20
|
+
export default positionSync.name;
|
|
21
|
+
|
|
22
|
+
// * Required for the editor to display the system and generate code
|
|
23
|
+
export const EDITOR_SYSTEM_MANIFEST: EditorSystemManifest = {
|
|
24
|
+
name: "positionSync",
|
|
25
|
+
description: "Overwrites the local entity's position with the latest value received from the server",
|
|
26
|
+
dependencies: ["Position2D"],
|
|
27
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig.json",<% if (workspace) { %>
|
|
3
|
+
"extends": "../../tsconfig.json",<% } else { %>
|
|
4
|
+
// Mapped from https://www.typescriptlang.org/tsconfig
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
// Type Checking
|
|
7
|
+
"allowUnreachableCode": <%= !strict %>,
|
|
8
|
+
"allowUnusedLabels": <%= !strict %>,
|
|
9
|
+
"exactOptionalPropertyTypes": <%= strict %>,
|
|
10
|
+
"noFallthroughCasesInSwitch": <%= strict %>,
|
|
11
|
+
"noImplicitOverride": <%= strict %>,
|
|
12
|
+
"noImplicitReturns": <%= strict %>,
|
|
13
|
+
"noPropertyAccessFromIndexSignature": <%= !strict %>,
|
|
14
|
+
"noUncheckedIndexedAccess": <%= strict %>,
|
|
15
|
+
"noUnusedLocals": <%= strict %>,
|
|
16
|
+
"noUnusedParameters": <%= strict %>,
|
|
17
|
+
"strict": <%= strict %>,
|
|
18
|
+
|
|
19
|
+
// Modules
|
|
20
|
+
"allowArbitraryExtensions": false,
|
|
21
|
+
"allowImportingTsExtensions": false,
|
|
22
|
+
"module": "ESNext",
|
|
23
|
+
"moduleResolution": "Bundler",
|
|
24
|
+
"resolveJsonModule": true,
|
|
25
|
+
"resolvePackageJsonExports": true,
|
|
26
|
+
"resolvePackageJsonImports": true,
|
|
27
|
+
|
|
28
|
+
// Interop Constraints
|
|
29
|
+
"allowSyntheticDefaultImports": true,
|
|
30
|
+
"esModuleInterop": false,
|
|
31
|
+
"forceConsistentCasingInFileNames": true,
|
|
32
|
+
"isolatedModules": true,
|
|
33
|
+
|
|
34
|
+
// Language and Environment
|
|
35
|
+
"experimentalDecorators": true,
|
|
36
|
+
"lib": ["ESNext", "esnext.disposable", "DOM"],
|
|
37
|
+
"target": "ESNext",
|
|
38
|
+
"useDefineForClassFields": true,
|
|
39
|
+
},<% } %>
|
|
40
|
+
"include": ["src"],
|
|
41
|
+
"exclude": ["node_modules", ".nanoforge", "dist"]
|
|
42
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Rule } from "@angular-devkit/schematics";
|
|
2
|
+
//#region src/libs/project/project.schema.d.ts
|
|
3
|
+
interface ProjectSchema {
|
|
4
|
+
/**
|
|
5
|
+
* The type of project to generate
|
|
6
|
+
*/
|
|
7
|
+
part: "client" | "server";
|
|
8
|
+
/**
|
|
9
|
+
* Name of the parent workspace, used to derive the project package name.
|
|
10
|
+
* Optional - when omitted, `name` is used as the whole package name
|
|
11
|
+
* instead of being appended to the workspace name.
|
|
12
|
+
*/
|
|
13
|
+
workspaceName?: string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Name used to derive the project package name. When `workspaceName` is
|
|
16
|
+
* set, the package name is `${workspaceName}-${name}` (replacing the
|
|
17
|
+
* previous `${workspaceName}-${part}` suffix). When `workspaceName` is
|
|
18
|
+
* absent, `name` becomes the whole package name. Defaults to `part`.
|
|
19
|
+
*/
|
|
20
|
+
name?: string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Full destination path for this project (e.g. "apps/client",
|
|
23
|
+
* "packages/player-client"). The caller is responsible for including any
|
|
24
|
+
* part-specific segment - it is not appended automatically.
|
|
25
|
+
*/
|
|
26
|
+
directory: string;
|
|
27
|
+
/**
|
|
28
|
+
* NanoForge project language
|
|
29
|
+
*/
|
|
30
|
+
language: "js" | "ts";
|
|
31
|
+
/**
|
|
32
|
+
* With strict mode
|
|
33
|
+
*/
|
|
34
|
+
strict: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The used package manager
|
|
37
|
+
*/
|
|
38
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
39
|
+
/**
|
|
40
|
+
* Whether this project is generated inside an existing NanoForge workspace
|
|
41
|
+
*/
|
|
42
|
+
workspace: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Generate a Dockerfile for the project. Ignored when `workspace` is true - a project
|
|
45
|
+
* inside a workspace is built and run by the workspace's own Dockerfile instead.
|
|
46
|
+
*/
|
|
47
|
+
docker: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Only meaningful when `part` is "client": whether the client syncs its
|
|
50
|
+
* entity position from a companion server instead of owning it locally.
|
|
51
|
+
* A server project always simulates and broadcasts its own position,
|
|
52
|
+
* regardless of this flag.
|
|
53
|
+
*/
|
|
54
|
+
hasServer: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Add editor dependencies
|
|
57
|
+
*/
|
|
58
|
+
editor: boolean;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/libs/project/project.factory.d.ts
|
|
62
|
+
export declare const main: (schema: ProjectSchema) => Rule;
|
|
63
|
+
//#endregion
|
|
64
|
+
//# sourceMappingURL=project.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.factory.d.ts","names":[],"sources":["../../../src/libs/project/project.schema.d.ts","../../../src/libs/project/project.factory.ts"],"mappings":";;UAAiB;;;;EAIf;;;;;;EAOA;;;;;;;EAQA;;;;;;EAOA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;;EAMA;;;;;;;EAQA;;;;EAKA;;;;qBC6DW,OAAQ,QAAQ,kBAAgB"}
|