Aprec commited on
Commit
5f5a503
·
verified ·
1 Parent(s): 8b2c378

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +694 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Test
3
- emoji: 🏢
4
- colorFrom: green
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: test
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,694 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>3D射击跟枪练习器</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/PointerLockControls.js"></script>
10
+ <style>
11
+ body {
12
+ margin: 0;
13
+ overflow: hidden;
14
+ font-family: 'Arial', sans-serif;
15
+ }
16
+ #container {
17
+ position: relative;
18
+ width: 100%;
19
+ height: 100vh;
20
+ }
21
+ #crosshair {
22
+ position: absolute;
23
+ top: 50%;
24
+ left: 50%;
25
+ transform: translate(-50%, -50%);
26
+ width: 30px;
27
+ height: 30px;
28
+ pointer-events: none;
29
+ z-index: 100;
30
+ }
31
+ #ui {
32
+ position: absolute;
33
+ top: 0;
34
+ left: 0;
35
+ width: 100%;
36
+ padding: 20px;
37
+ color: white;
38
+ background-color: rgba(0, 0, 0, 0.5);
39
+ z-index: 10;
40
+ }
41
+ #start-screen {
42
+ position: absolute;
43
+ top: 0;
44
+ left: 0;
45
+ width: 100%;
46
+ height: 100%;
47
+ background-color: rgba(0, 0, 0, 0.8);
48
+ display: flex;
49
+ flex-direction: column;
50
+ justify-content: center;
51
+ align-items: center;
52
+ z-index: 200;
53
+ color: white;
54
+ }
55
+ #instructions {
56
+ position: absolute;
57
+ bottom: 20px;
58
+ left: 20px;
59
+ color: white;
60
+ background-color: rgba(0, 0, 0, 0.5);
61
+ padding: 10px;
62
+ border-radius: 5px;
63
+ z-index: 10;
64
+ }
65
+ .target-hit {
66
+ position: absolute;
67
+ color: red;
68
+ font-size: 24px;
69
+ font-weight: bold;
70
+ animation: fadeOut 1s forwards;
71
+ }
72
+ @keyframes fadeOut {
73
+ to {
74
+ opacity: 0;
75
+ transform: translateY(-50px);
76
+ }
77
+ }
78
+ </style>
79
+ </head>
80
+ <body>
81
+ <div id="container">
82
+ <div id="crosshair">
83
+ <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
84
+ <circle cx="50" cy="50" r="40" fill="none" stroke="white" stroke-width="2"/>
85
+ <line x1="50" y1="10" x2="50" y2="30" stroke="white" stroke-width="2"/>
86
+ <line x1="50" y1="70" x2="50" y2="90" stroke="white" stroke-width="2"/>
87
+ <line x1="10" y1="50" x2="30" y2="50" stroke="white" stroke-width="2"/>
88
+ <line x1="70" y1="50" x2="90" y2="50" stroke="white" stroke-width="2"/>
89
+ </svg>
90
+ </div>
91
+
92
+ <div id="ui">
93
+ <div class="flex justify-between">
94
+ <div>
95
+ <h2 class="text-xl font-bold">3D射击跟枪练习器</h2>
96
+ <p>提高你的Roblox射击跟枪技巧</p>
97
+ </div>
98
+ <div class="text-right">
99
+ <p class="text-lg">得分: <span id="score">0</span></p>
100
+ <p>命中率: <span id="accuracy">0</span>%</p>
101
+ <p>剩余时间: <span id="time">60</span>秒</p>
102
+ <p>剩余敌人: <span id="enemies">5</span></p>
103
+ </div>
104
+ </div>
105
+ </div>
106
+
107
+ <div id="start-screen">
108
+ <h1 class="text-4xl font-bold mb-8">3D射击跟枪练习器</h1>
109
+ <p class="text-xl mb-8">练习你的跟枪技巧,提高Roblox游戏中的表现</p>
110
+ <div class="mb-8">
111
+ <label for="difficulty" class="block mb-2">选择难度:</label>
112
+ <select id="difficulty" class="bg-gray-700 text-white p-2 rounded">
113
+ <option value="easy">简单</option>
114
+ <option value="medium" selected>中等</option>
115
+ <option value="hard">困难</option>
116
+ <option value="extreme">极限</option>
117
+ </select>
118
+ </div>
119
+ <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">
120
+ 开始练习
121
+ </button>
122
+ </div>
123
+
124
+ <div id="instructions">
125
+ <p>WASD: 移动</p>
126
+ <p>鼠标: 瞄准</p>
127
+ <p>左键: 射击</p>
128
+ <p>空格: 跳跃</p>
129
+ <p>Shift: 冲刺</p>
130
+ </div>
131
+ </div>
132
+
133
+ <script>
134
+ // 游戏变量
135
+ let scene, camera, renderer, controls;
136
+ let enemies = [];
137
+ let score = 0;
138
+ let shotsFired = 0;
139
+ let hits = 0;
140
+ let gameTime = 60;
141
+ let gameInterval;
142
+ let difficulty = 'medium';
143
+ let gameStarted = false;
144
+ let clock = new THREE.Clock();
145
+ let player, playerVelocity = new THREE.Vector3();
146
+ let playerDirection = new THREE.Vector3();
147
+ let moveForward = false;
148
+ let moveBackward = false;
149
+ let moveLeft = false;
150
+ let moveRight = false;
151
+ let canJump = true;
152
+ let isSprinting = false;
153
+ let pointerLockEnabled = false;
154
+
155
+ // 初始化Three.js场景
156
+ function init() {
157
+ // 创建场景
158
+ scene = new THREE.Scene();
159
+ scene.background = new THREE.Color(0x88ccff);
160
+ scene.fog = new THREE.FogExp2(0x88ccff, 0.002);
161
+
162
+ // 创建相机
163
+ camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
164
+ camera.position.y = 1.6;
165
+
166
+ // 创建渲染器
167
+ renderer = new THREE.WebGLRenderer({ antialias: true });
168
+ renderer.setPixelRatio(window.devicePixelRatio);
169
+ renderer.setSize(window.innerWidth, window.innerHeight);
170
+ document.getElementById('container').prepend(renderer.domElement);
171
+
172
+ // 添加光线
173
+ const ambientLight = new THREE.AmbientLight(0x404040);
174
+ scene.add(ambientLight);
175
+
176
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
177
+ directionalLight.position.set(1, 1, 1);
178
+ scene.add(directionalLight);
179
+
180
+ // 添加地面
181
+ const groundGeometry = new THREE.PlaneGeometry(100, 100);
182
+ const groundMaterial = new THREE.MeshStandardMaterial({
183
+ color: 0x3a5f0b,
184
+ roughness: 0.8,
185
+ metalness: 0.2
186
+ });
187
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
188
+ ground.rotation.x = -Math.PI / 2;
189
+ ground.receiveShadow = true;
190
+ scene.add(ground);
191
+
192
+ // 添加障碍物
193
+ addObstacles();
194
+
195
+ // 创建玩家角色
196
+ createPlayer();
197
+
198
+ // 初始化指针锁定控制
199
+ controls = new THREE.PointerLockControls(camera, document.body);
200
+
201
+ // 添加事件监听器
202
+ window.addEventListener('resize', onWindowResize);
203
+ document.addEventListener('click', onMouseClick, false);
204
+ document.addEventListener('keydown', onKeyDown);
205
+ document.addEventListener('keyup', onKeyUp);
206
+
207
+ // 指针锁定状态变化事件
208
+ document.addEventListener('pointerlockchange', onPointerLockChange, false);
209
+ document.addEventListener('mozpointerlockchange', onPointerLockChange, false);
210
+ document.addEventListener('webkitpointerlockchange', onPointerLockChange, false);
211
+
212
+ // 开始按钮事件
213
+ document.getElementById('start-btn').addEventListener('click', function() {
214
+ // 先请求指针锁定
215
+ const element = document.body;
216
+ element.requestPointerLock = element.requestPointerLock ||
217
+ element.mozRequestPointerLock ||
218
+ element.webkitRequestPointerLock;
219
+ element.requestPointerLock();
220
+ });
221
+
222
+ // 难度选择
223
+ document.getElementById('difficulty').addEventListener('change', function(e) {
224
+ difficulty = e.target.value;
225
+ });
226
+
227
+ // 开始动画循环
228
+ animate();
229
+ }
230
+
231
+ // 指针锁定状态变化处理
232
+ function onPointerLockChange() {
233
+ pointerLockEnabled = (document.pointerLockElement === document.body ||
234
+ document.mozPointerLockElement === document.body ||
235
+ document.webkitPointerLockElement === document.body);
236
+
237
+ if (pointerLockEnabled && !gameStarted) {
238
+ // 指针锁定成功后开始游戏
239
+ startGame();
240
+ } else if (!pointerLockEnabled && gameStarted) {
241
+ // 指针锁定丢失时暂停游戏
242
+ pauseGame();
243
+ }
244
+ }
245
+
246
+ // 添加障碍物
247
+ function addObstacles() {
248
+ const boxGeometry = new THREE.BoxGeometry(5, 5, 5);
249
+ const boxMaterial = new THREE.MeshStandardMaterial({
250
+ color: 0x8b4513,
251
+ roughness: 0.7,
252
+ metalness: 0.3
253
+ });
254
+
255
+ // 添加几个箱子作为障碍物
256
+ for (let i = 0; i < 10; i++) {
257
+ const box = new THREE.Mesh(boxGeometry, boxMaterial);
258
+ box.position.x = Math.random() * 80 - 40;
259
+ box.position.z = Math.random() * 80 - 40;
260
+ box.position.y = 2.5;
261
+ box.castShadow = true;
262
+ box.receiveShadow = true;
263
+ scene.add(box);
264
+ }
265
+
266
+ // 添加一些墙
267
+ const wallGeometry = new THREE.BoxGeometry(1, 3, 20);
268
+ const wallMaterial = new THREE.MeshStandardMaterial({ color: 0x7f7f7f });
269
+
270
+ for (let i = 0; i < 5; i++) {
271
+ const wall = new THREE.Mesh(wallGeometry, wallMaterial);
272
+ wall.position.x = Math.random() * 60 - 30;
273
+ wall.position.z = Math.random() * 60 - 30;
274
+ wall.position.y = 1.5;
275
+ wall.castShadow = true;
276
+ wall.receiveShadow = true;
277
+ scene.add(wall);
278
+ }
279
+ }
280
+
281
+ // 创建玩家角色
282
+ function createPlayer() {
283
+ // 简单的玩家表示(只是一个立方体)
284
+ const geometry = new THREE.BoxGeometry(0.5, 1.8, 0.5);
285
+ const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
286
+ player = new THREE.Mesh(geometry, material);
287
+ player.position.y = 1.8;
288
+ player.visible = false; // 我们不渲染玩家模型,因为它是第一人称视角
289
+ scene.add(player);
290
+ }
291
+
292
+ // 窗口大小调整
293
+ function onWindowResize() {
294
+ camera.aspect = window.innerWidth / window.innerHeight;
295
+ camera.updateProjectionMatrix();
296
+ renderer.setSize(window.innerWidth, window.innerHeight);
297
+ }
298
+
299
+ // 鼠标点击事件
300
+ function onMouseClick(event) {
301
+ if (!gameStarted || !pointerLockEnabled) return;
302
+
303
+ // 只在游戏开始且指针锁定状态下处理射击
304
+ if (event.button === 0) { // 左键点击
305
+ shotsFired++;
306
+ updateAccuracy();
307
+
308
+ // 设置光线投射器
309
+ const raycaster = new THREE.Raycaster();
310
+ raycaster.setFromCamera(new THREE.Vector2(0, 0), camera);
311
+
312
+ // 检测与敌人的碰撞
313
+ const intersects = raycaster.intersectObjects(enemies);
314
+
315
+ if (intersects.length > 0) {
316
+ const enemy = intersects[0].object;
317
+
318
+ // 移除敌人
319
+ scene.remove(enemy);
320
+ enemies = enemies.filter(e => e !== enemy);
321
+ document.getElementById('enemies').textContent = enemies.length;
322
+
323
+ // 增加分数
324
+ score += 10;
325
+ document.getElementById('score').textContent = score;
326
+
327
+ // 增加命中数
328
+ hits++;
329
+ updateAccuracy();
330
+
331
+ // 显示命中效果
332
+ showHitEffect();
333
+
334
+ // 检查是否所有敌人都被消灭
335
+ if (enemies.length === 0) {
336
+ endGame(true);
337
+ }
338
+ }
339
+ }
340
+ }
341
+
342
+ // 显示命中效果
343
+ function showHitEffect() {
344
+ const hitEffect = document.createElement('div');
345
+ hitEffect.className = 'target-hit';
346
+ hitEffect.textContent = '+10';
347
+ hitEffect.style.left = '50%';
348
+ hitEffect.style.top = '50%';
349
+ document.getElementById('container').appendChild(hitEffect);
350
+
351
+ setTimeout(() => {
352
+ hitEffect.remove();
353
+ }, 1000);
354
+ }
355
+
356
+ // 更新命中率
357
+ function updateAccuracy() {
358
+ const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0;
359
+ document.getElementById('accuracy').textContent = accuracy;
360
+ }
361
+
362
+ // 键盘按下事件
363
+ function onKeyDown(event) {
364
+ if (!gameStarted || !pointerLockEnabled) return;
365
+
366
+ switch(event.code) {
367
+ case 'KeyW': moveForward = true; break;
368
+ case 'KeyA': moveLeft = true; break;
369
+ case 'KeyS': moveBackward = true; break;
370
+ case 'KeyD': moveRight = true; break;
371
+ case 'Space':
372
+ if (canJump) {
373
+ playerVelocity.y += 15;
374
+ canJump = false;
375
+ }
376
+ break;
377
+ case 'ShiftLeft':
378
+ isSprinting = true;
379
+ break;
380
+ case 'Escape':
381
+ // ESC键退出指针锁定
382
+ document.exitPointerLock = document.exitPointerLock ||
383
+ document.mozExitPointerLock ||
384
+ document.webkitExitPointerLock;
385
+ document.exitPointerLock();
386
+ break;
387
+ }
388
+ }
389
+
390
+ // 键盘释放事件
391
+ function onKeyUp(event) {
392
+ if (!gameStarted || !pointerLockEnabled) return;
393
+
394
+ switch(event.code) {
395
+ case 'KeyW': moveForward = false; break;
396
+ case 'KeyA': moveLeft = false; break;
397
+ case 'KeyS': moveBackward = false; break;
398
+ case 'KeyD': moveRight = false; break;
399
+ case 'ShiftLeft':
400
+ isSprinting = false;
401
+ break;
402
+ }
403
+ }
404
+
405
+ // 创建敌人
406
+ function createEnemy() {
407
+ const enemyGeometry = new THREE.BoxGeometry(0.8, 1.8, 0.8);
408
+ const enemyMaterial = new THREE.MeshStandardMaterial({
409
+ color: 0xff0000,
410
+ roughness: 0.7,
411
+ metalness: 0.3
412
+ });
413
+ const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
414
+
415
+ // 随机位置,但远离玩家
416
+ let x, z;
417
+ do {
418
+ x = (Math.random() * 60) - 30;
419
+ z = (Math.random() * 60) - 30;
420
+ } while (Math.sqrt(x*x + z*z) < 10); // 确保敌人不会生成在玩家附近
421
+
422
+ enemy.position.set(x, 0.9, z);
423
+ enemy.castShadow = true;
424
+ enemy.receiveShadow = true;
425
+ scene.add(enemy);
426
+ enemies.push(enemy);
427
+
428
+ // 添加敌人AI行为
429
+ animateEnemy(enemy);
430
+ }
431
+
432
+ // 敌人AI行为
433
+ function animateEnemy(enemy) {
434
+ let speed = 0.02;
435
+ let directionChangeTime = 0;
436
+ let currentDirection = new THREE.Vector3(
437
+ Math.random() * 2 - 1,
438
+ 0,
439
+ Math.random() * 2 - 1
440
+ ).normalize();
441
+
442
+ // 根据难度调整速度
443
+ switch(difficulty) {
444
+ case 'easy': speed = 0.015; break;
445
+ case 'medium': speed = 0.025; break;
446
+ case 'hard': speed = 0.035; break;
447
+ case 'extreme': speed = 0.045; break;
448
+ }
449
+
450
+ function move() {
451
+ if (!gameStarted) return;
452
+
453
+ // 定期改变方向
454
+ directionChangeTime--;
455
+ if (directionChangeTime <= 0) {
456
+ // 有时会朝玩家移动
457
+ if (Math.random() > 0.7) {
458
+ currentDirection = new THREE.Vector3().subVectors(
459
+ player.position,
460
+ enemy.position
461
+ ).normalize();
462
+ } else {
463
+ currentDirection = new THREE.Vector3(
464
+ Math.random() * 2 - 1,
465
+ 0,
466
+ Math.random() * 2 - 1
467
+ ).normalize();
468
+ }
469
+ directionChangeTime = 100 + Math.random() * 100;
470
+ }
471
+
472
+ // 移动敌人
473
+ enemy.position.x += currentDirection.x * speed;
474
+ enemy.position.z += currentDirection.z * speed;
475
+
476
+ // 确保敌人不会离开地图
477
+ if (enemy.position.x < -45) enemy.position.x = -45;
478
+ if (enemy.position.x > 45) enemy.position.x = 45;
479
+ if (enemy.position.z < -45) enemy.position.z = -45;
480
+ if (enemy.position.z > 45) enemy.position.z = 45;
481
+
482
+ // 面向玩家
483
+ enemy.lookAt(player.position);
484
+
485
+ requestAnimationFrame(move);
486
+ }
487
+
488
+ move();
489
+ }
490
+
491
+ // 开始游戏
492
+ function startGame() {
493
+ // 重置游戏状态
494
+ score = 0;
495
+ shotsFired = 0;
496
+ hits = 0;
497
+ gameTime = 60;
498
+ gameStarted = true;
499
+
500
+ // 更新UI
501
+ document.getElementById('score').textContent = score;
502
+ document.getElementById('accuracy').textContent = '0';
503
+ document.getElementById('time').textContent = gameTime;
504
+
505
+ // 隐藏开始屏幕
506
+ document.getElementById('start-screen').style.display = 'none';
507
+
508
+ // 清除现有敌人
509
+ enemies.forEach(enemy => scene.remove(enemy));
510
+ enemies = [];
511
+
512
+ // 创建初始敌人
513
+ const enemyCount = difficulty === 'easy' ? 3 :
514
+ difficulty === 'medium' ? 5 :
515
+ difficulty === 'hard' ? 7 : 10;
516
+
517
+ for (let i = 0; i < enemyCount; i++) {
518
+ createEnemy();
519
+ }
520
+
521
+ document.getElementById('enemies').textContent = enemyCount;
522
+
523
+ // 重置玩家位置
524
+ player.position.set(0, 1.8, 0);
525
+ controls.getObject().position.set(0, 1.6, 0);
526
+ controls.getObject().rotation.set(0, 0, 0);
527
+
528
+ // 开始计时器
529
+ gameInterval = setInterval(() => {
530
+ gameTime--;
531
+ document.getElementById('time').textContent = gameTime;
532
+
533
+ if (gameTime <= 0) {
534
+ endGame(false);
535
+ }
536
+ }, 1000);
537
+ }
538
+
539
+ // 暂停游戏
540
+ function pauseGame() {
541
+ // 显示开始屏幕
542
+ const startScreen = document.getElementById('start-screen');
543
+ startScreen.style.display = 'flex';
544
+
545
+ // 更新结果
546
+ const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0;
547
+ startScreen.innerHTML = `
548
+ <h1 class="text-4xl font-bold mb-8">游戏暂停</h1>
549
+ <div class="text-xl mb-8">
550
+ <p>当前得分: ${score}</p>
551
+ <p>命中率: ${accuracy}%</p>
552
+ <p>总射击次数: ${shotsFired}</p>
553
+ <p>命中次数: ${hits}</p>
554
+ <p>剩余敌人: ${enemies.length}</p>
555
+ </div>
556
+ <div class="mb-8">
557
+ <label for="difficulty" class="block mb-2">选择难度:</label>
558
+ <select id="difficulty" class="bg-gray-700 text-white p-2 rounded">
559
+ <option value="easy">简单</option>
560
+ <option value="medium" selected>中等</option>
561
+ <option value="hard">困难</option>
562
+ <option value="extreme">极限</option>
563
+ </select>
564
+ </div>
565
+ <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">
566
+ 继续游戏
567
+ </button>
568
+ `;
569
+
570
+ // 重新添加事件监听器
571
+ document.getElementById('start-btn').addEventListener('click', function() {
572
+ // 重新请求指针锁定
573
+ const element = document.body;
574
+ element.requestPointerLock = element.requestPointerLock ||
575
+ element.mozRequestPointerLock ||
576
+ element.webkitRequestPointerLock;
577
+ element.requestPointerLock();
578
+ });
579
+
580
+ document.getElementById('difficulty').addEventListener('change', function(e) {
581
+ difficulty = e.target.value;
582
+ });
583
+ }
584
+
585
+ // 结束游戏
586
+ function endGame(win) {
587
+ gameStarted = false;
588
+ clearInterval(gameInterval);
589
+
590
+ // 解锁指针
591
+ document.exitPointerLock = document.exitPointerLock ||
592
+ document.mozExitPointerLock ||
593
+ document.webkitExitPointerLock;
594
+ document.exitPointerLock();
595
+
596
+ // 显示开始屏幕
597
+ const startScreen = document.getElementById('start-screen');
598
+ startScreen.style.display = 'flex';
599
+
600
+ // 更新结果
601
+ const accuracy = shotsFired > 0 ? Math.round((hits / shotsFired) * 100) : 0;
602
+ startScreen.innerHTML = `
603
+ <h1 class="text-4xl font-bold mb-8">${win ? '胜利!' : '游戏结束'}</h1>
604
+ <div class="text-xl mb-8">
605
+ <p>最终得分: ${score}</p>
606
+ <p>命中率: ${accuracy}%</p>
607
+ <p>总射击次数: ${shotsFired}</p>
608
+ <p>命中次数: ${hits}</p>
609
+ <p>剩余敌人: ${enemies.length}</p>
610
+ </div>
611
+ <div class="mb-8">
612
+ <label for="difficulty" class="block mb-2">选择难度:</label>
613
+ <select id="difficulty" class="bg-gray-700 text-white p-2 rounded">
614
+ <option value="easy">简单</option>
615
+ <option value="medium" selected>中等</option>
616
+ <option value="hard">困难</option>
617
+ <option value="extreme">极限</option>
618
+ </select>
619
+ </div>
620
+ <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">
621
+ 再玩一次
622
+ </button>
623
+ `;
624
+
625
+ // 重新添加事件监听器
626
+ document.getElementById('start-btn').addEventListener('click', function() {
627
+ // 重新请求指针锁定
628
+ const element = document.body;
629
+ element.requestPointerLock = element.requestPointerLock ||
630
+ element.mozRequestPointerLock ||
631
+ element.webkitRequestPointerLock;
632
+ element.requestPointerLock();
633
+ });
634
+
635
+ document.getElementById('difficulty').addEventListener('change', function(e) {
636
+ difficulty = e.target.value;
637
+ });
638
+ }
639
+
640
+ // 动画循环
641
+ function animate() {
642
+ requestAnimationFrame(animate);
643
+
644
+ const delta = clock.getDelta();
645
+
646
+ if (controls.isLocked && gameStarted) {
647
+ // 玩家移动
648
+ const speed = isSprinting ? 30 : 15;
649
+
650
+ playerVelocity.x -= playerVelocity.x * 10.0 * delta;
651
+ playerVelocity.z -= playerVelocity.z * 10.0 * delta;
652
+
653
+ playerDirection.z = Number(moveForward) - Number(moveBackward);
654
+ playerDirection.x = Number(moveRight) - Number(moveLeft);
655
+ playerDirection.normalize();
656
+
657
+ if (moveForward || moveBackward) playerVelocity.z -= playerDirection.z * speed * delta;
658
+ if (moveLeft || moveRight) playerVelocity.x -= playerDirection.x * speed * delta;
659
+
660
+ // 应用重力
661
+ playerVelocity.y -= 9.8 * delta;
662
+
663
+ // 更新玩家位置
664
+ controls.moveRight(-playerVelocity.x * delta);
665
+ controls.moveForward(-playerVelocity.z * delta);
666
+ controls.getObject().position.y += playerVelocity.y * delta;
667
+
668
+ // 确保玩家不会掉出地图
669
+ if (controls.getObject().position.y < 1.6) {
670
+ playerVelocity.y = 0;
671
+ controls.getObject().position.y = 1.6;
672
+ canJump = true;
673
+ }
674
+
675
+ // 确保玩家不会离开地图
676
+ const pos = controls.getObject().position;
677
+ if (pos.x < -45) pos.x = -45;
678
+ if (pos.x > 45) pos.x = 45;
679
+ if (pos.z < -45) pos.z = -45;
680
+ if (pos.z > 45) pos.z = 45;
681
+
682
+ // 更新玩家模型位置(用于敌人AI)
683
+ player.position.copy(controls.getObject().position);
684
+ player.position.y += 0.2; // 调整高度差
685
+ }
686
+
687
+ renderer.render(scene, camera);
688
+ }
689
+
690
+ // 初始化游戏
691
+ init();
692
+ </script>
693
+ <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>
694
+ </html>