From b04402259fe3353fa19485001dc8af5118887a61 Mon Sep 17 00:00:00 2001 From: "julien.bouin.etu" <julien.bouin.etu@univ-lille.fr> Date: Sat, 6 Apr 2024 22:08:27 +0200 Subject: [PATCH] debut refactor --- client/src/afficher.js | 2 +- client/src/main.js | 193 ++++-------- client/src/render.js | 2 +- {client/src => common}/Coordinate.js | 0 {client/src => common}/avatar.js | 6 +- {client/src => common}/avatar.test.js | 0 {client/src => common}/utils.js | 0 {client/src => server}/Projectile.js | 2 +- server/bonus.js | 4 +- server/enemis.js | 4 +- {client/src => server}/entite.js | 0 server/gameLogic.js | 144 +++++++++ {client/src => server}/hitbox.js | 0 {client/src => server}/hitbox.test.js | 0 server/index.js | 356 ++++++++++++---------- {client/src => server}/projectile.test.js | 0 16 files changed, 412 insertions(+), 301 deletions(-) rename {client/src => common}/Coordinate.js (100%) rename {client/src => common}/avatar.js (95%) rename {client/src => common}/avatar.test.js (100%) rename {client/src => common}/utils.js (100%) rename {client/src => server}/Projectile.js (92%) rename {client/src => server}/entite.js (100%) create mode 100644 server/gameLogic.js rename {client/src => server}/hitbox.js (100%) rename {client/src => server}/hitbox.test.js (100%) rename {client/src => server}/projectile.test.js (100%) diff --git a/client/src/afficher.js b/client/src/afficher.js index 9a221f2..540067c 100644 --- a/client/src/afficher.js +++ b/client/src/afficher.js @@ -1,5 +1,5 @@ import setHtml from './setHtml.js'; -import { Coordinate } from './Coordinate.js'; +import { Coordinate } from '../../common/Coordinate.js'; export default class Afficher { gameStarted; diff --git a/client/src/main.js b/client/src/main.js index ca2d2e1..142b376 100644 --- a/client/src/main.js +++ b/client/src/main.js @@ -1,7 +1,7 @@ -import { Avatar } from './avatar.js'; +import { Avatar } from '../../common/avatar.js'; import { io } from 'socket.io-client'; import draw from './draw.js'; -import { bonusImages } from './utils.js'; +import { bonusImages } from '../../common/utils.js'; import Render from './render.js'; import Afficher from './afficher.js'; import setHtml from './setHtml.js'; @@ -55,24 +55,6 @@ function resampleCanvas() { canvas.height = canvas.clientHeight; } -document.addEventListener('keydown', event => { - let canShoot = true; - avatar.changerClick(event); - if (event.key === ' ') { - if (canShoot) { - avatar.tirer(); - canShoot = false; - setTimeout(function () { - canShoot = true; - }, 100); - } - } -}); - -document.addEventListener('keyup', event => { - avatar.changerClick(event); -}); - let newEnemis = []; let newBonus = []; @@ -80,157 +62,112 @@ function render() { context.clearRect(0, 0, canvas.width, canvas.height); renderObject.renderBackground(canvas); gameStarted = affichage.isGameStarted(); + if (gameStarted) { context.font = '40pt New Super Mario Font U'; - for (let i = 1; i < avatars.length; i++) { - if (avatars[i] != undefined) { - renderObject.renderScores(i, avatars[i], context); - renderObject.renderVies(avatars, context, i); - } - } - context.fillStyle = 'blue'; + context.fillText(`0:${min}:${sec}`, canvas.width / 2, 50); - context.fillText(0 + ':' + min + ':' + sec, canvas.width / 2, 50); - - for (let avatarId in avatars) { - renderObject.renderProjectile(context, avatar, avatars, avatarId); - for (let avatarId in avatars) { - renderObject.renderProjectile(context, avatar, avatars, avatarId); - } - socket.on('bonusArray', data => { - newBonus = data; - }); - newBonus.forEach(bonus => { - let img = new Image(); - img.src = bonusImages[bonus.choix]; - img.width = 75; - img.height = 75; - draw(canvas, context, img, bonus.x, bonus.y); - }); - socket.on('enemis', data => { - newEnemis = data; - }); - newEnemis.forEach(enemi => { - renderObject.renderEnnemi(canvas, context, enemi.x, enemi.y, enemi); + Object.entries(avatars) + .filter(([avatarId, avatarData]) => avatarData !== undefined) + .forEach(([avatarId, avatarData]) => { + renderObject.renderScores(avatarId, avatarData, context); + renderObject.renderVies(avatars, context, avatarId); }); - socket.on('bonusArray', data => { - newBonus = data; - }); - newBonus.forEach(bonus => { - renderObject.renderBonus( - canvas, - context, - bonusImages[bonus.choix], - bonus.x, - bonus.y - ); - }); - } + + renderProjectiles(); + renderBonuses(); + renderEnemies(); } requestAnimationFrame(render); } +function renderProjectiles() { + for (const avatarId in avatars) { + renderObject.renderProjectile(context, avatar, avatars, avatarId); + } +} + +function renderBonuses() { + socket.on('bonusArray', data => { + newBonus = data; + }); + + newBonus.forEach(bonus => { + const img = new Image(); + img.src = bonusImages[bonus.choix]; + img.width = 75; + img.height = 75; + draw(canvas, context, img, bonus.x, bonus.y); + }); +} + +function renderEnemies() { + socket.on('enemis', data => { + newEnemis = data; + }); + + newEnemis.forEach(enemi => { + renderObject.renderEnnemi(canvas, context, enemi.x, enemi.y, enemi); + }); +} + let avatars = []; -let avatarsScore = {}; // Objet pour stocker les scores associés à chaque avatarId +let avatarsScore = {}; socket.on('dead', avatarId => { - // Récupérer le score de l'avatar avant de le supprimer const score = avatars[avatarId] ? avatars[avatarId].score : 0; - // Stocker le score associé à l'avatarId dans l'objet avatarsScore avatarsScore[avatarId] = score; - // Supprimer l'avatar du tableau avatars delete avatars[avatarId]; - - // Afficher la fin de partie ou effectuer d'autres actions nécessaires - // affichage.afficherFinDePartie(); - console.log(`Avatar ${avatarId} est mort. Score sauvegardé : ${score}`); }); -socket.on('disconnectEvent', id => { - if (avatar.getNom() == id) { - // Si l'avatar est celui du joueur local, afficher la fin de partie - affichage.afficherFinDePartie(); - } - // Supprimer l'avatar de avatars - delete avatars[id]; -}); - -// Réception des données des avatars depuis le serveur socket.on('avatarsData', avatarData => { - avatarData.forEach(data => { - // Mise à jour des données de l'avatar dans avatars - if (avatars[data.id] != undefined) { - avatars[data.id].x = data.x; - avatars[data.id].y = data.y; - avatars[data.id].projectiles = data.projectiles; - avatars[data.id].vies = data.vies; - avatars[data.id].score = data.score; - avatars[data.id].socketId = data.socketId; - } else { - // Création d'un nouvel avatar dans avatars si celui-ci n'existe pas encore - avatars[data.id] = { - x: data.x, - y: data.y, - projectiles: data.projectiles, - vies: data.vies, - score: data.score, - socketId: data.socketId, - }; - } - }); + for (const data of avatarData) { + avatars[data.id] = { + x: data.x, + y: data.y, + projectiles: data.projectiles, + vies: data.vies, + score: data.score, + socketId: data.socketId, + }; + } }); const keysPressed = {}; -document.addEventListener('keydown', event => { - keysPressed[event.keyCode] = true; +document.addEventListener('keydown', handleKeyEvent); +document.addEventListener('keyup', handleKeyEvent); + +function handleKeyEvent(event) { + keysPressed[event.keyCode] = event.type === 'keydown'; + if (event.key === ' ') { socket.emit('shoot', { id: `${socket.id}`, shoot: true, }); } - socket.emit('clickEvent', { - id: `${socket.id}`, - key: event.keyCode, - pressed: true, - }); - event.preventDefault(); -}); - -document.addEventListener('keyup', event => { - keysPressed[event.keyCode] = false; socket.emit('clickEvent', { id: `${socket.id}`, key: event.keyCode, - pressed: false, + pressed: event.type === 'keydown', }); event.preventDefault(); -}); +} -let endGame = false; -socket.on('endGame', () => { - console.log( +socket.once('endGame', () => { + affichage.afficherFinDePartie( + canvas, avatarsScore[1], avatarsScore[2], avatarsScore[3], avatarsScore[4] ); - if (!endGame) { - affichage.afficherFinDePartie( - canvas, - avatarsScore[1], - avatarsScore[2], - avatarsScore[3], - avatarsScore[4] - ); - } - endGame = true; }); diff --git a/client/src/render.js b/client/src/render.js index 96812c8..e9343b3 100644 --- a/client/src/render.js +++ b/client/src/render.js @@ -1,5 +1,5 @@ import draw from './draw.js'; -import { colors } from './utils.js'; +import { colors } from '../../common/utils.js'; export default class Render { imageEnemi; imageEnemi2; diff --git a/client/src/Coordinate.js b/common/Coordinate.js similarity index 100% rename from client/src/Coordinate.js rename to common/Coordinate.js diff --git a/client/src/avatar.js b/common/avatar.js similarity index 95% rename from client/src/avatar.js rename to common/avatar.js index 424f844..809a10b 100644 --- a/client/src/avatar.js +++ b/common/avatar.js @@ -1,6 +1,6 @@ -import { Projectile } from './Projectile.js'; -import Entite from './entite.js'; -import { Hitbox } from './hitbox.js'; +import { Projectile } from '../server/Projectile.js'; +import Entite from '../server/entite.js'; +import { Hitbox } from '../server/hitbox.js'; export class Avatar extends Entite { nom; vies; diff --git a/client/src/avatar.test.js b/common/avatar.test.js similarity index 100% rename from client/src/avatar.test.js rename to common/avatar.test.js diff --git a/client/src/utils.js b/common/utils.js similarity index 100% rename from client/src/utils.js rename to common/utils.js diff --git a/client/src/Projectile.js b/server/Projectile.js similarity index 92% rename from client/src/Projectile.js rename to server/Projectile.js index 67c3ffb..65e4717 100644 --- a/client/src/Projectile.js +++ b/server/Projectile.js @@ -1,5 +1,5 @@ import { Hitbox } from './hitbox.js'; -import draw from './draw.js'; +import draw from '../client/src/draw.js'; import Entite from './entite.js'; export class Projectile extends Entite { diff --git a/server/bonus.js b/server/bonus.js index 93b152b..cd1e7f4 100644 --- a/server/bonus.js +++ b/server/bonus.js @@ -1,5 +1,5 @@ -import Entite from '../client/src/entite.js'; -import { Hitbox } from '../client/src/hitbox.js'; +import Entite from './entite.js'; +import { Hitbox } from './hitbox.js'; export default class Bonus extends Entite { nom; taille; diff --git a/server/enemis.js b/server/enemis.js index 45aa7ab..cc61a3f 100644 --- a/server/enemis.js +++ b/server/enemis.js @@ -1,5 +1,5 @@ -import Entite from '../client/src/entite.js'; -import { Hitbox } from '../client/src/hitbox.js'; +import Entite from './entite.js'; +import { Hitbox } from './hitbox.js'; export default class enemi extends Entite { vy; vx; diff --git a/client/src/entite.js b/server/entite.js similarity index 100% rename from client/src/entite.js rename to server/entite.js diff --git a/server/gameLogic.js b/server/gameLogic.js new file mode 100644 index 0000000..13b80cc --- /dev/null +++ b/server/gameLogic.js @@ -0,0 +1,144 @@ +import timer from './timer.js'; + +export function updateGame( + io, + enemis, + bonusArray, + avatars, + canvasSize, + t, + firstAvatar, + gameStarted, + cptConnexion +) { + io.emit('enemis', enemis); + io.emit('bonusArray', bonusArray); + + const areAvatarsActive = avatars.some(avatar => !avatar.spectateur); + + if (firstAvatar && areAvatarsActive) { + handleActiveAvatars(io, avatars, updateAvatar, canvasSize, t); + } else { + endGame(io, t, avatars, gameStarted, cptConnexion); + } +} + +export function handleActiveAvatars(io, avatars, updateAvatar, canvasSize, t) { + const avatarData = []; + avatars.forEach(avatar => { + updateAvatar(avatar, avatarData, canvasSize, t); + }); + io.emit('avatarsData', avatarData); +} + +export function updateAvatar(avatar, avatarData, canvasSize, t, enemis) { + avatar.canvasSize = canvasSize; + if ( + avatar.getStatut() === 'invincibilite' && + t.getTotalTime() - avatar.getStatutTime() === 15 + ) { + avatar.setStatut('null'); + } + + avatar.projectiles.forEach(projectile => projectile.deplacer()); + + if (!avatar.spectateur) { + avatarData.push({ + id: avatar.id, + x: avatar.getX(), + y: avatar.getY(), + projectiles: avatar.projectiles, + vies: avatar.getVies(), + score: avatar.getScore(), + socketId: avatar.nom, + }); + } + + handleAvatarEnemiCollisions(avatar, enemis); + handleAvatarBonusCollisions(avatar, t); +} + +export function handleAvatarEnemiCollisions(avatar, enemis) { + enemis.forEach(enemi => { + if ( + enemi.hitbox.colision(avatar.hitbox) && + avatar.getStatut() !== 'invincibilite' + ) { + handleAvatarEnemiCollisionEffects(avatar, enemi); + } + + if (enemi.getVies() < 0) { + avatar.incrementScore(5); + enemis.splice(enemis.indexOf(enemi), 1); + } + + enemi.deplacer(); + + avatar.projectiles.forEach(projectile => { + if (projectile.hitbox.colision(enemi.hitbox)) { + avatar.projectiles.splice(avatar.projectiles.indexOf(projectile), 1); + handleProjectileEnemiCollisionEffects(enemi); + } + }); + }); +} + +export function handleAvatarEnemiCollisionEffects(avatar, enemi) { + avatar.decrementScore(5); + enemis.splice(enemis.indexOf(enemi), 1); + avatar.perdreVie(); + + if (canLostLifeAvatar) { + canLostLifeAvatar = false; + setTimeout(() => { + canLostLifeAvatar = true; + }, 100); + } + + if (avatar.getVies() === 0) { + avatar.setSpectateur(); + io.emit('dead', avatar.id); + } +} + +export function handleProjectileEnemiCollisionEffects(enemi) { + enemi.perdreVie(); + + if (canLostLifeEnemi) { + canLostLifeEnemi = false; + setTimeout(() => { + canLostLifeEnemi = true; + }, 1000 / 60); + } +} + +export function handleAvatarBonusCollisions(avatar, t) { + bonusArray.forEach(bonus => { + if (bonus.hitbox.colision(avatar.hitbox)) { + handleBonusCollisionEffects(avatar, bonus, t); + } + + if (bonus.estExpire(t.getTotalTime())) { + bonusArray.splice(bonusArray.indexOf(bonus), 1); + } + }); +} + +export function handleBonusCollisionEffects(avatar, bonus, t) { + if (bonusNoms[bonus.getChoix()] === 'vie') { + avatar.gagnerVie(); + } else if (bonusNoms[bonus.getChoix()] === 'invincibilite') { + avatar.setStatut('invincibilite'); + avatar.setStatutTime(t.getTotalTime()); + } + + bonusArray.splice(bonusArray.indexOf(bonus), 1); +} + +export function endGame(io, t, avatars, gameStarted, cptConnexion) { + gameStarted = false; + cptConnexion = 0; + t = new timer(); + avatars.length = 0; + io.emit('endGame', true); +} diff --git a/client/src/hitbox.js b/server/hitbox.js similarity index 100% rename from client/src/hitbox.js rename to server/hitbox.js diff --git a/client/src/hitbox.test.js b/server/hitbox.test.js similarity index 100% rename from client/src/hitbox.test.js rename to server/hitbox.test.js diff --git a/server/index.js b/server/index.js index 368c662..11a5c5d 100644 --- a/server/index.js +++ b/server/index.js @@ -1,37 +1,42 @@ +// server.js import express from 'express'; import http from 'http'; import addWebpackMiddleware from './middlewares/addWebpackMiddleware.js'; import { Server as IOServer } from 'socket.io'; -import { Avatar } from '../client/src/avatar.js'; +import { Avatar } from '../common/avatar.js'; import enemi from './enemis.js'; -import { Coordinate } from '../client/src/Coordinate.js'; +import { Coordinate } from '../common/Coordinate.js'; import timer from './timer.js'; import Bonus from './bonus.js'; -import { bonusImages, bonusNoms, bonusTaille } from '../client/src/utils.js'; +import { bonusImages, bonusNoms, bonusTaille } from '../common/utils.js'; const app = express(); +const httpServer = http.createServer(app); +const io = new IOServer(httpServer); -let canvasSize = new Coordinate(1920, 1261); - -let canLostLifeAvatar = true; -let canLostLifeEnemi = true; +const canvasSize = new Coordinate(1920, 1261); let gameStarted = false; - let t = new timer(); - -const httpServer = http.createServer(app); -const fileOptions = { root: process.cwd() }; -addWebpackMiddleware(app); - -const io = new IOServer(httpServer); +let canLostLifeAvatar = true; +let canLostLifeEnemi = true; +let firstAvatar = false; +let cptConnexion = 0; +let canShoot = true; +let LVL2start = false; +let LVL3start = false; +const avatars = []; +const enemis = []; +const bonusArray = []; app.use(express.static('client/public')); - const port = process.env.PORT == null ? 8000 : process.env.PORT; + httpServer.listen(port, () => { console.log(`Server running at http://localhost:${port}/`); }); +addWebpackMiddleware(app); + setInterval(function () { if (gameStarted) { t.addTime(); @@ -41,106 +46,87 @@ setInterval(function () { } }, 1000); -const avatars = []; -const enemis = []; -const bonusArray = []; - -let cpt = 0; -let canShoot = true; -let LVL2start = false; -let LVL3start = false; - -let firstAvatar = false; - io.on('connection', socket => { - cpt++; - if (cpt <= 4) { + cptConnexion++; + if (cptConnexion <= 4) { firstAvatar = true; - const avatar = new Avatar(`${socket.id}`, cpt); - io.emit('newAvatar', { id: cpt, x: avatar.getX(), y: avatar.getY() }); + const avatar = new Avatar(`${socket.id}`, cptConnexion); + io.emit('newAvatar', { + id: cptConnexion, + x: avatar.getX(), + y: avatar.getY(), + }); avatars.push(avatar); socket.on('disconnect', () => { - avatars.forEach(avatar => { - if (avatar.nom == socket.id) { - io.emit('disconnectEvent', avatar.id); - avatars.splice(avatars.indexOf(avatar), 1); - } - }); - console.log(`Déconnexion du client ${socket.id}`); + const disconnectedAvatarIndex = avatars.findIndex( + avatar => avatar.nom === socket.id + ); + if (disconnectedAvatarIndex !== -1) { + io.emit('disconnectEvent', avatars[disconnectedAvatarIndex].id); + avatars.splice(disconnectedAvatarIndex, 1); + } + console.log(`Client disconnected: ${socket.id}`); }); socket.on('start', s => { - if (s == true && cpt != 0) { + if (s && cptConnexion !== 0) { gameStarted = s; - } else if (cpt == 0) { + } else if (cptConnexion === 0) { gameStarted = false; } }); + // Handling click events socket.on('clickEvent', clickEvent => { const playerAvatar = avatars.find(avatar => avatar.nom === clickEvent.id); if (playerAvatar) { playerAvatar.click[clickEvent.key] = clickEvent.pressed; } else { - console.log(`Aucun avatar trouvé avec le nom ${clickEvent.id}`); + console.log(`No avatar found with the name ${clickEvent.id}`); } }); socket.on('shoot', shoot => { const playerAvatar = avatars.find(avatar => avatar.nom === shoot.id); - - if (canShoot) { + if (canShoot && playerAvatar) { playerAvatar.tirer(); canShoot = false; - setTimeout(function () { + setTimeout(() => { canShoot = true; }, 200); } }); socket.on('canvasSize', canvasSize => { - console.log(canvasSize); canvasSize = canvasSize; }); } }); -let spawnIntervalLV1 = setInterval(() => { - if (gameStarted) { - if (t.getMin() >= 1) { - LVL2start = true; - } - if (t.getSec() >= 30) { - LVL3start = true; - } - - let randomY = Math.random() * (canvasSize.height - 0) + 0; - do { - randomY = Math.random() * (canvasSize.height - 0) + 0; - } while (randomY > canvasSize.height - 57); - const newEnemy = new enemi(canvasSize.width, randomY, 0, 1); - enemis.push(newEnemy); - } -}, 1000); - -let spawnIntervalLV2 = setInterval(() => { - if (LVL2start && gameStarted) { - let randomY = Math.random() * (canvasSize.height - 100); - const newEnemy = new enemi(canvasSize.width - 100, randomY, 1, 2); - enemis.push(newEnemy); - } -}, 800); +const spawnIntervals = [ + { delay: 1000, startCondition: () => gameStarted }, + { delay: 800, startCondition: () => LVL2start && gameStarted }, + { delay: 4000, startCondition: () => LVL3start && gameStarted }, +]; -let spawnIntervalLV3 = setInterval(() => { - if (LVL3start && gameStarted) { - let randomY = Math.random() * (canvasSize.height - 100); - const newEnemy = new enemi(canvasSize.width - 100, randomY, 1, 3); - enemis.push(newEnemy); - } -}, 4000); +spawnIntervals.forEach(({ delay, startCondition }, index) => { + setInterval(() => { + if (startCondition()) { + let randomY = + Math.random() * (canvasSize.height - (index === 0 ? 0 : 100)); + const newEnemy = new enemi( + canvasSize.width - (index === 0 ? 0 : 100), + randomY, + index, + index + 1 + ); + enemis.push(newEnemy); + } + }, delay); +}); -let spawnBonusInterval = setInterval(() => { +setInterval(() => { if (gameStarted) { let randomX; let randomY; @@ -157,96 +143,140 @@ let spawnBonusInterval = setInterval(() => { }, 15000); setInterval(() => { + updateGame(); +}, 1000 / 60); + +function updateGame() { io.emit('enemis', enemis); io.emit('bonusArray', bonusArray); - let areAvatarsActive = avatars.some(avatar => !avatar.spectateur); + const areAvatarsActive = avatars.some(avatar => !avatar.spectateur); if (firstAvatar && areAvatarsActive) { - let avatarData = []; - avatars.forEach(avatar => { - avatar.canvasSize = canvasSize; - if ( - avatar.getStatut() == 'invincibilite' && - t.getTotalTime() - avatar.getStatutTime() == 15 - ) { - avatar.setStatut('null'); - } - enemis.forEach(enemi => { - if ( - enemi.hitbox.colision(avatar.hitbox) && - avatar.getStatut() != 'invincibilite' - ) { - if (canLostLifeAvatar) { - avatar.decrementScore(5); - enemis.splice(enemis.indexOf(enemi), 1); - avatar.perdreVie(); - canLostLifeAvatar = false; - setTimeout(function () { - canLostLifeAvatar = true; - }, 100); - } - if (avatar.getVies() == 0) { - avatar.setSpectateur(); - io.emit('dead', avatar.id); - } - } - if (enemi.getVies() < 0) { - avatar.incrementScore(5); - enemis.splice(enemis.indexOf(enemi), 1); - } - enemi.deplacer(); - avatar.colision(enemi.hitbox); - avatar.projectiles.forEach(projectile => { - if (projectile.hitbox.colision(enemi.hitbox)) { - avatar.projectiles.splice( - avatar.projectiles.indexOf(projectile), - 1 - ); - if (canLostLifeEnemi) { - enemi.perdreVie(); - canLostLifeEnemi = false; - setTimeout(function () { - canLostLifeEnemi = true; - }, 1000 / 60); - } - } - }); - }); - avatar.deplacer(); - avatar.projectiles.forEach(projectile => projectile.deplacer()); - if (!avatar.spectateur) { - avatarData.push({ - id: avatar.id, - x: avatar.getX(), - y: avatar.getY(), - projectiles: avatar.projectiles, - vies: avatar.getVies(), - score: avatar.getScore(), - socketId: avatar.nom, - }); - } - bonusArray.forEach(bonus => { - if (bonus.hitbox.colision(avatar.hitbox)) { - if (bonusNoms[bonus.getChoix()] == 'vie') { - avatar.gagnerVie(); - } else if (bonusNoms[bonus.getChoix()] == 'invincibilite') { - avatar.setStatut('invincibilite'); - avatar.setStatutTime(t.getTotalTime()); - } - bonusArray.splice(bonusArray.indexOf(bonus), 1); - } - if (bonus.estExpire(t.getTotalTime())) { - bonusArray.splice(bonusArray.indexOf(bonus), 1); - } - }); - }); - io.emit('avatarsData', avatarData); + handleActiveAvatars(); } else { - gameStarted = false; - cpt = 0; - t = new timer(); - avatars.length = 0; // Réinitialiser le tableau d'avatars - io.emit('endGame', true); + endGame(); } -}, 1000 / 60); +} + +function handleActiveAvatars() { + const avatarData = []; + avatars.forEach(avatar => { + updateAvatar(avatar, avatarData); + }); + io.emit('avatarsData', avatarData); +} + +function updateAvatar(avatar, avatarData) { + avatar.canvasSize = canvasSize; + if ( + avatar.getStatut() === 'invincibilite' && + t.getTotalTime() - avatar.getStatutTime() === 15 + ) { + avatar.setStatut('null'); + } + + enemis.forEach(enemi => { + handleAvatarEnemiCollisions(avatar, enemi); + }); + + avatar.deplacer(); + avatar.projectiles.forEach(projectile => projectile.deplacer()); + + if (!avatar.spectateur) { + avatarData.push({ + id: avatar.id, + x: avatar.getX(), + y: avatar.getY(), + projectiles: avatar.projectiles, + vies: avatar.getVies(), + score: avatar.getScore(), + socketId: avatar.nom, + }); + } + + handleAvatarBonusCollisions(avatar); +} + +function handleAvatarEnemiCollisions(avatar, enemi) { + if ( + enemi.hitbox.colision(avatar.hitbox) && + avatar.getStatut() !== 'invincibilite' + ) { + handleAvatarEnemiCollisionEffects(avatar, enemi); + } + + if (enemi.getVies() < 0) { + avatar.incrementScore(5); + enemis.splice(enemis.indexOf(enemi), 1); + } + + enemi.deplacer(); + + avatar.projectiles.forEach(projectile => { + if (projectile.hitbox.colision(enemi.hitbox)) { + avatar.projectiles.splice(avatar.projectiles.indexOf(projectile), 1); + handleProjectileEnemiCollisionEffects(avatar, enemi); + } + }); +} + +function handleAvatarEnemiCollisionEffects(avatar, enemi) { + avatar.decrementScore(5); + enemis.splice(enemis.indexOf(enemi), 1); + avatar.perdreVie(); + + if (canLostLifeAvatar) { + canLostLifeAvatar = false; + setTimeout(() => { + canLostLifeAvatar = true; + }, 100); + } + + if (avatar.getVies() === 0) { + avatar.setSpectateur(); + io.emit('dead', avatar.id); + } +} + +function handleProjectileEnemiCollisionEffects(enemi) { + enemi.perdreVie(); + + if (canLostLifeEnemi) { + canLostLifeEnemi = false; + setTimeout(() => { + canLostLifeEnemi = true; + }, 1000 / 60); + } +} + +function handleAvatarBonusCollisions(avatar) { + bonusArray.forEach(bonus => { + if (bonus.hitbox.colision(avatar.hitbox)) { + handleBonusCollisionEffects(avatar, bonus); + } + + if (bonus.estExpire(t.getTotalTime())) { + bonusArray.splice(bonusArray.indexOf(bonus), 1); + } + }); +} + +function handleBonusCollisionEffects(avatar, bonus) { + if (bonusNoms[bonus.getChoix()] === 'vie') { + avatar.gagnerVie(); + } else if (bonusNoms[bonus.getChoix()] === 'invincibilite') { + avatar.setStatut('invincibilite'); + avatar.setStatutTime(t.getTotalTime()); + } + + bonusArray.splice(bonusArray.indexOf(bonus), 1); +} + +function endGame() { + gameStarted = false; + cptConnexion = 0; + t = new timer(); + avatars.length = 0; + io.emit('endGame', true); +} diff --git a/client/src/projectile.test.js b/server/projectile.test.js similarity index 100% rename from client/src/projectile.test.js rename to server/projectile.test.js -- GitLab