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

XII. Création du menu : affichage et choix dans le menu

Le résultat du premier test de l'écran n'était pas impressionnant mais nous a permis de valider le fonctionnement de l'interface d'écran clScreen

Il faut maintenant lui ajouter de l'affichage et répondre aux commandes de l'utilisateur pour faire un choix dans le menu.

Le code qui suit s'écrit dans le module clScreenMenu.

XII-A. Minuterie

N'oublions pas de mettre en place la minuterie !

Dans la procédure ClScreen_ScreenWait, ajoutez l'appel à la méthode Wait de l'objet clGdiplus.

Pour un menu, 10 images par seconde suffisent.

Cette méthode Wait n'est pas bloquante. DoEvents est déclenché dès que nécessaire pour traiter la file de message de l'application et permettre à l'utilisateur d'interagir.

Appel de la minuterie dans la fonction ClScreen_ScreenWait
Sélectionnez
'------------------------------------------------------------------------
' Minuterie d'attente
'------------------------------------------------------------------------
Private Function ClScreen_ScreenWait() As Boolean
' Attente de 1000 / 10 = 100 ms pour affichage de 10 images/s
oGdi.Wait 100
End Function

Maintenant nous pouvons tester en affichant le UserForm FormGame.

Il ne s'affiche qu'un UserForm vide.

XII-B. Affichage du menu

Pour pouvoir dessiner, il faut créer avec gdi+ une image en mémoire.

La création de l'image se fait avec la fonction CreateBitmapForControl de l'objet clGdiplus de l'écran.

L'image créée est de la même taille (en pixels) que le contrôle image Img que nous avions créé sur le formulaire FormGame.

Nous créons cette image à l'initialisation de l'écran de menu dans l'événement Initialize.

Code de création de l'image dans Class_Initialize
Sélectionnez
With oGdi
    ' Nouveau bitmap pour dessiner
    .CreateBitmapForControl FormGame
End With

Ensuite il faut créer le contenu statique du menu, c'est-à-dire le fond (uni) et le texte des options.
Ce contenu est dessiné une seule fois à l'initialisation de l'écran, puis sauvegardé pour pouvoir être restauré à la demande.
En effet la mise à jour de l'écran dans la fonction UpdateScreen devra :

  • recharger le contenu statique du menu ;
  • dessiner le contenu dynamique du menu : encadrement de l'entrée sélectionnée, autres animations si nécessaire…

Dans l'événement Initialize nous allons :

  1. Remplir le fond de gris avec la fonction Clear.
  2. Écrire le nom du jeu en haut de l'image avec la fonction DrawText.
  3. Écrire texte de chacune des options avec la fonction DrawText.

Commençons par les deux premières étapes.

Début du dessin du contenu statique
Sélectionnez
' Dessin du contenu statique
With oGdi
    ' Nouveau bitmap pour dessiner
    .CreateBitmapForControl FormGame
    ' Rempli l'image de gris
    .Clear RGB(150, 150, 150)
    ' Ecrit le nom du jeu en haut
    .DrawText "PacMan en VBA", 35, "Arial", 0, 10, _
            .ImageWidth, 10 + 50, 1, 0, vbBlue, , vbYellow
End With

Le code ci dessus rempli l'image de noir puis affiche le texte « Pacman en VBA » en haut et en bleu sur fond jaune.

Pour tester l'affichage, il faut gérer la fonction ClScreen_DisplayScreen.
Utilisons la fonction Repaint de clGdiplus pour dessiner l'image dans le contrôle du formulaire.

Affichage de l'image sur le formulaire
Sélectionnez
'------------------------------------------------------------------------
' Affichage de l'écran
'------------------------------------------------------------------------
Private Function ClScreen_DisplayScreen() As Boolean
' Dessine l'image sur le formulaire
oGdi.Repaint FormGame.Img
End Function

Affichez le formulaire avec F5 ou dans le menu Exécution => Exécuter Sub/Userform.

On obtient notre première image.

Image non disponible

