Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Barbie Beach Bonanza</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.waves.min.js"></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| font-family: 'Arial', sans-serif; | |
| } | |
| #ui-container { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| pointer-events: none; | |
| z-index: 100; | |
| } | |
| #loading-screen { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%); | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 9999; | |
| } | |
| .progress-bar { | |
| width: 50%; | |
| height: 20px; | |
| background-color: #fff; | |
| border-radius: 10px; | |
| margin-top: 20px; | |
| overflow: hidden; | |
| } | |
| .progress { | |
| height: 100%; | |
| width: 0%; | |
| background: linear-gradient(90deg, #ff758c 0%, #ff7eb3 100%); | |
| transition: width 0.3s ease; | |
| } | |
| .control-btn { | |
| pointer-events: all; | |
| background-color: rgba(255, 255, 255, 0.3); | |
| border: 2px solid white; | |
| border-radius: 50%; | |
| width: 60px; | |
| height: 60px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| margin: 10px; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| .control-btn:hover { | |
| background-color: rgba(255, 255, 255, 0.5); | |
| transform: scale(1.1); | |
| } | |
| .control-btn i { | |
| color: white; | |
| font-size: 24px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="loading-screen"> | |
| <h1 class="text-4xl font-bold text-white mb-4">Barbie Beach Bonanza</h1> | |
| <p class="text-xl text-white mb-8">Loading fabulous adventure...</p> | |
| <div class="progress-bar"> | |
| <div class="progress" id="progress-bar"></div> | |
| </div> | |
| </div> | |
| <div id="ui-container"> | |
| <div class="flex justify-between p-4"> | |
| <div class="bg-pink-500 bg-opacity-50 rounded-full p-2"> | |
| <h2 class="text-white font-bold text-xl">Score: <span id="score">0</span></h2> | |
| </div> | |
| <div class="bg-pink-500 bg-opacity-50 rounded-full p-2"> | |
| <h2 class="text-white font-bold text-xl">Time: <span id="timer">60</span>s</h2> | |
| </div> | |
| </div> | |
| <div class="absolute bottom-4 left-0 right-0 flex justify-center"> | |
| <div class="flex items-center"> | |
| <div class="control-btn" id="left-btn"> | |
| <i data-feather="chevron-left"></i> | |
| </div> | |
| <div class="flex flex-col items-center"> | |
| <div class="control-btn" id="up-btn"> | |
| <i data-feather="chevron-up"></i> | |
| </div> | |
| <div class="control-btn" id="down-btn"> | |
| <i data-feather="chevron-down"></i> | |
| </div> | |
| </div> | |
| <div class="control-btn" id="right-btn"> | |
| <i data-feather="chevron-right"></i> | |
| </div> | |
| <div class="control-btn ml-4" id="jump-btn"> | |
| <i data-feather="arrow-up"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script> | |
| // Loading simulation | |
| let progress = 0; | |
| const progressBar = document.getElementById('progress-bar'); | |
| const loadingInterval = setInterval(() => { | |
| progress += Math.random() * 10; | |
| if (progress > 100) progress = 100; | |
| progressBar.style.width = `${progress}%`; | |
| if (progress === 100) { | |
| clearInterval(loadingInterval); | |
| setTimeout(() => { | |
| document.getElementById('loading-screen').style.display = 'none'; | |
| initGame(); | |
| }, 500); | |
| } | |
| }, 300); | |
| // Game initialization | |
| function initGame() { | |
| feather.replace(); | |
| // Three.js setup | |
| const scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(0x87CEEB); // Sky blue | |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
| camera.position.set(0, 10, 20); | |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| renderer.shadowMap.enabled = true; | |
| document.body.appendChild(renderer.domElement); | |
| // Controls | |
| const controls = new THREE.OrbitControls(camera, renderer.domElement); | |
| controls.enableDamping = true; | |
| controls.dampingFactor = 0.05; | |
| // Lights | |
| const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); | |
| scene.add(ambientLight); | |
| const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); | |
| directionalLight.position.set(10, 20, 10); | |
| directionalLight.castShadow = true; | |
| directionalLight.shadow.mapSize.width = 2048; | |
| directionalLight.shadow.mapSize.height = 2048; | |
| scene.add(directionalLight); | |
| // Simple beach environment | |
| const sandGeometry = new THREE.PlaneGeometry(100, 100); | |
| const sandMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0xF5DEB3, | |
| roughness: 1.0 | |
| }); | |
| const sand = new THREE.Mesh(sandGeometry, sandMaterial); | |
| sand.rotation.x = -Math.PI / 2; | |
| sand.receiveShadow = true; | |
| scene.add(sand); | |
| // Ocean | |
| const waterGeometry = new THREE.PlaneGeometry(200, 200); | |
| const waterMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0x1E90FF, | |
| transparent: true, | |
| opacity: 0.8, | |
| roughness: 0.1, | |
| metalness: 0.5 | |
| }); | |
| const water = new THREE.Mesh(waterGeometry, waterMaterial); | |
| water.rotation.x = -Math.PI / 2; | |
| water.position.y = -0.5; | |
| water.position.z = -50; | |
| scene.add(water); | |
| // Simple placeholder for Barbie (we would normally use a 3D model here) | |
| const barbieGeometry = new THREE.BoxGeometry(1, 2, 0.5); | |
| const barbieMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0xFF69B4, | |
| roughness: 0.3, | |
| metalness: 0.1 | |
| }); | |
| const barbie = new THREE.Mesh(barbieGeometry, barbieMaterial); | |
| barbie.castShadow = true; | |
| barbie.position.y = 1; | |
| scene.add(barbie); | |
| // Add some beach items | |
| const addBeachItem = (x, z, color, size) => { | |
| const geometry = new THREE.SphereGeometry(size[0], size[1], size[2]); | |
| const material = new THREE.MeshStandardMaterial({ color }); | |
| const item = new THREE.Mesh(geometry, material); | |
| item.position.set(x, size[0], z); | |
| item.castShadow = true; | |
| scene.add(item); | |
| return item; | |
| }; | |
| const beachBall = addBeachItem(5, 0, 0xFF0000, [1, 16, 16]); | |
| const umbrella = addBeachItem(-5, 5, 0x00FF00, [0.5, 8, 4]); | |
| // Game state | |
| let score = 0; | |
| let time = 60; | |
| let gameActive = true; | |
| const scoreElement = document.getElementById('score'); | |
| const timerElement = document.getElementById('timer'); | |
| // Game timer | |
| const timerInterval = setInterval(() => { | |
| if (!gameActive) return; | |
| time--; | |
| timerElement.textContent = time; | |
| if (time <= 0) { | |
| gameActive = false; | |
| clearInterval(timerInterval); | |
| alert(`Game Over! Your score: ${score}`); | |
| } | |
| }, 1000); | |
| // Controls | |
| const moveSpeed = 0.2; | |
| const jumpHeight = 5; | |
| let isJumping = false; | |
| document.getElementById('up-btn').addEventListener('click', () => { | |
| barbie.position.z -= moveSpeed; | |
| }); | |
| document.getElementById('down-btn').addEventListener('click', () => { | |
| barbie.position.z += moveSpeed; | |
| }); | |
| document.getElementById('left-btn').addEventListener('click', () => { | |
| barbie.position.x -= moveSpeed; | |
| barbie.rotation.y = -Math.PI / 2; | |
| }); | |
| document.getElementById('right-btn').addEventListener('click', () => { | |
| barbie.position.x += moveSpeed; | |
| barbie.rotation.y = Math.PI / 2; | |
| }); | |
| document.getElementById('jump-btn').addEventListener('click', () => { | |
| if (!isJumping) { | |
| isJumping = true; | |
| barbie.position.y += jumpHeight; | |
| setTimeout(() => { | |
| barbie.position.y = 1; | |
| isJumping = false; | |
| }, 500); | |
| } | |
| }); | |
| // Keyboard controls | |
| document.addEventListener('keydown', (event) => { | |
| switch(event.key) { | |
| case 'ArrowUp': | |
| barbie.position.z -= moveSpeed; | |
| barbie.rotation.y = 0; | |
| break; | |
| case 'ArrowDown': | |
| barbie.position.z += moveSpeed; | |
| barbie.rotation.y = Math.PI; | |
| break; | |
| case 'ArrowLeft': | |
| barbie.position.x -= moveSpeed; | |
| barbie.rotation.y = -Math.PI / 2; | |
| break; | |
| case 'ArrowRight': | |
| barbie.position.x += moveSpeed; | |
| barbie.rotation.y = Math.PI / 2; | |
| break; | |
| case ' ': | |
| if (!isJumping) { | |
| isJumping = true; | |
| barbie.position.y += jumpHeight; | |
| setTimeout(() => { | |
| barbie.position.y = 1; | |
| isJumping = false; | |
| }, 500); | |
| } | |
| break; | |
| } | |
| }); | |
| // Collision detection | |
| const checkCollision = () => { | |
| const distanceToBall = barbie.position.distanceTo(beachBall.position); | |
| if (distanceToBall < 2) { | |
| score += 10; | |
| scoreElement.textContent = score; | |
| // Move the beach ball to a new random position | |
| beachBall.position.x = Math.random() * 30 - 15; | |
| beachBall.position.z = Math.random() * 30 - 15; | |
| } | |
| const distanceToUmbrella = barbie.position.distanceTo(umbrella.position); | |
| if (distanceToUmbrella < 2) { | |
| score += 5; | |
| scoreElement.textContent = score; | |
| // Move the umbrella to a new random position | |
| umbrella.position.x = Math.random() * 30 - 15; | |
| umbrella.position.z = Math.random() * 30 - 15; | |
| } | |
| }; | |
| // Animation loop | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| controls.update(); | |
| checkCollision(); | |
| // Simple wave animation for the beach ball | |
| beachBall.rotation.x += 0.01; | |
| beachBall.rotation.z += 0.01; | |
| renderer.render(scene, camera); | |
| } | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| }); | |
| animate(); | |
| } | |
| </script> | |
| </body> | |
| </html> | |