- Add multi local game
    - Some minor changes in html/css
Django
    - add path for /game and /multiLocalGamePage
    - add template for multiLocalGame
This commit is contained in:
Kum1ta
2024-09-14 02:05:44 +02:00
parent 906a713e8d
commit 92ff0e9e8d
19 changed files with 27995 additions and 284 deletions

View File

@ -6,12 +6,13 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/25 00:00:21 by edbernar #+# #+# */
/* Updated: 2024/09/13 11:05:33 by edbernar ### ########.fr */
/* Updated: 2024/09/14 00:57:30 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { HomePage } from "/static/javascript/homePage/main.js";
import { multiLocalGamePage } from "/static/javascript/multiLocalGame/multiLocalGamePage.js"
import { LobbyPage } from "/static/javascript/lobbyPage/main.js";
import { HomePage } from "/static/javascript/homePage/main.js";
class Page
{
@ -19,6 +20,7 @@ class Page
availablePages = [
{url:'/', servUrl: '/homePage', class: HomePage, name: 'homePage', title: 'PTME - Home'},
{url:'/lobby', servUrl: '/lobbyPage', class: LobbyPage, name: 'lobbyPage', title: 'PTME - Lobby'},
{url:'/game', servUrl: '/multiLocalGamePage', class: multiLocalGamePage, name: 'multiLocalGamePage', title: 'PTME - Game'},
]
constructor()
@ -63,13 +65,13 @@ class Page
})
.then(data => {
data.text().then(text => {
console.log("Page updated !");
document.body.innerHTML = text;
this.actualPage = this.availablePages[i].class;
document.title = this.availablePages[i].title;
if (!isBack)
history.pushState({}, this.availablePages[i].title, this.availablePages[i].url);
this.actualPage.create();
console.log("Page created.");
})
})
.catch(error => {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 17:19:17 by edbernar #+# #+# */
/* Updated: 2024/09/13 16:42:37 by edbernar ### ########.fr */
/* Updated: 2024/09/13 22:13:07 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@ -18,7 +18,7 @@ import * as THREE from '/static/javascript/three/build/three.module.js'
import { Screen, light } from '/static/javascript/home3D/Screen.js'
import { pageRenderer } from '/static/javascript/main.js'
const disable3D = true;
const disable3D = false;
let scene = null;
let renderer = null;

View File

@ -6,12 +6,12 @@
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/22 17:08:46 by madegryc #+# #+# */
/* Updated: 2024/09/13 15:43:17 by edbernar ### ########.fr */
/* Updated: 2024/09/14 01:28:25 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { barSelecter, goalSelecter } from '/static/javascript/lobbyPage/3d.js';
import { pageRenderer } from '/static/javascript/main.js'
/*
Information :
- 0: Multiplayer local
@ -29,9 +29,9 @@ class LobbyPage
{
static create()
{
console.log("Lobby created");
listSelectCard = document.getElementsByClassName('select-card');
const startButton = document.getElementsByClassName('buttonStartGame')[0];
listSelectCard = document.getElementsByClassName('select-card');
gameMode = 0;
document.getElementsByClassName('game-mode')[0].addEventListener('click', showGameMode);
document.getElementById('closePopupBtn').addEventListener('click', hideGameMode);
@ -46,11 +46,15 @@ class LobbyPage
}
barSelector = new barSelecter(document.getElementById('bar'));
goalSelector = new goalSelecter(document.getElementById('goal'));
startButton.addEventListener('click', startMode);
}
static dispose()
{
const startButton = document.getElementsByClassName('buttonStartGame')[0];
gameMode = 0;
startButton.removeEventListener('click', startMode);
document.getElementsByClassName('game-mode')[0].removeEventListener('click', showGameMode);
document.getElementById('closePopupBtn').removeEventListener('click', hideGameMode);
window.removeEventListener('click', closeClickOutsiteGameMode);
@ -63,9 +67,31 @@ class LobbyPage
barSelector = null;
goalSelector.dispose();
goalSelector = null;
listSelectCard = null;
}
}
function startMode()
{
if (gameMode == 0)
startMultiLocal();
else if (gameMode == 1)
alert("Not implemented");
else if (gameMode == 2)
alert("Not implemented");
else if (gameMode == 3)
alert("Not implemented");
}
function startMultiLocal()
{
console.log(1);
document.body.style.animation = "startGameAnim 0.5s";
document.body.style.opacity = 0;
setTimeout(() => {
pageRenderer.changePage("multiLocalGamePage");
}, 500);
}
function showGameMode()
{
@ -114,4 +140,4 @@ function selectGameModeFour()
}
export { LobbyPage };
export { LobbyPage };

View File

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Ball.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/28 15:58:03 by edbernar #+# #+# */
/* Updated: 2024/09/14 00:19:46 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import * as THREE from '/static/javascript/three/build/three.module.js'
import { wallTop, wallBottom } from '/static/javascript/multiLocalGame/Map.js'
let ball = null;
let speed = 0.15;
let dir = -1;
let interval = null;
class Ball
{
static create(scene)
{
ball = createBall();
scene.add(ball);
ball.rotateY(2.39);
}
static dispose()
{
ball = null;
}
static update()
{
}
}
function createBall()
{
const geometry = new THREE.SphereGeometry(0.3);
const material = new THREE.MeshPhysicalMaterial({color: 0xffffff});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.y += 0.3;
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.material.transparent = true;
mesh.position.set (0, mesh.position.y, 0);
return (mesh);
}
export { Ball, ball };

View File

@ -0,0 +1,428 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Map.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/28 12:23:48 by edbernar #+# #+# */
/* Updated: 2024/09/14 02:02:00 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import * as CANNON from '/static/javascript/cannon-es/dist/cannon-es.js'
// import * as CANNON from '/static/javascript/cannon/build/cannon.min.js'
import * as THREE from '/static/javascript/three/build/three.module.js'
import { ball } from '/static/javascript/multiLocalGame/Ball.js'
import { player1, player2 } from '/static/javascript/multiLocalGame/Players.js';
const width = 25;
const height = 12.5;
let ground = null;
let spotLight = null;
let wallTop = null;
let wallBottom = null;
let world = null;
const timeStep = 1 / 60;
let groundBody = null;
let wallTopBody = null;
let wallBottomBody = null;
let ballBody = null;
let vec3 = {x:0, y:0, z:0};
let player1Body = null;
let player2Body = null;
let speed = 3;
let initialZ = 0;
let score = {player1: 0, player2: 0};
let onUpdate = false;
let scoreElement = null;
let initialSpeed = 3;
let gameEndStatus = false;
const scoreToWin = 2; //+1 for real score to win
class Map
{
static create(scene)
{
scoreElement = document.getElementById('score');
world = new CANNON.World({
gravity: new CANNON.Vec3(0, -9.81, 0),
});
ground = createGround(scene, 0x222222);
wallBottom = createWall(false);
wallTop = createWall(true);
spotLight = new THREE.SpotLight({color: 0xffffff});
spotLight.castShadow = true;
spotLight.position.y = 10;
spotLight.intensity = 200;
scene.add(spotLight);
scene.add(wallTop);
scene.add(wallBottom);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
wallTopBody = new CANNON.Body({
shape: new CANNON.Box(new CANNON.Vec3(width / 2, 0.35, 0.1)),
type: CANNON.Body.STATIC,
})
wallTopBody.position.z = -6.15;
wallTopBody.position.y += 0.35;
wallTopBody.name = "wall";
world.addBody(wallTopBody);
wallBottomBody = new CANNON.Body({
shape: new CANNON.Box(new CANNON.Vec3(width / 2, 0.35, 0.1)),
type: CANNON.Body.STATIC,
})
wallBottomBody.position.z = 6.15;
wallBottomBody.position.y += 0.35;
wallBottomBody.name = "wall";
world.addBody(wallBottomBody);
groundBody = new CANNON.Body({
shape: new CANNON.Plane(),
type: CANNON.Body.STATIC,
});
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0);
world.addBody(groundBody);
player1Body = new CANNON.Body({
shape: new CANNON.Box(new CANNON.Vec3(0.3, 0.4, 1.25)),
type: CANNON.Body.STATIC,
});
player1Body.position.set(-12, 0.4, 0);
player1Body.name = "player1";
world.addBody(player1Body);
player2Body = new CANNON.Body({
shape: new CANNON.Box(new CANNON.Vec3(0.3, 0.4, 1.25)),
type: CANNON.Body.STATIC,
});
player2Body.position.set(12, 0.4, 0);
player2Body.name = "player2";
world.addBody(player2Body);
ballBody = new CANNON.Body({
shape: new CANNON.Sphere(0.3),
mass: 10,
});
ballBody.position.set(0, 0.15, 0);
world.addBody(ballBody);
this.#collision();
ground.position.copy(groundBody.position);
ground.quaternion.copy(groundBody.quaternion);
wallBottom.position.copy(wallBottomBody.position);
wallBottom.quaternion.copy(wallBottomBody.quaternion);
wallTop.position.copy(wallTopBody.position);
wallTop.quaternion.copy(wallTopBody.quaternion);
speed = 3;
if (Math.random() > 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 };

View File

@ -0,0 +1,105 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Players.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/28 15:12:25 by edbernar #+# #+# */
/* Updated: 2024/09/14 00:20:51 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import * as THREE from '/static/javascript/three/build/three.module.js'
const speed = 0.25;
let player1 = null;
let player2 = null;
let pressedButton = [];
class Players
{
static create(scene)
{
player1 = newBarPlayer(1, 0xffffff);
player2 = newBarPlayer(2, 0xffffff);
scene.add(player1);
scene.add(player2);
document.addEventListener('keydown', addKeyInArr);
document.addEventListener('keyup', remKeyInArr);
}
static dispose()
{
document.removeEventListener('keydown', addKeyInArr);
document.removeEventListener('keyup', remKeyInArr);
player1 = null;
player2 = null;
}
static update()
{
const limits = 4.55;
let i = 0;
while (i < pressedButton.length)
{
if (pressedButton[i] == 'w' && player1.position.z > -limits)
player1.position.z -= speed;
if (pressedButton[i] == 'z' && player1.position.z > -limits)
player1.position.z -= speed;
else if (pressedButton[i] == 's' && player1.position.z < limits)
player1.position.z += speed;
else if (pressedButton[i] == 'ArrowUp' && player2.position.z > -limits)
player2.position.z -= speed;
else if (pressedButton[i] == 'ArrowDown' && player2.position.z < limits)
player2.position.z += speed;
i++;
}
}
static changeColor(player, color)
{
player.material.color.set(color);
}
}
function newBarPlayer(nbPlayer, color)
{
const geometry = new THREE.BoxGeometry(0.3, 0.4, 2.5);
const material = new THREE.MeshPhysicalMaterial({color: color});
const mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
if (nbPlayer == 1)
mesh.position.set(-12, 0.4, 0);
else
mesh.position.set(12, 0.4, 0);
return (mesh);
}
function addKeyInArr(e)
{
let i;
i = 0;
while (i < pressedButton.length && e.key != pressedButton[i])
i++;
if (i == pressedButton.length)
pressedButton.push(e.key);
}
function remKeyInArr(e)
{
let i;
i = 0;
while (i < pressedButton.length && e.key != pressedButton[i])
i++;
if (i != pressedButton.length)
pressedButton.splice(i, 1);
}
export { Players, player1, player2 };

View File

@ -0,0 +1,119 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* multiLocalGamePage.js :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/28 12:07:39 by edbernar #+# #+# */
/* Updated: 2024/09/14 01:59:38 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
import { Map, ground, gameEndStatus, score, scoreElement } from '/static/javascript/multiLocalGame/Map.js'
import { Players, player1, player2 } from '/static/javascript/multiLocalGame/Players.js'
import * as THREE from '/static/javascript/three/build/three.module.js'
import { Ball } from '/static/javascript/multiLocalGame/Ball.js'
import { pageRenderer } from '/static/javascript/main.js'
let scene = null;
let renderer = null;
let camera = null;
/*
Controls :
- w : monter player1
- s : descendre player1
- haut : monter player2
- bas : descendre player2
- a : restart quand score debug
*/
class multiLocalGamePage
{
static create()
{
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
renderer.domElement.style.filter = 'brightness(1)';
document.getElementById('score').style.animation = 'fadeOutStartGames 1s';
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
Ball.create(scene);
Map.create(scene);
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight);
camera.rotation.x = -Math.PI / 2;
renderer.setSize(window.innerWidth, window.innerHeight);
scene.background = new THREE.Color(0x252525);
document.body.appendChild(renderer.domElement);
Players.create(scene);
camera.position.set(0, 22, 0);
document.addEventListener('keypress', (e) => {
if (e.key == 'a')
Map.reCreate(true);
})
renderer.setAnimationLoop(loop);
document.body.style.opacity = 1;
}
static dispose()
{
Map.dispose();
if (renderer)
renderer.dispose();
renderer = null;
camera = null;
if (scene)
{
scene.children.forEach(child => {
if (child.geometry)
child.geometry.dispose();
if (child.material)
child.material.dispose();
if (child.texture)
child.texture.dispose();
scene.remove(child);
});
}
scene = null;
}
};
function loop()
{
if (gameEndStatus)
{
renderer.setAnimationLoop(null);
gameFinish()
}
Ball.update();
Map.update();
Players.update();
if (renderer)
renderer.render(scene, camera);
}
function gameFinish()
{
scoreElement.innerHTML = "Player " + (score.player1 > score.player2 ? "1" : "2") + " win !";
scoreElement.style.fontSize = '10vh';
scoreElement.style.opacity = 1;
document.body.style.animation = 'none';
setTimeout(() => {
document.body.style.animation = 'end 1s';
setTimeout(() => {
pageRenderer.changePage('lobbyPage');
}, 500);
}, 3000);
}
export { multiLocalGamePage };