Ajoutons l'affichage des options :
Pour éviter d'écrire plusieurs fois le même code, on crée une petite procédure d'affichage d'une option.
En paramètre de cette procédure : le numéro de l'option et son texte.

Procédure d'affichage d'une option
Sélectionnez
'------------------------------------------------------------------------
' Affichage de l'option numéro pNum avec le texte pText
'------------------------------------------------------------------------
Private Sub DisplayOption(pNum As Long, pText As String)
' Position verticale de la première option
Const cPos As Long = 140
With oGdi
    ' Dessine un rectangle de fond en jaune pâle
    .DrawRectangle 150, cPos + (pNum - 1) * 60, 600, cPos + (pNum - 1) * 60 + 50, _
        RGB(255, 255, 200), , , , , "menu" & pNum
    ' Dessine le texte de l'option en bleu
    .DrawText pText, 50, "Arial", 150, cPos + (pNum - 1) * 60, _
            600, cPos + (pNum - 1) * 60 + 50, , , vbBlue
End With
End Sub

Le dessin d'une option se fait en deux étapes :

  1. Dessin d'un rectangle de fond.
  2. Dessin du texte.

Il faut ajuster les paramètres de position en pixels pour centrer les options.

On pense également à ajouter une région correspondant au rectangle et ayant pour identifiant « menu1 », « menu2 »…

La fonction DrawRectangle permet d'ajout cette région (paramètre pRegion).
Cette région nous servira ensuite à déterminer la région survolée par la souris.

On appelle ensuite cette fonction dans Class_Initialize pour chaque option.

A la fin du dessin du contenu statique, on le sauvegarde en mémoire comme prévu (pour pouvoir restaurer le contenu statique dans la fonction ClScreen_UpdateScreen).

Suite du dessin du contenu statique
Sélectionnez
[...]
    ' Affichage des options
    DisplayOption 1, "Commencer le jeu"
    DisplayOption 2, "Options"
    DisplayOption 3, "Scores"
    DisplayOption 4, "Crédits"
    DisplayOption 5, "Quitter"
    ' Sauvegarde l'image en mémoire
    .ImageKeep
End With

Affichez le formulaire pour voir le résultat.

Image non disponible

XII-C. Encadrement de l'entrée de menu sélectionnée

Pour l'instant on n'a pas encore travaillé sur la gestion des commandes.
On ne connait pas les touches définies par l'utilisateur, nous le verrons lors de la création de l'écran des options.

Nous allons dans un premier temps gérer les choix d'option de menu à la souris.

Lors du survol ou du click sur l'image, un événement est envoyé au contrôle du formulaire.
Pour récupérer cet événement, il nous faut dans notre module clScreenMenu un objet image qui recevra les événéments.

On déclare donc une variable de type Image, avec le mot-clé WithEvents qui permet de recevoir les événéments.

Déclaration de l'objet image en en-tête de module
Sélectionnez
' Contrôle image pour événements
Private WithEvents oImg As MSForms.image

Il faut également initialiser l'objet à la création de l'écran.

Initialisation de l'objet image à la création de l'écran
Sélectionnez
[...]
Private Sub Class_Initialize()
' Affectation de l'image pour événements
Set oImg = FormGame.Img
[...]

Pour générer le code événément correspondant à un survol de l'image, sélectionnez dans la liste déroulante en haut à gauche l'objet oImg puis dans la liste déroulante à droite sélectionnez MouseMove.
Lors du survol de l'image, la procédure oImg_MouseMove sera exécutée.

Dans cette procédure, nous allons lire (avec RegionGetXY) la région située sous la souris, puis l'affecter à une variable.
Nous pourrons ensuite encadrer cette région dans la fonction ClScreen_UpdateScreen.

On commence par déclarer la variable en en-tête de module :

Déclaration de la variable pour option sélectionnée
Sélectionnez
' Nom de l'option sélectionnée
Private gOption As String

Et ensuite on modifie cette variable au survol de la souris.

