gini1 commited on
Commit
c71414f
ยท
verified ยท
1 Parent(s): b01cf37

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +113 -44
index.html CHANGED
@@ -42,6 +42,22 @@
42
  #fileUpload.hidden {
43
  display: none;
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  #startButton {
46
  margin-top: 10px;
47
  padding: 10px 20px;
@@ -55,6 +71,22 @@
55
  background: #666;
56
  cursor: not-allowed;
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  </style>
59
  <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
60
  <script type="importmap">
@@ -85,10 +117,14 @@
85
  <div id="fileUpload">
86
  <h2>3D Open World Game</h2>
87
  <p>Upload your character model (GLB file)</p>
88
- <input type="file" id="glbFile" accept=".glb" />
89
- <br>
 
 
 
90
  <button id="startButton" disabled>Start Game</button>
91
  </div>
 
92
 
93
  <script type="module">
94
  import * as THREE from 'three';
@@ -98,15 +134,23 @@
98
  let scene, camera, renderer, controls;
99
  let character = null;
100
  let uploadedModel = null;
 
 
 
 
101
 
102
- // File upload handling
103
  const fileInput = document.getElementById('glbFile');
104
  const startButton = document.getElementById('startButton');
105
  const uploadDiv = document.getElementById('fileUpload');
 
 
 
106
 
107
  fileInput.addEventListener('change', function(e) {
108
  const file = e.target.files[0];
109
  if (file) {
 
110
  uploadedModel = URL.createObjectURL(file);
111
  startButton.disabled = false;
112
  }
@@ -119,6 +163,59 @@
119
  }
120
  });
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  function initGame() {
123
  // ๊ธฐ๋ณธ ์„ค์ •
124
  scene = new THREE.Scene();
@@ -128,6 +225,10 @@
128
  renderer.shadowMap.enabled = true;
129
  document.body.appendChild(renderer.domElement);
130
 
 
 
 
 
131
  // ๋ฌผ๋ฆฌ ์‹œ์Šคํ…œ ๋ณ€์ˆ˜
132
  const gravity = -0.5;
133
  let velocity = new THREE.Vector3();
@@ -135,10 +236,6 @@
135
  let canJump = true;
136
  let playerHeight = 2;
137
 
138
- // ์บ๋ฆญํ„ฐ ์ƒํƒœ
139
- let hp = 100;
140
- const hpElement = document.getElementById('hp');
141
-
142
  // ํฌ์ธํ„ฐ ๋ฝ ์ปจํŠธ๋กค
143
  controls = new PointerLockControls(camera, document.body);
144
 
@@ -230,45 +327,15 @@
230
  }
231
  };
232
 
233
- // NPC ์‹œ์Šคํ…œ
234
- class NPC {
235
- constructor(position) {
236
- const geometry = new THREE.CapsuleGeometry(1, 2, 4, 8);
237
- const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
238
- this.mesh = new THREE.Mesh(geometry, material);
239
- this.mesh.position.copy(position);
240
- this.mesh.castShadow = true;
241
- this.velocity = new THREE.Vector3();
242
- this.direction = new THREE.Vector3();
243
- scene.add(this.mesh);
244
- }
245
-
246
- update(playerPosition) {
247
- this.direction.subVectors(playerPosition, this.mesh.position);
248
- this.direction.normalize();
249
- this.velocity.add(this.direction.multiplyScalar(0.1));
250
- this.velocity.multiplyScalar(0.95);
251
- this.mesh.position.add(this.velocity);
252
-
253
- const distance = this.mesh.position.distanceTo(playerPosition);
254
- if (distance < 2) {
255
- hp -= 1;
256
- hpElement.textContent = hp;
257
- if (hp <= 0) {
258
- alert('Game Over!');
259
- location.reload();
260
- }
261
- }
262
- }
263
- }
264
-
265
  // NPC ์ƒ์„ฑ
266
  const npcs = [];
267
  for (let i = 0; i < 5; i++) {
 
 
268
  const position = new THREE.Vector3(
269
- (Math.random() - 0.5) * 100,
270
  2,
271
- (Math.random() - 0.5) * 100
272
  );
273
  npcs.push(new NPC(position));
274
  }
@@ -322,7 +389,9 @@
322
 
323
  // ๋ฐ”์œ„ ์ƒ์„ฑ
324
  const rockGeometry = new THREE.DodecahedronGeometry(2);
