XIII. Gestion des options de jeu▲
XIII-A. Stockage des options▲
Les options de jeu sont des valeurs modifiables par le joueur.
Il faut donc les stocker quelque part pour ne pas avoir à les redéfinir à chaque jeu.
On a plusieurs possibilités pour stocker ces valeurs d'options :
- Etant sous Excel on pourrait les stocker dans une feuille.
Mais ça impliquerait une sauvegarde du fichier Excel complet à chaque modification d'option et c'est un peu lourd. - On peut les stocker dans un fichier texte.
Gérer un fichier ini se fait facilement à l'aide des fonctions WritePrivateProfileString et GetPrivateProfileString de la bibliothèque kernel32.dll.
On va donc se créer une fonction de lecture et une fonction d'écriture d'option dans le fichier ini.
Ce fichier s'appelera config.ini et sera placé dans un sous-dossier config que nous créons dès maintenant dans le répertoire du projet.
Dans le module ModFunctions, ajoutez les déclarations en en-tête :
' Déclarations pour fichier ini
#If VBA7 Then
Private Declare PtrSafe Function WritePrivateProfileString Lib "kernel32" Alias _
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Declare PtrSafe Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, _
ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, _
ByVal lpFileName As String) As Long
#Else
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias _
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As Any, ByVal lpKeyName As Any, _
ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, _
ByVal lpFileName As String) As Long
#End IfPuis ajoutez ces deux fonctions :
'------------------------------------------------------------------------
' Lecture de la valeur d'une clé dans un fichier ini
'------------------------------------------------------------------------
Public Function ReadOption(pOption As String, Optional pDefault As String) As String
Dim lRet As Long
Dim lData As String
Dim lSize As Long
lData = Space$(8192)
lSize = 8192
lRet = GetPrivateProfileString("Options", pOption, pDefault, lData, lSize, ThisWorkbook.path & "\config\config.ini")
If lSize > 0 Then
ReadOption = Left$(lData, lRet)
Else
ReadOption = ""
End If
End Function
'------------------------------------------------------------------------
' Ecriture de la valeur d'une clé dans un fichier ini
'------------------------------------------------------------------------
Public Function WriteOption(pOption As String, Optional pValue As String) As Boolean
Dim lRet As Long
Dim lSize As Long
If pValue = "" Then
lRet = WritePrivateProfileString("Options", pOption, 0&, ThisWorkbook.path & "\config\config.ini")
Else
lRet = WritePrivateProfileString("Options", pOption, pValue, ThisWorkbook.path & "\config\config.ini")
End If
WriteOption = (lRet <> 0)
End FunctionReadOption pour lire une valeur.
WriteOption pour écrire une valeur.
Inutile de créer le fichier config.ini à la main, il sera créé automatiquement à la première écriture d'option.
Par contre le dossier dans lequel on écrit le fichier ini doit exister.
XIII-B. Les variables des options▲
Nos options devront être accessibles par tous les écrans.
En effet les touches paramétrées serviront aussi bien dans l'écran de jeu que dans les autres écrans (pour validation, choix dans le menu…).
Nous allons donc créer des variables dans le module de données partagées clSharedData.
' Code des touches
Public ToucheBas As Long
Public ToucheHaut As Long
Public ToucheDroite As Long
Public ToucheGauche As Long
Public ToucheValid As Long
' Nombre de fantômes
Public NbFantomes As Long
' Joystick utilisé
Public JoyNum As Long
' Bouton de validation du joystick
Public JoyButton As LongNous retrouvons les options définies au début :
- le nombre de fantômes ;
- les différentes commandes clavier et joystick.
XIII-C. Chargement des options▲
Nos options devront être chargées au lancement du jeu, dans la procédure RunGame de l'objet Jeu.
' Chargement des options
oSharedData.NbFantomes = ReadOption("NbFantomes", 5)
oSharedData.ToucheBas = ReadOption("ToucheBas", vbKeyDown)
oSharedData.ToucheDroite = ReadOption("ToucheDroite", vbKeyRight)
oSharedData.ToucheGauche = ReadOption("ToucheGauche", vbKeyLeft)
oSharedData.ToucheHaut = ReadOption("ToucheHaut", vbKeyUp)
oSharedData.ToucheValid = ReadOption("ToucheValid", vbKeyReturn)
oSharedData.JoyNum = ReadOption("JoyNum", 0)
oSharedData.JoyButton = ReadOption("JoyButton", 0)Les options sont lues dans le fichier config.ini grâce à la fonction ReadOption écrite précédemment.
On passe en paramètre une valeur par défaut pour le cas où l'option n'est pas définie dans le fichier de configuration.
Pour le joypad, une fois lu le joypad choisi dans les options, on affecte ce joypad à l'objet command.
' Affecte le joystick à l'objet command
oCommand.JoyPadNum = oSharedData.JoyNumXIII-D. Création de l'écran des options de jeu▲
Cet écran se programme dans le module clScreenOption.
Préparons l'écran en copiant dans ce module le contenu du module clScreenMenu de l'écran de menu.
Nettoyez le module en retirant la fonction DisplayOption qui ne nous servira pas pour cet écran, ainsi que tous les appels à cette fonction.
Il faut ensuite gérer l'enchaînement de l'écran des options.
Dans la fonction GameChangeScreen du module clGame, il faut ajouter l'enchainement vers l'écran des options.
Ajoutez un Case au Select.
' Changement pour les options
Case "options"
Set oScreen = Nothing
Set oScreen = New clScreenOptionsOn teste la valeur « options » car dans l'écran de menu c'est cette valeur qu'on utilise lors du click sur Options.
Puis modifier le texte de l'écran d'options pour pouvoir tester, en remplaçant la ligne qui écrivait « Pacman en VBA ».
' 0 - Ecrit le titre de l'écran en haut
.DrawText "Options de jeu", 35, "Arial", 0, 10, .ImageWidth, _
10 + 50, 1, 0, vbBlue, , vbYellowCliquez dans le menu sur « OPTIONS » affiche bien l'écran des options.
XIII-E. Affichage des options de jeu▲
Faisons une petite maquette (sous PowerPoint par exemple) pour se donner une idée de l'écran d'options que l'on doit réaliser.
Chaque cadre sera encadré lorsque sélectionné.
Après l'écriture du texte « Options de jeu », on écrit le code qui dessine la partie statique de l'écran d'options.
' 1 - Affichage du nombre de fantômes
.DrawText "Nombre de fantômes", 20, , 120, 100, 400, 130, 0, , vbBlue
.DrawRectangle 310, 100, 370, 130, , vbWhite, 2, , , "NbFantomes"
' 2 - Affichage commandes clavier
.DrawText "Commandes clavier", 20, , 120, 140, 400, 170, 0, , vbBlue
.DrawRectangle 120, 170, 600, 410, , vbBlack, 1
.DrawRectangle 310, 180, 400, 210, , vbWhite, 2, , , "ToucheHaut"
.DrawText "Haut", 20, , 310, 180, 400, 210, , , vbBlue
.DrawRectangle 310, 280, 400, 310, , vbWhite, 2, , , "ToucheBas"
.DrawText "Bas", 20, , 310, 280, 400, 310, , , vbBlue
.DrawRectangle 310, 350, 400, 380, , vbWhite, 2, , , "ToucheValid"
.DrawText "Valider", 20, , 310, 350, 400, 380, , , vbBlue
.DrawRectangle 160, 230, 250, 260, , vbWhite, 2, , , "ToucheGauche"
.DrawText "Gauche", 20, , 160, 230, 250, 260, , , vbBlue
.DrawRectangle 460, 230, 550, 260, , vbWhite, 2, , , "ToucheDroite"
.DrawText "Droite", 20, , 460, 230, 550, 260, , , vbBlue
' 2 - Affichage commandes joystick
.DrawText "Commandes joystick", 20, , 120, 420, 400, 450, 0, , vbBlue
.DrawRectangle 120, 450, 600, 510, , vbBlack, 1
.DrawRectangle 200, 460, 500, 490, , vbWhite, 2, , , "JoyButton"
.DrawText "Bouton de validation", 20, , 200, 460, 500, 490, , , vbBlue
' 4 - Affichage des boutons valider et annuler
.DrawRectangle 180, 530, 310, 560, RGB(150, 255, 150), vbBlack, 1, , , "BoutonValid"
.DrawText "Valider", 20, , 180, 530, 310, 560, , , vbBlue
.DrawRectangle 400, 530, 550, 560, RGB(255, 150, 150), vbBlack, 1, , , "BoutonCancel"
.DrawText "Annuler", 20, , 400, 530, 550, 560, , , vbBlueComme pour le menu, on ajoute des régions rectangulaires à l'appel des fonctions DrawRectangle.
Lancez le formulaire et cliquez sur le menu « OPTIONS » pour tester.