View File

@ -0,0 +1,99 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* games.css :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/20 11:23:41 by edbernar #+# #+# */
/* Updated: 2024/09/14 01:56:23 by edbernar ### ########.fr */
/* */
/* ************************************************************************** */
@keyframes fadeInGames {
from {
filter: brightness(1);
}
to {
filter: brightness(0);
}
}
@keyframes fadeOutGames {
from {
filter: brightness(0);
}
to {
filter: brightness(1);
}
}
@keyframes fadeOutStartGames {
0% {
filter: brightness(0);
}
70% {
filter: brightness(0);
}
100% {
filter: brightness(1);
}
}
@keyframes fadeInTextGames {
from {
color: rgb(255, 255, 255, 0.1);
}
to {
color: rgb(255, 255, 255, 1);
}
}
@keyframes fadeOutTextGames {
from {
color: rgb(255, 255, 255, 1);
}
to {
color: rgb(255, 255, 255, 0.1);
}
}
@keyframes end {
0% {
opacity: 1;
}
75% {
opacity: 0;
}
100% {
opacity: 1;
}
}
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
user-select: none;
}
#score {
line-height: 1.75;
vertical-align: top;
font-family: 'Poppins';
position: absolute;
font-size: 30vh;
top: 0;
bottom : 50%;
left: 50%;
transform: translate(-50%, 50%);
z-index: 800;
margin: 0;
padding: 0;
white-space: nowrap;
/* font-weight: 900; */
color: rgb(255, 255, 255, 0.1);
}