325
- const rockMaterial = new THREE.MeshStandardMaterial({ color: 0x666666 });
 
 
326
  addEnvironmentObject(rockGeometry, rockMaterial, 50, 1);
327
 
328
  // ์บ๋ฆญํ„ฐ ๋ชจ๋ธ ๋กœ๋“œ
@@ -392,7 +461,7 @@
392
  // ๋น„ ์—…๋ฐ์ดํŠธ
393
  if (rain.visible) {
394
  const positions = rain.geometry.attributes.position.array;
395
- for (let i = 1; i < positions.length; i +=3) {
396
  positions[i] -= 2;
397
  if (positions[i] < 0) {
398
  positions[i] = 500;
@@ -426,4 +495,4 @@
426
  };
427
  </script>
428
  </body>
429
- </html>
 
42
  #fileUpload.hidden {
43
  display: none;
44
  }
45
+ .custom-file-upload {
46
+ display: inline-block;
47
+ padding: 12px 24px;
48
+ background: #2196F3;
49
+ color: white;
50
+ border-radius: 5px;
51
+ cursor: pointer;
52
+ margin: 10px 0;
53
+ transition: background 0.3s;
54
+ }
55
+ .custom-file-upload:hover {
56
+ background: #1976D2;
57
+ }
58
+ input[type="file"] {
59
+ display: none;
60
+ }
61
  #startButton {
62
  margin-top: 10px;
63
  padding: 10px 20px;
 
71
  background: #666;
72
  cursor: not-allowed;
73
  }
74
+ #selectedFileName {
75
+ margin-top: 10px;
76
+ color: #4CAF50;
77
+ }
78
+ #safeTimer {
79
+ position: absolute;
80
+ top: 50%;
81
+ left: 50%;
82
+ transform: translate(-50%, -50%);
83
+ background: rgba(0,0,0,0.7);
84
+ color: white;
85
+ padding: 20px;
86
+ border-radius: 10px;
87
+ font-size: 24px;
88
+ display: none;
89
+ }
90
  </style>
91
  <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
92
  <script type="importmap">
 
117
  <div id="fileUpload">
118
  <h2>3D Open World Game</h2>
119
  <p>Upload your character model (GLB file)</p>
120
+ <label class="custom-file-upload">
121
+ Choose GLB File
122
+ <input type="file" id="glbFile" accept=".glb" />
123
+ </label>
124
+ <div id="selectedFileName"></div>
125
  <button id="startButton" disabled>Start Game</button>
126
  </div>
127
+ <div id="safeTimer"></div>
128
 
129
  <script type="module">
130
  import * as THREE from 'three';
 
134
  let scene, camera, renderer, controls;
135
  let character = null;
136
  let uploadedModel = null;
137
+ let hp = 100;
138
+ let gameStartTime = 0;
139
+ let isSafePeriod = true;
140
+ const SAFE_PERIOD = 30; // 30์ดˆ ์•ˆ์ „ ์‹œ๊ฐ„
141
 
142
+ // ํŒŒ์ผ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ
143
  const fileInput = document.getElementById('glbFile');
144
  const startButton = document.getElementById('startButton');
145
  const uploadDiv = document.getElementById('fileUpload');
146
+ const selectedFileName = document.getElementById('selectedFileName');
147
+ const safeTimer = document.getElementById('safeTimer');
148
+ const hpElement = document.getElementById('hp');
149
 
150
  fileInput.addEventListener('change', function(e) {
151
  const file = e.target.files[0];
152
  if (file) {
153
+ selectedFileName.textContent = `Selected: ${file.name}`;
154
  uploadedModel = URL.createObjectURL(file);
155
  startButton.disabled = false;
156
  }
 
163
  }
164
  });
165
 
166
+ // NPC ํด๋ž˜์Šค
167
+ class NPC {
168
+ constructor(position) {
169
+ const geometry = new THREE.CapsuleGeometry(1, 2, 4, 8);
170
+ const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
171
+ this.mesh = new THREE.Mesh(geometry, material);
172
+ this.mesh.position.copy(position);
173
+ this.mesh.castShadow = true;
174
+ this.velocity = new THREE.Vector3();
175
+ this.direction = new THREE.Vector3();
176
+ this.speed = 0.05; // ๊ฐ์†Œ๋œ ๊ธฐ๋ณธ ์†๋„
177
+ this.damage = 0.5; // ๊ฐ์†Œ๋œ ๋ฐ๋ฏธ์ง€
178
+ scene.add(this.mesh);
179
+ }
180
+
181
+ update(playerPosition) {
182
+ // ์•ˆ์ „ ์‹œ๊ฐ„ ์ฒดํฌ
183
+ if (isSafePeriod) {
184
+ const elapsedTime = Math.floor((Date.now() - gameStartTime) / 1000);
185
+ const remainingTime = SAFE_PERIOD - elapsedTime;
186
+
187
+ if (remainingTime > 0) {
188
+ safeTimer.style.display = 'block';
189
+ safeTimer.textContent = `Safe Period: ${remainingTime}s`;
190
+ return; // NPC ์›€์ง์ž„ ์ค‘์ง€
191
+ } else {
192
+ safeTimer.style.display = 'none';
193
+ isSafePeriod = false;
194
+ }
195
+ }
196
+
197
+ // ๊ฑฐ๋ฆฌ์— ๋”ฐ๋ฅธ ์†๋„์™€ ๋ฐ๋ฏธ์ง€ ์กฐ์ ˆ
198
+ const distance = this.mesh.position.distanceTo(playerPosition);
199
+ this.speed = Math.min(0.05 + (50 - distance) * 0.001, 0.15);
200
+
201
+ this.direction.subVectors(playerPosition, this.mesh.position);
202
+ this.direction.normalize();
203
+ this.velocity.add(this.direction.multiplyScalar(this.speed));
204
+ this.velocity.multiplyScalar(0.95);
205
+ this.mesh.position.add(this.velocity);
206
+
207
+ // ์ถฉ๋Œ ๋ฐ ๋ฐ๋ฏธ์ง€ ์ฒ˜๋ฆฌ
208
+ if (distance < 2 && !isSafePeriod) {
209
+ hp -= this.damage;
210
+ hpElement.textContent = Math.floor(hp);
211
+ if (hp <= 0) {
212
+ alert('Game Over! Play again?');
213
+ location.reload();
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
  function initGame() {
220
  // ๊ธฐ๋ณธ ์„ค์ •
221
  scene = new THREE.Scene();
 
225
  renderer.shadowMap.enabled = true;
226
  document.body.appendChild(renderer.domElement);
227
 
228
+ // ๊ฒŒ์ž„ ์‹œ์ž‘ ์‹œ๊ฐ„ ๊ธฐ๋ก
229
+ gameStartTime = Date.now();
230
+ isSafePeriod = true;
231
+
232
  // ๋ฌผ๋ฆฌ ์‹œ์Šคํ…œ ๋ณ€์ˆ˜
233
  const gravity = -0.5;
234
  let velocity = new THREE.Vector3();
 
236
  let canJump = true;
237
  let playerHeight = 2;
238
 
 
 
 
 
239
  // ํฌ์ธํ„ฐ ๋ฝ ์ปจํŠธ๋กค
240
  controls = new PointerLockControls(camera, document.body);
241
 
 
327
  }
328
  };
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  // NPC ์ƒ์„ฑ
331
  const npcs = [];
332
  for (let i = 0; i < 5; i++) {
333
+ const angle = (i / 5) * Math.PI * 2;
334
+ const radius = 100; // ๋” ๋ฉ€๋ฆฌ ๋ฐฐ์น˜
335
  const position = new THREE.Vector3(
336
+ Math.cos(angle) * radius,
337
  2,
338
+ Math.sin(angle) * radius
339
  );
340
  npcs.push(new NPC(position));
341
  }
 
389
 
390
  // ๋ฐ”์œ„ ์ƒ์„ฑ
391
  const rockGeometry = new THREE.DodecahedronGeometry(2);
392
+ const rockMaterial = new THREE.MeshSt
393
+
394
+ const rockMaterial = new THREE.MeshStandardMaterial({ color: 0x666666 });
395
  addEnvironmentObject(rockGeometry, rockMaterial, 50, 1);
396
 
397
  // ์บ๋ฆญํ„ฐ ๋ชจ๋ธ ๋กœ๋“œ
 
461
  // ๋น„ ์—…๋ฐ์ดํŠธ
462
  if (rain.visible) {
463
  const positions = rain.geometry.attributes.position.array;
464
+ for (let i = 1; i < positions.length; i += 3) {
465
  positions[i] -= 2;
466
  if (positions[i] < 0) {
467
  positions[i] = 500;
 
495
  };
496
  </script>
497
  </body>
498
+ </html>