IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel Gdi+ : programmez un jeu de Pacman complet en VBA

Image non disponible


précédentsommairesuivant

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.

déclaration des objets inclus dans l'objet Jeu
Sélectionnez
' 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 ».

Algorithme de déroulement du jeu dans l'objet Jeu
Sélectionnez
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 :

Code complet du module clGame
Sélectionnez
'***************************************************************************************
'*                                  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.

Pseudo code du formulaire FormGame
Sélectionnez
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
Pseudo code du module de fonctions ModFunctions
Sélectionnez
Function StartGame
                Exécute la fonction principale du formulaire
            Fin function StartGame

Traduisons en VBA :

Code VBA du formulaire FormGame
Sélectionnez
'***************************************************************************************
'*                                 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
Code VBA du module de fonctions ModFunctions
Sélectionnez
'***************************************************************************************
'*                             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.


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 Thierry GASPERMENT. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.