Discusión

Juego 3D de Angry Birds con Three.js

De Wikiprompt, la enciclopedia libre de prompts

Tim Jayas
Contribuido porTim JayasXFuente

14 ago 2026

Juego 3D de Angry Birds con Three.js Una solicitud de desarrollo de juego de un solo prompt para crear un juego 3D estilo Angry Birds usando three.js o HTML, con un fondo blanco para claridad.

Medios relacionados

Contenido del PromptGuardar

🌐
I'll create a complete Angry Birds-style physics game using Three.js with a clean white background. This will be a single HTML file with everything included. ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Angry Birds Style Game - Three.js</title> <style> body { margin: 0; overflow: hidden; font-family: Arial, sans-serif; background-color: #ffffff; } #info { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); color: #333; font-size: 18px; background: rgba(255,255,255,0.9); padding: 10px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 100; text-align: center; } #score { position: absolute; top: 10px; right: 20px; color: #333; font-size: 20px; font-weight: bold; background: rgba(255,255,255,0.9); padding: 10px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 100; } #controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); color: #555; font-size: 14px; background: rgba(255,255,255,0.9); padding: 8px 16px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 100; text-align: center; } #restart { position: absolute; top: 10px; left: 20px; color: #fff; font-size: 16px; background: #e74c3c; padding: 10px 20px; border-radius: 8px; border: none; cursor: pointer; z-index: 100; box-shadow: 0 2px 10px rgba(0,0,0,0.2); } #restart:hover { background: #c0392b; } canvas { display: block; } </style> </head> <body> <div id="info">🎯 Drag to aim and release to launch!</div> <div id="score">Score: <span id="scoreValue">0</span></div> <button id="restart">🔄 Restart</button> <div id="controls">Mouse: Drag from bird to aim | Release to launch</div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script> <script src="https://cdn.jsdelivr.net/npm/cannon@0.6.2/dist/cannon.min.js"></script> <script> // ====== GAME SETUP ====== const scene = new THREE.Scene(); scene.background = new THREE.Color(0xffffff); // White background const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 8, 15); camera.lookAt(0, 2, 0); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); // ====== PHYSICS WORLD ====== const world = new CANNON.World(); world.gravity.set(0, -9.82, 0); world.broadphase = new CANNON.NaiveBroadphase(); world.defaultContactMaterial.friction = 0.5; world.defaultContactMaterial.restitution = 0.3; // ====== LIGHTING ====== const ambientLight = new THREE.AmbientLight(0x404040, 0.6); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(5, 10, 7); directionalLight.castShadow = true; directionalLight.shadow.mapSize.width = 1024; directionalLight.shadow.mapSize.height = 1024; scene.add(directionalLight); const fillLight = new THREE.DirectionalLight(0xffffff, 0.3); fillLight.position.set(-5, 3, -5); scene.add(fillLight); // ====== GROUND ====== const groundGeo = new THREE.PlaneGeometry(30, 30); const groundMat = new THREE.MeshStandardMaterial({ color: 0xcccccc, roughness: 0.8 }); const groundMesh = new THREE.Mesh(groundGeo, groundMat); groundMesh.rotation.x = -Math.PI / 2; groundMesh.position.y = 0; groundMesh.receiveShadow = true; scene.add(groundMesh); // Physics ground const groundBody = new CANNON.Body({ mass: 0, shape: new CANNON.Plane() }); groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2); world.addBody(groundBody); // ====== GAME OBJECTS ====== const objects = []; const physicsBodies = []; // Helper to create physics-linked objects function createPhysicsObject(geometry, material, position, mass = 1, isStatic = false) { const mesh = new THREE.Mesh(geometry, material); mesh.castShadow = true; mesh.receiveShadow = true; mesh.position.copy(position); scene.add(mesh); // Create physics body let shape; if (geometry.type === 'BoxGeometry') { shape = new CANNON.Box(new CANNON.Vec3( geometry.parameters.width / 2, geometry.parameters.height / 2, geometry.parameters.depth / 2 )); } else if (geometry.type === 'SphereGeometry') { shape = new CANNON.Sphere(geometry.parameters.radius); } else if (geometry.type === 'CylinderGeometry') { shape = new CANNON.Cylinder( geometry.parameters.radiusTop, geometry.parameters.radiusBottom, geometry.parameters.height, 8 ); } const body = new CANNON.Body({ mass: isStatic ? 0 : mass, shape: shape, position: new CANNON.Vec3(position.x, position.y, position.z) }); world.addBody(body); objects.push({ mesh, body }); physicsBodies.push(body); return { mesh, body }; } // ====== CREATE LEVEL ====== function createLevel() { // Clear existing objects objects.forEach(obj => { scene.remove(obj.mesh); world.removeBody(obj.body); }); objects.length = 0; physicsBodies.length = 0; // Create ground blocks (static) const blockMat = new THREE.MeshStandardMaterial({ color: 0x8B4513, roughness: 0.7 }); const woodMat = new THREE.MeshStandardMaterial({ color: 0xDEB887, roughness: 0.6 }); const glassMat = new THREE.MeshStandardMaterial({ color: 0x87CEEB, roughness: 0.1, transparent: true, opacity: 0.8 }); const stoneMat = new THREE.MeshStandardMaterial({ color: 0x808080, roughness: 0.9 }); // Base platform createPhysicsObject( new THREE.BoxGeometry(6, 0.5, 1), blockMat, new THREE.Vector3(6, 0.25, 0), 0, true ); // Vertical blocks createPhysicsObject( new THREE.BoxGeometry(0.5, 2, 1), woodMat, new THREE.Vector3(4.5, 1, 0), 2 ); createPhysicsObject( new THREE.BoxGeometry(0.5, 2, 1), woodMat, new THREE.Vector3(7.5, 1, 0), 2 ); // Horizontal block on top createPhysicsObject( new THREE.BoxGeometry(3.5, 0.5, 1), woodMat, new THREE.Vector3(6, 2.25, 0), 1.5 ); // Second level createPhysicsObject( new THREE.BoxGeometry(0.5, 1.5, 1), glassMat, new THREE.Vector3(5, 3, 0), 1 ); createPhysicsObject( new THREE.BoxGeometry(0.5, 1.5, 1), glassMat, new THREE.Vector3(7, 3, 0), 1 ); // Top block createPhysicsObject( new THREE.BoxGeometry(2.5, 0.5, 1), stoneMat, new THREE.Vector3(6, 3.75, 0), 3 ); // Pigs (targets) const pigMat = new THREE.MeshStandardMaterial({ color: 0x2ECC71, roughness: 0.3 }); // Pig 1 - behind structure createPhysicsObject( new THREE.SphereGeometry(0.4, 16, 16), pigMat, new THREE.Vector3(6, 0.4, 0.5), 1 ); // Pig 2 - on top createPhysicsObject( new THREE.SphereGeometry(0.35, 16, 16), pigMat, new THREE.Vector3(6, 4.2, 0), 0.8 ); // Pig 3 - behind createPhysicsObject( new THREE.SphereGeometry(0.3, 16, 16), pigMat, new THREE.Vector3(8, 0.3, 0.3), 0.6 ); } // ====== BIRD ====== let birdMesh, birdBody; let isDragging = false; let dragStart = new THREE.Vector3(); let dragEnd = new THREE.Vector3(); let birdLaunched = false; let score = 0; let birdsRemaining = 3; function createBird() { // Remove old bird if exists if (birdMesh) { scene.remove(birdMesh); world.removeBody(birdBody); } const birdGeo = new THREE.SphereGeometry(0.4, 16, 16); const birdMat = new THREE.MeshStandardMaterial({ color: 0xFF0000, roughness: 0.4 }); birdMesh = new THREE.Mesh(birdGeo, birdMat); birdMesh.castShadow = true; birdMesh.position.set(0, 1, 0); scene.add(birdMesh); // Add eyes const eyeMat = new THREE.MeshStandardMaterial({ color: 0xFFFFFF }); const pupilMat = new THREE.MeshStandardMaterial({ color: 0x000000 }); const eyeGeo = new THREE.SphereGeometry(0.08, 8, 8); const pupilGeo = new THREE.SphereGeometry(0.04, 8, 8); const leftEye = new THREE.Mesh(eyeGeo, eyeMat); leftEye.position.set(-0.15, 0.15, 0.35); birdMesh.add(leftEye); const rightEye = new THREE.Mesh(eyeGeo, eyeMat); rightEye.position.set(0.15, 0.15, 0.35); birdMesh.add(rightEye); const leftPupil = new THREE.Mesh(pupilGeo, pupilMat); leftPupil.position.set(-0.15, 0.15, 0.43); birdMesh.add(leftPupil); const rightPupil = new THREE.Mesh(pupilGeo, pupilMat); rightPupil.position.set(0.15, 0.15, 0.43); birdMesh.add(rightPupil); // Physics body birdBody = new CANNON.Body({ mass: 2, shape: new CANNON.Sphere(0.4), position: new CANNON.Vec3(0, 1, 0) }); world.addBody(birdBody); birdLaunched = false; } // ====== TRAJECTORY LINE ====== const trajectoryPoints = []; const trajectoryLine = new THREE.Line( new THREE.BufferGeometry(), new THREE.LineBasicMaterial({ color: 0x333333, linewidth: 2 }) ); scene.add(trajectoryLine); function updateTrajectory() { if (!isDragging || birdLaunched) { trajectoryLine.visible = false; return; } trajectoryLine.visible = true; const start = birdMesh.position.clone(); const force = dragStart.clone().sub(dragEnd); const velocity = force.multiplyScalar(5); const points = []; const gravity = new THREE.Vector3(0, -9.82, 0); for (let i = 0; i < 30; i++) { const t = i * 0.05; const point = start.clone().add(velocity.clone().multiplyScalar(t)); point.y += 0.5 * gravity.y * t * t; points.push(point); } trajectoryLine.geometry.setFromPoints(points); } // ====== MOUSE CONTROLS ====== const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); const intersection = new THREE.Vector3(); function onMouseDown(event) { if (birdLaunched || birdsRemaining <= 0) return; mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); if (raycaster.ray.intersectObject(birdMesh).length > 0) { isDragging = true; dragStart.copy(birdMesh.position); raycaster.ray.intersectPlane(plane, intersection); dragEnd.copy(intersection); } } function onMouseMove(event) { if (!isDragging) return; mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); raycaster.ray.intersectPlane(plane, intersection); dragEnd.copy(intersection); updateTrajectory(); } function onMouseUp(event) { if (!isDragging) return; isDragging = false; const force = dragStart.clone().sub(dragEnd); const power = force.length(); if (power > 0.5) { // Launch the bird const launchForce = force.multiplyScalar(5); birdBody.velocity.set(launchForce.x, launchForce.y, launchForce.z); birdLaunched = true; trajectoryLine.visible = false; birdsRemaining--; updateScore(); } } // ====== SCORE & UI ====== function updateScore() { document.getElementById('scoreValue').textContent = score; } function checkPigs() { objects.forEach(obj => { if (obj.mesh.material.color.getHex() === 0x2ECC71) { // Check if pig is destroyed (fell or hit hard) if (obj.body.position.y < -1 || obj.body.velocity.length() > 5) { scene.remove(obj.mesh); world.removeBody(obj.body); score += 100; updateScore(); } } }); } // ====== RESTART ====== function restartGame() { score = 0; birdsRemaining = 3; updateScore(); createLevel(); createBird(); } document.getElementById('restart').addEventListener('click', restartGame); // ====== EVENT LISTENERS ====== renderer.domElement.addEventListener('mousedown', onMouseDown); renderer.domElement.addEventListener('mousemove', onMouseMove); renderer.domElement.addEventListener('mouseup', onMouseUp); window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // ====== ANIMATION LOOP ====== function animate() { requestAnimationFrame(animate); // Step physics world.step(1/60); // Update mesh positions from physics objects.forEach(obj => { obj.mesh.position.copy(obj.body.position); obj.mesh.quaternion.copy(obj.body.quaternion); }); if (birdMesh && birdBody) { birdMesh.position.copy(birdBody.position); birdMesh.quaternion.copy(birdBody.quaternion); } // Check if bird is out of bounds if (birdLaunched && birdBody.position.x > 15) { if (birdsRemaining > 0) { createBird(); } } // Check pig destruction checkPigs(); // Update trajectory updateTrajectory(); renderer.render(scene, camera); } // ====== INITIALIZE ====== createLevel(); createBird(); animate(); </script> </body> </html> ``` This game features: 1. **White background** - clearly shows all objects 2. **Physics engine** (Cannon.js) - realistic gravity, collisions, and destruction 3. **Drag-to-launch mechanic** - click and drag from the bird to aim, release to launch 4. **Trajectory preview** - dotted line showing predicted path 5. **Destructible structures** - wooden, glass, and stone blocks with different properties 6. **Pigs to destroy** - green targets worth 100 points each 7. **Score system** - tracks your points 8. **Restart button** - reset the game 9. **3 birds per round** - limited attempts 10. **3D graphics** - with shadows, lighting, and detailed models **How to play:** - Click and drag on the red bird to aim - Release to launch - Try to knock down the structures and hit the green pigs - Score points for each pig destroyed - Restart anytime with the red button The game uses Three.js for 3D rendering and Cannon.js for physics simulation, creating a satisfying Angry Birds experience in the browser.

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| twitter| game-dev| three-js

Discusión