gini1 commited on
Commit
726fff4
ยท
verified ยท
1 Parent(s): e4c0247

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +90 -320
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <title>Survival Game</title>
5
  <style>
6
- body { margin: 0; font-family: Arial, sans-serif; }
7
  canvas { display: block; }
8
  #gameInfo {
9
  position: absolute;
@@ -13,380 +13,150 @@
13
  color: white;
14
  padding: 10px;
15
  border-radius: 5px;
16
- }
17
- #safeTimer {
18
- position: absolute;
19
- top: 50%;
20
- left: 50%;
21
- transform: translate(-50%, -50%);
22
- background: rgba(0,0,0,0.7);
23
- color: white;
24
- padding: 20px;
25
- border-radius: 10px;
26
- font-size: 24px;
27
- display: none;
28
- }
29
- #weaponInfo {
30
- position: absolute;
31
- bottom: 20px;
32
- left: 50%;
33
- transform: translateX(-50%);
34
- background: rgba(0,0,0,0.7);
35
- color: white;
36
- padding: 10px;
37
- border-radius: 5px;
38
- font-size: 18px;
39
- display: none;
40
  }
41
  </style>
42
- <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
43
- <script type="importmap">
44
- {
45
- "imports": {
46
- "three": "https://unpkg.com/three@0.149.0/build/three.module.js",
47
- "three/addons/": "https://unpkg.com/three@0.149.0/examples/jsm/"
48
- }
49
- }
50
- </script>
51
  </head>
52
  <body>
53
  <div id="gameInfo">
54
- Controls:<br>
55
- W/S/A/D - Move<br>
56
- SPACE - Jump<br>
57
- Mouse - Look Around<br>
58
- Survive and find the weapon!
59
  </div>
60
- <div id="safeTimer"></div>
61
- <div id="weaponInfo">Weapon appeared! Get it to win!</div>
62
 
63
  <script type="module">
64
- import * as THREE from 'three';
65
- import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
66
- import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
67
-
68
  let scene, camera, renderer, controls;
69
- let playerModel, enemies = [], weapon;
70
- let isSafePeriod = true;
71
- let gameStartTime = Date.now();
72
- const SAFE_PERIOD = 10; // 10์ดˆ ์•ˆ์ „ ์‹œ๊ฐ„
73
- const MAP_SIZE = 2000; // ๋” ํฐ ๋งต ํฌ๊ธฐ
74
- const ENEMY_COUNT = 8; // ์ ์˜ ์ˆ˜ ์ฆ๊ฐ€
75
- let weaponSpawned = false;
76
 
77
- // ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™”
78
  function init() {
79
- // ๊ธฐ๋ณธ ์„ค์ •
80
  scene = new THREE.Scene();
81
- camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, MAP_SIZE * 0.6);
 
 
 
 
 
 
82
  renderer = new THREE.WebGLRenderer({ antialias: true });
83
  renderer.setSize(window.innerWidth, window.innerHeight);
84
  renderer.shadowMap.enabled = true;
85
- renderer.shadowMap.type = THREE.PCFSoftShadowMap;
86
  document.body.appendChild(renderer.domElement);
87
 
88
- // ํฌ์ธํ„ฐ ๋ฝ ์ปจํŠธ๋กค
89
  controls = new PointerLockControls(camera, document.body);
90
-
91
- // ํด๋ฆญ์œผ๋กœ ๊ฒŒ์ž„ ์‹œ์ž‘
92
- document.addEventListener('click', () => {
93
  controls.lock();
94
  });
95
 
96
- // ์ง€ํ˜• ์ƒ์„ฑ
97
- createTerrain();
98
-
99
- // ์กฐ๋ช… ์„ค์ •
100
- setupLights();
101
-
102
- // ํ”Œ๋ ˆ์ด์–ด ๋ชจ๋ธ ๋กœ๋“œ
103
- loadPlayerModel();
104
-
105
- // ์  ๋ชจ๋ธ ๋กœ๋“œ
106
- loadEnemies();
107
-
108
- // ํ™˜๊ฒฝ ์š”์†Œ ์ถ”๊ฐ€
109
- createEnvironment();
110
 
111
- // ๋ฌด๊ธฐ ์Šคํฐ ํƒ€์ด๋จธ ์„ค์ •
112
- setTimeout(spawnWeapon, getRandomTime(15000, 30000));
113
 
