@jjlmoya/utils-games-development 1.67.0 → 1.69.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/package.json +1 -1
- package/src/category/index.ts +2 -1
- package/src/entries.ts +5 -1
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/seo_translation_completeness.test.ts +18 -12
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/gamePixelPerUnitPlanner/bibliography.astro +6 -0
- package/src/tool/gamePixelPerUnitPlanner/bibliography.ts +20 -0
- package/src/tool/gamePixelPerUnitPlanner/component.astro +56 -0
- package/src/tool/gamePixelPerUnitPlanner/controller.ts +127 -0
- package/src/tool/gamePixelPerUnitPlanner/dom-views.ts +47 -0
- package/src/tool/gamePixelPerUnitPlanner/entry.ts +27 -0
- package/src/tool/gamePixelPerUnitPlanner/evaluator.ts +14 -0
- package/src/tool/gamePixelPerUnitPlanner/game-pixel-per-unit-planner.css +652 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/de.ts +51 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/en.ts +171 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/es.ts +53 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/fr.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/id.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/it.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/ja.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/ko.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/nl.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/pl.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/pt.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/ru.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/sv.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/tr.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/i18n/zh.ts +33 -0
- package/src/tool/gamePixelPerUnitPlanner/index.ts +11 -0
- package/src/tool/gamePixelPerUnitPlanner/logic.test.ts +34 -0
- package/src/tool/gamePixelPerUnitPlanner/logic.ts +129 -0
- package/src/tool/gamePixelPerUnitPlanner/seo.astro +15 -0
- package/src/tool/gamePixelPerUnitPlanner/storage.ts +23 -0
- package/src/tool/gamePixelPerUnitPlanner/ui.ts +65 -0
- package/src/tools.ts +2 -0
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
.gppu-tool {
|
|
2
|
+
--n-ink: #1d2530;
|
|
3
|
+
--n-muted: #5d6875;
|
|
4
|
+
--n-paper: #f3f6f8;
|
|
5
|
+
--n-panel: #fff;
|
|
6
|
+
--n-line: #d4dde4;
|
|
7
|
+
--n-grid: #b9c9d4;
|
|
8
|
+
--n-accent: #d45b37;
|
|
9
|
+
--n-accent-soft: #f5dfd7;
|
|
10
|
+
--n-cyan: #168ca0;
|
|
11
|
+
--n-cyan-soft: #d8f0f3;
|
|
12
|
+
--n-green: #23744d;
|
|
13
|
+
--n-yellow: #a86f17;
|
|
14
|
+
--n-red: #ae3d37;
|
|
15
|
+
--n-shadow: #b8c6ce;
|
|
16
|
+
|
|
17
|
+
color: var(--n-ink);
|
|
18
|
+
background-color: var(--n-paper);
|
|
19
|
+
border: 1px solid var(--n-line);
|
|
20
|
+
border-radius: 1.25rem;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.theme-dark .gppu-tool {
|
|
25
|
+
--n-ink: #f0f5f6;
|
|
26
|
+
--n-muted: #b4c2c8;
|
|
27
|
+
--n-paper: #182329;
|
|
28
|
+
--n-panel: #223038;
|
|
29
|
+
--n-line: #43545e;
|
|
30
|
+
--n-grid: #526d79;
|
|
31
|
+
--n-accent: #f08a63;
|
|
32
|
+
--n-accent-soft: #50342e;
|
|
33
|
+
--n-cyan: #6fd4dc;
|
|
34
|
+
--n-cyan-soft: #24484e;
|
|
35
|
+
--n-green: #8bd6a7;
|
|
36
|
+
--n-yellow: #e4b769;
|
|
37
|
+
--n-red: #ff998c;
|
|
38
|
+
--n-shadow: #0d1418;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.gppu-layout {
|
|
42
|
+
display: grid;
|
|
43
|
+
grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr);
|
|
44
|
+
gap: 1px;
|
|
45
|
+
background-color: var(--n-line);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.gppu-controls,
|
|
49
|
+
.gppu-stage {
|
|
50
|
+
background-color: var(--n-panel);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.gppu-controls {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
gap: 1rem;
|
|
57
|
+
padding: 1.3rem;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.gppu-upload {
|
|
61
|
+
padding: .9rem;
|
|
62
|
+
border: 1px dashed var(--n-accent);
|
|
63
|
+
border-radius: .75rem;
|
|
64
|
+
background-color: var(--n-accent-soft);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.gppu-upload-heading {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
gap: .5rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.gppu-upload-heading strong {
|
|
75
|
+
font-size: .82rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.gppu-upload-icon {
|
|
79
|
+
display: grid;
|
|
80
|
+
width: 1.5rem;
|
|
81
|
+
height: 1.5rem;
|
|
82
|
+
place-items: center;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
background-color: var(--n-ink);
|
|
85
|
+
color: var(--n-panel);
|
|
86
|
+
font-size: 1.2rem;
|
|
87
|
+
font-weight: 400;
|
|
88
|
+
line-height: 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.gppu-upload p {
|
|
92
|
+
margin: .35rem 0 .7rem;
|
|
93
|
+
color: var(--n-muted);
|
|
94
|
+
font-size: .75rem;
|
|
95
|
+
line-height: 1.4;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.gppu-upload-button {
|
|
99
|
+
display: block;
|
|
100
|
+
padding: .55rem .7rem;
|
|
101
|
+
border: 1px solid var(--n-accent);
|
|
102
|
+
border-radius: .45rem;
|
|
103
|
+
background-color: var(--n-panel);
|
|
104
|
+
color: var(--n-ink);
|
|
105
|
+
cursor: pointer;
|
|
106
|
+
font-size: .76rem;
|
|
107
|
+
font-weight: 900;
|
|
108
|
+
text-align: center;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.gppu-upload-button input {
|
|
112
|
+
position: absolute;
|
|
113
|
+
width: 1px;
|
|
114
|
+
height: 1px;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
clip-path: inset(50%);
|
|
117
|
+
white-space: nowrap;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.gppu-upload-button:focus-within {
|
|
121
|
+
outline: 3px solid var(--n-cyan);
|
|
122
|
+
outline-offset: 2px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.gppu-file-name {
|
|
126
|
+
display: block;
|
|
127
|
+
margin-top: .55rem;
|
|
128
|
+
overflow: hidden;
|
|
129
|
+
color: var(--n-muted);
|
|
130
|
+
font-size: .75rem;
|
|
131
|
+
text-overflow: ellipsis;
|
|
132
|
+
white-space: nowrap;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.gppu-clear-sprite {
|
|
136
|
+
margin-top: .45rem;
|
|
137
|
+
padding: 0;
|
|
138
|
+
border: 0;
|
|
139
|
+
background: none;
|
|
140
|
+
color: var(--n-red);
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
font: inherit;
|
|
143
|
+
font-size: .75rem;
|
|
144
|
+
font-weight: 800;
|
|
145
|
+
text-decoration: underline;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.gppu-heading,
|
|
149
|
+
.gppu-stage-heading,
|
|
150
|
+
.gppu-section-heading {
|
|
151
|
+
display: flex;
|
|
152
|
+
gap: .8rem;
|
|
153
|
+
align-items: start;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.gppu-heading {
|
|
157
|
+
padding-bottom: .75rem;
|
|
158
|
+
border-bottom: 1px solid var(--n-line);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.gppu-heading h2,
|
|
162
|
+
.gppu-stage-heading h2,
|
|
163
|
+
.gppu-section-heading h3 {
|
|
164
|
+
margin: 0;
|
|
165
|
+
font-size: 1.08rem;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.gppu-kicker {
|
|
169
|
+
flex: 0 0 auto;
|
|
170
|
+
color: var(--n-accent);
|
|
171
|
+
font-size: .75rem;
|
|
172
|
+
font-weight: 900;
|
|
173
|
+
letter-spacing: .12em;
|
|
174
|
+
line-height: 1.4;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.gppu-field-grid {
|
|
178
|
+
display: grid;
|
|
179
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
180
|
+
gap: .7rem;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.gppu-field-grid label,
|
|
184
|
+
.gppu-scale-field {
|
|
185
|
+
display: flex;
|
|
186
|
+
flex-direction: column;
|
|
187
|
+
gap: .3rem;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.gppu-field-grid span,
|
|
191
|
+
.gppu-scale-field span,
|
|
192
|
+
.gppu-preset-label {
|
|
193
|
+
color: var(--n-muted);
|
|
194
|
+
font-size: .75rem;
|
|
195
|
+
font-weight: 800;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.gppu-field-grid input {
|
|
199
|
+
width: 100%;
|
|
200
|
+
box-sizing: border-box;
|
|
201
|
+
padding: .5rem .45rem;
|
|
202
|
+
border: 1px solid var(--n-line);
|
|
203
|
+
border-radius: .45rem;
|
|
204
|
+
background-color: var(--n-paper);
|
|
205
|
+
color: var(--n-ink);
|
|
206
|
+
font: inherit;
|
|
207
|
+
font-variant-numeric: tabular-nums;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.gppu-scale-field {
|
|
211
|
+
display: grid;
|
|
212
|
+
grid-template-columns: 1fr auto;
|
|
213
|
+
align-items: center;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.gppu-scale-field input {
|
|
217
|
+
grid-column: 1 / -1;
|
|
218
|
+
width: 100%;
|
|
219
|
+
accent-color: var(--n-cyan);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.gppu-scale-field output {
|
|
223
|
+
padding: .25rem .45rem;
|
|
224
|
+
border: 1px solid var(--n-line);
|
|
225
|
+
border-radius: .4rem;
|
|
226
|
+
color: var(--n-ink);
|
|
227
|
+
font-size: .9rem;
|
|
228
|
+
font-weight: 900;
|
|
229
|
+
font-variant-numeric: tabular-nums;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.gppu-hint,
|
|
233
|
+
.gppu-stage-heading p,
|
|
234
|
+
.gppu-section-heading p,
|
|
235
|
+
.gppu-model-note,
|
|
236
|
+
.gppu-privacy {
|
|
237
|
+
color: var(--n-muted);
|
|
238
|
+
font-size: .78rem;
|
|
239
|
+
line-height: 1.5;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.gppu-hint {
|
|
243
|
+
margin: -.5rem 0 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.gppu-stage {
|
|
247
|
+
min-width: 0;
|
|
248
|
+
padding: 1.3rem;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.gppu-stage-heading {
|
|
252
|
+
justify-content: space-between;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.gppu-stage-heading p {
|
|
256
|
+
margin: .35rem 0 0;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.gppu-live {
|
|
260
|
+
padding: .35rem .55rem;
|
|
261
|
+
border: 1px solid var(--n-line);
|
|
262
|
+
border-radius: 99rem;
|
|
263
|
+
color: var(--n-green);
|
|
264
|
+
font-size: .75rem;
|
|
265
|
+
font-weight: 900;
|
|
266
|
+
white-space: nowrap;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.gppu-field {
|
|
270
|
+
margin-top: 1rem;
|
|
271
|
+
border: 1px solid var(--n-line);
|
|
272
|
+
border-radius: 1rem;
|
|
273
|
+
overflow: hidden;
|
|
274
|
+
box-shadow: 0 .4rem 0 var(--n-shadow);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.gppu-preview-shell {
|
|
278
|
+
background-color: var(--n-paper);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.gppu-preview-topline,
|
|
282
|
+
.gppu-preview-meta {
|
|
283
|
+
display: flex;
|
|
284
|
+
justify-content: space-between;
|
|
285
|
+
gap: 1rem;
|
|
286
|
+
padding: .75rem .85rem;
|
|
287
|
+
color: var(--n-muted);
|
|
288
|
+
font-size: .75rem;
|
|
289
|
+
font-weight: 800;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.gppu-preview-topline {
|
|
293
|
+
border-bottom: 1px solid var(--n-line);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.gppu-preview-topline strong {
|
|
297
|
+
color: var(--n-accent);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.gppu-preview-meta {
|
|
301
|
+
border-top: 1px solid var(--n-line);
|
|
302
|
+
font-variant-numeric: tabular-nums;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.gppu-hero-canvas {
|
|
306
|
+
display: grid;
|
|
307
|
+
min-height: 15rem;
|
|
308
|
+
padding: 2rem;
|
|
309
|
+
place-items: center;
|
|
310
|
+
overflow: auto;
|
|
311
|
+
background-color: var(--n-paper);
|
|
312
|
+
background-image: linear-gradient(45deg, var(--n-line) 25%, transparent 25%), linear-gradient(-45deg, var(--n-line) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--n-line) 75%), linear-gradient(-45deg, transparent 75%, var(--n-line) 75%);
|
|
313
|
+
background-position: 0 0, 0 .5rem, .5rem -.5rem, -.5rem 0;
|
|
314
|
+
background-size: 1rem 1rem;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.gppu-hero-canvas img,
|
|
318
|
+
.gppu-step-canvas img {
|
|
319
|
+
display: block;
|
|
320
|
+
max-width: none;
|
|
321
|
+
height: auto;
|
|
322
|
+
image-rendering: pixelated;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.gppu-empty-preview {
|
|
326
|
+
display: grid;
|
|
327
|
+
min-height: 20rem;
|
|
328
|
+
padding: 2rem;
|
|
329
|
+
place-items: center;
|
|
330
|
+
align-content: center;
|
|
331
|
+
gap: .8rem;
|
|
332
|
+
background-color: var(--n-paper);
|
|
333
|
+
color: var(--n-muted);
|
|
334
|
+
text-align: center;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.gppu-empty-preview span {
|
|
338
|
+
display: grid;
|
|
339
|
+
width: 3rem;
|
|
340
|
+
height: 3rem;
|
|
341
|
+
place-items: center;
|
|
342
|
+
border: 2px dashed var(--n-accent);
|
|
343
|
+
border-radius: 50%;
|
|
344
|
+
color: var(--n-accent);
|
|
345
|
+
font-size: 2rem;
|
|
346
|
+
font-weight: 300;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.gppu-empty-preview strong {
|
|
350
|
+
max-width: 18rem;
|
|
351
|
+
font-size: .85rem;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.gppu-field-svg {
|
|
355
|
+
display: block;
|
|
356
|
+
width: 100%;
|
|
357
|
+
height: auto;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.gppu-screen {
|
|
361
|
+
fill: var(--n-paper);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.gppu-grid-line {
|
|
365
|
+
stroke: var(--n-grid);
|
|
366
|
+
stroke-width: 1;
|
|
367
|
+
stroke-dasharray: 2 7;
|
|
368
|
+
opacity: .75;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.gppu-sprite-frame {
|
|
372
|
+
fill: var(--n-accent-soft);
|
|
373
|
+
stroke: var(--n-accent);
|
|
374
|
+
stroke-width: 2;
|
|
375
|
+
stroke-dasharray: 5 4;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.gppu-sprite-main {
|
|
379
|
+
fill: var(--n-cyan);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.gppu-sprite-light {
|
|
383
|
+
fill: var(--n-accent);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.gppu-sprite-shadow {
|
|
387
|
+
fill: var(--n-ink);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.gppu-scene-label,
|
|
391
|
+
.gppu-screen-label,
|
|
392
|
+
.gppu-sprite-label {
|
|
393
|
+
fill: var(--n-muted);
|
|
394
|
+
font-size: 11px;
|
|
395
|
+
font-weight: 800;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.gppu-sprite-label {
|
|
399
|
+
fill: var(--n-ink);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.gppu-summary-grid {
|
|
403
|
+
display: grid;
|
|
404
|
+
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|
405
|
+
gap: .5rem;
|
|
406
|
+
margin-top: 1rem;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.gppu-summary-title {
|
|
410
|
+
margin: 1rem 0 .55rem;
|
|
411
|
+
font-size: .9rem;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.gppu-summary-grid div {
|
|
415
|
+
min-width: 0;
|
|
416
|
+
padding: .65rem .55rem;
|
|
417
|
+
border-top: 2px solid var(--n-line);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.gppu-summary-grid span {
|
|
421
|
+
display: block;
|
|
422
|
+
color: var(--n-muted);
|
|
423
|
+
font-size: .75rem;
|
|
424
|
+
line-height: 1.3;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.gppu-summary-grid strong {
|
|
428
|
+
display: block;
|
|
429
|
+
margin-top: .25rem;
|
|
430
|
+
font-size: .85rem;
|
|
431
|
+
font-variant-numeric: tabular-nums;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.gppu-risk-low {
|
|
435
|
+
color: var(--n-green);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.gppu-risk-medium {
|
|
439
|
+
color: var(--n-yellow);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.gppu-risk-high {
|
|
443
|
+
color: var(--n-red);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.gppu-diagnostic {
|
|
447
|
+
margin: .7rem 0 0;
|
|
448
|
+
padding: .65rem .8rem;
|
|
449
|
+
border-left: 3px solid var(--n-green);
|
|
450
|
+
background-color: var(--n-paper);
|
|
451
|
+
font-size: .8rem;
|
|
452
|
+
line-height: 1.45;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.gppu-diagnostic-medium {
|
|
456
|
+
border-color: var(--n-yellow);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.gppu-diagnostic-high {
|
|
460
|
+
border-color: var(--n-red);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.gppu-crisp {
|
|
464
|
+
margin-top: 1.4rem;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.gppu-section-heading p {
|
|
468
|
+
margin: .3rem 0 .7rem;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.gppu-step-grid {
|
|
472
|
+
display: grid;
|
|
473
|
+
grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
|
|
474
|
+
gap: .55rem;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.gppu-step {
|
|
478
|
+
overflow: hidden;
|
|
479
|
+
padding: .7rem;
|
|
480
|
+
border: 1px solid var(--n-line);
|
|
481
|
+
border-radius: .65rem;
|
|
482
|
+
background-color: var(--n-paper);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.gppu-step-canvas {
|
|
486
|
+
display: grid;
|
|
487
|
+
min-height: 7rem;
|
|
488
|
+
margin: -.7rem -.7rem .7rem;
|
|
489
|
+
padding: .7rem;
|
|
490
|
+
place-items: center;
|
|
491
|
+
overflow: auto;
|
|
492
|
+
background-color: var(--n-paper);
|
|
493
|
+
background-image: linear-gradient(45deg, var(--n-line) 25%, transparent 25%), linear-gradient(-45deg, var(--n-line) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--n-line) 75%), linear-gradient(-45deg, transparent 75%, var(--n-line) 75%);
|
|
494
|
+
background-position: 0 0, 0 .5rem, .5rem -.5rem, -.5rem 0;
|
|
495
|
+
background-size: 1rem 1rem;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.gppu-step-current {
|
|
499
|
+
border-color: var(--n-accent);
|
|
500
|
+
box-shadow: inset 0 -3px 0 var(--n-accent);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.gppu-step-over {
|
|
504
|
+
opacity: .58;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.gppu-step div {
|
|
508
|
+
display: flex;
|
|
509
|
+
flex-wrap: wrap;
|
|
510
|
+
gap: .35rem;
|
|
511
|
+
align-items: center;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.gppu-step strong {
|
|
515
|
+
font-size: 1rem;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
.gppu-step span,
|
|
519
|
+
.gppu-step small {
|
|
520
|
+
display: block;
|
|
521
|
+
margin-top: .25rem;
|
|
522
|
+
color: var(--n-muted);
|
|
523
|
+
font-size: .75rem;
|
|
524
|
+
line-height: 1.35;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.gppu-recommended {
|
|
528
|
+
padding: .15rem .3rem;
|
|
529
|
+
border-radius: .25rem;
|
|
530
|
+
background-color: var(--n-cyan-soft);
|
|
531
|
+
color: var(--n-ink);
|
|
532
|
+
font-size: .75rem;
|
|
533
|
+
font-weight: 900;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.gppu-table {
|
|
537
|
+
margin-top: 1.1rem;
|
|
538
|
+
overflow-x: auto;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.gppu-table h3 {
|
|
542
|
+
margin: 0 0 .5rem;
|
|
543
|
+
font-size: .9rem;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
.gppu-table table {
|
|
547
|
+
width: 100%;
|
|
548
|
+
border-collapse: collapse;
|
|
549
|
+
font-size: .75rem;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.gppu-table th,
|
|
553
|
+
.gppu-table td {
|
|
554
|
+
padding: .45rem .5rem;
|
|
555
|
+
border-bottom: 1px solid var(--n-line);
|
|
556
|
+
text-align: left;
|
|
557
|
+
font-variant-numeric: tabular-nums;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.gppu-table th {
|
|
561
|
+
color: var(--n-muted);
|
|
562
|
+
font-size: .75rem;
|
|
563
|
+
text-transform: uppercase;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.gppu-preset-group {
|
|
567
|
+
display: flex;
|
|
568
|
+
flex-direction: column;
|
|
569
|
+
gap: .4rem;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.gppu-chip-row {
|
|
573
|
+
display: flex;
|
|
574
|
+
flex-wrap: wrap;
|
|
575
|
+
gap: .35rem;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.gppu-chip-row button,
|
|
579
|
+
.gppu-reset {
|
|
580
|
+
min-height: 2.1rem;
|
|
581
|
+
padding: .35rem .55rem;
|
|
582
|
+
border: 1px solid var(--n-line);
|
|
583
|
+
border-radius: .45rem;
|
|
584
|
+
background-color: var(--n-paper);
|
|
585
|
+
color: var(--n-ink);
|
|
586
|
+
font: inherit;
|
|
587
|
+
font-size: .75rem;
|
|
588
|
+
font-weight: 800;
|
|
589
|
+
cursor: pointer;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.gppu-chip-row button:hover,
|
|
593
|
+
.gppu-chip-row button:focus-visible {
|
|
594
|
+
border-color: var(--n-cyan);
|
|
595
|
+
color: var(--n-cyan);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.gppu-reset {
|
|
599
|
+
margin-top: auto;
|
|
600
|
+
color: var(--n-muted);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
.gppu-reset:hover,
|
|
604
|
+
.gppu-reset:focus-visible {
|
|
605
|
+
border-color: var(--n-accent);
|
|
606
|
+
color: var(--n-accent);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.gppu-chip-row button:focus-visible,
|
|
610
|
+
.gppu-reset:focus-visible,
|
|
611
|
+
.gppu-field-grid input:focus-visible,
|
|
612
|
+
.gppu-scale-field input:focus-visible {
|
|
613
|
+
outline: 3px solid var(--n-accent);
|
|
614
|
+
outline-offset: 2px;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.gppu-model-note {
|
|
618
|
+
margin: 1rem 0 0;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.gppu-privacy {
|
|
622
|
+
margin: .45rem 0 0;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
@media (max-width: 760px) {
|
|
626
|
+
.gppu-layout {
|
|
627
|
+
grid-template-columns: 1fr;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.gppu-summary-grid {
|
|
631
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.gppu-stage-heading {
|
|
635
|
+
flex-direction: column;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.gppu-live {
|
|
639
|
+
align-self: start;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
@media (max-width: 420px) {
|
|
644
|
+
.gppu-controls,
|
|
645
|
+
.gppu-stage {
|
|
646
|
+
padding: 1rem;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.gppu-summary-grid {
|
|
650
|
+
grid-template-columns: 1fr 1fr;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { GamePixelPerUnitPlannerUI } from '../ui';
|
|
4
|
+
import { bibliographyEntries } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const faq = [
|
|
7
|
+
{ question: 'Was bedeutet Pixel pro Einheit in einem Spiel?', answer: 'Pixel pro Einheit oder PPU beschreibt, wie viele Texturpixel eine Welteinheit darstellen. Eine einheitliche Dichte hält Sprites, Kacheln und Kamera auf einer vorhersehbaren Skala.' },
|
|
8
|
+
{ question: 'Warum sind ganzzahlige Skalierungen wichtig?', answer: 'Eine ganzzahlige Skalierung weist jedem Quellpixel dieselbe ganze Zahl an Bildschirmpixeln zu. Bruchteile können ungleichmäßige Kanten oder Weichzeichnung erzeugen.' },
|
|
9
|
+
{ question: 'Was ist Pixel Bleeding?', answer: 'Pixel Bleeding ist eine unerwünschte Farbe aus einem benachbarten Texel oder Atlasbereich. Filterung, Ränder, Subpixel-Bewegung und fehlendes Padding können es verursachen.' },
|
|
10
|
+
{ question: 'Wie verwende ich die empfohlene Skalierung?', answer: 'Nutze sie als Kandidaten, der in die Auflösung passt und nahe an deinem Ziel liegt. Prüfe danach im Spiel die Nearest-Filterung, die Kameraausrichtung und das Atlas-Padding.' },
|
|
11
|
+
{ question: 'Wählt der Planer den richtigen PPU für jede Engine?', answer: 'Nein. Er ist eine transparente Rechenhilfe. Kamera, Import, Mipmaps, Rundung und Pixel-Snapping unterscheiden sich je nach Engine und brauchen einen echten Test.' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const howTo = [
|
|
15
|
+
{ name: 'Zielbildschirm wählen', text: 'Gib Breite und Höhe des Spielbildes oder Referenzfensters in Pixeln an.' },
|
|
16
|
+
{ name: 'Sprite laden', text: 'Wähle ein Bild und lasse seine nativen Abmessungen erkennen. Alternativ kannst du das Bob-Beispiel nutzen.' },
|
|
17
|
+
{ name: 'Skalierung wählen', text: 'Bewege den Skalierungsregler oder wähle ein Preset. Ganze Multiplikatoren sind die schärfsten Kandidaten.' },
|
|
18
|
+
{ name: 'Preview lesen', text: 'Prüfe Sprite-Footprint, horizontalen und vertikalen PPU, sichtbare Welt und Bleeding-Hinweis.' },
|
|
19
|
+
{ name: 'In der Engine testen', text: 'Prüfe die Wahl mit Nearest-Filterung, ausgerichteter Kamera, Atlas-Padding und echten Spielauflösungen.' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planer für Pixel pro Einheit in Spielen', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
|
|
23
|
+
const faqPage: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
24
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'Pixel-Art-Sprite-Skalierung prüfen', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
|
|
25
|
+
|
|
26
|
+
export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
|
|
27
|
+
slug: 'pixel-pro-einheit-sprite-planer-spiele', title: 'Planer für Pixel pro Einheit bei Spielsprites', description: 'Lade ein Sprite oder nutze das Bob-Beispiel, um Footprints bei ganzen Skalierungen zu prüfen, PPU zu vergleichen und Pixel Bleeding früh zu erkennen.',
|
|
28
|
+
ui: {
|
|
29
|
+
inputsTitle: 'Sprite laden und prüfen', uploadTitle: 'Dein Quellbild', uploadHint: 'Wähle PNG, GIF, WebP oder JPEG. Die nativen Abmessungen steuern jede Preview.', chooseSpriteLabel: 'Sprite wählen', noSpriteLabel: 'Noch kein Sprite geladen', defaultSpriteLabel: 'Bob-Sprite als Beispiel', loadedSpriteLabel: 'Geladen', clearSpriteLabel: 'Sprite entfernen', displayWidthLabel: 'Bildschirmbreite px', displayHeightLabel: 'Bildschirmhöhe px', spriteWidthLabel: 'Spritebreite px', spriteHeightLabel: 'Spritehöhe px', worldWidthLabel: 'Spritebreite in Einheiten', worldHeightLabel: 'Spritehöhe in Einheiten', targetScaleLabel: 'Zielskalierung auf dem Bildschirm', targetScaleHint: 'Bildschirmpixel pro Pixel der Quelltextur.', resolutionPresetsLabel: 'Referenzauflösungen', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Schnelle Skalierungen', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Werte zurücksetzen', fieldTitle: 'In verschiedenen Größen ansehen', fieldCaption: 'Das geladene Bild wird mit Nearest-Skalierung gerendert, damit du seinen echten Footprint bei ganzen Multiplikatoren beurteilen kannst.', previewPlaceholder: 'Lade ein Sprite für den visuellen Test', previewScaleLabel: 'Preview-Skalierung', sourceImageAlt: 'Preview des geladenen Sprites', viewportLabel: 'Bildschirm', spriteLabel: 'Gerendertes Sprite', crispTitle: 'Scharfe Skalierungen', crispCaption: 'Ganze Multiplikatoren halten Quellpixel gleich groß. Graue Schritte überschreiten den angegebenen Bildschirm.', fitLabel: 'Passt auf den Bildschirm:', yesLabel: 'ja', noLabel: 'nein', recommendedLabel: 'nächster Treffer', summaryTitle: 'Plan-Zusammenfassung', ppuXLabel: 'PPU horizontal', ppuYLabel: 'PPU vertikal', viewportWorldLabel: 'Sichtbare Welt', fitScaleLabel: 'Größte passende Skalierung', bleedingRiskLabel: 'Bleeding-Risiko', lowRisk: 'Niedrig', mediumRisk: 'Mittel', highRisk: 'Hoch', riskLowMessage: 'Die Achsen sind ausgerichtet und die Zielskalierung ist ganzzahlig und passt. Prüfe trotzdem Filterung und Atlas-Padding.', riskMediumMessage: 'Das Ziel passt nur teilweise. Prüfe Achsenabweichung und die hervorgehobenen Skalierungen.', riskHighMessage: 'Die Skalierung kann ungleichmäßige Abtastung erzeugen. Bevorzuge einen ganzen Multiplikator und prüfe die Sprite-Abmessungen.', alignmentLabel: 'Abtastungshinweis', tableTitle: 'Zugängliches Skalierungsprotokoll', tableScale: 'Skalierung', tableWidth: 'Gerenderte Breite', tableHeight: 'Gerenderte Höhe', tableFits: 'Passt auf Bildschirm', modelNote: 'PPU wird als gerenderte Spritepixel geteilt durch die Spritegröße in Welteinheiten je Achse berechnet. Das Bleeding-Risiko ist eine Heuristik und keine Texturprüfung oder Engine-Garantie.', privacyDisclosure: 'Die Datei wird in diesem Browser verarbeitet. Sprites, Projektdateien und Telemetrie werden nicht hochgeladen.', statusReady: 'Preview aktualisiert', unitPixels: 'px', unitUnits: 'Einheiten',
|
|
30
|
+
},
|
|
31
|
+
seo: [
|
|
32
|
+
{ type: 'title', level: 2, text: 'Aus Spritegröße eine Skalierungsentscheidung machen' },
|
|
33
|
+
{ type: 'paragraph', html: 'Ein Sprite hat die Größe seines Bitmaps und die Größe, die es in der Spielwelt einnimmt. PPU verbindet beide Maße. Die Preview zeigt die visuelle Folge statt nur eine Zahl zu liefern.' },
|
|
34
|
+
{ type: 'paragraph', html: 'Lade ein echtes Bild, damit die nativen Maße übernommen werden. Danach multipliziert das Tool beide Achsen mit der gewählten Skalierung und berechnet die sichtbare Welt für die angegebene Auflösung.' },
|
|
35
|
+
{ type: 'title', level: 2, text: 'Worauf du in der Preview achten solltest' },
|
|
36
|
+
{ type: 'list', items: ['Vergleiche den Footprint mit dem Referenzbildschirm.', 'Teste zuerst ganze Skalierungen für gleichmäßige Pixel.', 'Nutze beide PPU-Werte, um unbeabsichtigte Streckung zu finden.', 'Behandle die Bleeding-Warnung als Anlass für einen Engine-Test.'] },
|
|
37
|
+
{ type: 'title', level: 2, text: 'Warum ganze Skalierungen oft sauberer sind' },
|
|
38
|
+
{ type: 'paragraph', html: 'Bei 3x belegt jeder Quellpixel drei Bildschirmpixel. Bei 2,5x muss der Renderer unterschiedliche Breiten verteilen. Nearest verhindert Farbmischung, korrigiert aber keine Kamera zwischen Pixelpositionen.' },
|
|
39
|
+
{ type: 'table', headers: ['Signal', 'Bedeutung', 'Nächste Entscheidung'], rows: [['Gleicher PPU', 'Beide Achsen haben dieselbe Dichte.', 'Mit Tiles und Projektraster vergleichen.'], ['Bruch-Skalierung', 'Der Footprint nutzt keinen ganzen Multiplikator.', 'Die nächste ganze Skalierung testen.'], ['Passt nicht', 'Das Sprite überschreitet den Bildschirm.', 'Skalierung reduzieren oder Referenzauflösung erhöhen.']] },
|
|
40
|
+
{ type: 'title', level: 2, text: 'Bleeding von reiner Spritegröße unterscheiden' },
|
|
41
|
+
{ type: 'paragraph', html: 'Pixel Bleeding entsteht oft durch Nachbartexel im Atlas, Filterung an Rändern oder nicht ausgerichtete Kamerakoordinaten. Bei Weichzeichnung zuerst die Filterung prüfen, bei Nähten zusätzlich Padding, Clamp und Atlasgrenzen.' },
|
|
42
|
+
{ type: 'title', level: 2, text: 'Mit dem Beispiel-Sprite den Ablauf lernen' },
|
|
43
|
+
{ type: 'paragraph', html: 'Das Bob-Beispiel zeigt die Figur mit rosa Schleife sofort. Ändere Auflösung und Skalierung und beobachte, wann Körper oder Schleife nicht mehr passen oder Pixel ihre Gleichmäßigkeit verlieren.' },
|
|
44
|
+
{ type: 'title', level: 2, text: 'Was dieses Tool prüft und was nicht' },
|
|
45
|
+
{ type: 'paragraph', html: 'Das Tool vergleicht Abmessungen und Footprints in einer kontrollierten Ansicht. Es öffnet kein Engine-Projekt, untersucht keinen Atlas, misst kein Gerät und garantiert keine pixelgenaue Bewegung.' },
|
|
46
|
+
{ type: 'title', level: 2, text: 'Ein kurzer Ablauf für die Skalierungswahl' },
|
|
47
|
+
{ type: 'paragraph', html: 'Sprite laden, Referenzauflösung wählen, 1x bis 4x prüfen und die größte ganze Skalierung mit genügend Luft wählen. Danach die echten Zielauflösungen des Spiels wiederholen.' },
|
|
48
|
+
{ type: 'tip', title: 'Die letzte Prüfung findet in der Engine statt', html: 'Nutze die Preview, um die Entscheidung einzugrenzen. Aktiviere danach Nearest-Filterung, prüfe Atlas-Padding und Kameraausrichtung und teste Bewegung bei mehreren Auflösungen.' },
|
|
49
|
+
],
|
|
50
|
+
faqTitle: 'Fragen zur Sprite-Skalierung', faq, bibliographyTitle: 'Referenzen zur Pixelgrafik', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
|
|
51
|
+
};
|