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 If
Puis 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
Function
ReadOption 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
Long
Nous 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.JoyNum
XIII-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
clScreenOptions
On 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
, , vbYellow
Cliquez 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
, , , vbBlue
Comme 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
Function
Nous 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
Function
Retour 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
Loop
Pour 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
Sub
Inutile 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
Sub
Affichez 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
If
Voilà 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
If
On peut ainsi naviguer dans menu et valider soit à la souris, au clavier, ou au joystick.