On s'aperçoit que le code utilisé pour encadrer les options de menu fonctionne toujours dans cet écran.
Par contre on va modifier l'option choisie par défaut :
' Option sélectionnée par défaut
gOption = "BoutonCancel"Ainsi le bouton « Annuler » est sélectionné par défaut.
Une fois tous les cadres dessinés, on va écrire les valeurs des options :
- on écrit le nombre de fantôme dans la région (=le rectangle) ;
- et on écrit le nom de chaque touche et bouton sous la région (=le rectangle).
Ecrivons deux petites procédures pour écrire ces données :
'------------------------------------------------------------------------
' Affichage texte sous une région
'------------------------------------------------------------------------
Private Function DisplayTextUnderRegion(pRegion As String, pText As String)
Dim lX1 As Long, lY1 As Long, lX2 As Long, lY2 As Long
' Position de la région pRegion
If oGdi.RegionGetRect(pRegion, lX1, lY1, lX2, lY2) Then
' Ecrit le texte en noir et italique
oGdi.DrawText pText, 15, , (lX2 + lX1) / 2, lY2 + 10, , , , , vbBlack, , , , True
End If
End Function'------------------------------------------------------------------------
' Affichage texte sur une région
'------------------------------------------------------------------------
Private Function DisplayTextInRegion(pRegion As String, pText As String)
Dim lX1 As Long, lY1 As Long, lX2 As Long, lY2 As Long
' Position de la région pRegion
If oGdi.RegionGetRect(pRegion, lX1, lY1, lX2, lY2) Then
' Ecrit le texte en noir
oGdi.DrawText pText, 20, , lX1, lY1, lX2, lY2, , , vbBlack
End If
End FunctionNous utiliserons ces procédures pour afficher les valeurs des options dans la procédure de mise à jour ClScreen_UpdateScreen.
Les différentes valeurs sont stockées dans l'objet oSharedData.
Pour les touches, la valeur de l'option est le code numérique de la touche.
On va créer une petite fonction pour récupérer le nom de la touche en toute lettre.
Plaçons cette procédure dans le module ModFunctions.
' Déclaration pour nom des touches
#If VBA7 Then
Private Declare PtrSafe Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" _
(ByVal wCode As Long, ByVal wMapType As Long) As Long
Private Declare PtrSafe Function GetKeyNameText Lib "user32" Alias "GetKeyNameTextA" _
(ByVal lParam As Long, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#Else
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" _
(ByVal wCode As Long, ByVal wMapType As Long) As Long
Private Declare Function GetKeyNameText Lib "user32" Alias "GetKeyNameTextA" _
(ByVal lParam As Long, ByVal lpBuffer As String, ByVal nSize As Long) As Long
#End If'------------------------------------------------------------------------
' Renvoit le texte d'une touche à partir de son code
'------------------------------------------------------------------------
Public Function KeyNameFromKeyCode(pKeyCode As Long) As String
Dim lKeyCode As Long
Dim lBuffer As String
Dim lSize As Long
lKeyCode = MapVirtualKey(pKeyCode, 0)
lKeyCode = lKeyCode * &H10000
lBuffer = Space$(256)
lSize = GetKeyNameText(lKeyCode, lBuffer, 256)
KeyNameFromKeyCode = Left$(lBuffer, lSize)
End FunctionRetour au module clScreenOptions.
Après l'encadrement de région, dans la procédure ClScreen_UpdateScreen, on ajoute le dessin des valeurs des options.
' Ecrit le nombre de fantômes
DisplayTextInRegion "NbFantomes", CStr(oSharedData.NbFantomes)
' Ecrit le texte des touches
DisplayTextUnderRegion "ToucheBas", "( " & KeyNameFromKeyCode(oSharedData.ToucheBas) & " )"
DisplayTextUnderRegion "ToucheHaut", "( " & KeyNameFromKeyCode(oSharedData.ToucheHaut) & " )"
DisplayTextUnderRegion "ToucheDroite", "( " & KeyNameFromKeyCode(oSharedData.ToucheDroite) & " )"
DisplayTextUnderRegion "ToucheGauche", "( " & KeyNameFromKeyCode(oSharedData.ToucheGauche) & " )"
DisplayTextUnderRegion "ToucheValid", "( " & KeyNameFromKeyCode(oSharedData.ToucheValid) & " )"
' Ecrit le texte pour le bouton de joystick
DisplayTextUnderRegion "JoyButton", _
"( Bouton " & oSharedData.JoyButton & " du joystick " & oCommand.JoyPadName & " )"Lancez le formulaire et cliquez sur le menu « OPTIONS » pour tester l'affichage des valeurs.

XIII-F. Modification des options de jeu▲
Pour modifier une option, l'utilisateur devra survoler l'option à la souris puis appuyer sur la touche souhaitée.
Pour connaître la touche appuyée, on utilisera la fonction KeyPressGetCode de l'objet oCommand.
Cette fonction revoit le code numérique d'une seule touche appuyée (même si on appuie sur plusieurs touches simultanément).
Si une touche est appuyée et qu'une option est survolée, alors on modifie la valeur de l'option.
Pour le joystick, on teste l'état de tous les boutons de tous les joysticks présents.
Si un bouton est appuyé, il devient le bouton de validation.
La détection de touche ou joystick se fait dans la fonction ClScreen_UpdateCommand.
Dim lKeyPress As Long
Dim loCommand As ClCommand
Dim lCpt As Long
' Code de la touche appuyée
lKeyPress = oCommand.KeyPressGetCode
' Si une touche est appuyée
If lKeyPress <> 0 Then
Select Case gOption
Case "ToucheHaut"
oSharedData.ToucheHaut = lKeyPress
Case "ToucheBas"
oSharedData.ToucheBas = lKeyPress
Case "ToucheDroite"
oSharedData.ToucheDroite = lKeyPress
Case "ToucheGauche"
oSharedData.ToucheGauche = lKeyPress
Case "ToucheValid"
oSharedData.ToucheValid = lKeyPress
Case "NbFantomes"
If IsNumeric(Chr(lKeyPress)) Then
' Touche numérique
oSharedData.NbFantomes = Val(Chr(lKeyPress))
ElseIf Val(KeyNameFromKeyCode(lKeyPress)) <> 0 Then
' Touche du pavé numérique
oSharedData.NbFantomes = Val(KeyNameFromKeyCode(lKeyPress))
End If
End Select
End If
' Teste des touches de joystick
' Objet command local pour test de tous les joysticks
Set loCommand = New ClCommand
' Premier joystick, commence à l'indice 0
loCommand.JoyPadNum = 0
Do
' Si pas de bouton => joystick invalide => sort de la boucle
If loCommand.JoyPadButtons = 0 Then Exit Do
' Teste l'état de tous les boutons
For lCpt = 0 To loCommand.JoyPadButtons
' Teste l'appui sur le bouton n° lCpt
If loCommand.TestJoypadButton(lCpt) Then
' Modifie les options en fonction du bouton et du joystick utilisé
oSharedData.JoyButton = lCpt
oSharedData.JoyNum = loCommand.JoyPadNum
' Affecte le joystick choisi à l'objet command global
oCommand.JoyPadNum = loCommand.JoyPadNum
' Sort de la boucle
Exit Do
End If
Next
' Joystick suivant
loCommand.JoyPadNum = loCommand.JoyPadNum + 1
LoopPour le nombre de fantôme, on vérifie si la touche appuyée correspond à une touche de chiffre (en haut sur le clavier), ou à une touche du pavé numérique.
XIII-G. Validation ou annulation des options de jeu▲
Il faut maintenant gérer la validation ou l'annulation des options.
Sur click sur le bouton « Valider » ou le bouton « Annuler », on retourne au menu.
Modifions donc l'écran suivant par défaut de cet écran d'options.
' Ecran suivant par défaut
gNextScreen = "menu"Ensuite modifions la procédure MenuSelect de notre écran.
'------------------------------------------------------------------------
' Sélection dans le menu
'------------------------------------------------------------------------
Private Sub MenuSelect()
Select Case gOption
Case "BoutonValid"
gChangeScreen = True
Case "BoutonCancel"
gChangeScreen = True
End Select
End SubInutile de préciser l'écran suivant, c'est l'écran par défaut dans les deux cas.
Pour compléter :
Sur click sur le bouton annuler on va recharger les options pour annuler les changements.
Par contre sur click sur le bouton valider, on va sauvegarder les options.
'------------------------------------------------------------------------
' Sélection dans le menu
'------------------------------------------------------------------------
Private Sub MenuSelect()
Select Case gOption
Case "BoutonValid"
' Sauvegarde des options
WriteOption "NbFantomes", oSharedData.NbFantomes
WriteOption "ToucheBas", oSharedData.ToucheBas
WriteOption "ToucheDroite", oSharedData.ToucheDroite
WriteOption "ToucheGauche", oSharedData.ToucheGauche
WriteOption "ToucheHaut", oSharedData.ToucheHaut
WriteOption "ToucheValid", oSharedData.ToucheValid
WriteOption "JoyNum", oSharedData.JoyNum
WriteOption "JoyButton", oSharedData.JoyButton
' Demande le changement d'écran
gChangeScreen = True
Case "BoutonCancel"
' Rechargement des options
oSharedData.NbFantomes = ReadOption("NbFantomes", 5)
oSharedData.ToucheBas = ReadOption("ToucheBas", vbKeyDown)
oSharedData.ToucheDroite = ReadOption("ToucheDroite", vbKeyRight)
oSharedData.ToucheGauche = ReadOption("ToucheGauche", vbKeyLeft)
oSharedData.ToucheHaut = ReadOption("ToucheHaut", vbKeyUp)
oSharedData.ToucheValid = ReadOption("ToucheValid", vbKeyReturn)
oSharedData.JoyNum = ReadOption("JoyNum", 0)
oSharedData.JoyButton = ReadOption("JoyButton", 0)
' Affecte le joystick à l'objet command
oCommand.JoyPadNum = oSharedData.JoyNum
' Demande le changement d'écran
gChangeScreen = True
End Select
End SubAffichez l'écran d'options et validez : le fichier congfig.ini a été créé dans le sous-dossier config.
Une dernière chose avant de clore ce chapitre.
Si on utilise le joystick, une fois entré dans l'écran d'options on ne peut en sortir qu'avec la souris.
Cela n'est pas très pratique, on va donc tester si on appuie sur le bouton de joystick de validation afin de pouvoir quitter l'écran au joystick.
' Si appui sur la touche de validation du joystick
If oCommand.TestJoypadButton(oSharedData.JoyButton) Then
' Valide le menu sélectionné (annuler par défaut)
MenuSelect
Exit Function
End IfVoilà qui est plus pratique.
XIII-H. Navigation dans l'écran de menu avec le clavier ou le joystick▲
Maintenant que nous avons toutes nos commandes définies, nous pouvons également les utiliser pour naviguer dans l'écran de menu.
Ouvrez le module clScreenMenu et ajouter la navigation au clavier et joystick dans la procédure ClScreen_UpdateCommand.
Dim lCpt As Long
Dim lDown As Boolean
Dim lUp As Boolean
' Test directions du joystick
oCommand.TestJoypadDir , , lUp, lDown
' Numéro du menu sélectionné
lCpt = Right(gOption, 1)
' Si appuis touche vers le bas
If oCommand.TestKey(oSharedData.ToucheBas, 100) Or lDown Then
lCpt = lCpt + 1
If lCpt = 6 Then lCpt = 1
gOption = "menu" & lCpt
End If
' Si appuis touche vers le haut
If oCommand.TestKey(oSharedData.ToucheHaut, 100) Or lUp Then
lCpt = lCpt - 1
If lCpt = 0 Then lCpt = 5
gOption = "menu" & lCpt
End If
' Test si validation
If oCommand.TestKey(oSharedData.ToucheValid, 100) Or oCommand.TestJoypadButton(oSharedData.JoyButton, 100) Then
MenuSelect
End IfOn peut ainsi naviguer dans menu et valider soit à la souris, au clavier, ou au joystick.



