Probleme avec KeyboardPushed (trop rapide?) [Résolu]

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
ElwoOOod
Messages : 14
Inscription : lun. 28/juil./2014 13:15

Probleme avec KeyboardPushed (trop rapide?) [Résolu]

Message par ElwoOOod »

Bonjour à tous,
Ca fait un moment que je bidouille en pb, mais depuis peu, j'ai changé le mode d'affichage de mes petites applis.
Avant j'ouvrais un Canvas dans une fenetre et pour tester l'appui de touches pour activer un cheatcode par exemple, j'avais placé un eventtype dans mon code et ca marchait niquel:

Code : Tout sélectionner

Repeat
  Select WaitWindowEvent(5)
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
        If EventType() = #PB_EventType_KeyUp
          If key = #PB_Shortcut_W : If CheatCode=0:CheatCode+1:EndIf : EndIf
          If key = #PB_Shortcut_O : If CheatCode=2:CheatCode+1:EndIf : EndIf
          If key = #PB_Shortcut_O : If CheatCode=1:CheatCode+1:EndIf : EndIf ;inverse pour vraiment appuyer sur les 2 'O'
          If key = #PB_Shortcut_D : If CheatCode=3:CheatCode+1:EndIf : EndIf
          If key = #PB_Shortcut_Y : If CheatCode=4:CheatCode+1:EndIf : EndIf
          If CheatCode=5
            CheatON=#True:CheatCode=6 ;pour refaire la MaJ de l'icone de cheat
            If SoundON:PlaySound(#sndCheatActivated):EndIf
            CreateSoundIconsSprites():StartDrawing(CanvasOutput(#MainCanvas)):DrawAlphaImage(ImageID(#sprSoundIcons),10,10):StopDrawing()
          EndIf
        EndIf
  EndSelect
ForEver
Cela marchait tres bien. Pour pouvoir profiter des commandes DX, j'ai remplacé mon canvas par un OpenWidowedScreen, et pour gerer le clavier, je suis obligé de passer par ExamineKeyboard(), sauf que là, quand j'appuie sur la touche O, la variable CheatCode passe directement à 3.
Si je remplace les KeyboardPushed par KeyboardInput, l''effet est le même. Si je remplace par Keyboard Released, ca ne marche carrèment plus.

Code : Tout sélectionner

Repeat
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_W) : If CheatCode=0:CheatCode+1:EndIf : EndIf
  If KeyboardPushed(#PB_Key_O) : If CheatCode=2:CheatCode+1:EndIf : EndIf
  If KeyboardPushed(#PB_Key_O) : If CheatCode=1:CheatCode+1:EndIf : EndIf ;inverse pour vraiment appuyer sur les 2 'O'
  If KeyboardPushed(#PB_Key_D) : If CheatCode=3:CheatCode+1:EndIf : EndIf
  If KeyboardPushed(#PB_Key_Y) : If CheatCode=4:CheatCode+1:EndIf : EndIf
  If CheatCode=5
    CheatON=#True:CheatCode=6 ;pour refaire la MaJ de l'icone de cheat
    If SoundON:PlaySound(#sndCheatActivated):EndIf
    CreateSoundIconsSprites():StartDrawing(ScreenOutput()):DrawAlphaImage(ImageID(#sprSoundIcons),10,10):StopDrawing():FlipBuffers()
  EndIf
ForEver
je pense que la boucle forever se fait trop vite, mais pourquoi en Released ca marche pas dans ce cas ?
Dernière modification par ElwoOOod le sam. 09/nov./2019 14:29, modifié 1 fois.
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par Marc56 »

Ne suis pas spécialiste de ce type de programme, mais d'après la doc, après KeyboardPushed() il faut utiliser KeyboardReleased() sinon, cela signifie que ton utilisateur doit presser les 5 touches en même temps. Et il n'y a qu'une touche O :)

https://www.purebasic.com/french/docume ... ushed.html
Remarques
- Un nombre quelconque de touches peut être pressé simultanément.
- Si vous voulez tester si une touche spécifique a été appuyée puis relâchée, utiliser la commande KeyboardReleased().


(Coquille dans la doc: Si vous voulez ... Utilisez...)


PS. Pourquoi ne pas utiliser And ?

Code : Tout sélectionner

If KeyboardPushed(#PB_Key_W) : If CheatCode=0 : CheatCode + 1 : EndIf : EndIf
...
If KeyboardPushed(#PB_Key_W) And  CheatCode=0 : CheatCode + 1 : EndIf 
ElwoOOod
Messages : 14
Inscription : lun. 28/juil./2014 13:15

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par ElwoOOod »

merci pour ta reponse.
vue que j'utilise de If séparés, pas besoin d'aller voir l'etat released (au pire j'ai essayé mais l'effet reste le même). a noter que le code marche, c'est juste la touche O qui passe a 3 en une seule pression, alors qu'avant il fallait vraiment appuyer 2 fois sur la touche.

Avant le ExamineKeyboard() il y a

Code : Tout sélectionner

  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_Timer
        If EventTimer() = #MainTimer : DisplayTimedFX() : EndIf
      Case #PB_Event_CloseWindow ; Si fermeture de la fenêtre
          End
      Case #PB_Event_LeftClick
          If ScreenIdx=4: Intro_Mouse_LeftClick():TheGame() :EndIf
          If (ScreenIdx=1 Or ScreenIdx=2 Or ScreenIdx=3) : Intro_Mouse_LeftClick() : EndIf
    EndSelect
  Until Event = 0
si j'ajoute un wait(5) (routine d'attente que j'ai faite qui fait la même chose que Delay sans freezer mes animations en arriere plan) juste avant le 'Event=WindowEvent(), la gestion du clavier fonctionne mais les coordonnées de la souris lague.
si je pose le wait juste avant le 'ExamineKeyboard()', rien ne change.

ps : merci pour le And, c'est carrèment plus lisible, j'avais même pas vu ;) ;) ;)
Avatar de l’utilisateur
Naheulf
Messages : 191
Inscription : dim. 10/mars/2013 22:22
Localisation : France

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par Naheulf »

Ton code fonctionne bien à quelques détails près :
  • par défaut la fonction « ExamineKeyboard() » considère que le clavier est configuré en mode QWERTY. Il faut donc taper « ZOODY » pour activer le cheat. Tu peux changer ce mode de fonctionnement avec « KeyboardMode() ».
  • La détection du code est brute de décoffrage :
    • Elle fonctionne en boucle si toutes les touches utiles sont appuyées en même temps.
    • Elle trop sujette aux faux positifs : Si dans un chat je saisi les messages « Will t'est où ? », « Salut Farod ! » et « Vas-y... » hé ben ça active le cheat…
ElwoOOod a écrit :Avant le ExamineKeyboard() il y a

Code : Tout sélectionner

  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_Timer
        If EventTimer() = #MainTimer : DisplayTimedFX() : EndIf
      Case #PB_Event_CloseWindow ; Si fermeture de la fenêtre
          End
      Case #PB_Event_LeftClick
          If ScreenIdx=4: Intro_Mouse_LeftClick():TheGame() :EndIf
          If (ScreenIdx=1 Or ScreenIdx=2 Or ScreenIdx=3) : Intro_Mouse_LeftClick() : EndIf
    EndSelect
  Until Event = 0
Rassure-moi, tu n'as pas deux boucles "Repeat" séparées ?
ElwoOOod
Messages : 14
Inscription : lun. 28/juil./2014 13:15

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par ElwoOOod »

je mets la portion du code complète au cas où mais bien sur le 2e repeat est imbriqué dans le 1er (donc ca marhce ^^)

Code : Tout sélectionner

Repeat
  Repeat
      ;wait(5) ;keyboard ok mais coordonnées souris lag
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_Timer
        If EventTimer() = #MainTimer : DisplayTimedFX() : EndIf
      Case #PB_Event_CloseWindow ; Si fermeture de la fenêtre
          End
      Case #PB_Event_LeftClick
          If ScreenIdx=4: Intro_Mouse_LeftClick():TheGame() :EndIf
          If (ScreenIdx=1 Or ScreenIdx=2 Or ScreenIdx=3) : Intro_Mouse_LeftClick() : EndIf
    EndSelect
  Until Event = 0

  ExamineMouse()
  If LastMouseX <> WindowMouseX(#MainForm) Or LastMouseY <> WindowMouseY(#MainForm)
    LastMouseX=WindowMouseX(#MainForm)
    LastMouseY=WindowMouseY(#MainForm)
    If (ScreenIdx=1 Or ScreenIdx=2) : Intro_Mouse_Move() : EndIf
  EndIf

    ;wait(5) ;aucun effet
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Escape)
    If ScreenIdx <= 2 : End : EndIf
    If ScreenIdx >= 3
      ScreenIdx=0:ShowScreen_FadeOut(#True,#False,#False) ;:ShowScreen_FadeIn(#picIntro,#True,#True,#True):ScreenIdx=1
      ShowIntroScreen()
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_W) And CheatCode=0: CheatCode+1 :EndIf
  If KeyboardPushed(#PB_Key_O) And CheatCode=2: CheatCode+1 :EndIf
  If KeyboardPushed(#PB_Key_O) And CheatCode=1: CheatCode+1 :EndIf ;inverse pour vraiment appuyer sur les 2 'O'
  If KeyboardPushed(#PB_Key_D) And CheatCode=3: CheatCode+1 :EndIf
  If KeyboardPushed(#PB_Key_Y) And CheatCode=4: CheatCode+1 :EndIf
  If CheatCode=5
    CheatON=#True:CheatCode=6 ;pour refaire la MaJ de l'icone de cheat
    If SoundON:PlaySound(#sndCheatActivated):EndIf
    CreateSoundIconsSprites():StartDrawing(ScreenOutput()):DrawAlphaImage(ImageID(#sprSoundIcons),10,10):StopDrawing():FlipBuffers()
  EndIf

  ;>>> DEBUG
  StartDrawing(ScreenOutput())
    Box(10,880,500,16,#Black)
    FrontColor(RGB(255,255,255))
    DrawingFont(#fonteArial8)
    DrawText(10,880,"X= "+Str(MouseX())+" - Y= "+Str(MouseY()))
    DrawText(100,880,"wX= "+Str(WindowMouseX(#MainForm))+" - wY= "+Str(WindowMouseY(#MainForm)))
    DrawText(10,860,"CheatCode= "+Str(CheatCode))
  StopDrawing()
  FlipBuffers()
ForEver
A noter egalement qu'avant la boucle le clavier est bien initialisé en Azerty et le ReleaseMouse est en true (j'ai un probleme de lag du mouvement de la souris en false).
En fait tout fonctionne bien, sauf que pour activer le cheat il suffit de taper 'WODY' au clavier. Il n'y a que la prise en compte du double O qui pose probleme.
Dans ce programme c'est la seule interaction clavier c'est pour le cheat, et si la fenetre est inactive le programme n'intercepte pas le clavier
pour mon autre programme, j'ajouterais une sorte de timer pour etre sur que les lettres sont taper dans l'ordre.
ElwoOOod
Messages : 14
Inscription : lun. 28/juil./2014 13:15

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par ElwoOOod »

finalement je viens de trouver une solution de bon matin.
j'ajoute ca juste après le ExamineKeybaord():

If KeyboardReleased(#PB_Key_O): Key_O_Released=#True :EndIf

et je modifie ma condition

If KeyboardPushed(#PB_Key_O) And CheatCode=2 And Key_O_Released: CheatCode+1 :EndIf

et là ca marche, il faut bien appuyer 2 fois sur la touche O pour que ca marche...
;)
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par falsam »

Cette solution serait elle la bonne ?

Code : Tout sélectionner

EnableExplicit

Define Event, CheatCode

InitSprite() : InitKeyboard()

OpenWindow(0, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)

KeyboardMode(#PB_Keyboard_International)

;Render Game
Repeat   
  
  ; Event window
  Repeat
    Event = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
    EndSelect  
  Until Event=0
  
  ; Keyboard event
  If ExamineKeyboard()
    If KeyboardReleased(#PB_Key_W) And CheatCode=0: CheatCode+1 :EndIf
    
    If KeyboardReleased(#PB_Key_O)
      If CheatCode=1: CheatCode+1 
      ElseIf CheatCode=2: CheatCode+1
      EndIf
    EndIf  
    
    If KeyboardReleased(#PB_Key_D) And CheatCode=3: CheatCode+1 :EndIf
    
    If KeyboardReleased(#PB_Key_Y) And CheatCode=4: CheatCode+1 :EndIf
    
    If CheatCode=5
      CheatCode = 0  
    EndIf    
  EndIf   
  
  ClearScreen(RGB(184, 134, 11))
  StartDrawing(ScreenOutput())
  DrawText(10, 10, "CheatCode = " + Str(CheatCode), RGB(255, 255, 255), RGB(184, 134, 11))
  StopDrawing()
  
  FlipBuffers()  
Until KeyboardReleased(#PB_Key_Escape)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
ElwoOOod
Messages : 14
Inscription : lun. 28/juil./2014 13:15

Re: Probleme avec KeyboardPushed (trop rapide?)

Message par ElwoOOod »

c'est bizarre, parce que ton code marche mais de mon coté si je change mes KeyboardPushed par KeyboardReleased, ca ne marche pas.
quoiqu'il en soit, l'effet fonctionne correctement maintenant et merci pour vos reponses ;)
Répondre