Modification de la variable gOption au survol de la souris
Sélectionnez
'------------------------------------------------------------------------
' Sur déplacement de la souris
'------------------------------------------------------------------------
Private Sub oImg_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Dim lRegion As String
With oGdi
' Région aux coordonnées X et Y
' Les valeurs de X et Y étant des coordonnées prises sur le contrôle,
'     on passe ce contrôle en cinquième paramètre
    lRegion = .RegionGetXY(X, Y, , , oImg)
    If lRegion <> "" Then
        gOption = lRegion
    End If
End With
End Sub

Et enfin dans la fonction ClScreen_UpdateScreen, on restaure le contenu statique et on encadre l'option sélectionnée.

Encadre l'option sélectionnée
Sélectionnez
'------------------------------------------------------------------------
' Mise à jour de l'écran
'------------------------------------------------------------------------
Private Function ClScreen_UpdateScreen() As Boolean
With oGdi
    ' Recharge l'image de la mémoire
    .ImageReset
    ' Encadre en rouge l'entrée de menu sélectionnée
    .RegionFrame gOption, vbRed, 4
End With
End Function

Si on affiche le formulaire, l'option de menu survolée s'encadre en rouge.
Mais on a oublié de sélectionner une option par défaut à l'initialisation de l'écran.

Option sélectionnée par défaut
Sélectionnez
'------------------------------------------------------------------------
' Initialisation de l'écran
'------------------------------------------------------------------------
Private Sub Class_Initialize()
' Option sélectionnée par défaut
gOption = "menu1"
[...]

Deux petits soucis à ce stade de la programmation du menu :

  1. Si on clique sur le formulaire, l'image ne change plus ensuite.
  2. L'affichage « clignote » et ça fait mal aux yeux.

Pour le premier problème, on peut forcer le formulaire à se redessiner avec un appel à la méthode Repaint du formulaire.

Pour le second problème, on peut augmenter le paramètre DrawBuffer du formulaire jusqu'à ce que les clignotements disparaissent (valeur maxi = 1048576).

Sinon une autre solution plus simple qui règle les deux problèmes : utilisez la méthode RepaintNoFormRepaint.
Cette méthode dessine l'image directement sur l'écran et évite ainsi tout problème d'affichage.

Améliore l'affichage
Sélectionnez
'------------------------------------------------------------------------
' Affichage de l'écran
'------------------------------------------------------------------------
Private Function ClScreen_DisplayScreen() As Boolean
' Dessine l'image sur le formulaire
oGdi.RepaintNoFormRepaint FormGame.Img
End Function

XII-D. Sélection d'une option de menu

Toujours à la souris, on va choisir l'option de menu désirée en cliquant sur l'image.
Créez le code événementiel sur souris appuyée MouseDown.

Code pour souris appuyée
Sélectionnez
'------------------------------------------------------------------------
' Sur click de la souris
'------------------------------------------------------------------------
Private Sub oImg_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call MenuSelect
End Sub

On garde en tête qu'on souhaitera plus tard gérer le choix des options au clavier, donc on appelle une fonction MenuSelect qui pourra ensuite servir au clavier.

En fonction du contenu de gOption, on défini le nom de l'écran suivant et on demande le changement d'écran en donnant la valeur Vrai à gChangeScreen.

Code pour choix d'option dans le menu
Sélectionnez
'------------------------------------------------------------------------
' Sélection dans le menu
'------------------------------------------------------------------------
Private Sub MenuSelect()
Select Case gOption
    Case "menu1"
        gNextScreen = "game"
        gChangeScreen = True
    Case "menu2"
        gNextScreen = "options"
        gChangeScreen = True
    Case "menu3"
        gNextScreen = "scores"
        gChangeScreen = True
    Case "menu4"
        gNextScreen = "credits"
        gChangeScreen = True
    Case "menu5"
        gNextScreen = "quit"
        gChangeScreen = True
End Select
End Sub

Si vous testez le click sur une option de menu, le formulaire se ferme quelque soit l'option choisie.
C'est normal car nous allons ensuite gérer l'enchaînement des écrans dans GameChangeScreen du module clGame au fur et à mesure de leur création.


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.