Discussion

Jeu spatial d'intrication quantique

De Wikiprompt, l’encyclopédie libre de prompts

loshu2000
Contribué parloshu2000Source

17 mai 2026

Jeu spatial d'intrication quantique Une invite pour créer un jeu Three.js en fichier unique où les joueurs associent des amas de particules 3D par orientation spatiale, avec des effets de fusion basés sur la physique.

Contenu du PromptEnregistrer

🌐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Quantum Entanglement</title> <style> body { margin: 0; overflow: hidden; background: #ffffff; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } #info { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: #333; font-size: 14px; background: rgba(255, 255, 255, 0.8); padding: 10px 20px; border-radius: 30px; backdrop-filter: blur(10px); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); z-index: 100; pointer-events: none; letter-spacing: 0.5px; } #status { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); color: #555; font-size: 13px; background: rgba(255, 255, 255, 0.7); padding: 8px 16px; border-radius: 20px; backdrop-filter: blur(8px); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); z-index: 100; pointer-events: none; transition: all 0.3s ease; } #status.match { color: #2e7d32; background: rgba(232, 245, 233, 0.9); } #status.error { color: #c62828; background: rgba(255, 235, 238, 0.9); } canvas { display: block; } .hint { position: absolute; top: 80px; left: 50%; transform: translateX(-50%); color: #999; font-size: 12px; z-index: 100; pointer-events: none; font-style: italic; } </style> </head> <body> <div id="info">Quantum Entanglement - Click to unfold, find matching pairs</div> <div class="hint">Drag to rotate clusters | Click to unfold/fold</div> <div id="status">Select a cluster to begin</div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script> // ============ CORE SETUP ============ const scene = new THREE.Scene(); scene.background = new THREE.Color(0xffffff); const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 12); camera.lookAt(0, 0, 0); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); // ============ LIGHTING ============ const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 10, 7); directionalLight.castShadow = true; scene.add(directionalLight); const backLight = new THREE.DirectionalLight(0x88ccff, 0.3); backLight.position.set(-5, -3, -5); scene.add(backLight); // ============ GEOMETRY DEFINITIONS ============ // Define unique 3D geometric matrices (topologies) const topologyDefinitions = [ // Tetrahedron { type: 'tetrahedron', vertices: [ [0, 1, 0], [0.94, -0.33, 0], [-0.47, -0.33, 0.82], [-0.47, -0.33, -0.82] ], edges: [[0,1],[0,2],[0,3],[1,2],[2,3],[3,1]] }, // Cube { type: 'cube', vertices: [ [-0.7,-0.7,-0.7], [0.7,-0.7,-0.7], [0.7,0.7,-0.7], [-0.7,0.7,-0.7], [-0.7,-0.7,0.7], [0.7,-0.7,0.7], [0.7,0.7,0.7], [-0.7,0.7,0.7] ], edges: [[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]] }, // Octahedron { type: 'octahedron', vertices: [ [0, 1, 0], [0, -1, 0], [1, 0, 0], [-1, 0, 0], [0, 0, 1], [0, 0, -1] ], edges: [[0,2],[0,3],[0,4],[0,5],[1,2],[1,3],[1,4],[1,5],[2,4],[4,3],[3,5],[5,2]] }, // Icosahedron (simplified) { type: 'icosahedron', vertices: [ [0, 1, 0.618], [0, -1, 0.618], [0, 1, -0.618], [0, -1, -0.618], [1, 0.618, 0], [-1, 0.618, 0], [1, -0.618, 0], [-1, -0.618, 0], [0.618, 0, 1], [-0.618, 0, 1], [0.618, 0, -1], [-0.618, 0, -1] ], edges: [[0,1],[0,4],[0,5],[0,8],[0,9],[1,6],[1,7],[1,8],[1,9],[2,3],[2,4],[2,5],[2,10],[2,11],[3,6],[3,7],[3,10],[3,11],[4,8],[4,10],[5,9],[5,11],[6,8],[6,10],[7,9],[7,11]] } ]; // ============ PARTICLE SYSTEM ============ class ParticleSystem { constructor() { this.particles = []; this.geometry = new THREE.BufferGeometry(); this.material = new THREE.PointsMaterial({ color: 0x4488ff, size: 0.08, transparent: true, opacity: 0.9, blending: THREE.AdditiveBlending }); this.points = new THREE.Points(this.geometry, this.material); this.points.visible = false; scene.add(this.points); } emit(position, color = 0x4488ff, count = 80) { for (let i = 0; i < count; i++) { this.particles.push({ pos: position.clone(), vel: new THREE.Vector3( (Math.random() - 0.5) * 0.3, (Math.random() - 0.5) * 0.3, (Math.random() - 0.5) * 0.3 ), life: 1.0, decay: 0.005 + Math.random() * 0.01, color: color }); } this.points.visible = true; } update() { if (this.particles.length === 0) { this.points.visible = false; return; } const positions = []; const colors = []; for (let i = this.particles.length - 1; i >= 0; i--) { const p = this.particles[i]; p.pos.add(p.vel); p.vel.multiplyScalar(0.98); p.life -= p.decay; if (p.life <= 0) { this.particles.splice(i, 1); continue; } positions.push(p.pos.x, p.pos.y, p.pos.z); const c = new THREE.Color(p.color); colors.push(c.r * p.life, c.g * p.life, c.b * p.life); } this.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); this.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); this.points.material.vertexColors = true; } } const particleSystem = new ParticleSystem(); // ============ CLUSTER CLASS ============ class Cluster { constructor(position, topologyIndex, id) { this.id = id; this.topologyIndex = topologyIndex; this.position = position.clone(); this.rotation = new THREE.Euler( Math.random() * Math.PI * 2, Math.random() * Math.PI * 2, Math.random() * Math.PI * 2 ); this.quaternion = new THREE.Quaternion().setFromEuler(this.rotation); this.isUnfolded = false; this.isMatched = false; this.isDragging = false; // Create group this.group = new THREE.Group(); this.group.position.copy(this.position); this.group.quaternion.copy(this.quaternion); // Create collapsed sphere (frosted glass) const sphereGeo = new THREE.SphereGeometry(0.5, 32, 32); const sphereMat = new THREE.MeshPhysicalMaterial({ color: 0xffffff, transparent: true, opacity: 0.3, roughness: 0.1, metalness: 0.1, transmission: 0.9, thickness: 0.5, envMapIntensity: 1.0 }); this.sphere = new THREE.Mesh(sphereGeo, sphereMat); this.sphere.castShadow = true; this.group.add(this.sphere); // Create unfolded geometry (hidden initially) this.geometryGroup = new THREE.Group(); this.buildGeometry(topologyIndex); this.geometryGroup.visible = false; this.group.add(this.geometryGroup); // Add glow ring const ringGeo = new THREE.RingGeometry(0.6, 0.7, 32); const ringMat = new THREE.MeshBasicMaterial({ color: 0x88ccff, transparent: true, opacity: 0.3, side: THREE.DoubleSide }); this.ring = new THREE.Mesh(ringGeo, ringMat); this.ring.rotation.x = Math.PI / 2; this.group.add(this.ring); scene.add(this.group); } buildGeometry(topologyIndex) { const def = topologyDefinitions[topologyIndex]; // Create vertices as small spheres def.vertices.forEach((v, i) => { const sphereGeo = new THREE.SphereGeometry(0.06, 8, 8); const sphereMat = new THREE.MeshPhysicalMaterial({ color: 0x4488ff, transparent: true, opacity: 0.8, roughness: 0.2, metalness: 0.3, transmission: 0.5 }); const mesh = new THREE.Mesh(sphereGeo, sphereMat); mesh.position.set(v[0], v[1], v[2]); this.geometryGroup.add(mesh); }); // Create edges as lines const lineMat = new THREE.LineBasicMaterial({ color: 0x4488ff, transparent: true, opacity: 0.6 }); def.edges.forEach(([a, b]) => { const points = [ new THREE.Vector3(def.vertices[a][0], def.vertices[a][1], def.vertices[a][2]), new THREE.Vector3(def.vertices[b][0], def.vertices[b][1], def.vertices[b][2]) ]; const lineGeo = new THREE.BufferGeometry().setFromPoints(points); const line = new THREE.Line(lineGeo, lineMat); this.geometryGroup.add(line); }); } toggleUnfold() { this.isUnfolded = !this.isUnfolded; this.sphere.visible = !this.isUnfolded; this.geometryGroup.visible = this.isUnfolded; this.ring.visible = !this.isUnfolded; if (this.isUnfolded) { // Emit small particle burst particleSystem.emit(this.position, 0x4488ff, 20); } } update(delta) { // Gentle floating animation if (!this.isDragging && !this.isMatched) { this.group.position.y += Math.sin(Date.now() * 0.001 + this.id) * 0.0005; } // Rotate ring if (this.ring) { this.ring.rotation.z += delta * 0.5; } } dispose() { scene.remove(this.group); // Clean up geometries this.group.traverse((child) => { if (child.geometry) child.geometry.dispose(); if (child.material) { if (Array.isArray(child.material)) { child.material.forEach(m => m.dispose()); } else { child.material.dispose(); } } }); } } // ============ CREATE CLUSTERS ============ const clusters = []; const clusterPositions = [ new THREE.Vector3(-3, 1.5, 0), new THREE.Vector3(3, 1.5, 0), new THREE.Vector3(-3, -1.5, 0), new THREE.Vector3(3, -1.5, 0), new THREE.Vector3(0, 0, -2), new THREE.Vector3(0, 0, 2) ]; // Create 6 clusters with 3 matching pairs const topologyAssignments = [0, 0, 1, 1, 2, 2]; // 3 pairs // Shuffle for (let i = topologyAssignments.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [topologyAssignments[i], topologyAssignments[j]] = [topologyAssignments[j], topologyAssignments[i]]; } clusterPositions.forEach((pos, i) => { const cluster = new Cluster(pos, topologyAssignments[i], i); clusters.push(cluster); }); // ============ INTERACTION ============ let selectedCluster = null; let isDragging = false; let previousMouse = { x: 0, y: 0 }; let dragCluster = null; const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); function onMouseClick(event) { if (isDragging) return; mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); // Check clusters for (const cluster of clusters) { if (cluster.isMatched) continue; const intersects = raycaster.intersectObject(cluster.sphere, true); if (intersects.length > 0) { if (selectedCluster && selectedCluster !== cluster && selectedCluster.isUnfolded) { // Check match if (selectedCluster.topologyIndex === cluster.topologyIndex) { // MATCH FOUND handleMatch(selectedCluster, cluster); } else { // Wrong match document.getElementById('status').textContent = 'No entanglement - try again'; document.getElementById('status').className = 'error'; setTimeout(() => { document.getElementById('status').textContent = 'Select a cluster to begin'; document.getElementById('status').className = ''; }, 1500); selectedCluster.toggleUnfold(); selectedCluster = null; } } else { // Toggle unfold if (selectedCluster && selectedCluster !== cluster) { selectedCluster.toggleUnfold(); } cluster.toggleUnfold(); selectedCluster = cluster; document.getElementById('status').textContent = 'Cluster unfolded - find its match'; document.getElementById('status').className = ''; } return; } } // Click empty space - deselect if (selectedCluster) { selectedCluster.toggleUnfold(); selectedCluster = null; document.getElementById('status').textContent = 'Select a cluster to begin'; document.getElementById('status').className = ''; } } function handleMatch(clusterA, clusterB) { document.getElementById('status').textContent = 'ENTANGLED!'; document.getElementById('status').className = 'match'; // Mark as matched clusterA.isMatched = true; clusterB.isMatched = true; // Calculate implosion vectors const midpoint = new THREE.Vector3().addVectors(clusterA.position, clusterB.position).multiplyScalar(0.5); // Emit particles at both clusters particleSystem.emit(clusterA.position, 0x4488ff, 60); particleSystem.emit(clusterB.position, 0x4488ff, 60); // Animate implosion const startTime = Date.now(); const duration = 1000; function animateImplosion() { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); // Move clusters toward midpoint clusterA.group.position.lerp(midpoint, 0.05); clusterB.group.position.lerp(midpoint, 0.05); // Scale down const scale = 1 - progress * 0.8; clusterA.group.scale.setScalar(scale); clusterB.group.scale.setScalar(scale); // Emit particles along the way if (Math.random() < 0.3) { particleSystem.emit(clusterA.group.position, 0x88ccff, 5); particleSystem.emit(clusterB.group.position, 0x88ccff, 5); } if (progress < 1) { requestAnimationFrame(animateImplosion); } else { // Destroy clusters clusterA.dispose(); clusterB.dispose(); // Big particle burst particleSystem.emit(midpoint, 0x88ccff, 100); particleSystem.emit(midpoint, 0x4488ff, 80); document.getElementById('status').textContent = 'Clusters fused!'; setTimeout(() => { document.getElementById('status').textContent = 'Select a cluster to begin'; document.getElementById('status').className = ''; }, 2000); selectedCluster = null; // Check win condition const remaining = clusters.filter(c => !c.isMatched); if (remaining.length === 0) { document.getElementById('status').textContent = 'ALL CLUSTERS ENTANGLED!'; document.getElementById('status').className = 'match'; } } } animateImplosion(); } // ============ DRAG ROTATION ============ function onMouseDown(event) { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); for (const cluster of clusters) { if (cluster.isMatched) continue; const intersects = raycaster.intersectObject(cluster.sphere, true); if (intersects.length > 0) { isDragging = true; dragCluster = cluster; cluster.isDragging = true; previousMouse = { x: event.clientX, y: event.clientY }; break; } } } function onMouseMove(event) { if (!isDragging || !dragCluster) return; const deltaX = event.clientX - previousMouse.x; const deltaY = event.clientY - previousMouse.y; const rotationSpeed = 0.01; const quaternion = new THREE.Quaternion() .setFromEuler(new THREE.Euler( deltaY * rotationSpeed, deltaX * rotationSpeed, 0 )); dragCluster.group.quaternion.multiplyQuaternions(quaternion, dragCluster.group.quaternion); previousMouse = { x: event.clientX, y: event.clientY }; } function onMouseUp() { isDragging = false; if (dragCluster) { dragCluster.isDragging = false; dragCluster = null; } } // ============ EVENT LISTENERS ============ renderer.domElement.addEventListener('click', onMouseClick); 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 ============ let lastTime = 0; function animate(time) { requestAnimationFrame(animate); const delta = lastTime ? (time - lastTime) / 1000 : 0; lastTime = time; // Update clusters clusters.forEach(cluster => { if (!cluster.isMatched) { cluster.update(delta); } }); // Update particle system particleSystem.update(); renderer.render(scene, camera); } // Start animation requestAnimationFrame(animate); // Initial status console.log('Quantum Entanglement game initialized'); </script> </body> </html>

Connectez-vous pour voir le prompt complet

Continuer avec:

En vous connectant, vous acceptez nos Conditions et Confidentialité

Utilisation

Ce prompt est conçu pour être utilisé avec coding. Copiez le contenu ci-dessus et collez-le dans votre outil d’IA préféré.

Pour de meilleurs résultats, personnalisez les espaces réservés (indiqués par des crochets ou des majuscules) selon vos besoins.

Références

Catégories :coding| prompts.chat| three-js| web-game

Discussion