Skip to main content

spatial-calculation-ui-layout

Spatial calculation helpers and UI layout patterns for Phaser games and web applications. Use when positioning UI elements, calculating text widths, or working with coordinate systems. Reduces UI positioning iterations from 3-5 to 1-2 by providing calculation patterns and common gotchas.

Datos de origen

Repositorio
pmarashian/cursor-agent-skills
Última actividad en el origen
13 de febrero de 2026 a las 19:51
Idioma detectado de SKILL.md
inglés
Estrellas
2
Forks
1

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
spatial-calculation-ui-layout
description
Spatial calculation helpers and UI layout patterns for Phaser games and web applications. Use when positioning UI elements, calculating text widths, or working with coordinate systems. Reduces UI positioning iterations from 3-5 to 1-2 by providing calculation patterns and common gotchas.
# Spatial Calculation and UI Layout Spatial calculation helpers and UI layout patterns to reduce UI positioning iterations from 3-5 to 1-2. Provides coordinate system documentation, text width measurement utilities, and layout calculation patterns. ## Overview **Problem**: UI positioning tasks require 3-5 iterations due to spatial calculation challenges. Agents struggle with coordinate systems, text width calculations, and layout positioning. **Solution**: Coordinate system documentation, text width measurement utilities, layout calculation patterns, and common gotchas. **Impact**: Reduces UI positioning iterations from 3-5 to 1-2, saves 2-3 minutes per UI layout task, improves first-attempt success rate ## Coordinate System Documentation ### World Coordinates vs Screen Coordinates **Understanding coordinate systems is critical for UI positioning tasks.** **World Coordinates**: - Game world space (e.g., 800x600 game world) - Camera-independent (objects exist in world space) - Used for game objects, sprites, physics bodies - Example: `sprite.x = 400` (400 pixels from world origin) **Screen Coordinates**: - Viewport/camera space (what player sees) - Camera-dependent (changes with camera scroll) - Used for UI elements, HUD, overlays - Example: `ui.x = 400` (400 pixels from screen edge, camera-independent) **Key Difference**: ```typescript // World coordinates (game object) sprite.x = 400; // 400 pixels in world space // Screen coordinates (UI element) ui.x = 400; // 400 pixels from screen edge (camera-independent) ``` ### Framework-Specific Coordinate Systems **Phaser 3**: - World coordinates: `sprite.x`, `sprite.y` (in world space) - Screen coordinates: `ui.x`, `ui.y` (camera-independent) - Camera scroll: `this.cameras.main.scrollX`, `this.cameras.main.scrollY` **React**: - Screen coordinates: `style.left`, `style.top` (relative to viewport) - Container coordinates: Relative to parent container **Canvas/WebGL**: - World coordinates: Canvas drawing coordinates - Screen coordinates: Viewport-relative coordinates ### Camera Scroll Offset Handling **When calculating positions, account for camera scroll**: ```typescript // ❌ WRONG: Not accounting for camera scroll const worldX = 400; sprite.x = worldX; // May be off-screen if camera scrolled // ✅ CORRECT: Account for camera scroll const cameraX = this.cameras.main.scrollX; const worldX = 400; sprite.x = cameraX + worldX; // Correct position relative to camera ``` **For UI Elements (Screen Coordinates)**: ```typescript // UI elements use screen coordinates (camera-independent) ui.x = 400; // Always 400 pixels from screen edge, regardless of camera ``` ## Text Width Measurement Utilities ### Measure Text Width Before Positioning **Always measure text width before calculating positions**: ```typescript // ❌ WRONG: Assuming fixed width text.x = 400; // May not be centered if text width varies // ✅ CORRECT: Calculate based on actual width const textWidth = text.width; const screenWidth = this.cameras.main.width; const centerX = (screenWidth - textWidth) / 2; text.x = centerX; ``` ### Text Width Measurement Patterns **Pattern 1: Measure Existing Text** ```typescript // Measure text that's already created const textWidth = text.width; const textHeight = text.height; ``` **Pattern 2: Measure Text Before Creation** ```typescript // Create temporary text to measure const tempText = this.add.text(0, 0, "Score: 100", style); const textWidth = tempText.width; const textHeight = tempText.height; tempText.destroy(); // Clean up temporary text // Use measurements for positioning const centerX = (screenWidth - textWidth) / 2; text.x = centerX; ``` **Pattern 3: Measure Text with Different Content** ```typescript // Measure text with longest expected content const longestText = "Score: 999999"; const tempText = this.add.text(0, 0, longestText, style); const maxWidth = tempText.width; tempText.destroy(); // Use max width for layout const centerX = (screenWidth - maxWidth) / 2; ``` ### Framework-Specific Text Measurement **Phaser 3**: ```typescript const text = this.add.text(0, 0, "Text", style); const width = text.width; const height = text.height; ``` **Canvas**: ```typescript const ctx = canvas.getContext('2d'); ctx.font = '16px Arial'; const width = ctx.measureText("Text").width; ``` **React**: ```typescript const textRef = useRef<HTMLDivElement>(null); const width = textRef.current?.offsetWidth || 0; ``` ## Layout Calculation Patterns ### Pattern 1: Center Text on Screen ```typescript // Calculate text width first const textWidth = text.width; const screenWidth = this.cameras.main.width; const centerX = (screenWidth - textWidth) / 2; text.x = centerX; // Center text horizontally ``` **Common Mistake**: Not accounting for text width ```typescript // ❌ WRONG: Assuming text is centered at screenWidth / 2 text.x = screenWidth / 2; // Text starts at center, not centered // ✅ CORRECT: Account for text width text.x = (screenWidth - text.width) / 2; // Text is centered ``` ### Pattern 2: Position Relative to Another Object ```typescript // Position button below text const textBottom = text.y + text.height; const spacing = 20; button.y = textBottom + spacing; ``` **Common Mistake**: Not accounting for object height ```typescript // ❌ WRONG: Assuming objects align at same y button.y = text.y; // Button overlaps text // ✅ CORRECT: Account for text height button.y = text.y + text.height + spacing; ``` ### Pattern 3: Account for Origin ```typescript // Sprite origin affects position calculation sprite.setOrigin(0.5, 0.5); // Center origin sprite.x = 400; // Center of sprite at x=400 // If origin is (0, 0), sprite.x is top-left corner sprite.setOrigin(0, 0); sprite.x = 400; // Top-left corner at x=400 ``` **Common Mistake**: Not accounting for origin ```typescript // ❌ WRONG: Assuming origin is (0, 0) sprite.x = 400; // May not be where expected if origin is (0.5, 0.5) // ✅ CORRECT: Account for origin sprite.setOrigin(0.5, 0.5); sprite.x = 400; // Center of sprite at x=400 ``` ### Pattern 4: Layout with Spacing ```typescript // Layout multiple elements with consistent spacing const elements = [text1, text2, text3]; const spacing = 20; let currentY = 100; elements.forEach(element => { element.y = currentY; currentY += element.height + spacing; }); ``` ### Pattern 5: Responsive Layout ```typescript // Responsive layout based on screen size const screenWidth = this.cameras.main.width; const screenHeight = this.cameras.main.height; // Center horizontally text.x = (screenWidth - text.width) / 2; // Position from bottom const bottomMargin = 50; text.y = screenHeight - text.height - bottomMargin; ``` ## Common Positioning Gotchas ### Gotcha 1: Not Accounting for Text Width ```typescript // ❌ WRONG: Assuming fixed width text.x = 400; // May not be centered if text width varies // ✅ CORRECT: Calculate based on actual width const textWidth = text.width; const centerX = (screenWidth - textWidth) / 2; text.x = centerX; ``` ### Gotcha 2: Confusing World vs Screen Coordinates ```typescript // ❌ WRONG: Using world coordinates for UI ui.x = sprite.x; // UI will move with camera scroll // ✅ CORRECT: Use screen coordinates for UI ui.x = 400; // UI stays fixed on screen ``` ### Gotcha 3: Not Considering Sprite Origin Offsets ```typescript // ❌ WRONG: Assuming origin is (0, 0) sprite.x = 100; // May not be where expected if origin is (0.5, 0.5) // ✅ CORRECT: Account for origin sprite.setOrigin(0.5, 0.5); sprite.x = 100; // Center of sprite at x=100 ``` ### Gotcha 4: Not Accounting for Object Height ```typescript // ❌ WRONG: Assuming objects align at same y button.y = text.y; // Button overlaps text // ✅ CORRECT: Account for text height button.y = text.y + text.height + spacing; ``` ### Gotcha 5: Assuming HMR Has Applied Changes ```typescript // ❌ WRONG: Assuming changes are applied immediately makeCodeChange(); captureScreenshot(); // May capture stale state // ✅ CORRECT: Verify HMR has applied changes makeCodeChange(); waitForHMR(); // Wait for HMR to apply captureScreenshot(); // Now captures updated state ``` ## Visual Debugging Techniques ### Technique 1: Programmatic Verification **Verify calculations programmatically before visual verification**: ```typescript // Calculate position const centerX = (screenWidth - text.width) / 2; text.x = centerX; // Verify calculation const expectedX = (screenWidth - text.width) / 2; console.log(`Text x: ${text.x}, Expected: ${expectedX}`); if (Math.abs(text.x - expectedX) < 1) { console.log('Position correct'); } else { console.log('Position incorrect'); } ``` ### Technique 2: Test Seam Verification **Use test seam commands to verify positions**: ```bash # Verify text position via test seam agent-browser eval "window.__TEST__?.getCurrentScene()?.texts?.score?.x" agent-browser eval "window.__TEST__?.getCurrentScene()?.texts?.score?.y" ``` ### Technique 3: Visual Markers **Add visual markers for debugging**: ```typescript // Add visual marker at expected position const marker = this.add.rectangle(centerX, 300, 5, 5, 0xff0000); // Text should be centered at marker ``` ## Examples of Successful Layout Calculations ### Example 1: Centered Score Display ```typescript // Calculate text width first const scoreText = "Score: 100"; const text = this.add.text(0, 0, scoreText, style); const textWidth = text.width; const screenWidth = this.cameras.main.width; // Center text horizontally const centerX = (screenWidth - textWidth) / 2; text.x = centerX; // Position from top with margin const topMargin = 50; text.y = topMargin; ``` **Key Points**: - Calculate text width before positioning - Account for screen width (not world width) - Use spacing constants for consistency ### Example 2: Button Below Text ```typescript // Position text first const text = this.add.text(100, 100, "Click Me", textStyle); const textBottom = text.y + text.height; // Position button below text with spacing const spacing = 20; const button = this.add.rectangle(100, textBottom + spacing, 200, 50, 0x00ff00); ``` **Key Points**: - Calculate text bottom position - Add spacing between elements - Align horizontally (same x for text and button) ### Example 3: Responsive Bottom Bar ```typescript // Get screen dimensions const screenWidth = this.cameras.main.width; const screenHeight = this.cameras.main.height; // Create bottom bar const barHeight = 60; const bar = this.add.rectangle( screenWidth / 2, // Center horizontally screenHeight - barHeight / 2, // Position from bottom screenWidth, // Full width barHeight, 0x000000 ); // Add text on bar const text = this.add.text(0, 0, "Game Over", textStyle); text.x = (screenWidth - text.width) / 2; // Center text text.y = screenHeight - barHeight / 2 - text.height / 2; // Center vertically on bar ``` **Key Points**: - Use screen dimensions for responsive layout - Calculate center positions - Account for object dimensions ## Programmatic Verification Patterns ### Pattern 1: Verify Before Visual Check **Verify calculations programmatically before capturing screenshots**: ```typescript // Calculate position const centerX = (screenWidth - text.width) / 2; text.x = centerX; // Verify calculation const isCentered = Math.abs(text.x - centerX) < 1; if (!isCentered) { console.error('Text not centered'); // Fix calculation before proceeding } // Only capture screenshot after verification agent-browser screenshot screenshots/verification.png; ``` ### Pattern 2: Test Seam Position Verification **Use test seam to verify positions**: ```bash # Verify text position agent-browser eval " const scene = window.__TEST__?.getCurrentScene(); const text = scene?.texts?.score; if (text) { const screenWidth = scene.cameras.main.width; const expectedX = (screenWidth - text.width) / 2; Math.abs(text.x - expectedX) < 1 ? 'Centered' : 'Not centered' } else { 'Text not found' } " ``` ### Pattern 3: Calculation Validation **Validate calculations before applying**: ```typescript // Validate calculation function validateCenterPosition(text: Phaser.GameObjects.Text, screenWidth: number): boolean { const expectedX = (screenWidth - text.width) / 2; const actualX = text.x; const tolerance = 1; // 1 pixel tolerance return Math.abs(actualX - expectedX) < tolerance; } // Use validation if (!validateCenterPosition(text, screenWidth)) { console.error('Position calculation incorrect'); // Recalculate }
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub