Advertisement

Stimulation

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cosmic Rider - Stylized Edition</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <style>
        body {
            overflow: hidden;
            margin: 0;
            background-color: #020205;
            font-family: 'Segoe UI', system-ui, sans-serif;
        }
        #webgl-canvas {
            display: block;
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
        }
        #ui-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 10;
            pointer-events: none;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            padding: 2.5rem;
        }
        .glass-panel {
            background: rgba(10, 10, 25, 0.4);
            backdrop-filter: blur(15px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.8);
            pointer-events: auto;
        }
        .pulse {
            animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
        }
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: .5; }
        }
    </style>
</head>
<body>

    <canvas id="webgl-canvas"></canvas>

    <div id="ui-layer">
        <div class="flex flex-col items-start gap-4">
            <div class="glass-panel p-8 rounded-3xl text-white">
                <h1 class="text-5xl font-black tracking-tighter text-transparent bg-clip-text bg-gradient-to-r from-yellow-300 via-orange-400 to-red-500">
                    STELLAR RIDE
                </h1>
                <p class="text-blue-200 text-lg font-light tracking-widest uppercase mt-2">Beyond the Horizon</p>
            </div>
        </div>
        
        <div class="flex justify-center mb-4">
            <div class="glass-panel px-8 py-4 rounded-2xl text-white text-sm flex items-center gap-3">
                <span class="w-2 h-2 rounded-full bg-green-400 pulse"></span>
                <span class="opacity-80 tracking-widest font-medium uppercase">Active Exploration Mode</span>
            </div>
        </div>
    </div>

    <script>
        let scene, camera, renderer, rocketGroup, character, thrusterLight, engineFire;
        let isDragging = false, previousMouseX = 0, previousMouseY = 0;
        let targetRotationX = 0.3, targetRotationY = 0;
        let zoomLevel = 18;

        // Function to create a capsule-like shape manually (r128 fix)
        function createCapsule(radius, height, material) {
            const group = new THREE.Group();
            const cylinderGeom = new THREE.CylinderGeometry(radius, radius, height, 32);
            const cylinder = new THREE.Mesh(cylinderGeom, material);
            
            const sphereGeom = new THREE.SphereGeometry(radius, 32, 32);
            const topSphere = new THREE.Mesh(sphereGeom, material);
            topSphere.position.y = height / 2;
            
            const bottomSphere = new THREE.Mesh(sphereGeom, material);
            bottomSphere.position.y = -height / 2;
            
            group.add(cylinder, topSphere, bottomSphere);
            return group;
        }

        function init() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x020206);
            scene.fog = new THREE.Fog(0x020206, 10, 100);

            camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(0, 5, zoomLevel);

            renderer = new THREE.WebGLRenderer({ 
                canvas: document.getElementById('webgl-canvas'), 
                antialias: true,
                alpha: true
            });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setPixelRatio(window.devicePixelRatio);

            // --- Advanced Lighting ---
            const ambientLight = new THREE.AmbientLight(0x223366, 1.5);
            scene.add(ambientLight);

            const sunLight = new THREE.DirectionalLight(0xffffff, 2.5);
            sunLight.position.set(20, 40, 20);
            scene.add(sunLight);

            const rimLight = new THREE.PointLight(0x6699ff, 3, 50);
            rimLight.position.set(-20, 10, -20);
            scene.add(rimLight);

            // --- Rocket Construction ---
            rocketGroup = new THREE.Group();

            const bodyGeom = new THREE.CylinderGeometry(0.8, 1.1, 4.5, 32);
            const rocketMat = new THREE.MeshStandardMaterial({ 
                color: 0xd63031, 
                metalness: 0.6, 
                roughness: 0.3
            });
            const rocketBody = new THREE.Mesh(bodyGeom, rocketMat);
            rocketGroup.add(rocketBody);

            const noseGeom = new THREE.ConeGeometry(0.8, 1.8, 32);
            const noseMat = new THREE.MeshStandardMaterial({ color: 0xfdcb6e, metalness: 0.4, roughness: 0.2 });
            const nose = new THREE.Mesh(noseGeom, noseMat);
            nose.position.y = 3.15;
            rocketGroup.add(nose);

            // Fins
            const finShape = new THREE.Shape();
            finShape.moveTo(0, 0);
            finShape.lineTo(1.2, -1);
            finShape.lineTo(1.2, -2.5);
            finShape.lineTo(0, -1.8);
            
            const extrudeSettings = { depth: 0.1, bevelEnabled: true, bevelThickness: 0.05, bevelSize: 0.05 };
            const finGeom = new THREE.ExtrudeGeometry(finShape, extrudeSettings);
            const finMat = new THREE.MeshStandardMaterial({ color: 0x0984e3, metalness: 0.5, roughness: 0.4 });

            for(let i=0; i<3; i++) {
                const fin = new THREE.Mesh(finGeom, finMat);
                fin.rotation.y = (Math.PI * 2 / 3) * i;
                fin.position.y = -0.5;
                rocketGroup.add(fin);
            }

            // Engine
            const engineGeom = new THREE.CylinderGeometry(0.6, 0.8, 0.5, 32);
            const engineMat = new THREE.MeshStandardMaterial({ color: 0x2d3436, metalness: 0.9 });
            const engine = new THREE.Mesh(engineGeom, engineMat);
            engine.position.y = -2.5;
            rocketGroup.add(engine);

            const fireGeom = new THREE.ConeGeometry(0.5, 2, 16);
            const fireMat = new THREE.MeshBasicMaterial({ color: 0xffaa00, transparent: true, opacity: 0.8 });
            engineFire = new THREE.Mesh(fireGeom, fireMat);
            engineFire.position.y = -3.5;
            engineFire.rotation.x = Math.PI;
            rocketGroup.add(engineFire);

            thrusterLight = new THREE.PointLight(0xff6600, 5, 10);
            thrusterLight.position.y = -3.5;
            rocketGroup.add(thrusterLight);

            // --- Stylized Character (Fixed r128 compatible) ---
            character = new THREE.Group();
            
            const charBodyMat = new THREE.MeshStandardMaterial({ color: 0xe84393, roughness: 0.8 });
            const charBody = createCapsule(0.4, 0.6, charBodyMat);
            character.add(charBody);

            const headGeom = new THREE.SphereGeometry(0.45, 32, 32);
            const skinMat = new THREE.MeshStandardMaterial({ color: 0xffdbac, roughness: 0.5 });
            const head = new THREE.Mesh(headGeom, skinMat);
            head.position.y = 0.9;
            character.add(head);

            const hairMat = new THREE.MeshStandardMaterial({ color: 0x2d3436, roughness: 0.9 });
            const pigtailGeom = new THREE.SphereGeometry(0.28, 16, 16);
            
            const lp = new THREE.Mesh(pigtailGeom, hairMat);
            lp.position.set(-0.4, 1.15, 0);
            lp.scale.y = 1.3;
            character.add(lp);

            const rp = new THREE.Mesh(pigtailGeom, hairMat);
            rp.position.set(0.4, 1.15, 0);
            rp.scale.y = 1.3;
            character.add(rp);

            const legMat = new THREE.MeshStandardMaterial({ color: 0x6c5ce7 });
            const lLeg = createCapsule(0.12, 0.6, legMat);
            lLeg.position.set(-0.25, -0.4, 0.4);
            lLeg.rotation.x = Math.PI / 1.8;
            character.add(lLeg);
            
            const rLeg = createCapsule(0.12, 0.6, legMat);
            rLeg.position.set(0.25, -0.4, 0.4);
            rLeg.rotation.x = Math.PI / 1.8;
            character.add(rLeg);

            character.position.set(0, 0.5, 1);
            character.rotation.y = Math.PI;
            rocketGroup.add(character);

            rocketGroup.rotation.z = -Math.PI / 4;
            scene.add(rocketGroup);

            // --- Environment ---
            const starCount = 4000;
            const starPos = new Float32Array(starCount * 3);
            const starColors = new Float32Array(starCount * 3);
            for(let i=0; i < starCount; i++) {
                const ix = i * 3;
                starPos[ix] = (Math.random() - 0.5) * 250;
                starPos[ix+1] = (Math.random() - 0.5) * 250;
                starPos[ix+2] = (Math.random() - 0.5) * 250;
                
                const c = new THREE.Color().setHSL(Math.random(), 0.2, 0.8);
                starColors[ix] = c.r; starColors[ix+1] = c.g; starColors[ix+2] = c.b;
            }
            const starGeom = new THREE.BufferGeometry();
            starGeom.setAttribute('position', new THREE.BufferAttribute(starPos, 3));
            starGeom.setAttribute('color', new THREE.BufferAttribute(starColors, 3));
            const starMat = new THREE.PointsMaterial({ size: 0.25, vertexColors: true, transparent: true, opacity: 0.8 });
            scene.add(new THREE.Points(starGeom, starMat));

            createPlanet(5, 0xff7f50, {x: 35, y: 15, z: -60}, true); 
            createPlanet(3, 0x00cec9, {x: -40, y: -20, z: -40}, false); 
            createPlanet(1.2, 0xa29bfe, {x: 15, y: -15, z: -25}, false); 

            window.addEventListener('resize', onWindowResize);
            window.addEventListener('mousedown', (e) => { isDragging = true; previousMouseX = e.clientX; previousMouseY = e.clientY; });
            window.addEventListener('mouseup', () => isDragging = false);
            window.addEventListener('mousemove', onMouseMove);
            window.addEventListener('wheel', (e) => { 
                zoomLevel += e.deltaY * 0.01; 
                zoomLevel = Math.max(8, Math.min(60, zoomLevel)); 
            });

            animate();
        }

        function createPlanet(radius, color, pos, ring) {
            const group = new THREE.Group();
            const geom = new THREE.SphereGeometry(radius, 64, 64);
            const mat = new THREE.MeshStandardMaterial({ color: color, roughness: 0.7, metalness: 0.1 });
            const planet = new THREE.Mesh(geom, mat);
            group.add(planet);

            if(ring) {
                const ringGeom = new THREE.TorusGeometry(radius + 2, 0.1, 2, 100);
                const ringMat = new THREE.MeshStandardMaterial({ color: 0xffffff, transparent: true, opacity: 0.3 });
                const planetRing = new THREE.Mesh(ringGeom, ringMat);
                planetRing.rotation.x = Math.PI / 2.1;
                group.add(planetRing);
            }

            group.position.set(pos.x, pos.y, pos.z);
            scene.add(group);
            group.userData.rotSpeed = (Math.random() - 0.5) * 0.005;
            return group;
        }

        function onMouseMove(e) {
            if (!isDragging) return;
            targetRotationY += (e.clientX - previousMouseX) * 0.005;
            targetRotationX += (e.clientY - previousMouseY) * 0.005;
            previousMouseX = e.clientX;
            previousMouseY = e.clientY;
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);
            const time = Date.now() * 0.001;

            rocketGroup.position.x = Math.sin(time * 0.4) * 12;
            rocketGroup.position.y = Math.cos(time * 0.6) * 6;
            rocketGroup.position.z = Math.sin(time * 0.2) * 8;

            rocketGroup.rotation.x = Math.sin(time * 0.8) * 0.15;
            rocketGroup.rotation.y += 0.01;
            rocketGroup.rotation.z = -Math.PI / 4 + Math.cos(time * 0.5) * 0.2;

            const fireScale = 1 + Math.sin(time * 20) * 0.2;
            engineFire.scale.set(fireScale, fireScale, fireScale);
            thrusterLight.intensity = 4 + Math.sin(time * 20) * 2;

            character.rotation.x = Math.sin(time * 3) * 0.03;

            const camTargetX = Math.sin(targetRotationY) * zoomLevel;
            const camTargetZ = Math.cos(targetRotationY) * zoomLevel;
            const camTargetY = targetRotationX * 10;

            camera.position.lerp(new THREE.Vector3(camTargetX, camTargetY, camTargetZ), 0.05);
            camera.lookAt(0, 0, 0);

            scene.children.forEach(obj => {
                if(obj.userData.rotSpeed) obj.rotation.y += obj.userData.rotSpeed;
            });

            renderer.render(scene, camera);
        }

        window.onload = init;
    </script>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *