Directx tuto 8 : gerer un menu

Soyez le premier à donner votre avis sur cette source.

Vue 4 696 fois - Téléchargée 656 fois

Description

            • JE CONSIDÈRE QUE VOUS POSSÉDER LES CONNAISSANCES PRESSENTE DANS MES PRÉCÉDENTS TUTORIAUX ******


Lors de la création d'un menu, je me suis retrouvé confronté à différents problèmes :

- Passer de mon jeu au menu sans faire bugger DirectX
- Faire différent bouton, le problème n'est pas de les afficher, mais d'accéder au bouton l'un après l'autre avec DirectInput.

Donc se sont les 2 gros problèmes qui se posent, pour la création d'un menu, et au quel je vais répondre.

Source / Exemple :


'Je pars en me disant que votre code comporte déjà cela : 

'Dans un module :

'- Une sub d'initialisation avec DirectDraw et DirectInput au minimum.
'- Une sub affichant votre écran principal.
'- Une sub qui gère le clavier

'Et BRunning qui permet l'affichage de votre boucle Do .... Loop Until BRunning = 
'False

'Vous allez mettre un nouveau module, appelé le MenuEchap par exemple.

'Et déclaré :

'Public EchapRunning as Boolean

'Ce qui sera notre variable d'affichage du menu echap.

'Puis mettez une sub appeler MEchap.

'Ensuite dans votre sub du clavier vous allez appeler la sub MEchap lorsqu'on 
'appuis sur la touche echap :

If (DIstate.Key(DIK_ESCAPE) And &H80) Then Call MEchap

'&H80 étant un cache pour dire que la touche est appuyée.

'Dans la sub MEchap vous mettez en tout premier

BRunning = False
'puis
EchapRunning = True

'Ces deux lignes permettent d'arrêter l'affichage de votre première boucle, et 
'd'accorder l'affichage de votre seconde.

'Vous déclarez une image pour le fond de votre menu, et ce qui change est que 
'vous avez un bouton pour quand c'est pas sélectionné et un pour quand s’est 
'sélectionné.

'Donc, on va faire la déclaration de  nos différents boutons.

'Il y en aura 3 :

Retour
Option
Quitter

'Donc les déclarations :

'Pour le bouton Retour :

Dim Retour(2) As DirectDrawSurface7

'Comme vous pouvez le voir notre variable est un tableau, ce qui change des 
'déclarations normales, ceci peut être utile pour les sprites (animations).

Dim ddsdRetour(2) As DDSURFACEDESC2
' De même pour le ddsd

For i = 1 To 2
' En faisant une boucle ça nous permet de réduire la longueur du code

    Set Retour(i) = CreateSurfaceFromFile(DD, App.Path & "\image\retour" & i & ".bmp", ddsdRetour(i))

'Donc Retour(1) sera retour1.bmp, et Retour(2) sera retour2.bmp

    Retour(i).SetColorKey DDCKEY_SRCBLT, cke
' Nous définissons une couleur de transparence par la même occasion
Next

'Comme vous pouvez le voir, ceci nous fait gagner des lignes de codes et facilite la suite du code

'Maintenant nous faisons de mémé pour Option et pour Quitter :

Dim BOption(2) As DirectDrawSurface7
'Comme vous pouvez le voir j'ai mis BOption car Option existe déjà en vb

Dim ddsdOption(2) As DDSURFACEDESC2
For i = 1 To 2
    Set BOption(i) = CreateSurfaceFromFile(DD, App.Path & "\image\option" & i & ".bmp", ddsdOption(i))
    BOption(i).SetColorKey DDCKEY_SRCBLT, cke
Next

' Meme schema que pour Retour.

Dim Quitter(2) As DirectDrawSurface7
Dim ddsdQuitter(2) As DDSURFACEDESC2
For i = 1 To 2
    Set Quitter(i) = CreateSurfaceFromFile(DD, App.Path & "\image\quitter" & i & ".bmp", ddsdQuitter(i))
    Quitter(i).SetColorKey DDCKEY_SRCBLT, cke
Next

'Ici nous avons défini nos boutons.

'Maintenant si on réfléchit un peu il va nous falloir une variable qui changera 
'suivant si c'est Retour(1) ou Retour(2).

Donc en dessous Public EchapRunning as Boolean
Vous mettez :

Public nbrQuitter As Integer     ' Integer car on se servira que de 1 et 2 donc pas la 
'peine de mettre long.
Public nbrRetour As Integer
Public nbrOption As Integer

'À la place de nbr vous auriez pu mettre State.

'Maintenant, passons à l'affichage :

'Alors comme d'habitude :

Do

    Backbuffer.BltFast 0, 0, FondEchap, ddRect(0, 0, 0, 0), DDBLTFAST_WAIT
' Ici nous affichons le fond du menu
 
    Backbuffer.BltFast 20, 30, Retour(nbrRetour), ddRect(0, 0, 116, 55), DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
    Backbuffer.BltFast 10, 100, BOption(nbrOption), ddRect(0, 0, 116, 55), DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
    Backbuffer.BltFast 10, 150, Quitter(nbrQuitter), ddRect(0, 0, 116, 55), DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY

' Et la nos boutons, les positions changes suivant votre menu et la taille de vos 
'boutons.
'N oubliez pas de préciser la taille dans ddRect sinon il se pourrait que ça bug
    
    ClavierEchap
' Nous appelons une sub pour le clavier, mais spécifique au menu
    
    Primary.Flip Nothing, DDFLIP_WAIT
' Et on affiche à l ecran, c'est très important, car autrement le menu buggera

Loop Until EchapRunning = False
' Notre boucle dure tant que EchapRunning = True

' Maintenant notre sub principal du menu échap et fini, nous avons réglé le 
' problème du passage d'une boucle à une autre.

( BRunning = False
  EchapRunning = True
  Primary.Flip Nothing, DDFLIP_WAIT
)

'Il faut régler le problème de DirectInput, je vous propose une solution que j'ai 
'élaborée et que je trouve plutôt pas mal.

'Nous disons que chaque Bouton possède un statut sélectionner ou non.
'Et nous disons que chaque bouton possède un statut dans tout le menu.

'Donc il faut ajouter une variable qui sera la position de la sélection, moi j'ai tout 
'simplement mis :

Public EchapState as Integer

'Donc maintenant dans une nouvelle fonction :

Function ClavierEchap()

'nous mettons l'acquisition du clavier :

DIdevice.GetDeviceStateKeyboard DIstate

'Ensuite il nous faut faire un "événement" pour si la flèche de bas est appuyée :

If (DIstate.Key(DIK_DOWN) And &H80) Then

'Puis nous allons incrémenter notre variable

If EchapState < 3 Then EchapState = EchapState + 1

'Que si Echapstate est inférieur à 3 car nous avons 3 boutons
' Puis nous allons changer la couleur de notre bouton pour le mettre sélectionnée
If EchapState = 1 Then
            nbrRetour = 2
End If

' Donc si EchapState = 1 alors nbrRetour = 2 se qui veux dire que notre bouton 
' retour sera sélectionné

'Seulement la fonction ClavierEchap est appelée un grand nombre de fois si l'on 
'considère qu'il y a environ 60Fps donc appelé 60 fois par seconde, se qui veux 
' dire qu’en un seul appui nous aurons EchapState qui sera égal à 3, donc 
' on ne verra pas le bouton du milieu.

'Pour arranger cela on va créé un système de timer
'Comme sa il faudra qu'un certain temps s’est écoulé pour que le bouton suivant 
'puisse être activé.

' Donc vous ajoutez :

Public TimerFirst As Long 
Public TimerSecond As Long
Public TimerSecondState As Long

' Pour pouvoir faire un système de timer il faut 2 relever de temps TimerFirst et 
' TimerSecond, puis dans notre code il faudra le statut de TimerSecond.

'Avant :

If EchapState < 3 Then EchapState = EchapState + 1

vous ajoutez :

    TimerSecondState = 0
' 0 se qui veux dire (dans l'exemple) que le deuxième ' timer n'a pas eu de relevé dans le temps donc qu'il va falloir en faire un

TimerFirst = DX.TickCount
'Dx.TickCount relève le temps passé sur le système en ms

'Ensuite vous ajoutez à la fin de la fonction aprés le end if

If TimerSecondState = 0 Then
' Si il faut faire un relevé (après un appui sur la fléche du bas)
    TimerSecond = DX.TickCount
' on fait un relevé
    TimerSecondState = 1
' on dit que le relevé a eu lieu pour pas qu'il soit refait
End If

'Maintenant il ne reste plus qu'as finir le code à l'intérieur du if

If TimerFirst - TimerSecond > 100 Then
'Donc si le temps entre le relevé de TimerFirst et le relevé de TimerSecond est 
' supérieurs à 100 
        If EchapState = 1 Then
            nbrRetour = 2
        End If
    End If
    If TimerFirst - TimerSecond > 100 Then
        If EchapState = 2 Then
            nbrRetour = 1
' Le bouton Retour n'est plus sélectionné, par contre le bouton Option l'est.
            nbrOption = 2
        End If
    End If
    If TimerFirst - TimerSecond > 100 Then
        If EchapState = 3 Then
            nbrOption = 1
 Le bouton Option n'est plus sélectionné, par contre le bouton Quitter l'est.
            nbrQuitter = 2
        End If
   End If

'Nous avons fait le système pour descendre dans les boutons de notre menu, 
'maintenant il faut remonter, le système est le meme :

If (DIstate.Key(DIK_UP) And &H80) Then
    TimerSecondState = 0
' On dit qu'il faut faire un relevé sur TimerSecond
    TimerFirst = DX.TickCount
' On fait un relevé sur TimerFirst
    
    If EchapState > 0 Then EchapState = EchapState - 1
' On décremente EchapState seulement s’il est supérieur à 0 car le bouton -1 
' n'existe pas.
    
'Puis de même que pour Dik_Down
sauf que EchapState = 3 n'y est pas vu qu'il n'y a pas 4 boutons
    If TimerFirst - TimerSecond > 100 Then
        If EchapState = 1 Then
            nbrRetour = 2
            nbrOption = 1
        End If
    End If
    If TimerFirst - TimerSecond > 100 Then
        If EchapState = 2 Then
            nbrOption = 2
            nbrQuitter = 1
        End If
    End If
End If

'Maintenant nous allons rajouter une précision pour que le code fonctionne 
'parfaitement :

If nbrRetour = 2 Then EchapState = 1
If nbrOption = 2 Then EchapState = 2
If nbrQuitter = 2 Then EchapState = 3

'Comme ça, il n'y aura pas d'erreur d'incrémentation ou de decrementation

'Maintenant si on appuis sur Retour :
If (DIstate.Key(DIK_RETURN) And &H80) And EchapState = 1 Then
    EchapRunning = False
    Call StartGame
End If

'Le bouton Retour étant au state 1 il faut que les deux conditions soit réunis, state 1 et appuis sur Entrée

'Pour Quitter :
If (DIstate.Key(DIK_ESCAPE) And &H80) Then Call UnloadDD

'UnloadDD étant une sub qui ferme proprement le jeu.

Pour UnloadDD je vous la donne sa peut toujours vous servir :

Public Sub UnloadDD()
EchapRunning = False       ' On arrete la boucle du menu echap
ShowCursor (True)            ' Api qui permet de cacher le curseur de la souris
DD.RestoreDisplayMode     'On repace a l'écran normal
Set Primary = Nothing        ' La surface primaire est nul
Set Backbuffer = Nothing    ' Le buffer est nul
Set DD = Nothing               'dd est nul
Set DX = Nothing               'dx est nul
DIdevice.Unacquire            ' On libere l'acquisition du clavier
End                                  ' on quitte
End Sub

'Voila vous avez un menu qui marche et qui peut faire bonne impression, et 
'surtout il y a peut de code, moins de 150 lignes dans l'exemple.

Conclusion :


Alors pour petite précision j'avais trouver un système sur le site de c2i qui permet de faire un Key Down, mais après avoir testé la méthode, j'ai pu constater qu'elle fonctionner très mal, donc je créé cette méthode.

Donc, pour voir bien à quoi ressemble ce tuto regarder l'exemple, par contre il n'est pas commenté, je pense pas que s’est nessecaire, vus la taille du tuto ci-dessus.

Si vous voulez des commentaires n'hésité pas je le ferais.
Et si vous avez envie d'un tuto sur un point particulier de DirectX (attention pas 3d) dites le moi .....

Bon code

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
589
Date d'inscription
lundi 25 août 2003
Statut
Membre
Dernière intervention
18 juillet 2010
1
Je te remerci pour ton commentaire c'est sympa ...
Messages postés
34
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
17 mai 2007

salut ciberrrique,

Je voulais te félicité pour tous les tutos directx 7 que tu as fait. avant, jy comprenais rien a directx mais grace a tes tutos tres bien faits, jme débrouille.

Continue comme ca!

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.