gini1 commited on
Commit
0d86eb7
โ€ข
1 Parent(s): 6ff4d9b

Update index.html

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