OpenGLGadget et détection de touches/Combinaison de touches

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

OpenGLGadget et détection de touches/Combinaison de touches

Message par falsam »

Certains d'entres vous doivent se souvenir de ce sujet sur la gestion des évènements claviers avec le gadget OpenGLGadget.
viewtopic.php?p=203226#p203226

Le déplacement du sprite représenté par un carré jaune, était très lent.

J'ai crée une petite procédure qui permet de tester si une touche ou une combinaison de touche est pressé.

KeyPushed(OpenGLGadget.i, ToucheID.i, Modifiers.i=0)
KeyPushed() : Teste l'état enfoncé ou non d'une touche ou combinaison de touches du clavier.

Parametre :
OpenGLGadget Identifiant du gadget OpenGL
ToucheID Identifiant PureBasic de la touche à tester
Modifiers Identifiant(s) de combinaison de touche(s) avec Ctrl, ALt et Shift

Valeur de retour:
Renvoie une valeur non nulle ou zéro
■ Exemple pour tester la touche Escape.

Code : Tout sélectionner

 KeyPush(#OpenGLGadget, #PB_Shortcut_Escape)
■ Exemple pour tester Ctrl + A

Code : Tout sélectionner

KeyPush(#OpenGLGadget, #PB_Shortcut_A, #PB_OpenGL_Control)

:arrow: Qu'est ce que j'aimerai résoudre ?
1 - Je rencontre un souci: Une combinaison de touche avec la touche Alt ne fonctionne pas. Peut être que cela est du à Windows 11.
2 - Comment envoyer une combinaison de touches dans une seule variable.

Voici le code qui permet de diriger le sprite avec les flèches du clavier.
j'ai ajouté quatre façons clavier de quitter l'application.

-Touche Escape qui fonctionne
-Touches Ctrl + A qui fonctionne,
-Touche Shift + B qui fonctionne.
-Touches Alt + C qui ne fonctionne pas,

Si chez vous la combinaison de touche Alt + Q fonctionne, pourriez vous m'indiquer votre système d'exploitation ? Merci 👍😉

Code : Tout sélectionner

EnableExplicit

; Fenetre principale Viewport et couleur arriere plan 
Global Window, ww = 800, wh = 600

; Viewport (OpenGLgadget)
Global Viewport, vColor.f = RGB(107, 142, 35)

; Sprite  
Global sx.f = 100, sy.f =100, sw = 64, sh = 64, sColor = RGB(255, 215, 0)

; Stocke les touches ou combinaisons de touches actuellement pressées
Global NewMap KeysPressed.i() 

;Plan de l'application
Declare Start()
Declare KeyPushed(OpenGLGadget.i, ToucheID.i, Modifiers.i=0)
Declare KeyReleased(OpenGLGadget.i, ToucheID.i, Modifiers.i=0)

Declare GameEvent()
Declare GameRender()
Declare Exit()

Start()

Procedure Start()
  Window = OpenWindow(#PB_Any, 0, 0, ww, wh, "Test Opengl", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Fenetre Open GL
  Viewport = OpenGLGadget(#PB_Any, 0, 0, ww, wh, #PB_OpenGL_Keyboard)
  SetActiveGadget(Viewport)
  
  ; Modifier le contexte courant
  SetGadgetAttribute(Viewport, #PB_OpenGL_SetContext, #True)
  
  ; Couleur d'arrirer plan
  glClearColor_(Red(vColor)/255, Green(vColor)/255, Blue(vColor)/255, 1.0)
  
  ; Volume de visualisation 
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_();
  gluOrtho2D_(0, ww, wh, 0)
  
  ;Triggers  
  BindEvent(#PB_Event_CloseWindow, @Exit())
  
  ;Loop
  Repeat
    GameEvent()
    GameRender()
  Until WindowEvent() = #PB_Event_CloseWindow  
EndProcedure

; KeyPushed() : Teste l'état enfoncé ou non d'une touche ou combinaison de touches du clavier.
; 
; Parametre :
;     OpenGLGadget    Identifiant du gadget OpenGL
;     ToucheID        Identifiant PureBasic de la touche à tester
;     Modifiers       Identifiant(s) de combinaison de touche(s)  avec Ctrl, ALt et Shift
; 
; Valeur de retour:
;     Renvoie une valeur non nulle ou zéro
;
Procedure KeyPushed(OpenGLGadget.i, ToucheID.i, Modifiers.i=0)
  Protected TestKey.i, TestModifiers.i, Result.b
  
  ; Mémorisation de la touche clavier à tester
  TestKey = GetGadgetAttribute(OpenGLGadget, #PB_OpenGL_Key)
  
  ; La touche est elle combinée avec la touche Ctrl ou Shift ou ALt ?
  TestModifiers = GetGadgetAttribute(OpenGLGadget, #PB_OpenGL_Modifiers)
  
  If TestKey = ToucheID And TestModifiers = Modifiers 
    Select EventType()
      Case #PB_EventType_KeyDown
        If Not FindMapElement(KeysPressed(), Str(TestKey))
          KeysPressed(Str(TestKey)) = TestModifiers
        EndIf
        
      Case #PB_EventType_KeyUp
        If FindMapElement(KeysPressed(), Str(TestKey))
          DeleteMapElement(KeysPressed())
        EndIf        
    EndSelect  
  EndIf 
  
  ; Validation de la touche ou combinaison de touches préssée
  ForEach KeysPressed()
    If ToucheID = Val(MapKey(KeysPressed())) And TestModifiers = KeysPressed()
      Result = #True
      Break
    EndIf
  Next
  ProcedureReturn Result
  EndProcedure
  
  
  ; KeyReleased() : Teste l'état relaché ou non d'une touche ou combinaison de touches du clavier.
  ; 
  ; Parametre :
  ;     OpenGLGadget    Identifiant du gadget OpenGL
  ;     ToucheID        Identifiant PureBasic de la touche à tester
  ;     Modifiers       Identifiant(s) de combinaison de touche(s)  avec Ctrl, ALt et Shift
  ; 
  ; Valeur de retour:
  ;     Renvoie une valeur non nulle ou zéro
  ;
  
  Procedure KeyReleased(OpenGLGadget.i, ToucheID.i, Modifiers.i=0)
    Static PreviousTestKey.i, PreviousTestModifiers.i
    Protected TestKey.i, TestModifiers.i, Result.b
    
    ; Mémorisation de la touche clavier à tester
    TestKey = GetGadgetAttribute(OpenGLGadget, #PB_OpenGL_Key)
    
    ; La touche est elle combinée avec la touche Ctrl ou Shift ou ALt ?
    TestModifiers = GetGadgetAttribute(OpenGLGadget, #PB_OpenGL_Modifiers)
    
    If PreviousTestKey <> TestKey 
      PreviousTestKey = TestKey
    EndIf   
    
    If PreviousTestModifiers <> TestModifiers
      PreviousTestModifiers = TestModifiers
    EndIf   
    
    If PreviousTestKey = ToucheID And PreviousTestModifiers = Modifiers 
      Select EventType()
        Case #PB_EventType_KeyUp
          PreviousTestKey = -1
          PreviousTestModifiers = -1
          Result = #True
      EndSelect  
    EndIf 
    
    ProcedureReturn Result
  EndProcedure
  
  ; Evenements clavier de la scene
  ;- Les fleches pour déplacer le sprite
  ;- Escape, Ctrl-A, Shift-B et Alt-Q pour quiter l'application
  Procedure GameEvent()
    Protected Speed.f = 8
    
    ;-Déplacement du sprite
    If KeyPushed(Viewport, #PB_Shortcut_Left) And sx > Speed 
      sx - Speed
    EndIf
    
    If KeyPushed(Viewport, #PB_Shortcut_Right)  And sx + sw + Speed < ww
      sx + Speed
    EndIf
    
    If KeyPushed(Viewport, #PB_Shortcut_Up) And sy > Speed
      sy - Speed
    EndIf
    
    If KeyPushed(Viewport, #PB_Shortcut_Down) And sy + sh + speed < wh
      sy + Speed
    EndIf
    
    ;-Quitter l'application 
    If KeyReleased(Viewport, #PB_Shortcut_Escape)
      Exit() 
    EndIf    
    
    If KeyPushed(Viewport, #PB_Shortcut_A, #PB_OpenGL_Control)
      Exit() 
    EndIf  
    
    If KeyPushed(Viewport, #PB_Shortcut_B, #PB_OpenGL_Shift)
      Exit() 
    EndIf  
    
    If KeyPushed(Viewport, #PB_Shortcut_C, #PB_OpenGL_Alt)
      Exit() 
    EndIf      
    
    ; Test fonction KeyReleased() 
    If KeyReleased(Viewport, #PB_Shortcut_Space)
      Debug "Touche [Espace] relaché"
    EndIf      
    
    If KeyReleased(Viewport, #PB_Shortcut_Space, #PB_OpenGL_Control)
      Debug "Touches [Ctrl + Espace] relachés"
    EndIf      
    
    If KeyReleased(Viewport, #PB_Shortcut_Space, #PB_OpenGL_Control|#PB_OpenGL_Shift)
      Debug "Touches [Ctrl + Shift + Espace] relachés"
    EndIf      
    
  EndProcedure
  
  ; Rendu de la scene OpenGl
  Procedure GameRender()
    
    ; ClearScreen
    glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
    ; Affichage d'un carré
    glMatrixMode_(#GL_MODELVIEW)    ;Initialiser la matrice de transformation courante
    glPushMatrix_()                 
    
    glBegin_(#GL_POLYGON)           
    glColor3f_(Red(sColor)/255, Green(sColor)/255, Blue(sColor)/255)
    
    glVertex2i_(sx, sy)             ;Point haut gauche
    glVertex2i_(sx + sw, sy)        ;Point haut droit
    glVertex2i_(sx + sw, sy + sh)   ;Point bas droit
    glVertex2i_(sx, sy + sh)        ;Point bas gauche
    glEnd_()                        ;Fin du polygone
    
    glPopMatrix_();
    
    ; Flip buffer
    SetGadgetAttribute(Viewport, #PB_OpenGL_FlipBuffers, #True)  
  EndProcedure
  
  Procedure Exit()  
    End
  EndProcedure
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: OpenGLGadget et détection de touches/Combinaison de touches

Message par falsam »

Le code du premier message est modifié.

Ajout de la fonction KeyReleased() pour tester l'état relâché ou non d'une touche du clavier ou d'une combinaison de touches.

Exemples :

Code : Tout sélectionner

KeyReleased(#OpenGLGadget, #PB_Shortcut_Escape)

Code : Tout sélectionner

KeyReleased(#OpenGLGadget, #PB_Shortcut_Space, #PB_OpenGL_Control)

Code : Tout sélectionner

KeyReleased(#OpenGLGadget, #PB_Shortcut_Space, #PB_OpenGL_Control|#PB_OpenGL_Shift)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre