@jjlmoya/utils-games-development 1.68.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.
Files changed (35) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +5 -1
  4. package/src/tests/locale_completeness.test.ts +2 -2
  5. package/src/tests/tool_validation.test.ts +2 -2
  6. package/src/tool/gamePixelPerUnitPlanner/bibliography.astro +6 -0
  7. package/src/tool/gamePixelPerUnitPlanner/bibliography.ts +20 -0
  8. package/src/tool/gamePixelPerUnitPlanner/component.astro +56 -0
  9. package/src/tool/gamePixelPerUnitPlanner/controller.ts +127 -0
  10. package/src/tool/gamePixelPerUnitPlanner/dom-views.ts +47 -0
  11. package/src/tool/gamePixelPerUnitPlanner/entry.ts +27 -0
  12. package/src/tool/gamePixelPerUnitPlanner/evaluator.ts +14 -0
  13. package/src/tool/gamePixelPerUnitPlanner/game-pixel-per-unit-planner.css +652 -0
  14. package/src/tool/gamePixelPerUnitPlanner/i18n/de.ts +51 -0
  15. package/src/tool/gamePixelPerUnitPlanner/i18n/en.ts +171 -0
  16. package/src/tool/gamePixelPerUnitPlanner/i18n/es.ts +53 -0
  17. package/src/tool/gamePixelPerUnitPlanner/i18n/fr.ts +33 -0
  18. package/src/tool/gamePixelPerUnitPlanner/i18n/id.ts +33 -0
  19. package/src/tool/gamePixelPerUnitPlanner/i18n/it.ts +33 -0
  20. package/src/tool/gamePixelPerUnitPlanner/i18n/ja.ts +33 -0
  21. package/src/tool/gamePixelPerUnitPlanner/i18n/ko.ts +33 -0
  22. package/src/tool/gamePixelPerUnitPlanner/i18n/nl.ts +33 -0
  23. package/src/tool/gamePixelPerUnitPlanner/i18n/pl.ts +33 -0
  24. package/src/tool/gamePixelPerUnitPlanner/i18n/pt.ts +33 -0
  25. package/src/tool/gamePixelPerUnitPlanner/i18n/ru.ts +33 -0
  26. package/src/tool/gamePixelPerUnitPlanner/i18n/sv.ts +33 -0
  27. package/src/tool/gamePixelPerUnitPlanner/i18n/tr.ts +33 -0
  28. package/src/tool/gamePixelPerUnitPlanner/i18n/zh.ts +33 -0
  29. package/src/tool/gamePixelPerUnitPlanner/index.ts +11 -0
  30. package/src/tool/gamePixelPerUnitPlanner/logic.test.ts +34 -0
  31. package/src/tool/gamePixelPerUnitPlanner/logic.ts +129 -0
  32. package/src/tool/gamePixelPerUnitPlanner/seo.astro +15 -0
  33. package/src/tool/gamePixelPerUnitPlanner/storage.ts +23 -0
  34. package/src/tool/gamePixelPerUnitPlanner/ui.ts +65 -0
  35. package/src/tools.ts +2 -0
