576 lines
13 KiB
HTML
Executable File
576 lines
13 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Jogo VR Rolimã do livro "Jean: entre jogos e brincadeiras"</title>
|
|
|
|
<meta name="description" content="">
|
|
|
|
<script src="aframe.0.8.2.min.js"></script>
|
|
|
|
|
|
<script src="aframe-aabb-collider-component.min.js"></script>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
var RotY;
|
|
|
|
var RotZ;
|
|
|
|
AFRAME.registerComponent('rotation-reader', {
|
|
|
|
tick: function () {
|
|
|
|
RotZ = this.el.object3D.rotation.y;
|
|
RotY = this.el.object3D.rotation.z;
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<a-scene>
|
|
|
|
<a-assets>
|
|
|
|
<img id="sky" src="fundo.jpg">
|
|
|
|
<a-asset-item id="cidade" src="cidade.glb"></a-asset-item>
|
|
<!-- A Cidade
|
|
"CCity Building Set 1" (https://skfb.ly/LpSC) by Neberkenezer is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
|
Alterações foram feitas
|
|
-->
|
|
|
|
<a-asset-item id="carrinho" src="carrinho.glb"></a-asset-item>
|
|
|
|
<a-asset-item id="cone" src="cone.glb"></a-asset-item>
|
|
<!--
|
|
Cone
|
|
"Orange street cone" (https://skfb.ly/6RUHP) by Mateusz Woliński is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).
|
|
Alterações foram feitas
|
|
|
|
-->
|
|
|
|
<audio id="rolima" src="429104__inspectorj__marble-rolling-on-wood-alt.mp3" ></audio>
|
|
|
|
<!-- Som Rolimã
|
|
Usuário InspectorJ do freesound.org
|
|
Marble, Rolling on Wood, A.wav
|
|
https://freesound.org/people/InspectorJ/sounds/429104/
|
|
licença: https://creativecommons.org/licenses/by/3.0/
|
|
Foram realizadas alterações no arquivo
|
|
-->
|
|
|
|
|
|
<audio id="cont" src="528730__alexhanj__ping_alt.mp3" ></audio>
|
|
|
|
<!-- Som contagem
|
|
Usuário Alexhanj do freesound.org
|
|
Ping.aiff
|
|
https://freesound.org/people/Alexhanj/sounds/528730/
|
|
licença: https://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
-->
|
|
|
|
<audio id="vai" src="403005__inspectorj__ui-confirmation-alert-a4_alt.mp3" ></audio>
|
|
|
|
<!-- Som do vai
|
|
Usuário InspectorJ do freesound.org
|
|
UI Confirmation Alert, A4.wav
|
|
https://freesound.org/people/InspectorJ/sounds/403005/
|
|
licença: https://creativecommons.org/licenses/by/3.0/
|
|
|
|
-->
|
|
|
|
<audio id="sucesso" src="60443__jobro__tada1.mp3" ></audio>
|
|
|
|
<!-- Som de sucesso, conclusão
|
|
Usuário jobro do freesound.org
|
|
Success!! » tada1.wav
|
|
https://freesound.org/people/jobro/sounds/60443/
|
|
licença: https://creativecommons.org/licenses/by/3.0/
|
|
Foi feita uma pequena alteração
|
|
-->
|
|
|
|
<audio id="batida" src="456319__cupido-1__hit-ball.mp3" ></audio>
|
|
|
|
<!-- Som batida no cone
|
|
Usuário cupido-1 do freesound.org
|
|
hit ball.WAV
|
|
https://freesound.org/people/cupido-1/sounds/456319/
|
|
licença: https://creativecommons.org/publicdomain/zero/1.0/
|
|
Alterações foram feitas
|
|
-->
|
|
|
|
<audio id="falhou" src="563850__nikplaymostories__fail-trombone-wah-wah-wah-sound-effect.mp3" ></audio>
|
|
|
|
<!-- Som de game over - você falhou
|
|
Usuário NikPlaymostories do freesound.org
|
|
Fail (Trombone wah, wah, wah…) - Sound Effect.mp3
|
|
https://freesound.org/people/NikPlaymostories/sounds/563850/
|
|
licença: https://creativecommons.org/publicdomain/zero/1.0/
|
|
Alterações foram feitas
|
|
-->
|
|
|
|
|
|
</a-assets>
|
|
|
|
|
|
|
|
<a-sky src="#sky"></a-sky>
|
|
|
|
|
|
<a-entity id="roll" sound="src: #rolima; volume: 3"></a-entity>
|
|
<a-entity id="contSom" sound="src: #cont"></a-entity>
|
|
<a-entity id="vaiSom" sound="src: #vai"></a-entity>
|
|
<a-entity id="batidaSom" sound="src: #batida; volume:5"></a-entity>
|
|
<a-entity id="gameOverSom" sound="src: #falhou; volume:5"></a-entity>
|
|
<a-entity id="sucessoSom" sound="src: #sucesso; volume:25"></a-entity>
|
|
|
|
|
|
<a-entity id="camera" camera="active: true;" position="0 13.2 5"> <!-- Necessário para posicionar a camera -->
|
|
|
|
<a-entity rotation-reader camera="active: true" look-controls position="0 0 0" rotation="0 0 0">
|
|
|
|
<a-text id="contagem" visible="false" value="3" position="0 0.1 -0.4" width="3" color="#FFFFFF" align="center"></a-text>
|
|
<a-text id="instrucao" value="Desvie dos cones. Clique no desenho do canto inferior direito para iniciar." position="0 0.05 -0.2" width="0.5" color="#FFFFFF" align="center"></a-text>
|
|
<a-text id="textoFinal" visible="false" value="Isso! Vamos complicar um pouco? Aguarde a contagem novamente." position="0 0.05 -0.2" width="0.5" color="#FFFFFF" align="center"></a-text>
|
|
<a-text id="gameOver" visible="false" value="Que pena... Tente outra vez! Aguarde..." position="0 0.05 -0.2" width="0.5" color="#FFFFFF" align="center"></a-text>
|
|
|
|
|
|
</a-entity>
|
|
|
|
</a-entity>
|
|
|
|
|
|
|
|
<a-entity gltf-model="#cidade" position="22.5 0 -180" rotation="0 90 0"></a-entity>
|
|
|
|
<a-entity id="player" class="player" gltf-model="#carrinho" position="0 13 5" rotation="-4 0 0"></a-entity>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</a-scene>
|
|
|
|
<script>
|
|
|
|
|
|
|
|
var cam = document.querySelector('#camera');
|
|
|
|
var player = document.querySelector('#player');
|
|
|
|
var textoFinal = document.querySelector('#textoFinal');
|
|
|
|
var contagem = document.querySelector('#contagem');
|
|
|
|
let play;
|
|
|
|
var Px;
|
|
|
|
var Py;
|
|
|
|
let roll = document.querySelector('#roll');
|
|
let contSom = document.querySelector('#contSom');
|
|
let vaiSom = document.querySelector('#vaiSom');
|
|
let batidaSom = document.querySelector('#batidaSom');
|
|
let sucessoSom = document.querySelector('#sucessoSom');
|
|
let gameOverSom = document.querySelector('#gameOverSom');
|
|
|
|
let k = 0.1; //velocidade
|
|
|
|
var fase = 1;
|
|
|
|
function contarElArr(arr, el) {
|
|
|
|
return arr.filter(item => item == el).length;
|
|
|
|
}
|
|
|
|
function finalizarJogo(e) {
|
|
|
|
player.removeEventListener('hitstart', finalizarJogo);
|
|
|
|
var obj = e.detail.id;
|
|
|
|
cancelAnimationFrame(play);
|
|
|
|
roll.components.sound.stopSound();
|
|
|
|
batidaSom.components.sound.playSound();
|
|
|
|
setTimeout(() => {
|
|
|
|
gameOverSom.components.sound.playSound();
|
|
|
|
batidaSom.components.sound.stopSound();
|
|
|
|
}, 500);
|
|
|
|
gameOver.setAttribute('visible', true);
|
|
|
|
setTimeout(() => {
|
|
|
|
gameOverSom.components.sound.stopSound();
|
|
|
|
gameOver.setAttribute('visible', false);
|
|
|
|
voltarPosicaoInicial(0);
|
|
|
|
}, 3000);
|
|
|
|
console.log("Objeto colidido: "+obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function sortearObstaculos() {
|
|
|
|
let val = 12 - fase;
|
|
|
|
let qtde = parseInt(val,10)-1;
|
|
|
|
let posicoes = [0,15,30,45,60,75,90,105,120,135,150,165,180,195];
|
|
|
|
let sorteados = [];
|
|
|
|
for (i=0;i<qtde;i++){
|
|
|
|
let status = false;
|
|
|
|
let sorteado = Math.floor(Math.random()*(posicoes.length-1)); // sorteia números de 0 até a quantidade de posições menos um.
|
|
|
|
let rep = contarElArr(sorteados,posicoes[sorteado]);
|
|
|
|
|
|
|
|
if ( rep >= 2){
|
|
|
|
|
|
|
|
posicoes.splice(sorteado, 1);
|
|
|
|
sorteado = Math.floor(Math.random()*(posicoes.length-1)); // sorteia números de 0 até a quantidade de posições menos um.
|
|
|
|
|
|
|
|
sorteados.push(posicoes[sorteado]);
|
|
|
|
|
|
|
|
status = true;
|
|
|
|
} else {
|
|
|
|
|
|
sorteados.push(posicoes[sorteado]);
|
|
|
|
|
|
status = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status){
|
|
|
|
let sorteadoECD = Math.floor((Math.random()*3)+1); //sorteia 1, 2 ou 3. "1" esquerda, "2", centro e "3", direita.
|
|
|
|
let id = sorteado.toString();
|
|
|
|
let posX;
|
|
|
|
if(sorteadoECD == 1){
|
|
|
|
posX = -2.1;
|
|
|
|
} else if(sorteadoECD == 2){
|
|
|
|
posX = 0;
|
|
|
|
} else {
|
|
|
|
posX = 2.1;
|
|
|
|
}
|
|
|
|
let el = document.createElement('a-entity');
|
|
|
|
el.setAttribute('gltf-model','#cone');
|
|
|
|
let sceneEl = document.querySelector('a-scene');
|
|
|
|
sceneEl.appendChild(el);
|
|
|
|
el.id = id;
|
|
|
|
el.object3D.position.x = posX;
|
|
|
|
el.object3D.position.z = -10 - sorteados[i]; // -10 para o primeiro obstáculo não ficar muito em cima no início
|
|
|
|
el.object3D.position.y = (10 + sorteados[i])*(-0.0699) + 12.65;
|
|
|
|
el.setAttribute('aabb-collider','objects: .player; collideNonVisible: true');
|
|
|
|
}//fecha if do status
|
|
|
|
}// fecha for
|
|
|
|
|
|
}// fecha a funcao sortearObstaculos
|
|
|
|
|
|
|
|
|
|
function checarFim() {
|
|
|
|
if(this.player.object3D.position.z <= -210){
|
|
|
|
cancelAnimationFrame(play);
|
|
|
|
sucessoSom.components.sound.playSound();
|
|
|
|
roll.components.sound.stopSound();
|
|
|
|
if (fase == 1){
|
|
|
|
textoFinal.setAttribute('visible', true);
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
voltarPosicaoInicial(1);
|
|
|
|
}, 3000);
|
|
|
|
} else if (fase == 2) {
|
|
|
|
textoFinal.setAttribute('value','Uau! Uma mais complicada?')
|
|
|
|
textoFinal.setAttribute('visible', true);
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
voltarPosicaoInicial(2);
|
|
|
|
}, 3000);
|
|
|
|
} else if (fase == 3) {
|
|
|
|
textoFinal.setAttribute('value','Irado! Vou complicar mais!')
|
|
|
|
textoFinal.setAttribute('visible', true);
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
voltarPosicaoInicial(3);
|
|
|
|
}, 3000);
|
|
|
|
} else if (fase == 4) {
|
|
|
|
textoFinal.setAttribute('value','Fim. Que fera!')
|
|
|
|
textoFinal.setAttribute('visible', true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function voltarPosicaoInicial(numFase) {
|
|
|
|
this.player.object3D.position.z = 5;
|
|
this.player.object3D.position.y = 13;
|
|
|
|
this.cam.object3D.position.z = 5;
|
|
this.cam.object3D.position.y = 13.2;
|
|
|
|
fase = numFase + 1;
|
|
|
|
k = parseInt(fase,10)*0.1;
|
|
|
|
console.log('Fase: '+fase+' k: '+k);
|
|
|
|
textoFinal.setAttribute('visible', false);
|
|
|
|
iniciarContagem();
|
|
|
|
}
|
|
|
|
|
|
|
|
function iniciarContagem() {
|
|
|
|
player.addEventListener('hitstart', finalizarJogo);
|
|
|
|
sortearObstaculos();
|
|
|
|
contSom.components.sound.stopSound();
|
|
|
|
instrucao.setAttribute('visible', false);
|
|
|
|
let tempoRestante = 3;
|
|
|
|
let contador = setInterval(function(){
|
|
|
|
contagem.setAttribute('visible', true);
|
|
|
|
if(tempoRestante <= -1){
|
|
|
|
clearInterval(contador);
|
|
contagem.setAttribute('visible', false);
|
|
requestAnimationFrame(moverPlayer);
|
|
roll.components.sound.playSound();
|
|
|
|
|
|
}
|
|
|
|
if(tempoRestante > 0){
|
|
|
|
contagem.setAttribute('value', tempoRestante);
|
|
contSom.components.sound.playSound();
|
|
|
|
} else if (tempoRestante == 0){
|
|
|
|
contagem.setAttribute('value', 'Vai!');
|
|
vaiSom.components.sound.playSound();
|
|
|
|
}
|
|
|
|
tempoRestante -= 1;
|
|
|
|
}, 1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function andarPraFrente(Py) {
|
|
|
|
this.player.object3D.position.z = -1*(Py + k);
|
|
this.player.object3D.position.y = (Py + k)*(-0.0699) + 13; //faz a descida do carrinho
|
|
|
|
this.cam.object3D.position.z = player.object3D.position.z;
|
|
this.cam.object3D.position.y = (Py + k)*(-0.0699) + 13.2; //faz a descida da câmera
|
|
|
|
checarFim();
|
|
|
|
}
|
|
|
|
|
|
const moverPlayer = () => {
|
|
|
|
play = requestAnimationFrame(moverPlayer);
|
|
|
|
|
|
Px = player.object3D.position.x;
|
|
|
|
Py = -1*(player.object3D.position.z);
|
|
|
|
if ((RotZ % Math.PI == 0) && ((RotZ/Math.PI) % 2 == 0)){//anda para frente
|
|
|
|
andarPraFrente(Py);
|
|
|
|
|
|
} else if ((-1*Math.sin(RotZ)) > 0 && Math.cos(RotZ) > 0){ //Diagonal entre frente e direita
|
|
|
|
this.player.object3D.rotation.y = RotZ;
|
|
|
|
let DeltaX = (Px + k*(-1*Math.sin(RotZ)));
|
|
|
|
DeltaX <= 2.5? null:DeltaX = 2.5;
|
|
|
|
this.player.object3D.position.z = -1*(Py + k*(Math.cos(RotZ)));
|
|
this.player.object3D.position.x = DeltaX;
|
|
this.player.object3D.position.y = (Py + k*(Math.cos(RotZ)))*(-0.0699) + 13; //faz a descida do carrinho
|
|
|
|
this.cam.object3D.position.z = player.object3D.position.z;
|
|
this.cam.object3D.position.x = DeltaX;
|
|
this.cam.object3D.position.y = player.object3D.position.y+0.2; //faz a descida da câmera
|
|
|
|
checarFim();
|
|
|
|
|
|
} else if (Math.sin(RotZ) > 0 && (-1*Math.cos(RotZ)) < 0){//Diagonal entre frente e esquerda
|
|
|
|
this.player.object3D.rotation.y = RotZ;
|
|
|
|
let DeltaX = (Px - k*(Math.sin(RotZ)));
|
|
|
|
DeltaX >= -2.5? null: DeltaX = -2.5;
|
|
|
|
this.player.object3D.position.z = -1*(Py + k*(Math.cos(RotZ)));
|
|
this.player.object3D.position.x = DeltaX;
|
|
this.player.object3D.position.y = (Py + k*(Math.cos(RotZ)))*(-0.0699) + 13; //faz a descida do carrinho
|
|
|
|
this.cam.object3D.position.z = player.object3D.position.z;
|
|
this.cam.object3D.position.x = DeltaX;
|
|
this.cam.object3D.position.y = player.object3D.position.y+0.2; //faz a descida da câmera
|
|
|
|
checarFim();
|
|
|
|
|
|
}else if ((RotZ/(Math.PI/2)) % 2 != 0 && (RotZ/(Math.PI/2)) % 4 == 1 || ((-1*Math.sin(RotZ)) < 0 && Math.cos(RotZ) < 0) || ((RotZ % Math.PI == 0) && ((RotZ/Math.PI) % 2 != 0)) || (Math.sin(RotZ) < 0 && (-1*Math.cos(RotZ))) || ((RotZ/(Math.PI/2)) % 2 != 0 && (RotZ/(Math.PI/2)) % 4 == 3)){
|
|
|
|
//Andar para esquerda || Diagonal entre esquerda e pra baixo || Andar pra baixo || Diagonal entre direita e pra baixo || Anda para direita - nessa ordem (separados por ou)
|
|
|
|
//Nesses casos, o carrinho deve continuar andando para frente
|
|
|
|
andarPraFrente(Py);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
document.querySelector('a-scene').addEventListener('enter-vr', function () {
|
|
|
|
|
|
|
|
|
|
iniciarContagem();
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|