Spaces:
Running
Running
cutechicken
commited on
Commit
โข
678cd65
1
Parent(s):
c3185e4
Update game.js
Browse files
game.js
CHANGED
@@ -105,41 +105,30 @@ class TankPlayer {
|
|
105 |
}
|
106 |
|
107 |
update(mouseX, mouseY) {
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
bullet.position.add(bullet.velocity);
|
124 |
-
|
125 |
-
// ์ด์์ด ๋งต ๋ฐ์ผ๋ก ๋๊ฐ๋ฉด ์ ๊ฑฐ
|
126 |
-
if (Math.abs(bullet.position.x) > MAP_SIZE/2 ||
|
127 |
-
Math.abs(bullet.position.z) > MAP_SIZE/2) {
|
128 |
-
scene.remove(bullet);
|
129 |
-
this.bullets.splice(i, 1);
|
130 |
-
}
|
131 |
-
}
|
132 |
-
}
|
133 |
|
134 |
move(direction) {
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
this.body.position.add(moveVector);
|
143 |
}
|
144 |
|
145 |
rotate(angle) {
|
@@ -339,142 +328,156 @@ class Game {
|
|
339 |
}
|
340 |
|
341 |
async initialize() {
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
|
395 |
setupEventListeners() {
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
case 'KeyA': this.keys.left = false; break;
|
418 |
-
case 'KeyD': this.keys.right = false; break;
|
419 |
-
}
|
420 |
-
});
|
421 |
-
|
422 |
-
// ๋ฐ์ฌ ๋ฐ ํฌ์ธํฐ ๋ฝ ์ด๋ฒคํธ
|
423 |
-
document.addEventListener('click', () => {
|
424 |
-
if (document.pointerLockElement !== document.body) {
|
425 |
-
this.controls.lock();
|
426 |
-
} else {
|
427 |
-
const bullet = this.tank.shoot(this.scene);
|
428 |
-
if (bullet) {
|
429 |
-
// ์ด์ ๋ฐ์ฌ ํจ๊ณผ์์ด๋ ์๊ฐํจ๊ณผ ์ถ๊ฐ ๊ฐ๋ฅ
|
430 |
-
}
|
431 |
-
}
|
432 |
-
});
|
433 |
-
|
434 |
-
// ์ฐฝ ํฌ๊ธฐ ๋ณ๊ฒฝ ์ด๋ฒคํธ
|
435 |
-
window.addEventListener('resize', () => {
|
436 |
-
this.camera.aspect = window.innerWidth / window.innerHeight;
|
437 |
-
this.camera.updateProjectionMatrix();
|
438 |
-
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
439 |
-
});
|
440 |
-
}
|
441 |
-
|
442 |
-
handleMovement() {
|
443 |
-
if (!this.tank.isLoaded || !this.controls.isLocked) return;
|
444 |
|
445 |
-
|
446 |
-
|
447 |
-
this.
|
448 |
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
if (this.keys.right) direction.x += 1;
|
453 |
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
}
|
464 |
}
|
|
|
465 |
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
this.
|
471 |
-
|
|
|
472 |
|
473 |
-
|
474 |
-
|
475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
476 |
}
|
477 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
478 |
createBuildings() {
|
479 |
const buildingTypes = [
|
480 |
{ width: 10, height: 30, depth: 10, color: 0x808080 },
|
|
|
105 |
}
|
106 |
|
107 |
update(mouseX, mouseY) {
|
108 |
+
if (!this.body || !this.turretGroup) return;
|
109 |
+
|
110 |
+
// ์ด์ ์
๋ฐ์ดํธ๋ง ์ํํ๊ณ ํฌํ ํ์ ์ Game ํด๋์ค์ handleMovement์์ ์ฒ๋ฆฌ
|
111 |
+
for (let i = this.bullets.length - 1; i >= 0; i--) {
|
112 |
+
const bullet = this.bullets[i];
|
113 |
+
bullet.position.add(bullet.velocity);
|
114 |
+
|
115 |
+
// ์ด์์ด ๋งต ๋ฐ์ผ๋ก ๋๊ฐ๋ฉด ์ ๊ฑฐ
|
116 |
+
if (Math.abs(bullet.position.x) > MAP_SIZE/2 ||
|
117 |
+
Math.abs(bullet.position.z) > MAP_SIZE/2) {
|
118 |
+
scene.remove(bullet);
|
119 |
+
this.bullets.splice(i, 1);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
move(direction) {
|
125 |
+
if (!this.body) return;
|
126 |
+
|
127 |
+
const moveVector = new THREE.Vector3();
|
128 |
+
moveVector.x = direction.x * this.moveSpeed;
|
129 |
+
moveVector.z = direction.z * this.moveSpeed;
|
130 |
+
|
131 |
+
this.body.position.add(moveVector);
|
|
|
132 |
}
|
133 |
|
134 |
rotate(angle) {
|
|
|
328 |
}
|
329 |
|
330 |
async initialize() {
|
331 |
+
try {
|
332 |
+
// ์กฐ๋ช
์ค์
|
333 |
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
|
334 |
+
this.scene.add(ambientLight);
|
335 |
+
|
336 |
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
337 |
+
directionalLight.position.set(50, 50, 50);
|
338 |
+
directionalLight.castShadow = true;
|
339 |
+
directionalLight.shadow.mapSize.width = 2048;
|
340 |
+
directionalLight.shadow.mapSize.height = 2048;
|
341 |
+
this.scene.add(directionalLight);
|
342 |
+
|
343 |
+
// ์งํ ์์ฑ
|
344 |
+
const ground = new THREE.Mesh(
|
345 |
+
new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE),
|
346 |
+
new THREE.MeshStandardMaterial({
|
347 |
+
color: 0x333333,
|
348 |
+
roughness: 0.9,
|
349 |
+
metalness: 0.1
|
350 |
+
})
|
351 |
+
);
|
352 |
+
ground.rotation.x = -Math.PI / 2;
|
353 |
+
ground.receiveShadow = true;
|
354 |
+
this.scene.add(ground);
|
355 |
+
|
356 |
+
// ๊ฑด๋ฌผ ์์ฑ
|
357 |
+
await this.createBuildings();
|
358 |
+
|
359 |
+
// ํฑํฌ ์ด๊ธฐํ
|
360 |
+
await this.tank.initialize(this.scene, this.loader);
|
361 |
+
if (!this.tank.isLoaded) {
|
362 |
+
throw new Error('Tank loading failed');
|
363 |
+
}
|
364 |
+
|
365 |
+
// ์นด๋ฉ๋ผ ์ค์ ์์
|
366 |
+
this.camera.position.set(-20, 10, -20);
|
367 |
+
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
|
368 |
+
|
369 |
+
// ๋ก๋ฉ ์๋ฃ
|
370 |
+
this.isLoading = false;
|
371 |
+
document.getElementById('loading').style.display = 'none';
|
372 |
+
|
373 |
+
// ๊ฒ์ ์์
|
374 |
+
this.animate();
|
375 |
+
this.spawnEnemies();
|
376 |
+
this.startGameTimer();
|
377 |
+
|
378 |
+
} catch (error) {
|
379 |
+
console.error('Game initialization error:', error);
|
380 |
+
this.handleLoadingError();
|
381 |
+
}
|
382 |
+
}
|
383 |
|
384 |
setupEventListeners() {
|
385 |
+
// ํค๋ณด๋ ์ด๋ฒคํธ
|
386 |
+
document.addEventListener('keydown', (event) => {
|
387 |
+
if (this.isLoading) return;
|
388 |
+
switch(event.code) {
|
389 |
+
case 'KeyW': this.keys.forward = true; break;
|
390 |
+
case 'KeyS': this.keys.backward = true; break;
|
391 |
+
case 'KeyA': this.keys.left = true; break;
|
392 |
+
case 'KeyD': this.keys.right = true; break;
|
393 |
+
case 'Escape': break; // controls ๊ด๋ จ ์ฝ๋ ์ ๊ฑฐ
|
394 |
+
}
|
395 |
+
});
|
396 |
+
|
397 |
+
document.addEventListener('keyup', (event) => {
|
398 |
+
if (this.isLoading) return;
|
399 |
+
switch(event.code) {
|
400 |
+
case 'KeyW': this.keys.forward = false; break;
|
401 |
+
case 'KeyS': this.keys.backward = false; break;
|
402 |
+
case 'KeyA': this.keys.left = false; break;
|
403 |
+
case 'KeyD': this.keys.right = false; break;
|
404 |
+
}
|
405 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
|
407 |
+
// ๋ง์ฐ์ค ์์ง์ ์ด๋ฒคํธ ์ถ๊ฐ
|
408 |
+
document.addEventListener('mousemove', (event) => {
|
409 |
+
if (this.isLoading) return;
|
410 |
|
411 |
+
// ํ๋ฉด ์ค์ ๊ธฐ์ค์ผ๋ก ๋ง์ฐ์ค ์์น ๊ณ์ฐ
|
412 |
+
const centerX = window.innerWidth / 2;
|
413 |
+
const centerY = window.innerHeight / 2;
|
|
|
414 |
|
415 |
+
this.mouse.x = (event.clientX - centerX) / centerX;
|
416 |
+
this.mouse.y = (event.clientY - centerY) / centerY;
|
417 |
+
});
|
418 |
+
|
419 |
+
// ๋ฐ์ฌ ์ด๋ฒคํธ (ํฌ์ธํฐ ๋ฝ ๊ด๋ จ ์ฝ๋ ์ ๊ฑฐ)
|
420 |
+
document.addEventListener('click', () => {
|
421 |
+
const bullet = this.tank.shoot(this.scene);
|
422 |
+
if (bullet) {
|
423 |
+
// ์ด์ ๋ฐ์ฌ ํจ๊ณผ์์ด๋ ์๊ฐํจ๊ณผ ์ถ๊ฐ ๊ฐ๋ฅ
|
|
|
424 |
}
|
425 |
+
});
|
426 |
|
427 |
+
// ์ฐฝ ํฌ๊ธฐ ๋ณ๊ฒฝ ์ด๋ฒคํธ
|
428 |
+
window.addEventListener('resize', () => {
|
429 |
+
this.camera.aspect = window.innerWidth / window.innerHeight;
|
430 |
+
this.camera.updateProjectionMatrix();
|
431 |
+
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
432 |
+
});
|
433 |
+
}
|
434 |
|
435 |
+
handleMovement() {
|
436 |
+
if (!this.tank.isLoaded) return;
|
437 |
+
|
438 |
+
const direction = new THREE.Vector3();
|
439 |
+
|
440 |
+
if (this.keys.forward) direction.z += 1;
|
441 |
+
if (this.keys.backward) direction.z -= 1;
|
442 |
+
if (this.keys.left) direction.x -= 1;
|
443 |
+
if (this.keys.right) direction.x += 1;
|
444 |
+
|
445 |
+
if (direction.length() > 0) {
|
446 |
+
direction.normalize();
|
447 |
+
// ํฑํฌ์ ํ์ฌ ํ์ ์ ๊ธฐ์ค์ผ๋ก ์ด๋
|
448 |
+
direction.applyEuler(this.tank.body.rotation);
|
449 |
+
this.tank.move(direction);
|
450 |
+
|
451 |
+
// ํฑํฌ ๋ณธ์ฒด ํ์
|
452 |
+
if (Math.abs(direction.z) > 0 || Math.abs(direction.x) > 0) {
|
453 |
+
const angle = Math.atan2(direction.x, direction.z);
|
454 |
+
this.tank.body.rotation.y = angle;
|
455 |
}
|
456 |
}
|
457 |
+
|
458 |
+
// ๋ง์ฐ์ค ์์ง์์ ๋ฐ๋ฅธ ํฌํ๊ณผ ์นด๋ฉ๋ผ ํ์
|
459 |
+
const rotationAngle = Math.atan2(this.mouse.x, -this.mouse.y);
|
460 |
+
|
461 |
+
// ํฌํ ํ์
|
462 |
+
if (this.tank.turretGroup) {
|
463 |
+
this.tank.turretGroup.rotation.y = rotationAngle;
|
464 |
+
}
|
465 |
+
|
466 |
+
// ์นด๋ฉ๋ผ ์์น ๋ฐ ํ์ ์
๋ฐ์ดํธ
|
467 |
+
const tankPos = this.tank.getPosition();
|
468 |
+
const cameraDistance = 20;
|
469 |
+
const cameraHeight = 10;
|
470 |
+
|
471 |
+
// ์นด๋ฉ๋ผ ์์น ๊ณ์ฐ
|
472 |
+
const cameraOffset = new THREE.Vector3(
|
473 |
+
Math.sin(rotationAngle) * cameraDistance,
|
474 |
+
cameraHeight,
|
475 |
+
Math.cos(rotationAngle) * cameraDistance
|
476 |
+
);
|
477 |
+
|
478 |
+
this.camera.position.copy(tankPos).sub(cameraOffset);
|
479 |
+
this.camera.lookAt(tankPos);
|
480 |
+
}
|
481 |
createBuildings() {
|
482 |
const buildingTypes = [
|
483 |
{ width: 10, height: 30, depth: 10, color: 0x808080 },
|