114
- // ํ‚ค๋ณด๋“œ ์ปจํŠธ๋กค ์„ค์ •
115
- setupControls();
116
-
117
- // ์นด๋ฉ”๋ผ ์ดˆ๊ธฐ ์œ„์น˜
118
- camera.position.set(0, 5, 0);
119
  }
120
 
121
  // ์ง€ํ˜• ์ƒ์„ฑ ํ•จ์ˆ˜
122
- function createTerrain() {
123
- const geometry = new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE, 200, 200);
124
- const material = new THREE.MeshStandardMaterial({
125
  color: 0x3a8c3a,
126
- wireframe: false
 
127
  });
128
-
129
- // ๋†’๋‚ฎ์ด ์„ค์ •
130
- const vertices = geometry.attributes.position.array;
131
- for (let i = 0; i < vertices.length; i += 3) {
132
- vertices[i + 2] = Math.pow(Math.sin(vertices[i] * 0.02) + Math.cos(vertices[i + 1] * 0.02), 2) * 15;
133
- }
134
- geometry.attributes.position.needsUpdate = true;
135
- geometry.computeVertexNormals();
136
-
137
- const terrain = new THREE.Mesh(geometry, material);
138
- terrain.rotation.x = -Math.PI / 2;
139
- terrain.receiveShadow = true;
140
- scene.add(terrain);
141
  }
142
 
143
- // ์กฐ๋ช… ์„ค์ •
144
- function setupLights() {
 
145
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
146
  scene.add(ambientLight);
147
 
 
148
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
149
- directionalLight.position.set(1000, 1000, 1000);
150
  directionalLight.castShadow = true;
151
- directionalLight.shadow.mapSize.width = 2048;
152
- directionalLight.shadow.mapSize.height = 2048;
153
- directionalLight.shadow.camera.near = 0.5;
154
- directionalLight.shadow.camera.far = 3000;
155
- directionalLight.shadow.camera.left = -1000;
156
- directionalLight.shadow.camera.right = 1000;
157
- directionalLight.shadow.camera.top = 1000;
158
- directionalLight.shadow.camera.bottom = -1000;
159
  scene.add(directionalLight);
160
  }
161
 
