-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
304 lines (256 loc) · 10.6 KB
/
script.js
File metadata and controls
304 lines (256 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
// Configuração para a cena, câmeras e renderizador
const scene = new THREE.Scene();
const mainCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const personCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
let activeCamera = mainCamera; // Define a câmera inicial como a câmera principal
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Posição da câmera principal (atrás da nave)
mainCamera.position.set(0, 0, -30);
mainCamera.lookAt(0, 0, 0);
// câmera em primeira pessoa (dentro da nave)
personCamera.position.set(0, 2, 5);
personCamera.lookAt(0, 2, 10);
const loader = new THREE.TextureLoader();
scene.background = loader.load('nave/background.jpg');
// Iluminação
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);
// Textura do Meteoro
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('texturas/10464_Asteroid_v1_diffuse.jpg');
// Arrays para armazenar meteoros e projéteis
const meteors = [];
const projectiles = [];
let pontuacao = 0;
// Carregar o arquivo MTL e OBJ para os meteoros
const mtlLoader = new MTLLoader();
mtlLoader.setPath('texturas/');
mtlLoader.load('10464_Asteroid_v1_Iteration-2.mtl', (materials) => {
materials.preload();
const objLoader = new OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('texturas/');
// Função para criar e distribuir meteoros
const createMeteors = () => {
for (let i = 0; i < 40; i++) {
objLoader.load('10464_Asteroid_v1_Iterations-2.obj', (object) => {
object.traverse((child) => {
if (child.isMesh) {
child.material.map = texture;
}
});
object.scale.set(0.004, 0.004, 0.004);
object.position.set(
Math.random() * 40 - 20,
Math.random() * 40 - 20,
Math.random() * 100 + 50
);
// Adicionar velocidade para os meteoros
object.userData.velocity = -(Math.random() * 0.2 + 0.1);
scene.add(object);
meteors.push(object); // Adiciona o meteoro ao array de meteoros
});
}
};
createMeteors();
});
// Carregar a nave
let spaceship;
const gltfLoader = new GLTFLoader();
gltfLoader.setPath('nave/');
gltfLoader.load('nave.glb', (gltf) => {
spaceship = gltf.scene;
spaceship.scale.set(1.0, 1.0, 1.0);
spaceship.position.set(0, 0, 0);
scene.add(spaceship);
});
// Carregar o buraco negro
const buracoloader = new GLTFLoader();
buracoloader.setPath('nave/'); // Ajuste o caminho conforme necessário
let blackhole = null;
buracoloader.load('blackhole.glb', (gltf) => {
const blackHoleMesh = gltf.scene;
// Habilitar sombreamento
blackHoleMesh.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
blackHoleMesh.scale.set(60, 60, 60);
blackHoleMesh.position.set(0, -10, 200); // Ajuste a posição conforme necessário
blackhole = blackHoleMesh;
scene.add(blackHoleMesh);
});
// Adicionar música de fundo
const listener = new THREE.AudioListener();
mainCamera.add(listener);
const sound = new THREE.Audio(listener);
const audioLoader = new THREE.AudioLoader();
audioLoader.load('music/Música Tema - Interestelar .mp3', function(buffer) {
sound.setBuffer(buffer);
sound.setLoop(true);
sound.setVolume(0.5);
sound.play();
});
// Função para criar projéteis a partir dos canhões
function createProjectileFromCannons () {
const projectileGeometry = new THREE.SphereGeometry(0.2, 8, 8);
const projectileMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// Posições dos canhões
const cannonOffsets = [
{ x: -0.8, y: 0, z: 5.5 }, // canhão esquerdo
{ x: 0.8, y: 0, z: 5.5 } // canhão direito
];
cannonOffsets.forEach((offset) => {
const projectile = new THREE.Mesh(projectileGeometry, projectileMaterial);
projectile.position.set(
spaceship.position.x + offset.x,
spaceship.position.y + offset.y,
spaceship.position.z + offset.z
);
scene.add(projectile);
projectiles.push(projectile);
});
};
// Atualizar a posição dos projéteis
function updateProjectiles () {
for (let i = projectiles.length - 1; i >= 0; i--) {
const projectile = projectiles[i];
projectile.position.z += 0.9;
// Remover projétil se sair da cena
if (projectile.position.z > 50) {
scene.remove(projectile);
projectiles.splice(i, 1);
}
}
};
// Controle da nave
window.addEventListener('keydown', (event) => {
if (!spaceship) return;
switch (event.key) {
case 'ArrowUp':
spaceship.position.y += 1;
break;
case 'ArrowDown':
spaceship.position.y -= 1;
break;
case 'ArrowLeft':
spaceship.position.x += 1;
break;
case 'ArrowRight':
spaceship.position.x -= 1;
break;
case 'w':
spaceship.position.z += 1;
break;
case 's':
spaceship.position.z -= 1;
break;
case ' ':
createProjectileFromCannons(); // Disparar projéteis
break;
case 'c':
// Alternar entre a câmera principal e a câmera de 1ª pessoa
activeCamera = (activeCamera === mainCamera) ? personCamera : mainCamera;
break;
}
});
// Função para detectar colisão
function detectCollision(obj1, obj2) {
const obj1Box = new THREE.Box3().setFromObject(obj1); // Caixas de colisão "Box3"
const obj2Box = new THREE.Box3().setFromObject(obj2); // setFromObject = usa as dimensões do objeto escolhido
return obj1Box.intersectsBox(obj2Box); // Retorna true se houver interseção
}
// Função para reiniciar o jogo
function restartGame() {
spaceship.position.set(0, 0, 0); // Coloca a nave no centro
scene.children.forEach((child) => {
if (child.userData.velocity) {
child.position.z = Math.random() * 100 + 50;
child.position.x = Math.random() * 40 - 20;
child.position.y = Math.random() * 40 - 20;
}
}); // Reinicia a geração de meteoros
const restartButton = document.getElementById('restartButton');
restartButton.style.display = 'none'; // Esconde o botão de reiniciar
pontuacao = 0; //Zera a pontuação
refreshPoints();//Atualiza a pontuação
isGamePaused = false;
animate();
}
// Exibir o botão de reiniciar
function showRestartButton() {
const restartButton = document.getElementById('restartButton');
restartButton.style.display = 'block'; // Mostra o botão de reiniciar
restartButton.addEventListener('click', restartGame); // Adiciona a função de reiniciar ao botão
}
function refreshPoints() {
const pontuacaoElement = document.getElementById('pontuacao');
if (pontuacaoElement) {
pontuacaoElement.innerText = "Pontuação: " + pontuacao;
}//Puxa pro html o valor da pontuação.
}
let isGamePaused = false;
// Loop de animação
function animate() {
if (!isGamePaused) { // O jogo é pausado quando acontece uma colisão com a nave
if(blackhole) {
//blackhole.position.z -= 0.1;
blackhole.rotation.y += 0.008;
}
requestAnimationFrame(animate);
// Atualizar posição dos meteoros
meteors.forEach((meteor) => {
meteor.position.z += meteor.userData.velocity;
if (meteor.position.z < -50) {
meteor.position.z = Math.random() * 100 + 50;
meteor.position.x = Math.random() * 40 - 20;
meteor.position.y = Math.random() * 40 - 20;
}
// Usando a função de colisão nos meteoros contra a nave
if (spaceship && detectCollision(spaceship, meteor)) {
isGamePaused = true; // Pausa o jogo se houver colisão com a nave
console.log("Colisão detectada com a nave! Jogo pausado.");
showRestartButton(); // Mostra o botão de reiniciar
}
});
// Atualizar e verificar colisões entre projéteis e meteoros
for (let i = projectiles.length - 1; i >= 0; i--) {
const projectile = projectiles[i];
for (let j = meteors.length - 1; j >= 0; j--) {
const meteor = meteors[j];
if (detectCollision(projectile, meteor)) {
// Remover projétil da cena e do array
scene.remove(projectile);
projectiles.splice(i, 1);
// Resetar posição do meteoro
meteor.position.set(
Math.random() * 40 - 20,
Math.random() * 40 - 20,
Math.random() * 100 + 50
);
pontuacao += 1;//soma um a pontuação quando o usuário quebra o meteoro
refreshPoints();//atualiza a pontuação no html
console.log("Meteoro destruído! Pontuação: " + pontuacao);
break; // Interrompe o loop de meteoros para este projétil
}
}
}
// Atualizar a posição da câmera em primeira pessoa para seguir a nave no eixo Z
if (activeCamera === personCamera) {
personCamera.position.set(spaceship.position.x, spaceship.position.y + 2, spaceship.position.z + 5);
personCamera.lookAt(spaceship.position.x, spaceship.position.y + 2, spaceship.position.z + 10);
}
updateProjectiles(); // Atualiza a posição dos projéteis
renderer.render(scene, activeCamera); // Renderiza a cena
}
}
animate();