/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* Map.js :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: edbernar 0.5) { vec3.z = Math.random() * 10 % 4 - 2; vec3.x = -Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } else { vec3.z = Math.random() * 10 % 4 - 2; vec3.x = Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } initialZ = vec3.z; ballBody.velocity.set(vec3.x, vec3.y, vec3.z); onUpdate = true; setTimeout(() => { scoreElement.innerHTML = '3'; }, 1000); setTimeout(() => { scoreElement.innerHTML = '2'; }, 1750); setTimeout(() => { scoreElement.innerHTML = '1'; }, 2500); setTimeout(() => { scoreElement.innerHTML = score.player1 + '-' +score.player2; }, 3250); setTimeout(() => { onUpdate = false; }, 4000); } static dispose() { if (spotLight) spotLight.dispose(); spotLight = null; score.player1 = 0; score.player2 = 0; gameEndStatus = false; } static update() { if (onUpdate) return ; world.step(timeStep); if (ballBody.position.x > 13) ball.material.opacity = 1 - ((ball.position.x - 13) / 2); if (ballBody.position.x < -13) ball.material.opacity = 1 - (-(ball.position.x + 13) / 2); if (ballBody.position.x > 23) return (Map.reCreate(false)); if (ballBody.position.x < -23) return (Map.reCreate(true)); ball.position.copy(ballBody.position); player1Body.position.copy(player1.position); player2Body.position.copy(player2.position); if (speed < 7) speed += 0.003; ballBody.velocity.set(vec3.x * speed, vec3.y * speed, vec3.z * speed); } static #collision() { let playerPosition; let relativePosition; let playerHalfExtents; let sideTouched; let ballPosition; let step = 0.75; ballBody.addEventListener("collide", function(e) { let bodyA = e.contact.bi; let bodyB = e.contact.bj; let collided = (bodyA === ballBody) ? bodyB : bodyA; switch(collided.name) { case "wall": vec3.z = -vec3.z; return; case "player1": collidedPlayer1(collided, e); return; case "player2": collidedPlayer2(collided, e); return; } }); function collidedPlayer1(collided, e) { scalePlayer(player1); ballPosition = ballBody.position; playerPosition = collided.position; relativePosition = ballPosition.vsub(playerPosition); playerHalfExtents = collided.shapes[0].halfExtents; if (Math.abs(relativePosition.x) > playerHalfExtents.x) sideTouched = (relativePosition.x > 0) ? 'right' : 'left'; else if (Math.abs(relativePosition.z) > playerHalfExtents.z) sideTouched = (relativePosition.z > 0) ? 'front' : 'back'; if (sideTouched == 'front' || sideTouched == 'back') { vec3.z = -vec3.z; return ; } initialSpeed = Math.sqrt(vec3.x * vec3.x + vec3.z * vec3.z); let random = Math.random(); if (random > 0.5) { vec3.z -= step; vec3.x = Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } else if (random < 0.5) { vec3.z += step; vec3.x = Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } } function collidedPlayer2(collided, e) { scalePlayer(player2); ballPosition = ballBody.position; playerPosition = collided.position; relativePosition = ballPosition.vsub(playerPosition); playerHalfExtents = collided.shapes[0].halfExtents; if (Math.abs(relativePosition.x) > playerHalfExtents.x) sideTouched = (relativePosition.x > 0) ? 'right' : 'left'; else if (Math.abs(relativePosition.z) > playerHalfExtents.z) sideTouched = (relativePosition.z > 0) ? 'front' : 'back'; if (sideTouched == 'front' || sideTouched == 'back') { vec3.z = -vec3.z; return ; } initialSpeed = Math.sqrt(vec3.x * vec3.x + vec3.z * vec3.z); let random = Math.random(); if (random > 0.5) { vec3.z -= step; vec3.x = -Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } else if (random < 0.5) { vec3.z += step; vec3.x = -Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } } function scalePlayer(player) { const value = 0.01; for (let i = 1; i < 10; i++) { setTimeout(() => { player.scale.z += value; player.scale.x += value * 2; }, i * 10); } for (let i = 10; i < 20; i++) { setTimeout(() => { player.scale.z -= value; player.scale.x -= value * 2; }, i * 10); } } } static reCreate(player1Lose) { onUpdate = true; document.getElementsByTagName('canvas')[0].style.animation = 'fadeInGames 0.199s'; document.getElementsByTagName('canvas')[0].style.filter = 'brightness(0)'; scoreElement.style.animation = 'fadeInTextGames 0.199s'; scoreElement.style.color = 'rgb(255, 255, 255, 1)'; setTimeout(() => { if (player1Lose) score.player2++; else score.player1++; scoreElement.innerHTML = score.player1 + '-' +score.player2; }, 500); if ((player1Lose && score.player2 >= scoreToWin) || (!player1Lose && score.player1 >= scoreToWin)) return (this.#endGame()); setTimeout(() => { speed = 3; initialSpeed = Math.sqrt(vec3.x * vec3.x + vec3.z * vec3.z); if (player1Lose) { vec3.z = Math.random() * 10 % 4 - 2; vec3.x = -Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } else { vec3.z = Math.random() * 10 % 4 - 2; vec3.x = Math.sqrt(initialSpeed * initialSpeed - vec3.z * vec3.z); } initialZ = vec3.z; onUpdate = false; }, 1700); setTimeout(() => { ballBody.velocity.set(0,0,0); ballBody.position.set(0, 0.15, 0); ball.position.copy(ballBody.position); ball.material.opacity = 1; player1Body.position.set(-12, 0.4, 0); player1.position.copy(player1Body.position); player2Body.position.set(12, 0.4, 0); player2.position.copy(player2Body.position); scoreElement.style.animation = 'fadeOutGames 0.199s'; document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)'; scoreElement.style.animation = 'fadeOutTextGames 0.399s'; scoreElement.style.color = 'rgb(255, 255, 255, 0.1)'; }, 1200); } static changeGround(ground, texture) { if (ground.material) ground.material.dispose(); if (typeof(texture) == 'string') { const textureLoader = new THREE.TextureLoader(); texture = textureLoader.load(texture); ground.material.map = texture; } else if (typeof(texture) == 'number') ground.material.color.set(texture); } static #endGame() { speed = 3; vec3.x = 0; vec3.y = 0; vec3.z = 0 initialZ = vec3.z; setTimeout(() => { ballBody.velocity.set(0,0,0); ballBody.position.set(0, 0.15, 0); ball.position.copy(ballBody.position); ball.material.opacity = 1; player1Body.position.set(-12, 0.4, 0); player1.position.copy(player1Body.position); player2Body.position.set(12, 0.4, 0); player2.position.copy(player2Body.position); scoreElement.style.animation = 'fadeOutGames 0.199s'; document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)'; scoreElement.style.animation = 'fadeOutTextGames 0.399s'; scoreElement.style.color = 'rgb(255, 255, 255, 0.1)'; onUpdate = false; gameEndStatus = true; }, 1200); } } function createGround(scene, texture) { const geometry = new THREE.PlaneGeometry(width, height); let material = null; let mesh = null; if (typeof(texture) == 'string') { const textureLoader = new THREE.TextureLoader(); texture = textureLoader.load(texture); material = new THREE.MeshPhysicalMaterial({ map: texture }); } else if (typeof(texture) == 'number') material = new THREE.MeshPhysicalMaterial({ color: texture }); else material = new THREE.MeshPhysicalMaterial({color: 0x222222}); mesh = new THREE.Mesh(geometry, material); mesh.rotateX(-Math.PI / 2); mesh.position.set(0, 0, 0); scene.add(mesh); return (mesh); } function createWall(onTop) { const geometry = new THREE.BoxGeometry(width, 0.7, 0.2); const material = new THREE.MeshPhysicalMaterial({color: 0x333333}); const mesh = new THREE.Mesh(geometry, material); return (mesh); } export { Map, wallBottom, wallTop, ground, gameEndStatus, score, scoreElement };