NeuroLink VR

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>フルダイブVR - 仮想世界体験</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
        }

        .vr-container {
            width: 95vw;
            height: 95vh;
            background: #000;
            border-radius: 20px;
            position: relative;
            overflow: hidden;
            box-shadow: 0 20px 50px rgba(0,0,0,0.3);
        }

        .boot-screen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: linear-gradient(45deg, #0f0f23, #1a1a2e);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 100;
            transition: opacity 1s ease-out;
        }

        .boot-screen.hidden {
            opacity: 0;
            pointer-events: none;
        }

        .logo {
            font-size: 3rem;
            color: #00d4ff;
            margin-bottom: 30px;
            text-shadow: 0 0 20px #00d4ff;
            animation: pulse 2s infinite;
        }

        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.7; }
        }

        .loading-bar {
            width: 300px;
            height: 4px;
            background: #333;
            border-radius: 2px;
            overflow: hidden;
            margin-bottom: 20px;
        }

        .loading-progress {
            height: 100%;
            background: linear-gradient(90deg, #00d4ff, #ff006e);
            width: 0%;
            animation: loading 3s ease-out forwards;
        }

        @keyframes loading {
            to { width: 100%; }
        }

        .boot-text {
            color: #00d4ff;
            font-size: 1.2rem;
            margin-top: 20px;
        }

        #canvas {
            width: 100%;
            height: 100%;
            display: block;
        }

        .hud {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 10;
        }

        .status-panel {
            position: absolute;
            top: 20px;
            left: 20px;
            background: rgba(0, 212, 255, 0.1);
            border: 1px solid #00d4ff;
            border-radius: 10px;
            padding: 15px;
            color: #00d4ff;
            font-family: 'Courier New', monospace;
            backdrop-filter: blur(10px);
        }

        .controls {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 15px;
            pointer-events: all;
        }

        .control-btn {
            background: rgba(0, 212, 255, 0.2);
            border: 2px solid #00d4ff;
            color: #00d4ff;
            padding: 12px 20px;
            border-radius: 25px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            transition: all 0.3s ease;
            backdrop-filter: blur(10px);
        }

        .control-btn:hover {
            background: rgba(0, 212, 255, 0.4);
            box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
            transform: translateY(-2px);
        }

        .neural-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: radial-gradient(circle at center, transparent 30%, rgba(0, 212, 255, 0.05) 100%);
            pointer-events: none;
            z-index: 5;
        }

        .dive-complete {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: #00d4ff;
            font-size: 2rem;
            text-align: center;
            opacity: 0;
            animation: fadeInOut 4s ease-in-out;
            z-index: 50;
            text-shadow: 0 0 20px #00d4ff;
        }

        @keyframes fadeInOut {
            0%, 100% { opacity: 0; }
            20%, 80% { opacity: 1; }
        }
    </style>
