X. Création de la boucle principale dans l'objet Jeu▲
On a à ce stade du projet tous les modules objets nécessaires à la création de l'objet Jeu.
Cet objet est programmé dans la classe clGame qui est pour l'instant vide.
On a déterminé précédemment dans le schéma des objets que l'objet Jeu (clGame) contenait :
- un objet de type clSharedData pour le partage des données entre les écrans ;
- un objet de type clScreen qui contient une instance de l'écran courant ;
- un objet de type clCommand pour la gestion des commandes.
Déclaration ces objets en en-tête du module clGame.
' Objet Ecran
Private
oScreen As
ClScreen
' Objet pour commandes
Private
oCommand As
ClCommand
' Objet pour données partagées entre les écrans
Private
oSharedData As
ClSharedData
L'algorithme de déroulement du jeu à été écrit sommairement lors de la création de la classe d'interface clScreen.
Réécrivont l'agorithme complet de cette classe Jeu en « pseudocode ».
Initialisation de l'objet Jeu
oCommand = Nouvel objet de commandes clCommand
oSharedData = Nouvel objet de données clSharedData
Changement d'écran vers écran de menu
Fin d'initialisation
Procédure de début de jeu
Mettre <demande de sortie> à Faux
Début boucle de jeu
Exécute mise à jour des commandes dans oScreen
Exécute mise à jour de l'écran dans oScreen
Exécute mise à jour de l'affichage dans oScreen
Exécute la fonction d'attente dans oScreen
Si oScreen demande un changement d'écran
oScreen = Nouvel écran fonction de l'écran suivant dans oScreen
Affecte oCommand et oSharedData à oScreen
Fin Si
Si <demande de sortie> = Vrai Alors Sortie de la boucle de jeu
Fin boucle de jeu
Fin procédure de début de jeu
Procédure de fin de jeu
Mettre <demande de sortie> à Vrai
Fin procédure de fin de jeu
Procédure de changement d'écran (paramètre = nom de l'écran)
oScreen = Nouvel écran fonction du pramètre
Affecte oCommand et oSharedData à oScreen
Fin procédure de changement d'écran
Notez qu'on défini deux procédures, une pour lancer le jeu et une autre pour l'arrêter.
Il est nécessaire de pouvoir sortir de la boucle de jeu (qui est sans fin) afin de libérer le programme avant de détruire l'objet jeu.
Traduisons ce « pseudocode » en VBA :
'***************************************************************************************
'* OBJET JEU
'***************************************************************************************
Option
Explicit
' Objet Ecran
Private
oScreen As
ClScreen
' Objet pour commandes
Private
oCommand As
ClCommand
' Objet pour données partagées entre les écrans
Private
oSharedData As
ClSharedData
' Flag pour arrêt de la boucle de jeu
Private
StopLoop As
Boolean
'------------------------------------------------------------------------
' Initialisation de l'objet de Jeu
'------------------------------------------------------------------------
Private
Sub
Class_Initialize
(
)
' Objet pour commandes
Set
oCommand =
New
ClCommand
' Objet pour données partagées
Set
oSharedData =
New
ClSharedData
' Premier écran = menu
GameChangeScreen "menu"
End
Sub
'------------------------------------------------------------------------
' Procédure de début de jeu
'------------------------------------------------------------------------
Public
Sub
RunGame
(
)
' Pas de sortie de boucle demandée au lancement du jeu
StopLoop =
False
Do
' Mise à jour des commandes
oScreen.UpdateCommand
' Mise à jour de l'écran
oScreen.UpdateScreen
' Affichage de l'écran
oScreen.DisplayScreen
' Minuterie
oScreen.ScreenWait
' Test si changement d'écran demandé
If
oScreen.ChangeScreen
Then
' Change l'écran
If
GameChangeScreen
(
oScreen.NextScreen
) =
False
Then
' Si pas d'écran suivant => quitte le jeu
Exit
Do
End
If
End
If
' Si sortie de boucle demandée => sort de la boucle
If
StopLoop Then
Exit
Do
Loop
End
Sub
'------------------------------------------------------------------------
' Procédure de fin de jeu
'------------------------------------------------------------------------
Public
Sub
StopGame
(
)
' Sortie de boucle demandée pour l'arrêt du jeu
StopLoop =
True
End
Sub
'------------------------------------------------------------------------
' Procédure de changement d'écran
'------------------------------------------------------------------------
Private
Function
GameChangeScreen
(
pScreenName) As
Boolean
' Renvoit Vrai par défaut
GameChangeScreen =
True
' Changement d'écran en fonction du nom d'écran en pramètre
Select
Case
pScreenName
' Changement pour le menu
Case
"menu"
Set
oScreen =
Nothing
Set
oScreen =
New
ClScreenMenu
' Autre changement
Case
Else
' Si pas d'écran suivant connu => renvoit Faux pour arrêter le jeu
GameChangeScreen =
False
End
Select
' Réaffecte les objets de commande et de données partagées au nouvel écran courant
Set
oScreen.Command
=
oCommand
Set
oScreen.SharedData
=
oSharedData
End
Function
L'objet Jeu est prêt !
On commence à voir l'intérêt de la programmation orientée objet.
Pour ajouter un nouvel écran il suffira de rajouter son enchainement dans la fonction GameChangeScreen.
XI. Lancement du jeu dans le formulaire▲
On a défini dans le schéma des objets que le formulaire contenait un objet de type clGame.
On déclare donc en en-tête de module un objet oGame que l'on instanciera au lancement du jeu.
Justement, parlons du lancement du jeu :
Si on souhaite lancer le jeu à l'ouverture du formulaire, on doit placer le code de lancement dans l'événement Initialize du formulaire.
On a alors un problème car le lancement du jeu fait entrer le programme dans une boucle sans fin.
C'est la boucle de la procédure RunGame.
Or la procédure Initialize du formulaire doit être menée à son terme afin que le formulaire soit totalementinitialisé et affiché.
Nous allons donc faire exécuter notre procédure de démarrage en différé par une minuterie, à l'aide de l'instruction OnTime de l'objet Application.
Cette instruction OnTime nécessite une fonction publique dans un module standard (donc pas dans le module du formulaire qui est un module de classe).
Voici en pseudocode le formulaire et la fonction différée dans un nouveau module ModFunctions.
Initialisation du formulaire
Appel différé d'une fonction StartGame d'un module nommé ModFunctions
Fin d'initialisation du formulaire
Fonction Principale Main
Crée l'objet Jeu
Lance le jeu (procédure RunGame de l'objet Jeu) => entre dans une boucle sans fin
Ferme le formulaire
Fin de la fonction Main
Evénément Demande de fermeture du formulaire
Arrête le jeu (procédure StopGame de l'objet Jeu) => sort de la boucle sans fin
Fin d'Evénément Demande de fermeture
Function StartGame
Exécute la fonction principale du formulaire
Fin function StartGame
Traduisons en VBA :
'***************************************************************************************
'* FORMULAIRE DE JEU
'***************************************************************************************
Option
Explicit
' objet Jeu
Private
oGame As
ClGame
'------------------------------------------------------------------------
' Initialisation du formulaire
'------------------------------------------------------------------------
Private
Sub
UserForm_Initialize
(
)
' Délais d'une seconde avant excution de la fonction principal
' La procédure UserForm_Initialize doit arriver à son terme
Application.OnTime
DateAdd
(
"s"
, 1
, Now
), "StartGame"
End
Sub
'------------------------------------------------------------------------
' Fonction principal
'------------------------------------------------------------------------
Public
Function
Main
(
)
' Instancie l'objet Jeu
Set
oGame =
New
ClGame
' Lance le jeu
oGame.RunGame
' Une fois le jeu terminé, décharge le formulaire
Unload Me
End
Function
'------------------------------------------------------------------------
' Demande de fermeture du formulaire
'------------------------------------------------------------------------
Private
Sub
UserForm_QueryClose
(
Cancel As
Integer
, CloseMode As
Integer
)
' Arrête le jeu si on demande la fermeture du formulaire
oGame.StopGame
End
Sub
'***************************************************************************************
'* FUNCTIONS DIVERSES
'***************************************************************************************
Option
Explicit
'------------------------------------------------------------------------
' Fonction de lancement du jeu
' Cette fonction est appelée depuis le formulaire par Application.OnTime
'------------------------------------------------------------------------
Public
Function
StartGame
(
)
FormGame.Main
End
Function
L'affichage du formulaire va donc demander l'exécution différée de la fonction StartGame qui à sont tour demandera l'exécution de la fonction Main du formulaire afin de lancer le jeu.
Il est important d'arrêter le jeu à la demande de fermeture du formulaire.
Sans ça, la boucle sans fin ne s'arrêterait pas.
Attention : la procédure ClScreen_ScreenWait n'a pas été programmée.
Pour tester à ce stade, il faudrait ajouter un DoEvents dans cette procédure.