View File

@ -33,7 +33,7 @@
* {
margin: 0;
padding: 0;
font-family: "Poppins", sans-serif;
font-family: "Poppins", sans-serif;
font-weight: 500;
font-style: normal;
}
@ -48,127 +48,127 @@ body {
}
.main{
padding-top: 80px;
padding-inline: 150px;
display: flex;
flex-direction: row;
gap: 2.6rem;
padding-top: 80px;
padding-inline: 150px;
display: flex;
flex-direction: row;
gap: 2.6rem;
}
.skin-select{
/* padding-block: 25px; */
width: 40%;
/* padding-block: 25px; */
width: 40%;
}
.popup {
display: none; /* La popup est masquée par défaut */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
justify-content: center;
align-items: center;
z-index: 503;
display: none; /* La popup est masquée par défaut */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
justify-content: center;
align-items: center;
z-index: 503;
}
.popup-content {
background-color: white;
padding: 20px;
text-align: center;
width: 40%;
position: relative;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
background-color: white;
padding: 20px;
text-align: center;
width: 40%;
position: relative;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
}
.popup-content form {
display: flex;
flex-direction: column;
display: flex;
flex-direction: column;
}
.choose{
display: flex;
justify-content: center;
gap: 20px;
display: flex;
justify-content: center;
gap: 20px;
}
.select-card{
margin: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
background-color: #d3d3d3;
color: #000;
height: 90px;
font-size: 1.2em;
transition: transform 0.3s ease;
margin: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
background-color: #d3d3d3;
color: #000;
height: 90px;
font-size: 1.2em;
transition: transform 0.3s ease;
}
.select-card:hover {
transform: scale(1.05);
transform: scale(1.05);
}
.switch {
position: relative;
position: relative;
}
.switch p{
color: white;
font-size: 1.2em;
color: white;
font-size: 1.2em;
}
.switch label {
width: 59px;
height: 28px;
background-color: #999;
position: absolute;
top: 0;
left: 0;
border-radius: 50px;
width: 59px;
height: 28px;
background-color: #999;
position: absolute;
top: 0;
left: 0;
border-radius: 50px;
}
.switch input[type="checkbox"] {
visibility: hidden;
visibility: hidden;
}
.switch label:after {
content: '';
margin-top: 2px;
margin-left: 2px;
width: 22px;
height: 22px;
border-radius: 50px;
position: absolute;
top: 1px;
left: 1px;
transition: 200ms;
background-color: white;
content: '';
margin-top: 2px;
margin-left: 2px;
width: 22px;
height: 22px;
border-radius: 50px;
position: absolute;
top: 1px;
left: 1px;
transition: 200ms;
background-color: white;
}
.switch .look:checked + label:after {
left: 32px;
left: 32px;
}
.switch .look:checked + label {
background-color: rgb(18, 223, 96);
background-color: rgb(18, 223, 96);
}
#bar{
margin: 15px;
width: 250px;
height: 250px;
border: 5px solid white;
margin: 15px;
width: 250px;
height: 250px;
border: 5px solid white;
}
#goal{
margin: 15px;
width: 250px;
height: 250px;
border: 5px solid white;
margin: 15px;
width: 250px;
height: 250px;
border: 5px solid white;
}
#topBar {
@ -179,60 +179,91 @@ body {
background-color: #020202;
gap: 2rem;
align-items: center;
justify-content: center;
justify-content: center;
inset-inline: 0;
top: 0;
}
.game-mode {
display: flex;
justify-content: flex-start;
display: flex;
justify-content: flex-start;
}
.mode-card {
background-color: #d3d3d3;
color: #000;
padding: 20px;
width: 300px;
height: 550px;
display: flex;
justify-content: center;
font-size: 1.2em;
background-color: #d3d3d3;
color: #000;
padding: 20px;
width: 300px;
height: 550px;
display: flex;
justify-content: center;
font-size: 1.2em;
transition: transform 0.3s ease;
}
.mode-card:hover {
transform: scale(1.05);
transform: scale(1.05);
}
.search-container {
display: flex;
align-items: center;
width: 40%;
display: flex;
align-items: center;
width: 40%;
}
.search-input {
width: 100%;
padding: 10px;
border: 2px solid #ccc;
font-size: 16px;
outline: none;
width: 100%;
padding: 10px;
border: 2px solid #ccc;
font-size: 16px;
outline: none;
}
.search-input:focus {
border-color: white;
border-color: white;
}
.search-button {
padding: 10px 20px;
border: 2px solid white;
background-color: #272727;
color: white;
cursor: pointer;
font-size: 16px;
padding: 10px 20px;
border: 2px solid white;
background-color: #272727;
color: white;
cursor: pointer;
font-size: 16px;
}
.search-button:hover {
background-color: #202020;
border-color: #c4c4c4;
background-color: #202020;
border-color: #c4c4c4;
}
.bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
}
.buttonStartGame {
background-color: white;
padding: 10px;
cursor: pointer;
}
.buttonStartGame:hover {
background-color: rgb(186, 186, 186);
transform: scale(1.1);
}
@keyframes startGameAnim {
0% {
transform: translateX(-0%);
opacity: 1;
}
100% {
transform: translateX(-20%);
opacity: 0;
}
}