</head>
<body>
    <div class="vr-container">
        <div class="boot-screen" id="bootScreen">
            <div class="logo">NeuroLink VR</div>
            <div class="loading-bar">
                <div class="loading-progress"></div>
            </div>
            <div class="boot-text">Neural Interface Initializing...</div>
        </div>

        <canvas id="canvas"></canvas>
        
        <div class="neural-overlay"></div>
        
        <div class="hud">
            <div class="status-panel">
                <div>Neural Sync: <span id="sync">98.7%</span></div>
                <div>Reality Index: <span id="reality">VIRTUAL</span></div>
                <div>Immersion Level: <span id="immersion">MAXIMUM</span></div>
                <div>Connected Users: <span id="users">1,247</span></div>
            </div>
        </div>

        <div class="controls">
            <button class="control-btn" onclick="changeWorld('cyber')">サイバー都市</button>
            <button class="control-btn" onclick="changeWorld('forest')">森林世界</button>
            <button class="control-btn" onclick="changeWorld('space')">宇宙ステーション</button>
            <button class="control-btn" onclick="disconnect()">ログアウト</button>
        </div>

        <div class="dive-complete" id="diveComplete">
            フルダイブ完了<br>
            <small>仮想世界へようこそ</small>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        let scene, camera, renderer, world = 'cyber';
        let particles = [];
        let buildings = [];
        let stars = [];
        let trees = [];
        
        // 起動シーケンス
        setTimeout(() => {
            document.getElementById('bootScreen').classList.add('hidden');
            initVR();
            setTimeout(() => {
                document.getElementById('diveComplete').style.display = 'block';
            }, 1000);
        }, 3500);

        function initVR() {
            // Three.js セットアップ
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('canvas'), antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor(0x000011);

            // 初期世界を構築
            buildCyberWorld();
            
            // カメラ位置
            camera.position.set(0, 5, 10);
            
            // アニメーションループ
            animate();
            
            // HUD更新
            updateHUD();
        }

        function buildCyberWorld() {
            // クリア
            clearWorld();
            scene.fog = new THREE.Fog(0x000033, 10, 100);
            
            // ネオンビル群
            for (let i = 0; i < 50; i++) {
                const height = Math.random() * 20 + 5;
                const geometry = new THREE.BoxGeometry(
                    Math.random() * 3 + 1, 
                    height, 
                    Math.random() * 3 + 1
                );
                
                const material = new THREE.MeshBasicMaterial({ 
                    color: Math.random() > 0.5 ? 0x00ffff : 0xff00ff,
                    transparent: true,
                    opacity: 0.8
                });
                
                const building = new THREE.Mesh(geometry, material);
                building.position.set(
                    (Math.random() - 0.5) * 100,
                    height / 2,
                    (Math.random() - 0.5) * 100
                );
                
                scene.add(building);
                buildings.push(building);
            }
            
            // パーティクル効果
            createParticles(0x00ffff);
            
            // 地面
            const floorGeometry = new THREE.PlaneGeometry(200, 200);
            const floorMaterial = new THREE.MeshBasicMaterial({ 
                color: 0x001122, 
                transparent: true, 
                opacity: 0.5 
            });
            const floor = new THREE.Mesh(floorGeometry, floorMaterial);
            floor.rotation.x = -Math.PI / 2;
            scene.add(floor);
        }

        function buildForestWorld() {
            clearWorld();
            scene.fog = new THREE.Fog(0x228B22, 5, 50);
            
            // 木々
            for (let i = 0; i < 100; i++) {
                // 幹
                const trunkGeometry = new THREE.CylinderGeometry(0.3, 0.5, 8);
                const trunkMaterial = new THREE.MeshBasicMaterial({ color: 0x8B4513 });
                const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
                
                // 葉
                const leavesGeometry = new THREE.SphereGeometry(3);
                const leavesMaterial = new THREE.MeshBasicMaterial({ color: 0x228B22 });
                const leaves = new THREE.Mesh(leavesGeometry, leavesMaterial);
                leaves.position.y = 6;
                
                const tree = new THREE.Group();
                tree.add(trunk);
                tree.add(leaves);
                
                tree.position.set(
                    (Math.random() - 0.5) * 80,
                    4,
                    (Math.random() - 0.5) * 80
                );
                
                scene.add(tree);
                trees.push(tree);
            }
            
            createParticles(0x90EE90);
            
            // 地面
            const floorGeometry = new THREE.PlaneGeometry(200, 200);
            const floorMaterial = new THREE.MeshBasicMaterial({ color: 0x2F4F2F });
            const floor = new THREE.Mesh(floorGeometry, floorMaterial);
            floor.rotation.x = -Math.PI / 2;
            scene.add(floor);
        }

        function buildSpaceWorld() {
            clearWorld();
            scene.fog = null;
            renderer.setClearColor(0x000000);
            
            // 星々
            for (let i = 0; i < 1000; i++) {
                const starGeometry = new THREE.SphereGeometry(0.1);
                const starMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
                const star = new THREE.Mesh(starGeometry, starMaterial);
                
                star.position.set(
                    (Math.random() - 0.5) * 200,
                    (Math.random() - 0.5) * 200,
                    (Math.random() - 0.5) * 200
                );
                
                scene.add(star);
                stars.push(star);
            }
            
            // 宇宙ステーション
            const stationGeometry = new THREE.TorusGeometry(10, 3, 8, 20);
            const stationMaterial = new THREE.MeshBasicMaterial({ 
                color: 0x888888, 
                wireframe: true 
            });
            const station = new THREE.Mesh(stationGeometry, stationMaterial);
            station.position.set(0, 0, -20);
            scene.add(station);
            
            createParticles(0xffffff);
        }

        function createParticles(color) {
            for (let i = 0; i < 200; i++) {
                const particleGeometry = new THREE.SphereGeometry(0.05);
                const particleMaterial = new THREE.MeshBasicMaterial({ 
                    color: color,
                    transparent: true,
                    opacity: 0.6
                });
                const particle = new THREE.Mesh(particleGeometry, particleMaterial);
                
                particle.position.set(
                    (Math.random() - 0.5) * 50,
                    Math.random() * 20,
                    (Math.random() - 0.5) * 50
                );
                
                particle.velocity = {
                    x: (Math.random() - 0.5) * 0.02,
                    y: Math.random() * 0.01,
                    z: (Math.random() - 0.5) * 0.02
                };
                
                scene.add(particle);
                particles.push(particle);
            }
        }

        function clearWorld() {
            buildings.forEach(b => scene.remove(b));
            trees.forEach(t => scene.remove(t));
            stars.forEach(s => scene.remove(s));
            particles.forEach(p => scene.remove(p));
            
            buildings = [];
            trees = [];
            stars = [];
            particles = [];
            
            // シーン全体をクリア
            while(scene.children.length > 0) {
                scene.remove(scene.children[0]);
            }
        }

        function animate() {
            requestAnimationFrame(animate);
            
            // カメラの自動回転
            const time = Date.now() * 0.0005;
            camera.position.x = Math.cos(time) * 20;
            camera.position.z = Math.sin(time) * 20;
            camera.lookAt(scene.position);
            
            // パーティクルアニメーション
            particles.forEach(particle => {
                particle.position.add(particle.velocity);
                
                if (particle.position.y > 25) {
                    particle.position.y = -5;
                }
                if (particle.position.x > 25) particle.position.x = -25;
                if (particle.position.x < -25) particle.position.x = 25;
                if (particle.position.z > 25) particle.position.z = -25;
                if (particle.position.z < -25) particle.position.z = 25;
            });
            
            // ビルの光る効果
            buildings.forEach(building => {
                if (Math.random() > 0.98) {
                    building.material.opacity = Math.random() * 0.5 + 0.5;
                }
            });
            
            renderer.render(scene, camera);
        }

        function changeWorld(newWorld) {
            world = newWorld;
            
            switch(world) {
                case 'cyber':
                    buildCyberWorld();
                    break;
                case 'forest':
                    buildForestWorld();
                    break;
                case 'space':
                    buildSpaceWorld();
                    break;
            }
        }

        function updateHUD() {
            setInterval(() => {
                document.getElementById('sync').textContent = (98 + Math.random() * 2).toFixed(1) + '%';
                document.getElementById('users').textContent = (1200 + Math.floor(Math.random() * 100)).toLocaleString();
            }, 2000);
        }

        function disconnect() {
            document.querySelector('.vr-container').style.opacity = '0';
            setTimeout(() => {
                document.body.innerHTML = `
                    <div style="display: flex; justify-content: center; align-items: center; height: 100vh; color: #00d4ff; font-size: 2rem; text-align: center;">
                        <div>
                            <div>Neural Link Disconnected</div>
                            <div style="font-size: 1rem; margin-top: 20px; opacity: 0.7;">現実世界へ戻りました</div>
                        </div>
                    </div>
                `;
            }, 1000);
        }

        // リサイズ対応
        window.addEventListener('resize', () => {
            if (camera && renderer) {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            }
        });
    </script>
</body>
</html>

投稿者: chosuke

趣味はゲームやアニメや漫画などです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です