Création de Personnage
La page Création de Personnage (CharacterCreationPage) permet aux joueurs de choisir leur avatar et leur nom de personnage avant de rejoindre la salle d'attente.
CharacterCreationPage
Type : ConsumerStatefulWidget
State : _CharacterCreationPageState extends ConsumerState(CharacterCreationPage)
Propriétés de constructeur
| Propriété | Type | Description |
|---|---|---|
mode |
String |
Mode de création ("create" ou "join") |
gameCode |
String? |
Code de la partie |
gameStatus |
String? |
Statut de la partie ("waiting" ou "started") |
dropInOut |
bool |
Si le drop-in/drop-out est activé (défaut: false) |
isLocked |
bool |
Si la partie est verrouillée (défaut: false) |
Propriétés d'état
| Propriété | Type | Description |
|---|---|---|
_dropInGameDataSubscription |
StreamSubscription? |
Souscription au stream de drop-in |
_gameLockUpdatedSubscription |
StreamSubscription? |
Souscription aux mises à jour de verrouillage |
errorMessage |
String? |
Message d'erreur à afficher |
Propriétés statiques
| Propriété | Type | Description |
|---|---|---|
avatars |
List(String) | Liste de tous les avatars disponibles (depuis GameCharacters.gameCharacters) |
Méthodes
initState()
Description : Initialise la page et configure les écouteurs.
Actions :
- Réinitialise l'état du provider de création de personnage
- Si mode "join", demande mise à jour de la partie
- Met à jour les avatars déjà pris
- Configure l'écouteur de verrouillage de partie (drop-in/drop-out)
Retour : void
dispose()
Description : Libère les souscriptions aux streams.
Retour : void
void _setupGameLockListener()
Description : Configure l'écouteur pour détecter quand la partie se verrouille (pleine en mode drop-in/drop-out).
Event : onGameLockUpdated
Action : Affiche popup d'erreur si partie pleine
Retour : void
void _updateTakenAvatarsFromGame()
Description : Met à jour la liste des avatars déjà pris par d'autres joueurs.
Délai : 100ms pour s'assurer que le state est chargé
Retour : void
void _requestGameUpdate()
Description : Demande une mise à jour de l'état de la partie.
Retour : void
void _showErrorPopup(String message)
Description : Affiche un popup d'erreur.
Retour : void
void _showGameCancelledPopup(String message)
Description : Affiche un popup de partie annulée et redirige vers HomePage.
Retour : void
bool _isGameFull()
Description : Vérifie si la partie est pleine selon la taille de la grille.
Limites :
- Grille 10: max 2 joueurs
- Grille 15: max 4 joueurs
- Grille 20: max 6 joueurs
Retour : bool
bool _verifyForm()
Description : Valide le formulaire de création de personnage.
Validations :
- Avatar sélectionné
- Avatar non pris par un autre joueur
- Nom de personnage non vide
- Nom de personnage valide (alphanumériques et espaces, 1-12 caractères)
- Nom de personnage unique (en mode join)
Retour : bool
_createCharacterAndJoinWaitingRoom()
Description : Crée le personnage et rejoint la salle d'attente.
Flux :
- Valide le formulaire
- Sélectionne l'avatar et le nom
- Navigue vers
WaitingRoomPage
Retour : Future
void _goBack()
Description : Retourne à la page précédente.
Retour : void
void _selectAvatar(int index)
Description : Sélectionne un avatar.
Action : Appelle characterCreationNotifier.selectAvatar(index)
Retour : void
void _setCharacterName(String name)
Description : Définit le nom du personnage.
Action : Appelle characterCreationNotifier.setCharacterName(name)
Retour : void
Widget _buildAvatarGrid()
Description : Construit la grille d'avatars.
Layout : Grid scrollable avec 4 colonnes
Retour : Widget
Widget _buildAvatarCard(int index)
Description : Construit une carte d'avatar.
États :
- Sélectionné : Bordure colorée épaisse
- Pris : Désactivé avec overlay "PRIS"
- Normal : Bordure fine, cliquable
Retour : Widget
String extractAvatarName(String fullAvatarName)
Description : Extrait le nom de l'avatar depuis le chemin complet.
Exemple : "assets/sprites/Guerrier_1.svg" → "Guerrier"
Retour : String
Éléments visuels
En-tête
- Bouton Retour : "←" vers la page précédente
- Titre : "CRÉATION DE PERSONNAGE" centré
Section Avatars
- Label : "CHOISIS TON AVATAR"
- Grille d'avatars : 4 colonnes, scrollable
- Cartes d'avatar avec image SVG
- Nom de l'avatar en bas
- État sélectionné : Bordure épaisse colorée
- État pris : Désactivé avec overlay noir + texte "PRIS"
- État normal : Bordure fine, hover effect
Section Nom
- Label : "ENTRE TON NOM DE PERSONNAGE"
- Champ de saisie :
- Placeholder : "Nom du personnage"
- Validation en temps réel
- Limite : 12 caractères
- Format : Alphanumériques et espaces uniquement
Bouton de validation
- Texte : "CONFIRMER ET REJOINDRE"
- État : Actif si formulaire valide
- Action : Navigue vers WaitingRoomPage
Overlays
- UserProfileWidget : Profil utilisateur
- ChatboxWidget : Chat
- HelpButtonWidget : Aide
- HelpPopupWidget : Aide contextuelle
Composants utilisés
OneButtonPopup
Popup avec un seul bouton (erreurs, annulation).
UserProfileWidget
Widget de profil utilisateur.
ChatboxWidget
Widget de chat.
HelpButtonWidget
Bouton d'aide.
HelpPopupWidget
Popup d'aide.
Providers utilisés
characterCreationNotifierProvider
Type : StateNotifierProvider(CharacterCreationNotifier, CharacterCreationState)
Provider gérant l'état de création de personnage.
CharacterCreationState
| Propriété | Type | Description |
|---|---|---|
selectedAvatarIndex |
int |
Index de l'avatar sélectionné (-1 si aucun) |
characterName |
String |
Nom du personnage saisi |
takenAvatars |
List(String) | Liste des avatars déjà pris |
CharacterCreationNotifier - Méthodes
void reset()
Description : Réinitialise l'état de création.
Retour : void
void selectAvatar(int index)
Description : Sélectionne un avatar par son index.
Retour : void
void setCharacterName(String name)
Description : Définit le nom du personnage.
Retour : void
void updateTakenAvatarsWithLocked(List playerTakenAvatars, UserProfileEntity userProfile)
Description : Met à jour les avatars pris en incluant les avatars verrouillés.
Paramètres :
playerTakenAvatars: Avatars déjà pris par les joueursuserProfile: Profil de l'utilisateur (pour préserver son avatar si déjà choisi)
Retour : void
waitingRoomNotifierProvider
Type : StateNotifierProvider(WaitingRoomNotifier, WaitingRoomState)
Provider gérant la salle d'attente.
WaitingRoomState
| Propriété | Type | Description |
|---|---|---|
currentGame |
OnGoingGameModel? |
Partie actuelle |
currentPlayer |
PlayerModel? |
Joueur actuel |
WaitingRoomNotifier - Méthodes
void requestGameUpdate(String gameCode)
Description : Demande une mise à jour de la partie.
Retour : void
waitingRoomSocketDataSourceProvider
Type : Provider(WaitingRoomSocketDataSource)
Provider fournissant la source de données Socket.IO.
WaitingRoomSocketDataSource - Méthodes
onGameLockUpdated()
Description : Stream émettant les mises à jour de verrouillage de partie.
Retour : Stream(bool)
userProfileProvider
Type : Provider(UserProfileEntity?)
Provider du profil utilisateur.
translationProvider
Type : Provider(TranslationWrapper)
Provider de traduction.
themeNotifierProvider
Type : StateNotifierProvider(ThemeNotifier, ThemeState)
Provider de thème.
helpPopupProvider
Type : StateNotifierProvider(HelpPopupNotifier, HelpPopupState)
Provider d'aide.
Navigation
- Retour : Dépend du mode
- Mode "create" : Retour vers
GameCreationPage - Mode "join" : Retour vers
JoinPage
- Mode "create" : Retour vers
- Confirmer :
AppRoutes.waitingRoom.path→WaitingRoomPage- Paramètre :
mode(identique au mode reçu)
- Paramètre :
- Partie annulée :
AppRoutes.home.path→HomePage
Validation
Nom de personnage
Règles :
- Non vide : Le nom ne peut pas être vide
- Longueur : 1-12 caractères
- Format : Lettres, chiffres, espaces et underscores uniquement
- RegEx :
^[a-zA-Z0-9_ ]+$
- RegEx :
- Unicité : En mode "join", vérifie que le nom n'est pas déjà pris
Messages d'erreur :
- "CHARACTER_CREATION.CHOOSE_AVATAR" : Aucun avatar sélectionné
- "CHARACTER_CREATION.AVATAR_TAKEN" : Avatar déjà pris
- "CHARACTER_CREATION.ENTER_NAME" : Nom vide
- "CHARACTER_CREATION.NAME_INVALID" : Format invalide
- "CHARACTER_CREATION.NAME_TAKEN" : Nom déjà utilisé
- "CHARACTER_CREATION.NAME_TOO_LONG" : Plus de 12 caractères
- "CHARACTER_CREATION.GAME_FULL" : Partie pleine (drop-in/drop-out)
Avatar
Règles :
- Sélectionné : Un avatar doit être sélectionné
- Disponible : L'avatar ne doit pas être déjà pris
Extraction du nom d'avatar
La fonction extractAvatarName permet de normaliser les noms d'avatars :
- Enlève le chemin (
assets/sprites/) - Enlève l'extension (
.svg) - Enlève le suffixe numérique (
_1,_2, etc.)
Exemple :
"assets/sprites/Guerrier_1.svg" → "Guerrier"
"Guerrier_1" → "Guerrier"
"Guerrier" → "Guerrier"
Cela permet de comparer les avatars même si les formats diffèrent entre le serveur et le client.
Gestion des avatars pris
Mode "create"
Les avatars pris sont gérés localement. Au fur et à mesure que les joueurs rejoignent, la liste est mise à jour via Socket.IO.
Mode "join"
Les avatars pris sont récupérés depuis l'état actuel de la partie. La méthode _updateTakenAvatarsFromGame() synchronise la liste.
Drop-in/drop-out
En mode drop-in/drop-out, seuls les joueurs actifs (qui n'ont pas quitté) sont comptés pour déterminer si la partie est pleine.
Écouteurs Socket.IO
gameLockUpdated
Description : Émis quand la partie se verrouille (devient pleine).
Condition : Seulement en mode drop-in/drop-out
Action : Affiche popup "Partie pleine" et empêche de rejoindre
Limites de joueurs par taille de grille
| Taille de grille | Joueurs max |
|---|---|
| 10x10 | 2 |
| 15x15 | 4 |
| 20x20 | 6 |
Ces limites sont définies dans la constante gridLimits.
Liste des avatars
Les avatars sont chargés depuis GameCharacters.gameCharacters, qui contient tous les sprites de personnages disponibles dans le jeu (Guerrier, Mage, Archer, etc.).