@@ -0,0 +1,171 @@
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
+ {
8
+ question: 'What does pixels per unit mean in a game?',
9
+ answer: 'Pixels per unit, or PPU, describes how many texture pixels represent one world unit. A consistent PPU helps a sprite keep a predictable visual size beside tiles, UI, and other assets. This planner calculates horizontal and vertical PPU separately so stretched or mismatched assumptions are visible.',
10
+ },
11
+ {
12
+ question: 'Why do integer scales matter for pixel art?',
13
+ answer: 'An integer scale maps each source pixel to the same whole number of screen pixels. Fractional scaling can make neighboring source pixels cover different amounts of the screen and can introduce uneven edges or blur, especially when smoothing is enabled.',
14
+ },
15
+ {
16
+ question: 'What is pixel bleeding?',
17
+ answer: 'Pixel bleeding is an unwanted sample from a neighboring texel or atlas region. Non integer scaling, filtered sampling, subpixel placement, and missing padding can all contribute to visible seams. The planner reports a heuristic risk from scale, axis alignment, and viewport fit; it cannot inspect an actual texture atlas or renderer.',
18
+ },
19
+ {
20
+ question: 'How should I use the recommended scale?',
21
+ answer: 'Use it as a candidate integer multiplier that stays inside the declared display resolution and is close to your target. Then validate the choice in the engine with nearest filtering, pixel grid alignment, atlas padding, and the camera settings your project actually uses.',
22
+ },
23
+ {
24
+ question: 'Does this planner choose the correct PPU for every engine?',
25
+ answer: 'No. It is a transparent arithmetic and planning aid. Engines differ in camera models, reference resolutions, import settings, texture filtering, mipmaps, rounding, and pixel snapping. Treat the result as a design constraint to test in your project, not as a renderer guarantee.',
26
+ },
27
+ ];
28
+
29
+ const howTo = [
30
+ {
31
+ name: 'Enter the destination display',
32
+ text: 'Set the width and height of the game view or reference canvas in screen pixels. Resolution presets provide common starting points for a quick experiment.',
33
+ },
34
+ {
35
+ name: 'Describe the source sprite',
36
+ text: 'Enter the sprite texture dimensions in pixels and its intended width and height in world units. Keep the two axes separate when the asset is not square.',
37
+ },
38
+ {
39
+ name: 'Choose a target scale',
40
+ text: 'Move the target scale slider or choose a preset. Whole numbers are the crisp candidates. Quarter steps are allowed so the risk panel can make a fractional choice visible.',
41
+ },
42
+ {
43
+ name: 'Inspect the pixel field',
44
+ text: 'Read the horizontal and vertical PPU, the visible world viewport, the sprite footprint, and the bleed risk. A mismatch between PPU axes usually means an assumption needs correction.',
45
+ },
46
+ {
47
+ name: 'Test a crisp step in the engine',
48
+ text: 'Use the scale strip to choose a fitting integer multiplier, then verify nearest filtering, camera snapping, atlas padding, and motion at the real target resolutions.',
49
+ },
50
+ ];
51
+
52
+ const softwareApplication: WithContext<SoftwareApplication> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'SoftwareApplication',
55
+ name: 'Game Pixel Per Unit Planner',
56
+ applicationCategory: 'DeveloperApplication',
57
+ operatingSystem: 'Any',
58
+ };
59
+
60
+ const faqPage: WithContext<FAQPage> = {
61
+ '@context': 'https://schema.org',
62
+ '@type': 'FAQPage',
63
+ mainEntity: faq.map((item) => ({
64
+ '@type': 'Question',
65
+ name: item.question,
66
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
67
+ })),
68
+ };
69
+
70
+ const howToSchema: WithContext<HowTo> = {
71
+ '@context': 'https://schema.org',
72
+ '@type': 'HowTo',
73
+ name: 'How to plan pixels per unit for a pixel art game',
74
+ step: howTo.map((step) => ({
75
+ '@type': 'HowToStep',
76
+ name: step.name,
77
+ text: step.text,
78
+ })),
79
+ };
80
+
81
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
82
+ slug: 'game-pixel-per-unit-planner',
83
+ title: 'Game Pixel Per Unit Planner',
84
+ description: 'Plan sprite pixels per unit, integer scaling, viewport fit, and pixel bleeding risk from your display, texture, and world dimensions.',
85
+ ui: {
86
+ inputsTitle: 'Upload and test your sprite',
87
+ uploadTitle: 'Your source image',
88
+ uploadHint: 'Choose a PNG, GIF, WebP, or JPEG. Its native dimensions drive every preview.',
89
+ chooseSpriteLabel: 'Choose sprite',
90
+ noSpriteLabel: 'No sprite loaded yet',
91
+ defaultSpriteLabel: 'GameBob cat sample',
92
+ loadedSpriteLabel: 'Loaded',
93
+ clearSpriteLabel: 'Remove sprite',
94
+ displayWidthLabel: 'Display width px',
95
+ displayHeightLabel: 'Display height px',
96
+ spriteWidthLabel: 'Sprite width px',
97
+ spriteHeightLabel: 'Sprite height px',
98
+ worldWidthLabel: 'Sprite width units',
99
+ worldHeightLabel: 'Sprite height units',
100
+ targetScaleLabel: 'Target screen scale',
101
+ targetScaleHint: 'Pixels from the source texture per source pixel on screen.',
102
+ resolutionPresetsLabel: 'Reference resolutions',
103
+ preset320: '320 x 180',
104
+ preset384: '384 x 216',
105
+ preset640: '640 x 360',
106
+ scalePresetsLabel: 'Quick scale steps',
107
+ scale1: '1x',
108
+ scale2: '2x',
109
+ scale3: '3x',
110
+ scale4: '4x',
111
+ scale6: '6x',
112
+ resetLabel: 'Reset values',
113
+ fieldTitle: 'See it at different sizes',
114
+ fieldCaption: 'The uploaded image is rendered with nearest-neighbour scaling so you can judge the actual footprint at each integer multiplier.',
115
+ previewPlaceholder: 'Upload a sprite to start the visual test',
116
+ previewScaleLabel: 'Preview scale',
117
+ sourceImageAlt: 'Uploaded sprite preview',
118
+ viewportLabel: 'Declared display',
119
+ spriteLabel: 'Rendered sprite',
120
+ crispTitle: 'Crisp scale steps',
121
+ crispCaption: 'Whole number multipliers keep source pixels evenly sized. Grey steps exceed the declared display on at least one axis.',
122
+ fitLabel: 'Fits display:',
123
+ yesLabel: 'yes',
124
+ noLabel: 'no',
125
+ recommendedLabel: 'closest fit',
126
+ summaryTitle: 'Plan summary',
127
+ ppuXLabel: 'Horizontal PPU',
128
+ ppuYLabel: 'Vertical PPU',
129
+ viewportWorldLabel: 'Visible world',
130
+ fitScaleLabel: 'Largest fitting scale',
131
+ bleedingRiskLabel: 'Bleeding risk',
132
+ lowRisk: 'Low',
133
+ mediumRisk: 'Medium',
134
+ highRisk: 'High',
135
+ riskLowMessage: 'Axes align and the target is an integer scale inside the declared viewport. Still verify filtering and atlas padding.',
136
+ riskMediumMessage: 'The target fits imperfectly: it is close to a safe plan but has an axis mismatch or exceeds the fitting scale. Inspect the highlighted steps.',
137
+ riskHighMessage: 'This plan can create uneven sampling because the scale is fractional or the two PPU axes diverge strongly. Prefer an integer step and review the source dimensions.',
138
+ alignmentLabel: 'Sampling note',
139
+ tableTitle: 'Accessible scale ledger',
140
+ tableScale: 'Scale',
141
+ tableWidth: 'Rendered width',
142
+ tableHeight: 'Rendered height',
143
+ tableFits: 'Fits display',
144
+ modelNote: 'The planner calculates PPU as rendered sprite pixels divided by the sprite world size on each axis. Bleeding risk is a warning heuristic, not a texture inspection, renderer test, or guarantee of pixel perfect motion.',
145
+ privacyDisclosure: 'Your values stay in this browser so the plan is ready when you return. No project files, textures, or telemetry are uploaded.',
146
+ statusReady: 'Plan updated',
147
+ unitPixels: 'px',
148
+ unitUnits: 'units',
149
+ },
150
+ seo: [
151
+ { type: 'title', level: 2, text: 'Why pixels per unit is a useful art and camera contract' },
152
+ { type: 'paragraph', html: 'A pixel art sprite has two sizes: the bitmap size stored in the texture and the size it occupies in the game world. Pixels per unit connects those two descriptions. If a 16 pixel sprite represents one world unit, its source density is 16 pixels per unit before any screen scaling. Making that relationship explicit helps artists, level designers, camera programmers, and UI developers reason about a shared grid.' },
153
+ { type: 'paragraph', html: 'This planner keeps the horizontal and vertical axes visible because a square texture does not automatically imply a square world size. It multiplies the source dimensions by the target screen scale, then divides by the intended world dimensions. The result is a PPU value for each axis and a derived world viewport for the declared display resolution.' },
154
+ { type: 'title', level: 2, text: 'Read the four decisions in the result' },
155
+ { type: 'list', items: ['Use the PPU values to compare the sprite with tiles and other assets.', 'Use the visible world size to check whether the camera framing matches the level design.', 'Use the scale ledger to find whole number multipliers that fit the target display.', 'Use the bleed warning to decide where an engine test is necessary, not to certify the renderer.'] },
156
+ { type: 'title', level: 2, text: 'Integer scaling protects the pixel grid' },
157
+ { type: 'paragraph', html: 'A whole number scale gives every source pixel an even footprint on the screen. A fractional scale asks the renderer to distribute source pixels unevenly, which can show up as soft edges, alternating line widths, or unstable details during movement. Nearest filtering preserves hard texel choices, but it does not solve every problem: camera positions, atlas boundaries, sampling coordinates, and aspect ratios still matter.' },
158
+ { type: 'table', headers: ['Planning signal', 'What it tells you', 'What to verify next'], rows: [['Matched PPU axes', 'The sprite world rectangle has the same density horizontally and vertically.', 'Compare it with tiles and the project reference grid.'], ['Fractional target scale', 'The requested source pixel footprint is not a whole number.', 'Try the closest fitting integer step and test the camera.'], ['Scale exceeds viewport', 'The sprite footprint is larger than the declared display on at least one axis.', 'Choose a smaller step or use a larger reference resolution.'], ['Axis mismatch', 'The world rectangle assigns different pixel densities to X and Y.', 'Check whether non uniform scaling is intentional.']] },
159
+ { type: 'title', level: 2, text: 'Understand pixel bleeding as a sampling problem' },
160
+ { type: 'paragraph', html: 'Pixel bleeding usually describes an unwanted color from a neighboring texel or atlas region. Linear filtering blends nearby samples, while nearest filtering selects the closest texel. Even with nearest filtering, sampling at texture borders or moving a camera between pixel positions can expose seams or flicker. That is why padding, clamp behavior, integer placement, and the project camera settings deserve a separate engine test.' },
161
+ { type: 'title', level: 2, text: 'Use the planner before building a scene' },
162
+ { type: 'paragraph', html: 'Start with the reference resolution your game is designed around. Enter one representative sprite and its intended world size, then compare both PPU axes. Try the integer scale steps that fit the display. If the result is not visually stable, change one assumption at a time: the reference resolution, sprite import size, world dimension, or camera policy. This gives the team a small, auditable design decision instead of a vague pixel perfect promise.' },
163
+ { type: 'tip', title: 'What the number cannot prove', html: 'A PPU plan cannot inspect an atlas, choose an engine import preset, measure a device, or guarantee that motion will lock to a pixel grid. Use the number as a contract between assets and camera setup, then validate the actual render at every resolution and motion path you support.' },
164
+ ],
165
+ faqTitle: 'Pixel per unit questions',
166
+ faq,
167
+ bibliographyTitle: 'Pixel rendering references',
168
+ bibliography: bibliographyEntries,
169
+ howTo,
170
+ schemas: [softwareApplication, faqPage, howToSchema],
171
+ };
@@ -0,0 +1,53 @@
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: '¿Qué significa píxeles por unidad en un juego?', answer: 'Los píxeles por unidad, o PPU, indican cuántos píxeles de textura representan una unidad del mundo. Una densidad coherente ayuda a que sprites, tiles y cámara compartan una escala predecible.' },
8
+ { question: '¿Por qué importan las escalas enteras?', answer: 'Una escala entera asigna el mismo número completo de píxeles de pantalla a cada píxel original. Las escalas fraccionarias pueden producir bordes desiguales o suavizado.' },
9
+ { question: '¿Qué es el pixel bleeding?', answer: 'Es la aparición de color de un texel vecino o de otra zona de un atlas. El filtrado, los bordes, el movimiento subpixel y la falta de padding pueden provocarlo.' },
10
+ { question: '¿Cómo uso la escala recomendada?', answer: 'Úsala como candidata que cabe en la resolución y se acerca a tu objetivo. Después comprueba en el motor el filtrado nearest, el snapping de cámara y el padding del atlas.' },
11
+ { question: '¿El planificador elige el PPU correcto para cualquier motor?', answer: 'No. Es una ayuda aritmética transparente. Cada motor puede cambiar cámara, importación, mipmaps, redondeo y pixel snapping, así que el resultado necesita una prueba real.' },
12
+ ];
13
+
14
+ const howTo = [
15
+ { name: 'Elige la pantalla de destino', text: 'Indica el ancho y alto de la vista de juego o del lienzo de referencia en píxeles.' },
16
+ { name: 'Carga el sprite', text: 'Elige una imagen y deja que la herramienta detecte su ancho y alto nativos. También puedes usar el sprite de ejemplo de Bob.' },
17
+ { name: 'Elige una escala', text: 'Mueve el control de escala o pulsa un preset. Los multiplicadores enteros son los candidatos más nítidos.' },
18
+ { name: 'Lee la preview', text: 'Comprueba el footprint del sprite, el PPU horizontal y vertical, el viewport visible y el aviso de bleeding.' },
19
+ { name: 'Valida en el motor', text: 'Prueba la escala elegida con filtrado nearest, cámara alineada, padding de atlas y las resoluciones reales del juego.' },
20
+ ];
21
+
22
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planificador de píxeles por unidad para juegos', 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: 'Cómo probar el escalado de un sprite pixel art', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
25
+
26
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
27
+ slug: 'planificador-pixeles-por-unidad-sprite-juegos',
28
+ title: 'Planificador de píxeles por unidad para sprites de juegos',
29
+ description: 'Sube un sprite o usa el ejemplo de Bob para ver su footprint a distintas escalas enteras, comprobar el PPU y detectar riesgos de pixel bleeding.',
30
+ ui: {
31
+ inputsTitle: 'Carga y prueba tu sprite', uploadTitle: 'Tu imagen de origen', uploadHint: 'Elige un PNG, GIF, WebP o JPEG. Sus dimensiones nativas alimentan cada preview.', chooseSpriteLabel: 'Elegir sprite', noSpriteLabel: 'No hay sprite cargado', defaultSpriteLabel: 'Sprite de Bob de ejemplo', loadedSpriteLabel: 'Cargado', clearSpriteLabel: 'Quitar sprite', displayWidthLabel: 'Ancho de pantalla px', displayHeightLabel: 'Alto de pantalla px', spriteWidthLabel: 'Ancho del sprite px', spriteHeightLabel: 'Alto del sprite px', worldWidthLabel: 'Ancho del sprite en unidades', worldHeightLabel: 'Alto del sprite en unidades', targetScaleLabel: 'Escala objetivo en pantalla', targetScaleHint: 'Píxeles de pantalla por cada píxel de la textura.', resolutionPresetsLabel: 'Resoluciones de referencia', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Escalas rápidas', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Restablecer valores', fieldTitle: 'Míralo a distintos tamaños', fieldCaption: 'La imagen cargada se renderiza con escalado nearest para valorar su footprint real en cada multiplicador entero.', previewPlaceholder: 'Carga un sprite para empezar la prueba visual', previewScaleLabel: 'Escala de preview', sourceImageAlt: 'Preview del sprite cargado', viewportLabel: 'Pantalla', spriteLabel: 'Sprite renderizado', crispTitle: 'Escalas nítidas', crispCaption: 'Los multiplicadores enteros conservan el tamaño uniforme de los píxeles. Las escalas grises superan la pantalla declarada.', fitLabel: 'Cabe en pantalla:', yesLabel: 'sí', noLabel: 'no', recommendedLabel: 'ajuste más cercano', summaryTitle: 'Resumen del plan', ppuXLabel: 'PPU horizontal', ppuYLabel: 'PPU vertical', viewportWorldLabel: 'Mundo visible', fitScaleLabel: 'Mayor escala que cabe', bleedingRiskLabel: 'Riesgo de bleeding', lowRisk: 'Bajo', mediumRisk: 'Medio', highRisk: 'Alto', riskLowMessage: 'Los ejes están alineados y la escala objetivo es entera y cabe en la pantalla. Comprueba aun así el filtrado y el padding del atlas.', riskMediumMessage: 'El objetivo encaja de forma imperfecta: revisa el desajuste de ejes o las escalas resaltadas.', riskHighMessage: 'La escala puede producir muestreo desigual. Prefiere un multiplicador entero y revisa las dimensiones del sprite.', alignmentLabel: 'Nota de muestreo', tableTitle: 'Registro accesible de escalas', tableScale: 'Escala', tableWidth: 'Ancho renderizado', tableHeight: 'Alto renderizado', tableFits: 'Cabe en pantalla', modelNote: 'El PPU se calcula como píxeles renderizados del sprite divididos por su tamaño en unidades en cada eje. El riesgo de bleeding es una heurística, no una inspección de textura ni una garantía del motor.', privacyDisclosure: 'El archivo se procesa en este navegador. No se suben sprites, archivos de proyecto ni telemetría.', statusReady: 'Preview actualizada', unitPixels: 'px', unitUnits: 'unidades',
32
+ },
33
+ seo: [
34
+ { type: 'title', level: 2, text: 'Convierte el tamaño del sprite en una decisión de escala' },
35
+ { type: 'paragraph', html: 'Un sprite tiene el tamaño de su bitmap y el tamaño que ocupa en el mundo del juego. El PPU conecta ambas medidas. La preview te permite ver la consecuencia visual en lugar de confiar solo en una cifra.' },
36
+ { type: 'paragraph', html: 'Carga una imagen real y la herramienta toma sus dimensiones nativas. Después multiplica cada eje por la escala elegida y calcula qué parte del mundo queda visible en la resolución declarada.' },
37
+ { type: 'title', level: 2, text: 'Qué debes mirar en la preview' },
38
+ { type: 'list', items: ['Compara el footprint del sprite con la pantalla de referencia.', 'Prueba primero escalas enteras para mantener cada píxel uniforme.', 'Usa el PPU de ambos ejes para encontrar estiramientos no intencionados.', 'Trata el aviso de bleeding como una señal para probar el motor.'] },
39
+ { type: 'title', level: 2, text: 'Por qué una escala entera suele ser más limpia' },
40
+ { type: 'paragraph', html: 'A 3x, cada píxel de origen ocupa tres píxeles de pantalla. A 2.5x, el renderer debe repartir algunos píxeles con anchos distintos. El filtrado nearest evita mezclar colores, pero no puede corregir una cámara colocada entre posiciones de píxel.' },
41
+ { type: 'table', headers: ['Señal', 'Lectura', 'Siguiente decisión'], rows: [['PPU igual', 'Los dos ejes comparten densidad.', 'Compáralo con tiles y la cuadrícula del proyecto.'], ['Escala fraccionaria', 'El footprint no usa un multiplicador entero.', 'Prueba la escala entera más cercana.'], ['No cabe', 'El sprite supera la pantalla.', 'Reduce la escala o aumenta la resolución de referencia.']] },
42
+ { type: 'title', level: 2, text: 'Distingue el bleeding del simple tamaño' },
43
+ { type: 'paragraph', html: 'El pixel bleeding suele venir de muestras vecinas en un atlas, bordes filtrados o coordenadas de cámara no alineadas. Si la imagen se ve suave, primero revisa el filtrado; si aparecen costuras, revisa padding, clamp y límites del atlas.' },
44
+ { type: 'title', level: 2, text: 'Usa el sprite de ejemplo para aprender el flujo' },
45
+ { type: 'paragraph', html: 'El Bob de ejemplo deja ver la forma del personaje con el lazo rosa desde el primer momento. Cambia la resolución y la escala para observar cuándo el cuerpo deja de caber o cuándo los píxeles pierden uniformidad.' },
46
+ { type: 'title', level: 2, text: 'Qué valida y qué no valida esta herramienta' },
47
+ { type: 'paragraph', html: 'La herramienta compara dimensiones y footprints en una vista controlada. No abre un proyecto del motor, no inspecciona un atlas, no mide un dispositivo y no puede garantizar movimiento pixel perfect durante una partida.' },
48
+ { type: 'title', level: 2, text: 'Un flujo corto para elegir una escala' },
49
+ { type: 'paragraph', html: 'Carga el sprite, selecciona la resolución de referencia, prueba 1x, 2x, 3x y 4x, y elige la mayor escala entera que conserve aire en pantalla. Luego repite la comprobación en las resoluciones que realmente soporta el juego.' },
50
+ { type: 'tip', title: 'La última comprobación ocurre en el motor', html: 'Usa esta preview para acotar una decisión. Después activa nearest filtering, revisa el padding del atlas, alinea la cámara y prueba movimiento y diferentes resoluciones antes de dar por bueno el resultado.' },
51
+ ],
52
+ faqTitle: 'Preguntas sobre escalado de sprites', faq, bibliographyTitle: 'Referencias de renderizado pixel art', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
53
+ };
@@ -0,0 +1,33 @@
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: 'Que signifie pixels par unité dans un jeu ?', answer: 'Les pixels par unité, ou PPU, indiquent combien de pixels de texture représentent une unité du monde. Une densité cohérente aide les sprites, les tuiles et la caméra à partager une échelle prévisible.' },
8
+ { question: 'Pourquoi les échelles entières sont-elles importantes ?', answer: 'Une échelle entière donne à chaque pixel source le même nombre entier de pixels à l écran. Une fraction peut produire des bords irréguliers ou un flou.' },
9
+ { question: 'Quest-ce que le pixel bleeding ?', answer: 'C est la couleur indésirable d un texel voisin ou d une autre zone de l atlas. Le filtrage, les bords, le mouvement subpixel et le manque de marge peuvent le provoquer.' },
10
+ { question: 'Comment utiliser l échelle recommandée ?', answer: 'Utilisez-la comme candidate qui tient dans la résolution et reste proche de votre objectif. Vérifiez ensuite le filtrage nearest, la caméra et la marge de l atlas dans le moteur.' },
11
+ { question: 'Le planificateur choisit-il le bon PPU pour chaque moteur ?', answer: 'Non. C est une aide de calcul transparente. La caméra, l import, les mipmaps, l arrondi et le pixel snapping diffèrent selon le moteur et demandent un vrai test.' },
12
+ ];
13
+ const howTo = [
14
+ { name: 'Choisir l écran cible', text: 'Saisissez la largeur et la hauteur de la vue du jeu ou de la résolution de référence en pixels.' },
15
+ { name: 'Charger le sprite', text: 'Choisissez une image pour détecter ses dimensions natives. Vous pouvez aussi utiliser le sprite Bob fourni.' },
16
+ { name: 'Choisir une échelle', text: 'Déplacez le curseur ou choisissez un preset. Les multiplicateurs entiers sont les candidats les plus nets.' },
17
+ { name: 'Lire la preview', text: 'Vérifiez l empreinte du sprite, les PPU horizontal et vertical, le monde visible et le risque de bleeding.' },
18
+ { name: 'Tester dans le moteur', text: 'Validez le choix avec le filtrage nearest, une caméra alignée, la marge de l atlas et les résolutions réelles.' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planificateur de pixels par unité pour jeux', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'Tester le redimensionnement d un sprite pixel art', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'planificateur-pixels-par-unite-sprite-jeu', title: 'Planificateur de pixels par unité pour sprites de jeux', description: 'Chargez un sprite ou utilisez l exemple de Bob pour voir son empreinte à plusieurs échelles entières, comparer le PPU et repérer le pixel bleeding.',
26
+ ui: {
27
+ inputsTitle: 'Charger et tester votre sprite', uploadTitle: 'Votre image source', uploadHint: 'Choisissez un PNG, GIF, WebP ou JPEG. Ses dimensions natives alimentent chaque preview.', chooseSpriteLabel: 'Choisir un sprite', noSpriteLabel: 'Aucun sprite chargé', defaultSpriteLabel: 'Sprite Bob d exemple', loadedSpriteLabel: 'Chargé', clearSpriteLabel: 'Retirer le sprite', displayWidthLabel: 'Largeur écran px', displayHeightLabel: 'Hauteur écran px', spriteWidthLabel: 'Largeur du sprite px', spriteHeightLabel: 'Hauteur du sprite px', worldWidthLabel: 'Largeur du sprite en unités', worldHeightLabel: 'Hauteur du sprite en unités', targetScaleLabel: 'Échelle cible à l écran', targetScaleHint: 'Pixels à l écran pour chaque pixel de la texture.', resolutionPresetsLabel: 'Résolutions de référence', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Échelles rapides', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Réinitialiser les valeurs', fieldTitle: 'Le voir à plusieurs tailles', fieldCaption: 'L image chargée est rendue avec une échelle nearest pour juger son empreinte réelle à chaque multiplicateur entier.', previewPlaceholder: 'Chargez un sprite pour commencer le test visuel', previewScaleLabel: 'Échelle de preview', sourceImageAlt: 'Preview du sprite chargé', viewportLabel: 'Écran', spriteLabel: 'Sprite rendu', crispTitle: 'Échelles nettes', crispCaption: 'Les multiplicateurs entiers gardent les pixels uniformes. Les étapes grises dépassent l écran déclaré.', fitLabel: 'Tient dans l écran :', yesLabel: 'oui', noLabel: 'non', recommendedLabel: 'ajustement proche', summaryTitle: 'Résumé du plan', ppuXLabel: 'PPU horizontal', ppuYLabel: 'PPU vertical', viewportWorldLabel: 'Monde visible', fitScaleLabel: 'Plus grande échelle adaptée', bleedingRiskLabel: 'Risque de bleeding', lowRisk: 'Faible', mediumRisk: 'Moyen', highRisk: 'Élevé', riskLowMessage: 'Les axes sont alignés et l échelle cible est entière et adaptée. Vérifiez tout de même le filtrage et la marge de l atlas.', riskMediumMessage: 'La cible est imparfaite. Examinez l écart entre les axes et les échelles mises en avant.', riskHighMessage: 'L échelle peut créer un échantillonnage irrégulier. Préférez un multiplicateur entier et contrôlez les dimensions.', alignmentLabel: 'Note d échantillonnage', tableTitle: 'Registre accessible des échelles', tableScale: 'Échelle', tableWidth: 'Largeur rendue', tableHeight: 'Hauteur rendue', tableFits: 'Tient dans l écran', modelNote: 'Le PPU est calculé comme les pixels rendus du sprite divisés par sa taille en unités sur chaque axe. Le risque de bleeding est une heuristique, pas une inspection de texture ni une garantie du moteur.', privacyDisclosure: 'Le fichier est traité dans ce navigateur. Aucun sprite, fichier de projet ou suivi n est envoyé.', statusReady: 'Preview mise à jour', unitPixels: 'px', unitUnits: 'unités',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: 'Transformer la taille du sprite en choix d échelle' }, { type: 'paragraph', html: 'Un sprite possède la taille de son bitmap et celle qu il occupe dans le monde du jeu. Le PPU relie ces deux mesures. La preview montre la conséquence visuelle au lieu de laisser une valeur abstraite décider.' }, { type: 'paragraph', html: 'Chargez une image réelle pour utiliser ses dimensions natives. L outil multiplie ensuite chaque axe par l échelle choisie et calcule la portion du monde visible dans la résolution déclarée.' }, { type: 'title', level: 2, text: 'Ce qu il faut observer dans la preview' }, { type: 'list', items: ['Comparez l empreinte avec l écran de référence.', 'Testez d abord les échelles entières.', 'Utilisez les deux PPU pour trouver un étirement involontaire.', 'Prenez le risque de bleeding comme signal pour tester le moteur.'] }, { type: 'title', level: 2, text: 'Pourquoi les échelles entières sont souvent plus propres' }, { type: 'paragraph', html: 'À 3x, chaque pixel source occupe trois pixels écran. À 2,5x, le rendu doit répartir des largeurs différentes. Nearest évite le mélange des couleurs, mais ne corrige pas une caméra entre deux positions de pixel.' }, { type: 'table', headers: ['Signal', 'Lecture', 'Décision suivante'], rows: [['PPU égal', 'Les deux axes ont la même densité.', 'Comparer aux tuiles et à la grille.'], ['Échelle fractionnaire', 'L empreinte n utilise pas un entier.', 'Essayer l entier le plus proche.'], ['Ne tient pas', 'Le sprite dépasse l écran.', 'Réduire l échelle ou augmenter la résolution.']] }, { type: 'title', level: 2, text: 'Distinguer le bleeding de la taille' }, { type: 'paragraph', html: 'Le pixel bleeding vient souvent des texels voisins dans un atlas, du filtrage sur les bords ou de coordonnées de caméra non alignées. Pour un flou, vérifiez le filtrage ; pour les coutures, vérifiez aussi la marge et les limites.' }, { type: 'title', level: 2, text: 'Apprendre avec le sprite Bob' }, { type: 'paragraph', html: 'Le sprite Bob avec son nœud rose est visible dès le départ. Changez la résolution et l échelle pour voir quand le personnage ne tient plus ou quand les pixels deviennent irréguliers.' }, { type: 'title', level: 2, text: 'Ce que l outil valide et ce qu il ne valide pas' }, { type: 'paragraph', html: 'L outil compare dimensions et empreintes dans une vue contrôlée. Il n ouvre pas de projet, n inspecte pas un atlas, ne mesure pas un appareil et ne garantit pas un mouvement pixel perfect.' }, { type: 'title', level: 2, text: 'Un parcours court pour choisir une échelle' }, { type: 'paragraph', html: 'Chargez le sprite, choisissez la résolution, essayez 1x à 4x et retenez la plus grande échelle entière avec de l espace. Répétez ensuite avec les résolutions réellement supportées.' }, { type: 'tip', title: 'La dernière vérification se fait dans le moteur', html: 'Utilisez la preview pour réduire le choix. Activez ensuite le filtrage nearest, vérifiez la marge de l atlas et l alignement de la caméra, puis testez plusieurs résolutions.' },
31
+ ],
32
+ faqTitle: 'Questions sur la mise à l échelle des sprites', faq, bibliographyTitle: 'Références du pixel art', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };
@@ -0,0 +1,33 @@
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: 'Apa arti piksel per unit dalam game?', answer: 'Piksel per unit atau PPU menunjukkan jumlah piksel tekstur yang mewakili satu unit dunia. Kepadatan yang konsisten membuat sprite, tile, dan kamera memiliki skala yang mudah diprediksi.' },
8
+ { question: 'Mengapa skala bilangan bulat penting?', answer: 'Skala bilangan bulat memberi setiap piksel sumber jumlah piksel layar yang sama. Skala pecahan dapat menghasilkan tepi yang tidak rata atau gambar buram.' },
9
+ { question: 'Apa itu pixel bleeding?', answer: 'Pixel bleeding adalah warna yang tidak diinginkan dari texel tetangga atau area atlas lain. Filtering, tepi, gerakan subpiksel, dan padding yang kurang dapat menyebabkannya.' },
10
+ { question: 'Bagaimana cara memakai skala yang direkomendasikan?', answer: 'Gunakan sebagai kandidat yang muat dalam resolusi dan dekat dengan target. Setelah itu periksa filtering nearest, posisi kamera, dan padding atlas di engine.' },
11
+ { question: 'Apakah planner memilih PPU yang benar untuk setiap engine?', answer: 'Tidak. Ini adalah alat bantu aritmetika yang transparan. Kamera, import, mipmap, pembulatan, dan pixel snapping berbeda di setiap engine sehingga perlu diuji.' },
12
+ ];
13
+ const howTo = [
14
+ { name: 'Pilih layar tujuan', text: 'Masukkan lebar dan tinggi tampilan game atau resolusi referensi dalam piksel.' },
15
+ { name: 'Muat sprite', text: 'Pilih gambar agar ukuran aslinya terdeteksi. Anda juga dapat memakai sprite contoh Bob.' },
16
+ { name: 'Pilih skala', text: 'Gerakkan slider atau pilih preset. Pengali bilangan bulat adalah kandidat paling tajam.' },
17
+ { name: 'Baca preview', text: 'Periksa footprint sprite, PPU horizontal dan vertikal, dunia yang terlihat, serta peringatan bleeding.' },
18
+ { name: 'Uji di engine', text: 'Validasi pilihan dengan filtering nearest, kamera yang sejajar, padding atlas, dan resolusi game sebenarnya.' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planner piksel per unit untuk game', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'Menguji skala sprite pixel art', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'planner-piksel-per-unit-sprite-game', title: 'Planner piksel per unit untuk sprite game', description: 'Unggah sprite atau gunakan contoh Bob untuk melihat footprint pada berbagai skala bilangan bulat, membandingkan PPU, dan menemukan risiko pixel bleeding.',
26
+ ui: {
27
+ inputsTitle: 'Muat dan uji sprite Anda', uploadTitle: 'Gambar sumber Anda', uploadHint: 'Pilih PNG, GIF, WebP, atau JPEG. Ukuran asli gambar digunakan di setiap preview.', chooseSpriteLabel: 'Pilih sprite', noSpriteLabel: 'Belum ada sprite yang dimuat', defaultSpriteLabel: 'Sprite contoh Bob', loadedSpriteLabel: 'Dimuat', clearSpriteLabel: 'Hapus sprite', displayWidthLabel: 'Lebar layar px', displayHeightLabel: 'Tinggi layar px', spriteWidthLabel: 'Lebar sprite px', spriteHeightLabel: 'Tinggi sprite px', worldWidthLabel: 'Lebar sprite dalam unit', worldHeightLabel: 'Tinggi sprite dalam unit', targetScaleLabel: 'Skala target di layar', targetScaleHint: 'Piksel layar untuk setiap piksel tekstur.', resolutionPresetsLabel: 'Resolusi referensi', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Skala cepat', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Atur ulang nilai', fieldTitle: 'Lihat dalam beberapa ukuran', fieldCaption: 'Gambar yang dimuat dirender dengan skala nearest agar footprint sebenarnya dapat dinilai pada setiap pengali bilangan bulat.', previewPlaceholder: 'Muat sprite untuk memulai pengujian visual', previewScaleLabel: 'Skala preview', sourceImageAlt: 'Preview sprite yang dimuat', viewportLabel: 'Layar', spriteLabel: 'Sprite yang dirender', crispTitle: 'Skala tajam', crispCaption: 'Pengali bilangan bulat menjaga ukuran piksel tetap seragam. Langkah abu-abu melebihi layar yang dinyatakan.', fitLabel: 'Muat di layar:', yesLabel: 'ya', noLabel: 'tidak', recommendedLabel: 'paling mendekati', summaryTitle: 'Ringkasan rencana', ppuXLabel: 'PPU horizontal', ppuYLabel: 'PPU vertikal', viewportWorldLabel: 'Dunia terlihat', fitScaleLabel: 'Skala terbesar yang muat', bleedingRiskLabel: 'Risiko bleeding', lowRisk: 'Rendah', mediumRisk: 'Sedang', highRisk: 'Tinggi', riskLowMessage: 'Sumbu selaras dan skala target berupa bilangan bulat yang muat di layar. Tetap periksa filtering dan padding atlas.', riskMediumMessage: 'Target hanya cocok sebagian. Periksa perbedaan sumbu dan skala yang disorot.', riskHighMessage: 'Skala ini dapat membuat sampling tidak rata. Pilih pengali bilangan bulat dan periksa ukuran sprite.', alignmentLabel: 'Catatan sampling', tableTitle: 'Daftar skala yang mudah diakses', tableScale: 'Skala', tableWidth: 'Lebar render', tableHeight: 'Tinggi render', tableFits: 'Muat di layar', modelNote: 'PPU dihitung sebagai piksel sprite yang dirender dibagi ukuran sprite dalam unit pada setiap sumbu. Risiko bleeding adalah heuristik, bukan pemeriksaan tekstur atau jaminan engine.', privacyDisclosure: 'File diproses di browser ini. Sprite, file proyek, dan telemetri tidak dikirim.', statusReady: 'Preview diperbarui', unitPixels: 'px', unitUnits: 'unit',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: 'Ubah ukuran sprite menjadi keputusan skala' }, { type: 'paragraph', html: 'Sprite memiliki ukuran bitmap dan ukuran yang ditempatinya di dunia game. PPU menghubungkan kedua ukuran tersebut. Preview menunjukkan akibat visualnya, bukan hanya angka abstrak.' }, { type: 'paragraph', html: 'Muat gambar nyata untuk memakai ukuran aslinya. Alat ini mengalikan setiap sumbu dengan skala pilihan lalu menghitung bagian dunia yang terlihat pada resolusi yang diberikan.' }, { type: 'title', level: 2, text: 'Hal yang perlu dilihat di preview' }, { type: 'list', items: ['Bandingkan footprint dengan layar referensi.', 'Uji skala bilangan bulat terlebih dahulu.', 'Gunakan kedua nilai PPU untuk menemukan peregangan yang tidak disengaja.', 'Anggap peringatan bleeding sebagai sinyal untuk menguji engine.'] }, { type: 'title', level: 2, text: 'Mengapa skala bilangan bulat lebih bersih' }, { type: 'paragraph', html: 'Pada 3x setiap piksel sumber menempati tiga piksel layar. Pada 2,5x renderer harus membagi lebar yang berbeda. Nearest mencegah pencampuran warna, tetapi tidak memperbaiki kamera di antara posisi piksel.' }, { type: 'table', headers: ['Sinyal', 'Makna', 'Keputusan berikutnya'], rows: [['PPU sama', 'Kedua sumbu memiliki kepadatan yang sama.', 'Bandingkan dengan tile dan grid proyek.'], ['Skala pecahan', 'Footprint tidak memakai bilangan bulat.', 'Coba skala bilangan bulat terdekat.'], ['Tidak muat', 'Sprite melampaui layar.', 'Kurangi skala atau tambah resolusi.']] }, { type: 'title', level: 2, text: 'Bedakan bleeding dari ukuran' }, { type: 'paragraph', html: 'Pixel bleeding biasanya berasal dari texel tetangga di atlas, filtering di tepi, atau koordinat kamera yang tidak sejajar. Untuk buram periksa filtering; untuk garis sambungan periksa padding dan batas atlas.' }, { type: 'title', level: 2, text: 'Pelajari alur dengan sprite Bob' }, { type: 'paragraph', html: 'Contoh Bob dengan pita merah muda langsung terlihat. Ubah resolusi dan skala untuk melihat kapan karakter tidak lagi muat atau piksel kehilangan keseragaman.' }, { type: 'title', level: 2, text: 'Apa yang diperiksa alat ini' }, { type: 'paragraph', html: 'Alat ini membandingkan dimensi dan footprint dalam tampilan terkontrol. Alat ini tidak membuka proyek engine, memeriksa atlas, mengukur perangkat, atau menjamin gerakan pixel perfect.' }, { type: 'title', level: 2, text: 'Alur singkat memilih skala' }, { type: 'paragraph', html: 'Muat sprite, pilih resolusi, coba 1x sampai 4x, dan pilih skala bilangan bulat terbesar yang masih menyisakan ruang. Ulangi pada resolusi game sebenarnya.' }, { type: 'tip', title: 'Pemeriksaan terakhir dilakukan di engine', html: 'Gunakan preview untuk mempersempit pilihan. Aktifkan filtering nearest, periksa padding atlas dan posisi kamera, lalu uji beberapa resolusi.' },
31
+ ],
32
+ faqTitle: 'Pertanyaan tentang skala sprite', faq, bibliographyTitle: 'Referensi pixel art', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };
@@ -0,0 +1,33 @@
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: 'Che cosa significa pixel per unità in un gioco?', answer: 'I pixel per unità, o PPU, indicano quanti pixel della texture rappresentano una unità del mondo. Una densità coerente mantiene sprite, tile e camera su una scala prevedibile.' },
8
+ { question: 'Perché sono importanti le scale intere?', answer: 'Una scala intera assegna a ogni pixel sorgente lo stesso numero intero di pixel sullo schermo. Le frazioni possono creare bordi irregolari o sfocatura.' },
9
+ { question: 'Che cos è il pixel bleeding?', answer: 'È un colore indesiderato preso da un texel vicino o da un altra zona dell atlas. Filtro, bordi, movimento subpixel e margine insufficiente possono causarlo.' },
10
+ { question: 'Come uso la scala consigliata?', answer: 'Usala come candidata che entra nella risoluzione ed è vicina al tuo obiettivo. Poi verifica nel motore filtro nearest, allineamento della camera e margine dell atlas.' },
11
+ { question: 'Il planner sceglie il PPU corretto per ogni motore?', answer: 'No. È un aiuto matematico trasparente. Camera, importazione, mipmap, arrotondamento e pixel snapping cambiano da motore a motore e richiedono un test reale.' },
12
+ ];
13
+ const howTo = [
14
+ { name: 'Scegliere lo schermo di destinazione', text: 'Inserisci larghezza e altezza della vista di gioco o della risoluzione di riferimento in pixel.' },
15
+ { name: 'Caricare lo sprite', text: 'Scegli un immagine per rilevare le dimensioni native. Puoi anche usare lo sprite Bob incluso.' },
16
+ { name: 'Scegliere una scala', text: 'Sposta il cursore o scegli un preset. I moltiplicatori interi sono i candidati più nitidi.' },
17
+ { name: 'Leggere la preview', text: 'Controlla footprint, PPU orizzontale e verticale, mondo visibile e avviso di bleeding.' },
18
+ { name: 'Provare nel motore', text: 'Verifica la scelta con filtro nearest, camera allineata, margine dell atlas e risoluzioni reali.' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planner dei pixel per unità per giochi', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'Provare la scala di uno sprite pixel art', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'planner-pixel-per-unita-sprite-giochi', title: 'Planner dei pixel per unità per sprite di giochi', description: 'Carica uno sprite o usa l esempio di Bob per vedere il footprint a diverse scale intere, confrontare il PPU e trovare il rischio di pixel bleeding.',
26
+ ui: {
27
+ inputsTitle: 'Carica e prova il tuo sprite', uploadTitle: 'La tua immagine sorgente', uploadHint: 'Scegli PNG, GIF, WebP o JPEG. Le dimensioni native alimentano ogni preview.', chooseSpriteLabel: 'Scegli sprite', noSpriteLabel: 'Nessuno sprite caricato', defaultSpriteLabel: 'Sprite Bob di esempio', loadedSpriteLabel: 'Caricato', clearSpriteLabel: 'Rimuovi sprite', displayWidthLabel: 'Larghezza schermo px', displayHeightLabel: 'Altezza schermo px', spriteWidthLabel: 'Larghezza sprite px', spriteHeightLabel: 'Altezza sprite px', worldWidthLabel: 'Larghezza sprite in unità', worldHeightLabel: 'Altezza sprite in unità', targetScaleLabel: 'Scala obiettivo sullo schermo', targetScaleHint: 'Pixel sullo schermo per ogni pixel della texture.', resolutionPresetsLabel: 'Risoluzioni di riferimento', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Scale rapide', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Ripristina valori', fieldTitle: 'Guardalo a più dimensioni', fieldCaption: 'L immagine caricata usa lo scaling nearest per valutare il footprint reale a ogni moltiplicatore intero.', previewPlaceholder: 'Carica uno sprite per iniziare il test visivo', previewScaleLabel: 'Scala preview', sourceImageAlt: 'Preview dello sprite caricato', viewportLabel: 'Schermo', spriteLabel: 'Sprite renderizzato', crispTitle: 'Scale nitide', crispCaption: 'I moltiplicatori interi mantengono uniformi i pixel. I passaggi grigi superano lo schermo dichiarato.', fitLabel: 'Entra nello schermo:', yesLabel: 'sì', noLabel: 'no', recommendedLabel: 'adattamento vicino', summaryTitle: 'Riepilogo del piano', ppuXLabel: 'PPU orizzontale', ppuYLabel: 'PPU verticale', viewportWorldLabel: 'Mondo visibile', fitScaleLabel: 'Scala massima adatta', bleedingRiskLabel: 'Rischio bleeding', lowRisk: 'Basso', mediumRisk: 'Medio', highRisk: 'Alto', riskLowMessage: 'Gli assi sono allineati e la scala obiettivo è intera e adatta. Controlla comunque filtro e margine dell atlas.', riskMediumMessage: 'L obiettivo si adatta in modo imperfetto. Esamina la differenza tra gli assi e le scale evidenziate.', riskHighMessage: 'La scala può creare campionamento irregolare. Preferisci un moltiplicatore intero e controlla le dimensioni.', alignmentLabel: 'Nota sul campionamento', tableTitle: 'Registro accessibile delle scale', tableScale: 'Scala', tableWidth: 'Larghezza renderizzata', tableHeight: 'Altezza renderizzata', tableFits: 'Entra nello schermo', modelNote: 'Il PPU è calcolato come pixel renderizzati dello sprite divisi per la sua dimensione in unità su ogni asse. Il rischio di bleeding è un euristico, non una verifica della texture o una garanzia del motore.', privacyDisclosure: 'Il file viene elaborato in questo browser. Sprite, file di progetto e telemetria non vengono inviati.', statusReady: 'Preview aggiornata', unitPixels: 'px', unitUnits: 'unità',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: 'Trasforma la dimensione dello sprite in una scelta di scala' }, { type: 'paragraph', html: 'Uno sprite ha la dimensione del bitmap e quella che occupa nel mondo di gioco. Il PPU collega queste misure. La preview mostra la conseguenza visiva invece di lasciare decidere a un numero astratto.' }, { type: 'paragraph', html: 'Carica un immagine reale per usare le sue dimensioni native. Lo strumento moltiplica ogni asse per la scala scelta e calcola la parte di mondo visibile nella risoluzione dichiarata.' }, { type: 'title', level: 2, text: 'Cosa osservare nella preview' }, { type: 'list', items: ['Confronta il footprint con lo schermo di riferimento.', 'Prova prima le scale intere per pixel uniformi.', 'Usa entrambi i PPU per trovare stiramenti involontari.', 'Considera il bleeding un segnale per provare il motore.'] }, { type: 'title', level: 2, text: 'Perché le scale intere sono spesso più pulite' }, { type: 'paragraph', html: 'A 3x ogni pixel sorgente occupa tre pixel sullo schermo. A 2,5x il renderer deve distribuire larghezze diverse. Nearest evita di mescolare i colori, ma non corregge una camera tra posizioni di pixel.' }, { type: 'table', headers: ['Segnale', 'Lettura', 'Decisione successiva'], rows: [['PPU uguale', 'I due assi hanno la stessa densità.', 'Confronta tile e griglia del progetto.'], ['Scala frazionaria', 'Il footprint non usa un intero.', 'Prova l intero più vicino.'], ['Non entra', 'Lo sprite supera lo schermo.', 'Riduci la scala o aumenta la risoluzione.']] }, { type: 'title', level: 2, text: 'Distinguere il bleeding dalla semplice dimensione' }, { type: 'paragraph', html: 'Il pixel bleeding nasce spesso da texel vicini nell atlas, filtro sui bordi o coordinate della camera non allineate. Per la sfocatura controlla il filtro; per le cuciture controlla anche margine e limiti dell atlas.' }, { type: 'title', level: 2, text: 'Imparare con lo sprite Bob' }, { type: 'paragraph', html: 'L esempio Bob con il fiocco rosa è visibile subito. Cambia risoluzione e scala per vedere quando il personaggio non entra più o i pixel perdono uniformità.' }, { type: 'title', level: 2, text: 'Cosa verifica e cosa non verifica lo strumento' }, { type: 'paragraph', html: 'Lo strumento confronta dimensioni e footprint in una vista controllata. Non apre un progetto, non ispeziona un atlas, non misura un dispositivo e non garantisce movimento pixel perfect.' }, { type: 'title', level: 2, text: 'Un percorso breve per scegliere la scala' }, { type: 'paragraph', html: 'Carica lo sprite, scegli la risoluzione, prova da 1x a 4x e usa la scala intera più grande che lasci spazio. Ripeti poi con le risoluzioni realmente supportate.' }, { type: 'tip', title: 'L ultima verifica avviene nel motore', html: 'Usa la preview per restringere la scelta. Attiva poi il filtro nearest, controlla margine dell atlas e allineamento della camera, quindi prova più risoluzioni.' },
31
+ ],
32
+ faqTitle: 'Domande sullo scaling degli sprite', faq, bibliographyTitle: 'Riferimenti sul pixel art', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };
@@ -0,0 +1,33 @@
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: 'ゲームのピクセルパーユニットとは何ですか?', answer: 'PPUは、ワールドの1単位を何個のテクスチャピクセルで表すかを示します。密度をそろえると、スプライト、タイル、カメラの大きさを予測しやすくなります。' },
8
+ { question: 'なぜ整数倍率が重要ですか?', answer: '整数倍率では、元の各ピクセルが画面上で同じ整数個のピクセルになります。小数倍率では輪郭が不均一になったり、ぼやけたりします。' },
9
+ { question: 'ピクセルブリーディングとは何ですか?', answer: '隣のテクセルやアトラス領域の色が意図せず混ざる現象です。フィルター、境界、サブピクセル移動、余白不足が原因になります。' },
10
+ { question: '推奨倍率はどう使いますか?', answer: '解像度に収まり、目標に近い候補として使います。その後、エンジンでnearestフィルター、カメラ位置、アトラスの余白を確認してください。' },
11
+ { question: 'どのエンジンでも正しいPPUを選べますか?', answer: 'いいえ。これは計算を確認する道具です。カメラ、インポート、ミップマップ、丸め、ピクセルスナップはエンジンごとに異なります。' },
12
+ ];
13
+ const howTo = [
14
+ { name: '対象画面を選ぶ', text: 'ゲーム画面または基準解像度の幅と高さをピクセルで入力します。' },
15
+ { name: 'スプライトを読み込む', text: '画像を選ぶと元のサイズを検出します。付属のBobサンプルも使えます。' },
16
+ { name: '倍率を選ぶ', text: 'スライダーまたはプリセットを使います。整数倍率が最も鮮明な候補です。' },
17
+ { name: 'プレビューを読む', text: 'スプライトの占有サイズ、横と縦のPPU、見えるワールド、ブリーディング警告を確認します。' },
18
+ { name: 'エンジンで試す', text: 'nearestフィルター、整列したカメラ、アトラス余白、実際の解像度で検証します。' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'ゲーム用ピクセルパーユニットプランナー', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'ピクセルアートのスプライト倍率を試す方法', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'game-pixel-per-unit-planner', title: 'ゲームスプライトのピクセルパーユニットプランナー', description: 'スプライトを読み込むかBobの例を使い、整数倍率での占有サイズを確認し、PPUとピクセルブリーディングのリスクを調べます。',
26
+ ui: {
27
+ inputsTitle: 'スプライトを読み込んで試す', uploadTitle: '元画像', uploadHint: 'PNG、GIF、WebP、JPEGを選びます。元のサイズがすべてのプレビューに使われます。', chooseSpriteLabel: 'スプライトを選ぶ', noSpriteLabel: 'スプライト未読み込み', defaultSpriteLabel: 'Bobのサンプルスプライト', loadedSpriteLabel: '読み込み済み', clearSpriteLabel: 'スプライトを削除', displayWidthLabel: '画面幅 px', displayHeightLabel: '画面高 px', spriteWidthLabel: 'スプライト幅 px', spriteHeightLabel: 'スプライト高 px', worldWidthLabel: 'スプライト幅 units', worldHeightLabel: 'スプライト高 units', targetScaleLabel: '画面上の目標倍率', targetScaleHint: 'テクスチャの1ピクセルあたりの画面ピクセル数。', resolutionPresetsLabel: '基準解像度', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'クイック倍率', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: '値をリセット', fieldTitle: '複数のサイズで見る', fieldCaption: '読み込んだ画像をnearest方式で描画し、整数倍率ごとの実際の占有サイズを確認します。', previewPlaceholder: 'スプライトを読み込んで視覚テストを開始', previewScaleLabel: 'プレビュー倍率', sourceImageAlt: '読み込んだスプライトのプレビュー', viewportLabel: '画面', spriteLabel: '描画スプライト', crispTitle: '鮮明な倍率', crispCaption: '整数倍率はピクセルを均一に保ちます。灰色の倍率は指定画面を超えます。', fitLabel: '画面に収まる:', yesLabel: 'はい', noLabel: 'いいえ', recommendedLabel: '最も近い候補', summaryTitle: '計画の概要', ppuXLabel: '横PPU', ppuYLabel: '縦PPU', viewportWorldLabel: '表示ワールド', fitScaleLabel: '収まる最大倍率', bleedingRiskLabel: 'ブリーディングリスク', lowRisk: '低', mediumRisk: '中', highRisk: '高', riskLowMessage: '軸がそろい、整数の目標倍率が画面に収まっています。それでもフィルターとアトラス余白を確認してください。', riskMediumMessage: '目標は完全には収まりません。軸の差と強調された倍率を確認してください。', riskHighMessage: 'この倍率は不均一なサンプリングを生む可能性があります。整数倍率と画像サイズを確認してください。', alignmentLabel: 'サンプリングメモ', tableTitle: 'アクセシブルな倍率一覧', tableScale: '倍率', tableWidth: '描画幅', tableHeight: '描画高', tableFits: '画面に収まる', modelNote: 'PPUは各軸の描画ピクセル数をワールド単位のサイズで割って計算します。ブリーディングリスクはヒューリスティックであり、テクスチャ検査やエンジンの保証ではありません。', privacyDisclosure: 'ファイルはこのブラウザー内で処理されます。画像、プロジェクト、テレメトリーは送信されません。', statusReady: 'プレビュー更新済み', unitPixels: 'px', unitUnits: 'units',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: 'スプライトの大きさを倍率の判断に変える' }, { type: 'paragraph', html: 'スプライトにはビットマップの大きさと、ゲーム世界で占める大きさがあります。PPUはこの2つをつなぎます。プレビューなら抽象的な数字だけでなく見た目を確認できます。' }, { type: 'paragraph', html: '実際の画像を読み込むと、元のサイズが使われます。選んだ倍率から各軸の占有サイズと、指定解像度で見えるワールドを計算します。' }, { type: 'title', level: 2, text: 'プレビューで確認すること' }, { type: 'list', items: ['占有サイズを基準画面と比べる。', '均一なピクセルのため整数倍率を先に試す。', '横と縦のPPUで意図しない伸縮を探す。', 'ブリーディング警告をエンジンテストの合図にする。'] }, { type: 'title', level: 2, text: '整数倍率がきれいに見える理由' }, { type: 'paragraph', html: '3倍なら元の1ピクセルが画面の3ピクセルになります。2.5倍では異なる幅を配分する必要があります。nearestは色の混合を防ぎますが、ピクセル間にあるカメラは直しません。' }, { type: 'table', headers: ['サイン', '意味', '次の判断'], rows: [['PPUが同じ', '両軸の密度が一致しています。', 'タイルとプロジェクトのグリッドを比べる。'], ['小数倍率', '占有サイズが整数でありません。', '最も近い整数倍率を試す。'], ['収まらない', 'スプライトが画面を超えます。', '倍率を下げるか解像度を上げる。']] }, { type: 'title', level: 2, text: 'ブリーディングと大きさを分けて考える' }, { type: 'paragraph', html: 'ピクセルブリーディングは、アトラスの隣接テクセル、境界のフィルター、ずれたカメラ座標から起きます。ぼやけるならフィルター、継ぎ目なら余白と境界も確認します。' }, { type: 'title', level: 2, text: 'Bobのスプライトで流れを学ぶ' }, { type: 'paragraph', html: 'ピンクのリボンを付けたBobが最初から表示されます。解像度と倍率を変え、キャラクターが収まらなくなる点やピクセルの不均一さを確認できます。' }, { type: 'title', level: 2, text: 'このツールが確認する範囲' }, { type: 'paragraph', html: '寸法と占有サイズを管理された表示で比較します。エンジンのプロジェクトやアトラスを検査せず、端末を測定せず、pixel perfectの動作も保証しません。' }, { type: 'title', level: 2, text: '倍率を選ぶ短い手順' }, { type: 'paragraph', html: 'スプライトを読み込み、解像度を選び、1倍から4倍を試します。余白を残す最大の整数倍率を選び、実際の対応解像度でも繰り返します。' }, { type: 'tip', title: '最後はエンジンで確認する', html: 'プレビューで候補を絞り、nearestフィルター、アトラス余白、カメラ位置を確認して、複数の解像度で動きを試してください。' },
31
+ ],
32
+ faqTitle: 'スプライト倍率の質問', faq, bibliographyTitle: 'ピクセルアートの参考資料', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };
@@ -0,0 +1,33 @@
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: '게임에서 단위당 픽셀이란 무엇인가요?', answer: '단위당 픽셀 또는 PPU는 월드의 한 단위를 몇 개의 텍스처 픽셀로 표현하는지 나타냅니다. 일관된 밀도는 스프라이트, 타일, 카메라의 크기를 예측하기 쉽게 합니다.' },
8
+ { question: '정수 배율이 중요한 이유는 무엇인가요?', answer: '정수 배율은 원본 픽셀마다 같은 수의 화면 픽셀을 배정합니다. 소수 배율은 가장자리를 고르지 않게 하거나 흐리게 만들 수 있습니다.' },
9
+ { question: '픽셀 블리딩이란 무엇인가요?', answer: '인접한 텍셀이나 아틀라스 영역의 색이 의도치 않게 나타나는 현상입니다. 필터, 경계, 서브픽셀 이동, 부족한 여백이 원인이 될 수 있습니다.' },
10
+ { question: '추천 배율은 어떻게 사용하나요?', answer: '해상도에 들어가고 목표에 가까운 후보로 사용하세요. 이후 엔진에서 nearest 필터, 카메라 위치, 아틀라스 여백을 확인하세요.' },
11
+ { question: '모든 엔진에 맞는 PPU를 선택해 주나요?', answer: '아니요. 이 도구는 계산을 확인하는 도구입니다. 카메라, 임포트, 밉맵, 반올림, 픽셀 스냅은 엔진마다 달라 실제 테스트가 필요합니다.' },
12
+ ];
13
+ const howTo = [
14
+ { name: '대상 화면 선택', text: '게임 화면이나 기준 해상도의 너비와 높이를 픽셀로 입력합니다.' },
15
+ { name: '스프라이트 불러오기', text: '이미지를 선택하면 원본 크기를 감지합니다. 포함된 Bob 샘플도 사용할 수 있습니다.' },
16
+ { name: '배율 선택', text: '슬라이더를 움직이거나 프리셋을 선택합니다. 정수 배율이 가장 선명한 후보입니다.' },
17
+ { name: '미리보기 읽기', text: '스프라이트 footprint, 가로와 세로 PPU, 보이는 월드, 블리딩 경고를 확인합니다.' },
18
+ { name: '엔진에서 테스트', text: 'nearest 필터, 정렬된 카메라, 아틀라스 여백, 실제 게임 해상도로 검증합니다.' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: '게임용 단위당 픽셀 플래너', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: '픽셀 아트 스프라이트 배율 테스트 방법', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'game-pixel-per-unit-planner', title: '게임 스프라이트 단위당 픽셀 플래너', description: '스프라이트를 올리거나 Bob 예제를 사용해 정수 배율별 footprint를 보고 PPU와 픽셀 블리딩 위험을 확인합니다.',
26
+ ui: {
27
+ inputsTitle: '스프라이트를 불러와 테스트', uploadTitle: '원본 이미지', uploadHint: 'PNG, GIF, WebP 또는 JPEG를 선택하세요. 원본 크기가 모든 미리보기에 사용됩니다.', chooseSpriteLabel: '스프라이트 선택', noSpriteLabel: '스프라이트가 아직 없음', defaultSpriteLabel: 'Bob 샘플 스프라이트', loadedSpriteLabel: '불러옴', clearSpriteLabel: '스프라이트 제거', displayWidthLabel: '화면 너비 px', displayHeightLabel: '화면 높이 px', spriteWidthLabel: '스프라이트 너비 px', spriteHeightLabel: '스프라이트 높이 px', worldWidthLabel: '월드 단위 너비', worldHeightLabel: '월드 단위 높이', targetScaleLabel: '화면 목표 배율', targetScaleHint: '텍스처 픽셀 하나가 차지하는 화면 픽셀 수입니다.', resolutionPresetsLabel: '기준 해상도', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: '빠른 배율', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: '값 초기화', fieldTitle: '여러 크기로 확인', fieldCaption: '불러온 이미지를 nearest 방식으로 렌더링해 정수 배율별 실제 footprint를 확인합니다.', previewPlaceholder: '스프라이트를 불러와 시각 테스트를 시작하세요', previewScaleLabel: '미리보기 배율', sourceImageAlt: '불러온 스프라이트 미리보기', viewportLabel: '화면', spriteLabel: '렌더링된 스프라이트', crispTitle: '선명한 배율', crispCaption: '정수 배율은 픽셀 크기를 일정하게 유지합니다. 회색 단계는 지정한 화면을 넘습니다.', fitLabel: '화면에 맞음:', yesLabel: '예', noLabel: '아니요', recommendedLabel: '가장 가까운 조합', summaryTitle: '계획 요약', ppuXLabel: '가로 PPU', ppuYLabel: '세로 PPU', viewportWorldLabel: '보이는 월드', fitScaleLabel: '맞는 최대 배율', bleedingRiskLabel: '블리딩 위험', lowRisk: '낮음', mediumRisk: '중간', highRisk: '높음', riskLowMessage: '축이 정렬되고 정수 목표 배율이 화면에 맞습니다. 그래도 필터와 아틀라스 여백을 확인하세요.', riskMediumMessage: '목표가 완벽하게 맞지 않습니다. 축 차이와 강조된 배율을 살펴보세요.', riskHighMessage: '이 배율은 불규칙한 샘플링을 만들 수 있습니다. 정수 배율과 스프라이트 크기를 확인하세요.', alignmentLabel: '샘플링 메모', tableTitle: '접근 가능한 배율 기록', tableScale: '배율', tableWidth: '렌더 너비', tableHeight: '렌더 높이', tableFits: '화면에 맞음', modelNote: 'PPU는 각 축에서 렌더링된 스프라이트 픽셀을 월드 단위 크기로 나누어 계산합니다. 블리딩 위험은 휴리스틱이며 텍스처 검사나 엔진 보장이 아닙니다.', privacyDisclosure: '파일은 이 브라우저에서 처리됩니다. 스프라이트, 프로젝트 파일, 텔레메트리는 전송되지 않습니다.', statusReady: '미리보기 업데이트됨', unitPixels: 'px', unitUnits: '단위',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: '스프라이트 크기를 배율 결정으로 바꾸기' }, { type: 'paragraph', html: '스프라이트에는 비트맵 크기와 게임 월드에서 차지하는 크기가 있습니다. PPU는 두 측정을 연결합니다. 미리보기는 추상적인 숫자 대신 실제 모습을 보여 줍니다.' }, { type: 'paragraph', html: '실제 이미지를 불러오면 원본 크기를 사용합니다. 선택한 배율로 두 축을 계산하고 지정한 해상도에서 보이는 월드를 구합니다.' }, { type: 'title', level: 2, text: '미리보기에서 볼 항목' }, { type: 'list', items: ['footprint를 기준 화면과 비교합니다.', '픽셀을 일정하게 유지하려면 정수 배율부터 시험합니다.', '두 PPU 값으로 의도하지 않은 늘어남을 찾습니다.', '블리딩 경고를 엔진 테스트 신호로 사용합니다.'] }, { type: 'title', level: 2, text: '정수 배율이 더 깨끗한 이유' }, { type: 'paragraph', html: '3배에서는 원본 픽셀 하나가 화면 픽셀 세 개가 됩니다. 2.5배에서는 렌더러가 서로 다른 너비를 배분해야 합니다. Nearest는 색 혼합은 막지만 픽셀 사이에 놓인 카메라는 고치지 못합니다.' }, { type: 'table', headers: ['신호', '의미', '다음 결정'], rows: [['같은 PPU', '두 축의 밀도가 같습니다.', '타일과 프로젝트 그리드와 비교합니다.'], ['소수 배율', 'footprint가 정수를 쓰지 않습니다.', '가장 가까운 정수 배율을 시험합니다.'], ['맞지 않음', '스프라이트가 화면을 넘습니다.', '배율을 낮추거나 해상도를 높입니다.']] }, { type: 'title', level: 2, text: '블리딩과 크기를 구분하기' }, { type: 'paragraph', html: '픽셀 블리딩은 아틀라스의 이웃 텍셀, 경계 필터, 정렬되지 않은 카메라 좌표에서 생기는 경우가 많습니다. 흐림에는 필터를, 이음새에는 여백과 경계를 확인하세요.' }, { type: 'title', level: 2, text: 'Bob 스프라이트로 흐름 익히기' }, { type: 'paragraph', html: '분홍색 리본을 단 Bob 예제가 처음부터 표시됩니다. 해상도와 배율을 바꾸며 캐릭터가 언제 맞지 않는지 확인할 수 있습니다.' }, { type: 'title', level: 2, text: '도구가 확인하는 것과 확인하지 않는 것' }, { type: 'paragraph', html: '도구는 통제된 화면에서 크기와 footprint를 비교합니다. 엔진 프로젝트나 아틀라스를 검사하지 않으며 장치나 pixel perfect 움직임을 보장하지 않습니다.' }, { type: 'title', level: 2, text: '배율을 고르는 짧은 순서' }, { type: 'paragraph', html: '스프라이트를 불러오고 해상도를 고른 뒤 1배부터 4배를 시험합니다. 여백이 남는 가장 큰 정수 배율을 실제 지원 해상도에서도 반복합니다.' }, { type: 'tip', title: '마지막 확인은 엔진에서 합니다', html: '미리보기로 후보를 좁힌 다음 nearest 필터, 아틀라스 여백, 카메라 정렬을 확인하고 여러 해상도에서 테스트하세요.' },
31
+ ],
32
+ faqTitle: '스프라이트 배율 질문', faq, bibliographyTitle: '픽셀 아트 참고 자료', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };
@@ -0,0 +1,33 @@
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: 'Wat betekent pixels per eenheid in een game?', answer: 'Pixels per eenheid, of PPU, geeft aan hoeveel textuurpixels één wereldeenheid voorstellen. Een vaste dichtheid houdt sprites, tegels en camera op een voorspelbare schaal.' },
8
+ { question: 'Waarom zijn gehele schalen belangrijk?', answer: 'Een gehele schaal geeft elke bronpixel hetzelfde gehele aantal schermpixels. Breukschalen kunnen ongelijke randen of onscherpte veroorzaken.' },
9
+ { question: 'Wat is pixel bleeding?', answer: 'Dat is ongewenste kleur van een naburige texel of een ander atlasgebied. Filtering, randen, subpixelbeweging en te weinig marge kunnen dit veroorzaken.' },
10
+ { question: 'Hoe gebruik ik de aanbevolen schaal?', answer: 'Gebruik haar als kandidaat die binnen de resolutie past en dicht bij je doel ligt. Controleer daarna nearest-filtering, camera-uitlijning en atlasmarge in de engine.' },
11
+ { question: 'Kiest de planner de juiste PPU voor elke engine?', answer: 'Nee. Dit is een transparante rekentool. Camera, import, mipmaps, afronding en pixel snapping verschillen per engine en moeten echt worden getest.' },
12
+ ];
13
+ const howTo = [
14
+ { name: 'Kies het doelbeeld', text: 'Voer de breedte en hoogte van de gameweergave of referentieresolutie in pixels in.' },
15
+ { name: 'Laad de sprite', text: 'Kies een afbeelding zodat de oorspronkelijke afmetingen worden gevonden. Je kunt ook de Bob-sprite gebruiken.' },
16
+ { name: 'Kies een schaal', text: 'Gebruik de schuifregelaar of een preset. Gehele vermenigvuldigers zijn de scherpste kandidaten.' },
17
+ { name: 'Lees de preview', text: 'Controleer de sprite-footprint, horizontale en verticale PPU, zichtbare wereld en bleeding-waarschuwing.' },
18
+ { name: 'Test in de engine', text: 'Controleer de keuze met nearest-filtering, een uitgelijnde camera, atlasmarge en echte spelresoluties.' },
19
+ ];
20
+ const softwareApplication: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: 'Planner voor pixels per eenheid in games', applicationCategory: 'DeveloperApplication', operatingSystem: 'Any' };
21
+ 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 } })) };
22
+ const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: 'Pixel-art-spriteschaling testen', step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) };
23
+
24
+ export const content: ToolLocaleContent<GamePixelPerUnitPlannerUI> = {
25
+ slug: 'pixels-per-eenheid-sprite-planner-games', title: 'Planner voor pixels per eenheid voor gamesprites', description: 'Upload een sprite of gebruik het Bob-voorbeeld om footprints op gehele schalen te bekijken, PPU te vergelijken en pixel bleeding te vinden.',
26
+ ui: {
27
+ inputsTitle: 'Laad en test je sprite', uploadTitle: 'Je bronafbeelding', uploadHint: 'Kies PNG, GIF, WebP of JPEG. De oorspronkelijke afmetingen sturen elke preview.', chooseSpriteLabel: 'Sprite kiezen', noSpriteLabel: 'Nog geen sprite geladen', defaultSpriteLabel: 'Bob-voorbeeldsprite', loadedSpriteLabel: 'Geladen', clearSpriteLabel: 'Sprite verwijderen', displayWidthLabel: 'Schermbreedte px', displayHeightLabel: 'Schermhoogte px', spriteWidthLabel: 'Spritebreedte px', spriteHeightLabel: 'Spritehoogte px', worldWidthLabel: 'Spritebreedte in eenheden', worldHeightLabel: 'Spritehoogte in eenheden', targetScaleLabel: 'Doelschaal op scherm', targetScaleHint: 'Schermpixels voor elke pixel van de textuur.', resolutionPresetsLabel: 'Referentieresoluties', preset320: '320 x 180', preset384: '384 x 216', preset640: '640 x 360', scalePresetsLabel: 'Snelle schalen', scale1: '1x', scale2: '2x', scale3: '3x', scale4: '4x', scale6: '6x', resetLabel: 'Waarden herstellen', fieldTitle: 'Bekijk in verschillende groottes', fieldCaption: 'De geladen afbeelding wordt met nearest-schaling weergegeven zodat je de echte footprint per gehele vermenigvuldiger kunt beoordelen.', previewPlaceholder: 'Laad een sprite om de visuele test te starten', previewScaleLabel: 'Preview-schaal', sourceImageAlt: 'Preview van geladen sprite', viewportLabel: 'Scherm', spriteLabel: 'Gerenderde sprite', crispTitle: 'Scherpe schalen', crispCaption: 'Gehele vermenigvuldigers houden pixels gelijk. Grijze stappen overschrijden het opgegeven scherm.', fitLabel: 'Past op scherm:', yesLabel: 'ja', noLabel: 'nee', recommendedLabel: 'dichtste passende', summaryTitle: 'Plansamenvatting', ppuXLabel: 'Horizontale PPU', ppuYLabel: 'Verticale PPU', viewportWorldLabel: 'Zichtbare wereld', fitScaleLabel: 'Grootste passende schaal', bleedingRiskLabel: 'Bleeding-risico', lowRisk: 'Laag', mediumRisk: 'Middel', highRisk: 'Hoog', riskLowMessage: 'De assen zijn uitgelijnd en de gehele doelschaal past op het scherm. Controleer toch filtering en atlasmarge.', riskMediumMessage: 'Het doel past niet perfect. Bekijk het verschil tussen de assen en de gemarkeerde schalen.', riskHighMessage: 'Deze schaal kan ongelijke sampling geven. Kies een gehele vermenigvuldiger en controleer de afmetingen.', alignmentLabel: 'Opmerking over sampling', tableTitle: 'Toegankelijk schaaloverzicht', tableScale: 'Schaal', tableWidth: 'Gerenderde breedte', tableHeight: 'Gerenderde hoogte', tableFits: 'Past op scherm', modelNote: 'PPU wordt berekend als gerenderde spritepixels gedeeld door de spritegrootte in eenheden per as. Bleeding-risico is een heuristiek, geen textuurcontrole of enginegarantie.', privacyDisclosure: 'Het bestand wordt in deze browser verwerkt. Sprites, projectbestanden en telemetrie worden niet verzonden.', statusReady: 'Preview bijgewerkt', unitPixels: 'px', unitUnits: 'eenheden',
28
+ },
29
+ seo: [
30
+ { type: 'title', level: 2, text: 'Maak van spritegrootte een schaalbeslissing' }, { type: 'paragraph', html: 'Een sprite heeft de bitmapgrootte en de grootte die hij in de spelwereld inneemt. PPU verbindt die maten. De preview toont het visuele gevolg in plaats van alleen een abstract getal.' }, { type: 'paragraph', html: 'Laad een echte afbeelding zodat de oorspronkelijke maten worden gebruikt. De tool vermenigvuldigt beide assen met de gekozen schaal en berekent de zichtbare wereld.' }, { type: 'title', level: 2, text: 'Wat je in de preview bekijkt' }, { type: 'list', items: ['Vergelijk de footprint met het referentiescherm.', 'Test gehele schalen eerst voor gelijkmatige pixels.', 'Gebruik beide PPU-waarden om onbedoeld uitrekken te vinden.', 'Zie de bleeding-waarschuwing als signaal voor een enginetest.'] }, { type: 'title', level: 2, text: 'Waarom gehele schalen vaak schoner zijn' }, { type: 'paragraph', html: 'Bij 3x neemt elke bronpixel drie schermpixels in. Bij 2,5x moet de renderer verschillende breedtes verdelen. Nearest voorkomt kleurmenging, maar corrigeert geen camera tussen pixelposities.' }, { type: 'table', headers: ['Signaal', 'Betekenis', 'Volgende keuze'], rows: [['Gelijke PPU', 'Beide assen hebben dezelfde dichtheid.', 'Vergelijk met tegels en projectraster.'], ['Breukschaal', 'De footprint gebruikt geen geheel getal.', 'Test de dichtstbijzijnde gehele schaal.'], ['Past niet', 'De sprite overschrijdt het scherm.', 'Verlaag de schaal of verhoog de resolutie.']] }, { type: 'title', level: 2, text: 'Bleeding onderscheiden van grootte' }, { type: 'paragraph', html: 'Pixel bleeding komt vaak door naburige texels in een atlas, filtering aan randen of niet-uitgelijnde cameracoördinaten. Controleer bij onscherpte de filter en bij naden ook marge en grenzen.' }, { type: 'title', level: 2, text: 'Leer de werkwijze met de Bob-sprite' }, { type: 'paragraph', html: 'Het voorbeeld van Bob met de roze strik staat meteen klaar. Verander resolutie en schaal om te zien wanneer het personage niet meer past of pixels ongelijk worden.' }, { type: 'title', level: 2, text: 'Wat deze tool wel en niet controleert' }, { type: 'paragraph', html: 'De tool vergelijkt maten en footprints in een gecontroleerde weergave. Hij opent geen engineproject, inspecteert geen atlas, meet geen apparaat en garandeert geen pixel-perfecte beweging.' }, { type: 'title', level: 2, text: 'Een korte route naar een schaal' }, { type: 'paragraph', html: 'Laad de sprite, kies de resolutie, test 1x tot 4x en kies de grootste gehele schaal met ruimte over. Herhaal dit voor de echte spelresoluties.' }, { type: 'tip', title: 'De laatste controle gebeurt in de engine', html: 'Gebruik de preview om de keuze te beperken. Activeer daarna nearest-filtering, controleer atlasmarge en camera-uitlijning en test meerdere resoluties.' },
31
+ ],
32
+ faqTitle: 'Vragen over spriteschaling', faq, bibliographyTitle: 'Bronnen over pixel art', bibliography: bibliographyEntries, howTo, schemas: [softwareApplication, faqPage, howToSchema],
33
+ };