162
- // ํ”Œ๋ ˆ์ด์–ด ๋ชจ๋ธ ๋กœ๋“œ
163
- function loadPlayerModel() {
164
- const loader = new GLTFLoader();
165
- loader.load('me.glb', (gltf) => {
166
- playerModel = gltf.scene;
167
- playerModel.scale.set(0.5, 0.5, 0.5);
168
- playerModel.castShadow = true;
169
- playerModel.receiveShadow = true;
170
- scene.add(playerModel);
171
-
172
- playerModel.traverse((node) => {
173
- if (node.isMesh) {
174
- node.castShadow = true;
175
- node.receiveShadow = true;
176
- }
177
- });
178
- });
179
- }
180
-
181
- // ์  ๋กœ๋“œ ๋ฐ ์ƒ์„ฑ
182
- function loadEnemies() {
183
- const loader = new GLTFLoader();
184
- loader.load('enemy.glb', (gltf) => {
185
- const enemyModel = gltf.scene;
186
-
187
- for (let i = 0; i < ENEMY_COUNT; i++) {
188
- const enemy = enemyModel.clone();
189
- enemy.scale.set(0.5, 0.5, 0.5);
190
- enemy.position.set(
191
- (Math.random() - 0.5) * MAP_SIZE * 0.8,
192
- 5,
193
- (Math.random() - 0.5) * MAP_SIZE * 0.8
194
- );
195
- enemy.castShadow = true;
196
- enemy.receiveShadow = true;
197
- scene.add(enemy);
198
-
199
- enemies.push({
200
- model: enemy,
201
- velocity: new THREE.Vector3(),
202
- speed: 0.3 + Math.random() * 0.3
203
- });
204
- }
205
- });
206
- }
207
-
208
- // ํ™˜๊ฒฝ ์š”์†Œ ์ƒ์„ฑ
209
- function createEnvironment() {
210
- // ๋‚˜๋ฌด ์ƒ์„ฑ
211
- const treeGeometry = new THREE.CylinderGeometry(0, 4, 20, 8);
212
- const treeMaterial = new THREE.MeshStandardMaterial({ color: 0x0d5c0d });
213
- for (let i = 0; i < 500; i++) {
214
- const tree = new THREE.Mesh(treeGeometry, treeMaterial);
215
- tree.position.set(
216
- (Math.random() - 0.5) * MAP_SIZE * 0.9,
217
- 10,
218
- (Math.random() - 0.5) * MAP_SIZE * 0.9
219
- );
220
- tree.castShadow = true;
221
- tree.receiveShadow = true;
222
- scene.add(tree);
223
  }
 
224
 
225
- // ๋ฐ”์œ„ ์ƒ์„ฑ
226
- const rockGeometry = new THREE.DodecahedronGeometry(3);
227
- const rockMaterial = new THREE.MeshStandardMaterial({ color: 0x666666 });
228
- for (let i = 0; i < 200; i++) {
229
- const rock = new THREE.Mesh(rockGeometry, rockMaterial);
230
- rock.position.set(
231
- (Math.random() - 0.5) * MAP_SIZE * 0.9,
232
- 3,
233
- (Math.random() - 0.5) * MAP_SIZE * 0.9
234
- );
235
- rock.castShadow = true;
236
- rock.receiveShadow = true;
237
- scene.add(rock);
238
  }
 
239
 
240
- // ์•ˆ๊ฐœ ์ถ”๊ฐ€
241
- scene.fog = new THREE.Fog(0xcce0ff, 0, MAP_SIZE * 0.3);
242
- }
243
-
244
- // ๋ฌด๊ธฐ ์ƒ์„ฑ
245
- function spawnWeapon() {
246
- const weaponGeometry = new THREE.BoxGeometry(2, 0.5, 8);
247
- const weaponMaterial = new THREE.MeshStandardMaterial({
248
- color: 0xffd700,
249
- metalness: 0.7,
250
- roughness: 0.3,
251
- emissive: 0xffd700,
252
- emissiveIntensity: 0.5
253
- });
254
- weapon = new THREE.Mesh(weaponGeometry, weaponMaterial);
255
- weapon.position.set(
256
- (Math.random() - 0.5) * MAP_SIZE * 0.6,
257
- 5,
258
- (Math.random() - 0.5) * MAP_SIZE * 0.6
259
- );
260
- weapon.rotation.y = Math.random() * Math.PI * 2;
261
- weapon.castShadow = true;
262
- scene.add(weapon);
263
- weaponSpawned = true;
264
-
265
- // ๋ฌด๊ธฐ ์ถœํ˜„ ์•Œ๋ฆผ ํ‘œ์‹œ
266
- const weaponInfo = document.getElementById('weaponInfo');
267
- weaponInfo.style.display = 'block';
268
- setTimeout(() => weaponInfo.style.display = 'none', 5000);
269
- }
270
-
271
- // ๋žœ๋ค ์‹œ๊ฐ„ ์ƒ์„ฑ
272
- function getRandomTime(min, max) {
273
- return Math.floor(Math.random() * (max - min)) + min;
274
- }
275
-
276
- // ์ปจํŠธ๋กค ์„ค์ •
277
- function setupControls() {
278
- const moveState = {
279
- forward: false,
280
- backward: false,
281
- left: false,
282
- right: false,
283
- jump: false
284
- };
285
-
286
- document.addEventListener('keydown', (event) => {
287
- switch (event.code) {
288
- case 'KeyW': moveState.forward = true; break;
289
- case 'KeyS': moveState.backward = true; break;
290
- case 'KeyA': moveState.left = true; break;
291
- case 'KeyD': moveState.right = true; break;
292
- }
293
- });
294
-
295
- document.addEventListener('keyup', (event) => {
296
- switch (event.code) {
297
- case 'KeyW': moveState.forward = false; break;
298
- case 'KeyS': moveState.backward = false; break;
299
- case 'KeyA': moveState.left = false; break;
300
- case 'KeyD': moveState.right = false; break;
301
- }
302
- });
303
- }
304
-
305
- // ๊ฒŒ์ž„ ์Šน๋ฆฌ
306
- function victory() {
307
- alert('Congratulations! You found the weapon and won!');
308
- location.reload();
309
- }
310
-
311
- // ๊ฒŒ์ž„ ์˜ค๋ฒ„
312
- function gameOver() {
313
- alert('Game Over! You were caught!');
314
- location.reload();
315
- }
316
-
317
- // ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฃจํ”„
318
  function animate() {
319
  requestAnimationFrame(animate);
320
 
321
  if (controls.isLocked) {
322
- // ์•ˆ์ „ ์‹œ๊ฐ„ ์ฒดํฌ
323
- const elapsedTime = Math.floor((Date.now() - gameStartTime) / 1000);
324
- const remainingTime = SAFE_PERIOD - elapsedTime;
325
-
326
- const safeTimer = document.getElementById('safeTimer');
327
- if (remainingTime > 0) {
328
- safeTimer.style.display = 'block';
329
- safeTimer.textContent = `Safe Period: ${remainingTime}s`;
330
- isSafePeriod = true;
331
- } else {
332
- safeTimer.style.display = 'none';
333
- isSafePeriod = false;
334
- }
335
-
336
- // ์  ์—…๋ฐ๏ฟฝ๏ฟฝ๏ฟฝํŠธ
337
- enemies.forEach(enemy => {
338
- if (!isSafePeriod) {
339
- const direction = new THREE.Vector3();
340
- direction.subVectors(camera.position, enemy.model.position);
341
- direction.y = 0;
342
- direction.normalize();
343
-
344
- enemy.velocity.add(direction.multiplyScalar(enemy.speed));
345
- enemy.velocity.multiplyScalar(0.98);
346
- enemy.model.position.add(enemy.velocity);
347
-
348
- // ์ ๊ณผ์˜ ์ถฉ๋Œ ์ฒดํฌ
349
- if (enemy.model.position.distanceTo(camera.position) < 3) {
350
- gameOver();
351
- }
352
-
353
- // ์  ํšŒ์ „
354
- enemy.model.lookAt(camera.position);
355
- }
356
- });
357
-
358
- // ๋ฌด๊ธฐ์™€์˜ ์ถฉ๋Œ ์ฒดํฌ
359
- if (weaponSpawned && weapon) {
360
- if (weapon.position.distanceTo(camera.position) < 3) {
361
- victory();
362
- }
363
- }
364
-
365
- // ํ”Œ๋ ˆ์ด์–ด ๋ชจ๋ธ ์—…๋ฐ์ดํŠธ
366
- if (playerModel) {
367
- playerModel.position.copy(camera.position);
368
- playerModel.position.y -= 2;
369
- playerModel.rotation.y = camera.rotation.y;
370
- }
371
  }
372
 
373
  renderer.render(scene, camera);
374
  }
