Download index.html from Aprec/test: direct link, hf CLI and curl.
- Browser
- Download file 28.2 kB
-
https://huggingface.co/spaces/Aprec/test/resolve/main/index.html
- Command line
-
hf download hf://spaces/Aprec/test/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Aprec/test/resolve/main/index.html
28.2 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>3D射击跟枪练习器</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/three@0.128.0/examples/js/controls/PointerLockControls.js"></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| font-family: 'Arial', sans-serif; | |
| } | |
| #container { | |
| position: relative; | |
| width: 100%; | |
| height: 100vh; | |
| } | |
| #crosshair { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| width: 30px; | |
| height: 30px; | |
| pointer-events: none; | |
| z-index: 100; | |
| } | |
| #ui { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| padding: 20px; | |
| color: white; | |
| background-color: rgba(0, 0, 0, 0.5); | |
| z-index: 10; | |
| } | |
| #start-screen { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background-color: rgba(0, 0, 0, 0.8); | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 200; | |
| color: white; | |
| } | |
| #instructions { | |
| position: absolute; | |
| bottom: 20px; | |
| left: 20px; | |
| color: white; | |
| background-color: rgba(0, 0, 0, 0.5); | |
| padding: 10px; | |
| border-radius: 5px; | |
| z-index: 10; | |
| } | |
| .target-hit { | |
| position: absolute; | |
| color: red; | |
| font-size: 24px; | |
| font-weight: bold; | |
| animation: fadeOut 1s forwards; | |
| } | |
| @keyframes fadeOut { | |
| to { | |
| opacity: 0; | |
| transform: translateY(-50px); | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="container"> | |
| <div id="crosshair"> | |
| <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> | |
| <circle cx="50" cy="50" r="40" fill="none" stroke="white" stroke-width="2"/> | |
| <line x1="50" y1="10" x2="50" y2="30" stroke="white" stroke-width="2"/> | |
| <line x1="50" y1="70" x2="50" y2="90" stroke="white" stroke-width="2"/> | |
| <line x1="10" y1="50" x2="30" y2="50" stroke="white" stroke-width="2"/> | |
| <line x1="70" y1="50" x2="90" y2="50" stroke="white" stroke-width="2"/> | |
| </svg> | |
| </div> | |
| <div id="ui"> | |
| <div class="flex justify-between"> | |
| <div> | |
| <h2 class="text-xl font-bold">3D射击跟枪练习器</h2> | |
| <p>提高你的Roblox射击跟枪技巧</p> | |
| </div> | |
| <div class="text-right"> | |
| <p class="text-lg">得分: <span id="score">0</span></p> | |
| <p>命中率: <span id="accuracy">0</span>%</p> | |
| <p>剩余时间: <span id="time">60</span>秒</p> | |
| <p>剩余敌人: <span id="enemies">5</span></p> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="start-screen"> | |
| <h1 class="text-4xl font-bold mb-8">3D射击跟枪练习器</h1> | |
| <p class="text-xl mb-8">练习你的跟枪技巧,提高Roblox游戏中的表现</p> | |
| <div class="mb-8"> | |
| <label for="difficulty" class="block mb-2">选择难度:</label> | |
| <select id="difficulty" class="bg-gray-700 text-white p-2 rounded"> | |
| <option value="easy">简单</option> | |
| <option value="medium" selected>中等</option> | |
| <option value="hard">困难</option> | |
| <option value="extreme">极限</option> | |
| </select> | |
| </div> | |
| <button id="start-btn" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-full text-xl transition duration-300"> | |
| 开始练习 | |
| </button> | |
| </div> | |
| <div id="instructions"> | |
| <p>WASD: 移动</p> | |
| <p>鼠标: 瞄准</p> | |
| <p>左键: 射击</p> | |
| <p>空格: 跳跃</p> | |
| <p>Shift: 冲刺</p> | |
| </div> | |
| </div> | |
| <script> | |
| // 游戏变量 | |
| let scene, camera, renderer, controls; | |
| let enemies = []; | |
| let score = 0; | |
| let shotsFired = 0; | |
| let hits = 0; | |
| let gameTime = 60; | |
| let gameInterval; | |
| let difficulty = 'medium'; | |
| let gameStarted = false; | |
| let clock = new THREE.Clock(); | |
| let player, playerVelocity = new THREE.Vector3(); | |
| let playerDirection = new THREE.Vector3(); | |
| let moveForward = false; | |
| let moveBackward = false; | |
| let moveLeft = false; | |
| let moveRight = false; | |
| let canJump = true; | |
| let isSprinting = false; | |
| let pointerLockEnabled = false; | |
| // 初始化Three.js场景 | |
| function init() { | |
| // 创建场景 | |
| scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(0x88ccff); | |
| scene.fog = new THREE.FogExp2(0x88ccff, 0.002); | |
| // 创建相机 | |
| camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
| camera.position.y = 1.6; | |
| // 创建渲染器 | |
| renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| document.getElementById('container').prepend(renderer.domElement); | |
| // 添加光线 | |
| const ambientLight = new THREE.AmbientLight(0x404040); | |
| scene.add(ambientLight); | |
| const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); | |
| directionalLight.position.set(1, 1, 1); | |
| scene.add(directionalLight); | |
| // 添加地面 | |
| const groundGeometry = new THREE.PlaneGeometry(100, 100); | |
| const groundMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0x3a5f0b, | |
| roughness: 0.8, | |
| metalness: 0.2 | |
| }); | |
| const ground = new THREE.Mesh(groundGeometry, groundMaterial); | |
| ground.rotation.x = -Math.PI / 2; | |
| ground.receiveShadow = true; | |
| scene.add(ground); | |
| // 添加障碍物 | |
| addObstacles(); | |
| // 创建玩家角色 | |
| createPlayer(); | |
| // 初始化指针锁定控制 | |
| controls = new THREE.PointerLockControls(camera, document.body); | |
| // 添加事件监听器 | |
| window.addEventListener('resize', onWindowResize); | |
| document.addEventListener('click', onMouseClick, false); | |
| document.addEventListener('keydown', onKeyDown); | |
| document.addEventListener('keyup', onKeyUp); | |
| // 指针锁定状态变化事件 | |
| document.addEventListener('pointerlockchange', onPointerLockChange, false); | |
| document.addEventListener('mozpointerlockchange', onPointerLockChange, false); | |
| document.addEventListener('webkitpointerlockchange', onPointerLockChange, false); | |
| // 开始按钮事件 | |
| document.getElementById('start-btn').addEventListener('click', function() { | |
| // 先请求指针锁定 | |
| const element = document.body; | |
| element.requestPointerLock = element.requestPointerLock || | |
| element.mozRequestPointerLock || | |
| element.webkitRequestPointerLock; | |
| element.requestPointerLock(); | |
| }); | |
| // 难度选择 | |
| document.getElementById('difficulty').addEventListener('change', function(e) { | |
| difficulty = e.target.value; | |
| }); | |
| // 开始动画循环 | |
| animate(); | |
| } | |
| // 指针锁定状态变化处理 | |
| function onPointerLockChange() { | |
| pointerLockEnabled = (document.pointerLockElement === document.body || | |
| document.mozPointerLockElement === document.body || | |
| document.webkitPointerLockElement === document.body); | |
| if (pointerLockEnabled && !gameStarted) { | |
| // 指针锁定成功后开始游戏 | |
| startGame(); | |
| } else if (!pointerLockEnabled && gameStarted) { | |
| // 指针锁定丢失时暂停游戏 | |
| pauseGame(); | |
| } | |
| } | |
| // 添加障碍物 | |
| function addObstacles() { | |
| const boxGeometry = new THREE.BoxGeometry(5, 5, 5); | |
| const boxMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0x8b4513, | |
| roughness: 0.7, | |
| metalness: 0.3 | |
| }); | |
| // 添加几个箱子作为障碍物 | |
| for (let i = 0; i < 10; i++) { | |
| const box = new THREE.Mesh(boxGeometry, boxMaterial); | |
| box.position.x = Math.random() * 80 - 40; | |
| box.position.z = Math.random() * 80 - 40; | |
| box.position.y = 2.5; | |
| box.castShadow = true; | |
| box.receiveShadow = true; | |
| scene.add(box); | |
| } | |
| // 添加一些墙 | |
| const wallGeometry = new THREE.BoxGeometry(1, 3, 20); | |
| const wallMaterial = new THREE.MeshStandardMaterial({ color: 0x7f7f7f }); | |
| for (let i = 0; i < 5; i++) { | |
| const wall = new THREE.Mesh(wallGeometry, wallMaterial); | |
| wall.position.x = Math.random() * 60 - 30; | |
| wall.position.z = Math.random() * 60 - 30; | |
| wall.position.y = 1.5; | |
| wall.castShadow = true; | |
| wall.receiveShadow = true; | |
| scene.add(wall); | |
| } | |
| } | |
| // 创建玩家角色 | |
| function createPlayer() { | |
| // 简单的玩家表示(只是一个立方体) | |
| const geometry = new THREE.BoxGeometry(0.5, 1.8, 0.5); | |
| const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true }); | |
| player = new THREE.Mesh(geometry, material); | |
| player.position.y = 1.8; | |
| player.visible = false; // 我们不渲染玩家模型,因为它是第一人称视角 | |
| scene.add(player); | |
| } | |
| // 窗口大小调整 | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| // 鼠标点击事件 | |
| function onMouseClick(event) { | |
| if (!gameStarted || !pointerLockEnabled) return; | |
| // 只在游戏开始且指针锁定状态下处理射击 | |
| if (event.button === 0) { // 左键点击 | |
| shotsFired++; | |
| updateAccuracy(); | |
| // 设置光线投射器 | |
| const raycaster = new THREE.Raycaster(); | |
| raycaster.setFromCamera(new THREE.Vector2(0, 0), camera); | |
| // 检测与敌人的碰撞 | |
| const intersects = raycaster.intersectObjects(enemies); | |
| if (intersects.length > 0) { | |
| const enemy = intersects[0].object; | |
| // 移除敌人 | |
| scene.remove(enemy); | |
| enemies = enemies.filter(e => e !== enemy); | |
| document.getElementById('enemies').textContent = enemies.length; | |
| // 增加分数 | |
| score += 10; | |
| document.getElementById('score').textContent = score; | |
| // 增加命中数 | |
| hits++; | |
| updateAccuracy(); | |
| // 显示命中效果 | |
| showHitEffect(); | |
| // 检查是否所有敌人都被消灭 | |
| if (enemies.length === 0) { | |
| endGame(true); | |
| } | |
| } | |
| } | |
| } | |
| // 显示命中效果 | |
| function showHitEffect() { | |
| const hitEffect = document.createElement('div'); | |
| hitEffect.className = 'target-hit'; | |
| hitEffect.textContent = '+10'; | |
| hitEffect.style.left = '50%'; | |
| hitEffect.style.top = '50%'; | |
| document.getElementById('container').appendChild(hitEffect); | |
| setTimeout(() => { | |
| hitEffect.remove(); | |
| }, 1000); | |
| } | |
| // 更新命中率 | |
| function updateAccuracy() { | |
| const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0; | |
| document.getElementById('accuracy').textContent = accuracy; | |
| } | |
| // 键盘按下事件 | |
| function onKeyDown(event) { | |
| if (!gameStarted || !pointerLockEnabled) return; | |
| switch(event.code) { | |
| case 'KeyW': moveForward = true; break; | |
| case 'KeyA': moveLeft = true; break; | |
| case 'KeyS': moveBackward = true; break; | |
| case 'KeyD': moveRight = true; break; | |
| case 'Space': | |
| if (canJump) { | |
| playerVelocity.y += 15; | |
| canJump = false; | |
| } | |
| break; | |
| case 'ShiftLeft': | |
| isSprinting = true; | |
| break; | |
| case 'Escape': | |
| // ESC键退出指针锁定 | |
| document.exitPointerLock = document.exitPointerLock || | |
| document.mozExitPointerLock || | |
| document.webkitExitPointerLock; | |
| document.exitPointerLock(); | |
| break; | |
| } | |
| } | |
| // 键盘释放事件 | |
| function onKeyUp(event) { | |
| if (!gameStarted || !pointerLockEnabled) return; | |
| switch(event.code) { | |
| case 'KeyW': moveForward = false; break; | |
| case 'KeyA': moveLeft = false; break; | |
| case 'KeyS': moveBackward = false; break; | |
| case 'KeyD': moveRight = false; break; | |
| case 'ShiftLeft': | |
| isSprinting = false; | |
| break; | |
| } | |
| } | |
| // 创建敌人 | |
| function createEnemy() { | |
| const enemyGeometry = new THREE.BoxGeometry(0.8, 1.8, 0.8); | |
| const enemyMaterial = new THREE.MeshStandardMaterial({ | |
| color: 0xff0000, | |
| roughness: 0.7, | |
| metalness: 0.3 | |
| }); | |
| const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial); | |
| // 随机位置,但远离玩家 | |
| let x, z; | |
| do { | |
| x = (Math.random() * 60) - 30; | |
| z = (Math.random() * 60) - 30; | |
| } while (Math.sqrt(x*x + z*z) < 10); // 确保敌人不会生成在玩家附近 | |
| enemy.position.set(x, 0.9, z); | |
| enemy.castShadow = true; | |
| enemy.receiveShadow = true; | |
| scene.add(enemy); | |
| enemies.push(enemy); | |
| // 添加敌人AI行为 | |
| animateEnemy(enemy); | |
| } | |
| // 敌人AI行为 | |
| function animateEnemy(enemy) { | |
| let speed = 0.02; | |
| let directionChangeTime = 0; | |
| let currentDirection = new THREE.Vector3( | |
| Math.random() * 2 - 1, | |
| 0, | |
| Math.random() * 2 - 1 | |
| ).normalize(); | |
| // 根据难度调整速度 | |
| switch(difficulty) { | |
| case 'easy': speed = 0.015; break; | |
| case 'medium': speed = 0.025; break; | |
| case 'hard': speed = 0.035; break; | |
| case 'extreme': speed = 0.045; break; | |
| } | |
| function move() { | |
| if (!gameStarted) return; | |
| // 定期改变方向 | |
| directionChangeTime--; | |
| if (directionChangeTime <= 0) { | |
| // 有时会朝玩家移动 | |
| if (Math.random() > 0.7) { | |
| currentDirection = new THREE.Vector3().subVectors( | |
| player.position, | |
| enemy.position | |
| ).normalize(); | |
| } else { | |
| currentDirection = new THREE.Vector3( | |
| Math.random() * 2 - 1, | |
| 0, | |
| Math.random() * 2 - 1 | |
| ).normalize(); | |
| } | |
| directionChangeTime = 100 + Math.random() * 100; | |
| } | |
| // 移动敌人 | |
| enemy.position.x += currentDirection.x * speed; | |
| enemy.position.z += currentDirection.z * speed; | |
| // 确保敌人不会离开地图 | |
| if (enemy.position.x < -45) enemy.position.x = -45; | |
| if (enemy.position.x > 45) enemy.position.x = 45; | |
| if (enemy.position.z < -45) enemy.position.z = -45; | |
| if (enemy.position.z > 45) enemy.position.z = 45; | |
| // 面向玩家 | |
| enemy.lookAt(player.position); | |
| requestAnimationFrame(move); | |
| } | |
| move(); | |
| } | |
| // 开始游戏 | |
| function startGame() { | |
| // 重置游戏状态 | |
| score = 0; | |
| shotsFired = 0; | |
| hits = 0; | |
| gameTime = 60; | |
| gameStarted = true; | |
| // 更新UI | |
| document.getElementById('score').textContent = score; | |
| document.getElementById('accuracy').textContent = '0'; | |
| document.getElementById('time').textContent = gameTime; | |
| // 隐藏开始屏幕 | |
| document.getElementById('start-screen').style.display = 'none'; | |
| // 清除现有敌人 | |
| enemies.forEach(enemy => scene.remove(enemy)); | |
| enemies = []; | |
| // 创建初始敌人 | |
| const enemyCount = difficulty === 'easy' ? 3 : | |
| difficulty === 'medium' ? 5 : | |
| difficulty === 'hard' ? 7 : 10; | |
| for (let i = 0; i < enemyCount; i++) { | |
| createEnemy(); | |
| } | |
| document.getElementById('enemies').textContent = enemyCount; | |
| // 重置玩家位置 | |
| player.position.set(0, 1.8, 0); | |
| controls.getObject().position.set(0, 1.6, 0); | |
| controls.getObject().rotation.set(0, 0, 0); | |
| // 开始计时器 | |
| gameInterval = setInterval(() => { | |
| gameTime--; | |
| document.getElementById('time').textContent = gameTime; | |
| if (gameTime <= 0) { | |
| endGame(false); | |
| } | |
| }, 1000); | |
| } | |
| // 暂停游戏 | |
| function pauseGame() { | |
| // 显示开始屏幕 | |
| const startScreen = document.getElementById('start-screen'); | |
| startScreen.style.display = 'flex'; | |
| // 更新结果 | |
| const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0; | |
| startScreen.innerHTML = ` | |
| <h1 class="text-4xl font-bold mb-8">游戏暂停</h1> | |
| <div class="text-xl mb-8"> | |
| <p>当前得分: ${score}</p> | |
| <p>命中率: ${accuracy}%</p> | |
| <p>总射击次数: ${shotsFired}</p> | |
| <p>命中次数: ${hits}</p> | |
| <p>剩余敌人: ${enemies.length}</p> | |
| </div> | |
| <div class="mb-8"> | |
| <label for="difficulty" class="block mb-2">选择难度:</label> | |
| <select id="difficulty" class="bg-gray-700 text-white p-2 rounded"> | |
| <option value="easy">简单</option> | |
| <option value="medium" selected>中等</option> | |
| <option value="hard">困难</option> | |
| <option value="extreme">极限</option> | |
| </select> | |
| </div> | |
| <button id="start-btn" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-full text-xl transition duration-300"> | |
| 继续游戏 | |
| </button> | |
| `; | |
| // 重新添加事件监听器 | |
| document.getElementById('start-btn').addEventListener('click', function() { | |
| // 重新请求指针锁定 | |
| const element = document.body; | |
| element.requestPointerLock = element.requestPointerLock || | |
| element.mozRequestPointerLock || | |
| element.webkitRequestPointerLock; | |
| element.requestPointerLock(); | |
| }); | |
| document.getElementById('difficulty').addEventListener('change', function(e) { | |
| difficulty = e.target.value; | |
| }); | |
| } | |
| // 结束游戏 | |
| function endGame(win) { | |
| gameStarted = false; | |
| clearInterval(gameInterval); | |
| // 解锁指针 | |
| document.exitPointerLock = document.exitPointerLock || | |
| document.mozExitPointerLock || | |
| document.webkitExitPointerLock; | |
| document.exitPointerLock(); | |
| // 显示开始屏幕 | |
| const startScreen = document.getElementById('start-screen'); | |
| startScreen.style.display = 'flex'; | |
| // 更新结果 | |
| const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0; | |
| startScreen.innerHTML = ` | |
| <h1 class="text-4xl font-bold mb-8">${win ? '胜利!' : '游戏结束'}</h1> | |
| <div class="text-xl mb-8"> | |
| <p>最终得分: ${score}</p> | |
| <p>命中率: ${accuracy}%</p> | |
| <p>总射击次数: ${shotsFired}</p> | |
| <p>命中次数: ${hits}</p> | |
| <p>剩余敌人: ${enemies.length}</p> | |
| </div> | |
| <div class="mb-8"> | |
| <label for="difficulty" class="block mb-2">选择难度:</label> | |
| <select id="difficulty" class="bg-gray-700 text-white p-2 rounded"> | |
| <option value="easy">简单</option> | |
| <option value="medium" selected>中等</option> | |
| <option value="hard">困难</option> | |
| <option value="extreme">极限</option> | |
| </select> | |
| </div> | |
| <button id="start-btn" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-full text-xl transition duration-300"> | |
| 再玩一次 | |
| </button> | |
| `; | |
| // 重新添加事件监听器 | |
| document.getElementById('start-btn').addEventListener('click', function() { | |
| // 重新请求指针锁定 | |
| const element = document.body; | |
| element.requestPointerLock = element.requestPointerLock || | |
| element.mozRequestPointerLock || | |
| element.webkitRequestPointerLock; | |
| element.requestPointerLock(); | |
| }); | |
| document.getElementById('difficulty').addEventListener('change', function(e) { | |
| difficulty = e.target.value; | |
| }); | |
| } | |
| // 动画循环 | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| const delta = clock.getDelta(); | |
| if (controls.isLocked && gameStarted) { | |
| // 玩家移动 | |
| const speed = isSprinting ? 30 : 15; | |
| playerVelocity.x -= playerVelocity.x * 10.0 * delta; | |
| playerVelocity.z -= playerVelocity.z * 10.0 * delta; | |
| playerDirection.z = Number(moveForward) - Number(moveBackward); | |
| playerDirection.x = Number(moveRight) - Number(moveLeft); | |
| playerDirection.normalize(); | |
| if (moveForward || moveBackward) playerVelocity.z -= playerDirection.z * speed * delta; | |
| if (moveLeft || moveRight) playerVelocity.x -= playerDirection.x * speed * delta; | |
| // 应用重力 | |
| playerVelocity.y -= 9.8 * delta; | |
| // 更新玩家位置 | |
| controls.moveRight(-playerVelocity.x * delta); | |
| controls.moveForward(-playerVelocity.z * delta); | |
| controls.getObject().position.y += playerVelocity.y * delta; | |
| // 确保玩家不会掉出地图 | |
| if (controls.getObject().position.y < 1.6) { | |
| playerVelocity.y = 0; | |
| controls.getObject().position.y = 1.6; | |
| canJump = true; | |
| } | |
| // 确保玩家不会离开地图 | |
| const pos = controls.getObject().position; | |
| if (pos.x < -45) pos.x = -45; | |
| if (pos.x > 45) pos.x = 45; | |
| if (pos.z < -45) pos.z = -45; | |
| if (pos.z > 45) pos.z = 45; | |
| // 更新玩家模型位置(用于敌人AI) | |
| player.position.copy(controls.getObject().position); | |
| player.position.y += 0.2; // 调整高度差 | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| // 初始化游戏 | |
| init(); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Aprec/test" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body> | |
| </html> |