Discusión

Flujo Gravitacional: Juego de Evasión de Vuelo Basado en Física

De Wikiprompt, la enciclopedia libre de prompts

loshu2000
Contribuido porloshu2000Fuente

17 may 2026

Flujo Gravitacional: Juego de Evasión de Vuelo Basado en Física Un prompt detallado para generar un juego HTML de un solo archivo con jugabilidad basada en física, obstáculos Bezier procedimentales, síntesis de Web Audio y una estética pastel zen.

Contenido del PromptGuardar

🌐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Gravity Flux</title> <style> body { margin: 0; overflow: hidden; background: #1a1a2e; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } canvas { display: block; margin: 0 auto; background: #1a1a2e; } #ui { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: #e0e0e0; font-size: 18px; text-align: center; pointer-events: none; text-shadow: 0 0 10px rgba(0,0,0,0.5); } #score { font-size: 24px; font-weight: bold; color: #f0e6d3; } #instructions { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); color: #b0a8a0; font-size: 14px; text-align: center; pointer-events: none; opacity: 0.7; } </style> </head> <body> <div id="ui"> <div>Gravity Flux</div> <div id="score">0</div> </div> <div id="instructions">Click or tap to start - Navigate through the gates</div> <canvas id="gameCanvas"></canvas> <script> // Audio context and synthesis let audioCtx = null; let pulseInterval = null; let isPlaying = false; function initAudio() { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } if (audioCtx.state === 'suspended') { audioCtx.resume(); } } function playPulse() { if (!audioCtx) return; const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(80 + Math.random() * 40, audioCtx.currentTime); gain.gain.setValueAtTime(0.08, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.3); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 0.3); } function playSweep() { if (!audioCtx) return; const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(200, audioCtx.currentTime); osc.frequency.exponentialRampToValueAtTime(600, audioCtx.currentTime + 0.2); gain.gain.setValueAtTime(0.15, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.3); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 0.3); } function startPulse() { if (pulseInterval) clearInterval(pulseInterval); pulseInterval = setInterval(() => { if (isPlaying) playPulse(); }, 800); } // Canvas setup const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); let W, H; function resizeCanvas() { W = canvas.width = window.innerWidth; H = canvas.height = window.innerHeight; } resizeCanvas(); window.addEventListener('resize', resizeCanvas); // Game state let score = 0; let gameOver = false; let gameStarted = false; // Player (soft-body sphere) const player = { x: W / 2, y: H / 2, radius: 20, vx: 0, vy: 0, targetRadius: 20, currentRadius: 20, inflation: 0, // Soft body deformation deformX: 0, deformY: 0, deformSpeed: 0.02 }; // Gates let gates = []; const GATE_WIDTH = 120; const GATE_HEIGHT_MIN = 80; const GATE_HEIGHT_MAX = 180; const GATE_SPEED = 1.2; const GATE_SPAWN_INTERVAL = 120; // frames let frameCount = 0; // Gate class with Bezier curves class Gate { constructor(x, y, height, direction) { this.x = x; this.y = y; this.height = height; this.direction = direction; // 1 for down, -1 for up this.passed = false; this.time = Math.random() * Math.PI * 2; this.morphSpeed = 0.02 + Math.random() * 0.02; this.amplitude = 15 + Math.random() * 20; this.phase = Math.random() * Math.PI * 2; } update() { this.x -= GATE_SPEED; this.time += this.morphSpeed; // Organic morphing using sine waves const morph = Math.sin(this.time) * this.amplitude; this.currentHeight = this.height + morph; // Ensure minimum height if (this.currentHeight < 40) this.currentHeight = 40; } draw(ctx) { const halfH = this.currentHeight / 2; const centerY = this.y; const topY = centerY - halfH; const bottomY = centerY + halfH; const leftX = this.x - GATE_WIDTH / 2; const rightX = this.x + GATE_WIDTH / 2; // Draw organic Bezier curves for the gate boundaries ctx.save(); ctx.shadowColor = 'rgba(200, 180, 160, 0.3)'; ctx.shadowBlur = 20; ctx.strokeStyle = '#d4c5b0'; ctx.lineWidth = 3; ctx.globalAlpha = 0.8; // Top curve (upper boundary) ctx.beginPath(); ctx.moveTo(leftX, topY); const cp1x = leftX + GATE_WIDTH * 0.3; const cp1y = topY - Math.sin(this.time * 0.5 + this.phase) * 10; const cp2x = rightX - GATE_WIDTH * 0.3; const cp2y = topY + Math.cos(this.time * 0.7 + this.phase) * 10; ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, rightX, topY); ctx.stroke(); // Bottom curve (lower boundary) ctx.beginPath(); ctx.moveTo(leftX, bottomY); const cp3x = leftX + GATE_WIDTH * 0.3; const cp3y = bottomY + Math.sin(this.time * 0.6 + this.phase + 1) * 10; const cp4x = rightX - GATE_WIDTH * 0.3; const cp4y = bottomY - Math.cos(this.time * 0.8 + this.phase + 1) * 10; ctx.bezierCurveTo(cp3x, cp3y, cp4x, cp4y, rightX, bottomY); ctx.stroke(); // Side connectors (organic) ctx.beginPath(); ctx.moveTo(leftX, topY); ctx.lineTo(leftX, bottomY); ctx.stroke(); ctx.beginPath(); ctx.moveTo(rightX, topY); ctx.lineTo(rightX, bottomY); ctx.stroke(); ctx.restore(); // Store gate bounds for collision (simplified as rectangle with morph) this.topBound = topY; this.bottomBound = bottomY; this.leftBound = leftX; this.rightBound = rightX; } isOffScreen() { return this.x + GATE_WIDTH / 2 < 0; } checkCollision(px, py, pr) { // Check if player is within gate horizontal bounds if (px + pr > this.leftBound && px - pr < this.rightBound) { // Check vertical bounds if (py - pr < this.topBound || py + pr > this.bottomBound) { return true; // collision with gate boundary } } return false; } checkPassed(px, pr) { if (!this.passed && px - pr > this.rightBound) { this.passed = true; return true; } return false; } } // Initialize game function initGame() { score = 0; gameOver = false; gameStarted = true; gates = []; frameCount = 0; player.x = W / 2; player.y = H / 2; player.vx = 0; player.vy = 0; player.currentRadius = 20; player.targetRadius = 20; player.inflation = 0; document.getElementById('score').textContent = '0'; // Start audio pulse if (audioCtx) { isPlaying = true; startPulse(); } } // Spawn a new gate function spawnGate() { const height = GATE_HEIGHT_MIN + Math.random() * (GATE_HEIGHT_MAX - GATE_HEIGHT_MIN); const y = 100 + Math.random() * (H - 200); const direction = Math.random() > 0.5 ? 1 : -1; gates.push(new Gate(W + 50, y, height, direction)); } // Update player physics (soft body) function updatePlayer() { // Gravity (gentle) player.vy += 0.05; // Damping player.vx *= 0.98; player.vy *= 0.98; // Update position player.x += player.vx; player.y += player.vy; // Soft body inflation/deflation based on vertical speed const speed = Math.abs(player.vy); player.targetRadius = 20 + speed * 0.5; if (player.targetRadius > 35) player.targetRadius = 35; if (player.targetRadius < 15) player.targetRadius = 15; // Smooth radius transition player.currentRadius += (player.targetRadius - player.currentRadius) * 0.1; // Deformation based on movement player.deformX = Math.sin(Date.now() * 0.003) * 2; player.deformY = Math.cos(Date.now() * 0.002) * 2; // Keep player on screen (with soft boundaries) if (player.y - player.currentRadius < 10) { player.y = player.currentRadius + 10; player.vy = 0; } if (player.y + player.currentRadius > H - 10) { player.y = H - player.currentRadius - 10; player.vy = 0; } if (player.x - player.currentRadius < 10) { player.x = player.currentRadius + 10; player.vx = 0; } if (player.x + player.currentRadius > W - 10) { player.x = W - player.currentRadius - 10; player.vx = 0; } } // Draw player as soft-body sphere function drawPlayer() { ctx.save(); ctx.shadowColor = 'rgba(200, 180, 160, 0.4)'; ctx.shadowBlur = 30; // Draw soft body with deformation const r = player.currentRadius; const deformX = player.deformX; const deformY = player.deformY; // Create gradient for soft look const gradient = ctx.createRadialGradient( player.x - r * 0.3, player.y - r * 0.3, r * 0.1, player.x, player.y, r ); gradient.addColorStop(0, '#f0e6d3'); gradient.addColorStop(0.5, '#d4c5b0'); gradient.addColorStop(1, '#b0a090'); ctx.beginPath(); // Draw deformed circle using bezier curves const points = 12; const angleStep = (Math.PI * 2) / points; for (let i = 0; i <= points; i++) { const angle = i * angleStep; const rad = r + Math.sin(angle * 2 + Date.now() * 0.002) * 3 + Math.cos(angle * 3 + Date.now() * 0.001) * 2; const x = player.x + Math.cos(angle) * rad + deformX; const y = player.y + Math.sin(angle) * rad + deformY; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.closePath(); ctx.fillStyle = gradient; ctx.fill(); ctx.strokeStyle = '#c0b0a0'; ctx.lineWidth = 1.5; ctx.stroke(); ctx.restore(); } // Draw background elements (ambient) function drawBackground() { ctx.save(); ctx.globalAlpha = 0.1; ctx.fillStyle = '#d4c5b0'; // Draw subtle floating particles for (let i = 0; i < 20; i++) { const x = (Math.sin(Date.now() * 0.0005 + i * 100) * 0.5 + 0.5) * W; const y = (Math.cos(Date.now() * 0.0003 + i * 50) * 0.5 + 0.5) * H; const size = 2 + Math.sin(Date.now() * 0.001 + i) * 1; ctx.beginPath(); ctx.arc(x, y, size, 0, Math.PI * 2); ctx.fill(); } ctx.restore(); } // Game loop function gameLoop() { if (!gameStarted) { // Draw start screen ctx.clearRect(0, 0, W, H); drawBackground(); ctx.fillStyle = '#f0e6d3'; ctx.font = '48px Segoe UI, sans-serif'; ctx.textAlign = 'center'; ctx.fillText('Gravity Flux', W/2, H/2 - 40); ctx.font = '20px Segoe UI, sans-serif'; ctx.fillText('Click or tap to start', W/2, H/2 + 20); requestAnimationFrame(gameLoop); return; } if (gameOver) { // Draw game over screen ctx.clearRect(0, 0, W, H); drawBackground(); ctx.fillStyle = '#f0e6d3'; ctx.font = '48px Segoe UI, sans-serif'; ctx.textAlign = 'center'; ctx.fillText('Game Over', W/2, H/2 - 40); ctx.font = '24px Segoe UI, sans-serif'; ctx.fillText('Score: ' + score, W/2, H/2 + 10); ctx.font = '18px Segoe UI, sans-serif'; ctx.fillText('Click to restart', W/2, H/2 + 50); requestAnimationFrame(gameLoop); return; } // Update frameCount++; if (frameCount % GATE_SPAWN_INTERVAL === 0) { spawnGate(); } // Update gates for (let i = gates.length - 1; i >= 0; i--) { gates[i].update(); if (gates[i].isOffScreen()) { gates.splice(i, 1); } } // Update player updatePlayer(); // Check collisions and scoring for (let i = 0; i < gates.length; i++) { const gate = gates[i]; // Collision check if (gate.checkCollision(player.x, player.y, player.currentRadius)) { gameOver = true; isPlaying = false; if (pulseInterval) clearInterval(pulseInterval); break; } // Score check if (gate.checkPassed(player.x, player.currentRadius)) { score++; document.getElementById('score').textContent = score; playSweep(); } } // Draw everything ctx.clearRect(0, 0, W, H); drawBackground(); // Draw gates for (const gate of gates) { gate.draw(ctx); } // Draw player drawPlayer(); // Draw ambient glow ctx.save(); ctx.shadowColor = 'rgba(200, 180, 160, 0.1)'; ctx.shadowBlur = 50; ctx.fillStyle = 'transparent'; ctx.fillRect(0, 0, W, H); ctx.restore(); requestAnimationFrame(gameLoop); } // Input handling canvas.addEventListener('click', (e) => { initAudio(); if (!gameStarted || gameOver) { initGame(); return; } // Apply impulse to player (upward) player.vy = -3; player.vx += (e.clientX - player.x) * 0.02; }); canvas.addEventListener('touchstart', (e) => { e.preventDefault(); initAudio(); const touch = e.touches[0]; if (!gameStarted || gameOver) { initGame(); return; } player.vy = -3; player.vx += (touch.clientX - player.x) * 0.02; }); // Keyboard support document.addEventListener('keydown', (e) => { if (e.key === ' ' || e.key === 'ArrowUp') { e.preventDefault(); initAudio(); if (!gameStarted || gameOver) { initGame(); return; } player.vy = -3; } if (e.key === 'ArrowLeft') { player.vx = -2; } if (e.key === 'ArrowRight') { player.vx = 2; } }); // Start game loop gameLoop(); </script> </body> </html>

Iniciá sesión para ver el prompt completo

Continuar con:

Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad

Uso

Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.

Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.

Referencias

Categorías:coding| prompts.chat| game-development| physics-engine

Discusión