375
 
376
- // ์œˆ๋„์šฐ ๋ฆฌ์‚ฌ์ด์ฆˆ ์ฒ˜๋ฆฌ
377
- window.addEventListener('resize', () => {
 
 
378
  camera.aspect = window.innerWidth / window.innerHeight;
379
  camera.updateProjectionMatrix();
380
- renderer.setSize(window.innerWidth, window
381
-
382
-
383
-
384
- renderer.setSize(window.innerWidth, window.innerHeight);
385
- });
386
 
387
- // ๊ฒŒ์ž„ ์‹œ์ž‘
388
  init();
389
  animate();
390
  </script>
391
  </body>
392
- </html>
 
3
  <head>
4
  <title>Survival Game</title>
5
  <style>
6
+ body { margin: 0; }
7
  canvas { display: block; }
8
  #gameInfo {
9
  position: absolute;
 
13
  color: white;
14
  padding: 10px;
15
  border-radius: 5px;
16
+ z-index: 100;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
  </style>
 
 
 
 
 
 
 
 
 
19
  </head>
20
  <body>
21
  <div id="gameInfo">
22
+ Click to start<br>
23
+ WASD - Move<br>
24
+ Mouse - Look Around
 
 
25
  </div>
 
 
26
 
27
  <script type="module">
28
+ import * as THREE from 'https://unpkg.com/three@0.149.0/build/three.module.js';
29
+ import { PointerLockControls } from 'https://unpkg.com/three@0.149.0/examples/jsm/controls/PointerLockControls.js';
30
+
31
+ // ๋ฉ”์ธ ๋ณ€์ˆ˜
32
  let scene, camera, renderer, controls;
 
 
 
 
 
 
 
33
 
34
+ // ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜
35
  function init() {
36
+ // Scene ์ƒ์„ฑ
37
  scene = new THREE.Scene();
38
+ scene.background = new THREE.Color(0x87ceeb); // ํ•˜๋Š˜์ƒ‰ ๋ฐฐ๊ฒฝ
39
+
40
+ // Camera ์„ค์ •
41
+ camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
42
+ camera.position.set(0, 5, 10);
43
+
44
+ // Renderer ์„ค์ •
45
  renderer = new THREE.WebGLRenderer({ antialias: true });
46
  renderer.setSize(window.innerWidth, window.innerHeight);
47
  renderer.shadowMap.enabled = true;
 
48
  document.body.appendChild(renderer.domElement);
49
 
50
+ // Controls ์„ค์ •
51
  controls = new PointerLockControls(camera, document.body);
52
+
53
+ // ํด๋ฆญ ์ด๋ฒคํŠธ
54
+ document.addEventListener('click', function() {
55
  controls.lock();
56
  });
57
 
58
+ // ๊ธฐ๋ณธ ์ง€ํ˜• ์ƒ์„ฑ
59
+ createGround();
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ // ๊ธฐ๋ณธ ์กฐ๋ช… ์ถ”๊ฐ€
62
+ addLights();
63
 
64
+ // ํ…Œ์ŠคํŠธ์šฉ ๋ฐ•์Šค ์ถ”๊ฐ€
65
+ addTestBox();
 
 
 
66
  }
67
 
68
  // ์ง€ํ˜• ์ƒ์„ฑ ํ•จ์ˆ˜
69
+ function createGround() {
70
+ const groundGeometry = new THREE.PlaneGeometry(100, 100);
71
+ const groundMaterial = new THREE.MeshStandardMaterial({
72
  color: 0x3a8c3a,
73
+ roughness: 0.8,
74
+ metalness: 0.2
75
  });
76
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
77
+ ground.rotation.x = -Math.PI / 2;
78
+ ground.receiveShadow = true;
79
+ scene.add(ground);
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
+ // ์กฐ๋ช… ์ถ”๊ฐ€ ํ•จ์ˆ˜
83
+ function addLights() {
84
+ // ์ฃผ๋ณ€๊ด‘
85
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
86
  scene.add(ambientLight);
87
 
88
+ // ์ง์‚ฌ๊ด‘
89
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
90
+ directionalLight.position.set(20, 30, 20);
91
  directionalLight.castShadow = true;
 
 
 
 
 
 
 
 
92
  scene.add(directionalLight);
93
  }
94
 
95
+ // ํ…Œ์ŠคํŠธ์šฉ ๋ฐ•์Šค ์ถ”๊ฐ€
96
+ function addTestBox() {
97
+ const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
98
+ const boxMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
99
+ const box = new THREE.Mesh(boxGeometry, boxMaterial);
100
+ box.position.set(0, 1, -5);
101
+ box.castShadow = true;
102
+ box.receiveShadow = true;
103
+ scene.add(box);
104
+ }
105
+
106
+ // ์›€์ง์ž„ ๊ด€๋ จ ๋ณ€์ˆ˜๋“ค
107
+ const moveState = {
108
+ forward: false,
109
+ backward: false,
110
+ left: false,
111
+ right: false
112
+ };
113
+
114
+ // ํ‚ค๋ณด๋“œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
115
+ document.addEventListener('keydown', (event) => {
116
+ switch (event.code) {
117
+ case 'KeyW': moveState.forward = true; break;
118
+ case 'KeyS': moveState.backward = true; break;
119
+ case 'KeyA': moveState.left = true; break;
120
+ case 'KeyD': moveState.right = true; break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
+ });
123
 
124
+ document.addEventListener('keyup', (event) => {
125
+ switch (event.code) {
126
+ case 'KeyW': moveState.forward = false; break;
127
+ case 'KeyS': moveState.backward = false; break;
128
+ case 'KeyA': moveState.left = false; break;
129
+ case 'KeyD': moveState.right = false; break;
 
 
 
 
 
 
 
130
  }
131
+ });
132
 
133
+ // ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ•จ์ˆ˜
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  function animate() {
135
  requestAnimationFrame(animate);
136
 
137
  if (controls.isLocked) {
138
+ const speed = 0.2;
139
+ if (moveState.forward) controls.moveForward(speed);
140
+ if (moveState.backward) controls.moveForward(-speed);
141
+ if (moveState.left) controls.moveRight(-speed);
142
+ if (moveState.right) controls.moveRight(speed);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  }
144
 
145
  renderer.render(scene, camera);
146
  }
147
 
148
+ // ํ™”๋ฉด ํฌ๊ธฐ ์กฐ์ • ์ฒ˜๋ฆฌ
149
+ window.addEventListener('resize', onWindowResize, false);
150
+
151
+ function onWindowResize() {
152
  camera.aspect = window.innerWidth / window.innerHeight;
153
  camera.updateProjectionMatrix();
154
+ renderer.setSize(window.innerWidth, window.innerHeight);
155
+ }
 
 
 
 
156
 
157
+ // ์ดˆ๊ธฐํ™” ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘
158
  init();
159
  animate();
160
  </script>
161
  </body>
162
+ </html>