← Tous les projets

Game

Frogger

Jeu web multijoueur inspiré de l'arcade classique. Une grenouille à guider à travers routes et rivières — en solo ou en temps réel contre un adversaire via WebSocket.

JavaReactTypeScriptWebSocketDocker
Frogger

Contexte

Frogger est un jeu vidéo web inspiré du classique arcade des années 80, développé en binôme avec Quentin Houillon dans le cadre du projet de L3 Programmation Orientée Objet à l'Université Evry Paris-Saclay. L'objectif pédagogique était de concevoir un système logiciel complet en appliquant les principes de la POO — héritage, polymorphisme, encapsulation — tout en ajoutant une dimension multijoueur en ligne.

Le projet est une application full-stack découplée : un backend Java exposant la logique de jeu et les scores via WebSocket, et un frontend React/TypeScript rendant le jeu dans le navigateur en temps réel.

Gameplay

Le joueur incarne une grenouille qu'il doit guider de la zone de départ jusqu'aux nénuphars de l'autre côté de l'écran, en évitant les obstacles sur la route et en traversant la rivière en sautant sur les troncs et les tortues.

  • Mode solo — partie locale avec gestion des vies, du temps et du score
  • Mode multijoueur en ligne — deux joueurs s'affrontent en simultané via WebSocket, chacun contrôlant sa propre grenouille
  • Système de scores persistants — classement des meilleurs scores sauvegardé en JSON côté serveur
  • Effets visuels — animations de mort (explosion de particules), ondulations d'eau à la collision, sprites animés en plusieurs frames
  • Effets sonores — ambiance musicale, sons de déplacement, mort, score et collecte (Howler.js)

Architecture

Le projet repose sur une séparation nette entre backend et frontend, déployés ensemble via Docker Compose :

backend/                     — Logique de jeu côté serveur
  app/src/main/java/frogger/
    App.java                 — Point d'entrée du serveur
    controller/
      FroggerWebSocket.java  — Serveur WebSocket (sessions, sync multijoueur)
    model/
      Entity.java            — Classe de base des entités
      Frog.java              — Modèle de la grenouille
      Lane.java / LaneConfig.java — Voies de circulation et rivière
      Obstacle.java          — Obstacles mobiles
      GameMap.java           — Carte du jeu et logique de progression
      CollisionManager.java  — Détection des collisions
      ScoreManager.java      — Gestion des scores et persistance
      HighScoreRepository.java — Lecture / écriture du classement JSON
  scores.json                — Persistance des meilleurs scores

frontend/src/                — Interface de jeu React/TypeScript
  Game.tsx                   — Boucle de jeu principale
  components/
    Frog.tsx / Lane.tsx / Obstacles.tsx
    ParkedFrog.tsx           — Grenouilles ayant atteint leur destination
    hud/HUD.tsx              — Affichage du score, des vies et du chrono
    menu/                    — Écrans Menu, Scores, Lobby multijoueur, Paramètres
    effects/                 — DeathBurst, WaterRipple (animations)
    overlays/GameOverlays    — Écrans de fin de partie
  hooks/useGameLogic.ts      — Hook centralisant toute la logique de jeu
  services/
    WebsocketService.ts      — Connexion et synchronisation temps réel
    SoundService.ts          — Gestion des effets audio (Howler.js)
  sprites/                   — Sprites pixel art (grenouille, véhicules, tuiles…)

Stack technique

Backend
─────────────────────────────────────────────────
Java          Langage principal
Gradle        Build et gestion des dépendances
WebSocket     Communication temps réel (multijoueur)
JSON          Persistance des scores (HighScoreRepository)

Frontend
─────────────────────────────────────────────────
React         Framework UI
TypeScript    Typage statique
Vite          Bundler et serveur de développement
Howler.js     Gestion des effets sonores
CSS           Animations et rendu des sprites

Infra
─────────────────────────────────────────────────
Docker Compose  Orchestration backend + frontend
Nginx           Serveur de fichiers statiques (frontend)

Modèle de jeu (backend)

La logique de jeu est entièrement gérée côté serveur pour garantir la cohérence en mode multijoueur. Le FroggerWebSocket orchestre les sessions de jeu, synchronise les états des joueurs et valide les mouvements :

GameMap        — Carte complète : voies, nénuphars, état général
Lane           — Voie individuelle (route ou rivière) avec ses obstacles
LaneConfig     — Configuration de chaque voie (vitesse, direction, type)
CollisionManager — Détection des collisions entre la grenouille et les obstacles
ScoreManager   — Calcul du score en fonction de la progression et du temps
HighScoreRepository — Lecture et écriture du classement persisté

Ce que j'ai appris

Ce projet a été une introduction concrète au développement de jeux vidéo en environnement web. Implémenter une boucle de jeu fluide dans React — sans canvas, uniquement avec le DOM et les hooks — a demandé de maîtriser la gestion des requestAnimationFrame, les effets de bord et la synchronisation d'état.

La partie multijoueur via WebSocket a été la plus ambitieuse : il fallait synchroniser l'état de deux parties en parallèle, gérer les connexions/déconnexions en cours de partie et assurer la cohérence des scores malgré la latence réseau.

Côté backend, appliquer les principes POO dans un contexte de jeu m'a permis de comprendre concrètement la valeur du polymorphisme — par exemple, faire hériter Frog et Obstacle d'Entity pour uniformiser la gestion des collisions et des positions. La séparation controller / model reproduit naturellement un pattern MVC adapté aux contraintes temps réel.

Projet suivant

WashFamily.