Sélection par positions de souris en mode turbo

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Sélection par positions de souris en mode turbo

Message par microdevweb »

Prenons l’exemple si dessous,déplacez la souris dans le coin supérieur gauche ensuite passé dans le coin inférieur droit et regardé la différence.

Le temps de réponse est plus long, c'est normal j'ai stocké les positions (plus de 10.000) dans une liste de gauche à droite et de haut en bas. Donc sur le coin supérieur gauche l'élément sera trouvé dans les première liste alors que sur le coin inférieur droit on sera sur +- le dernier élément.

Dans ce cas la différence à condition d'avoir un pc +- puissant est à peine perceptible, mais imaginer un jeu avec plusieurs tableaux.

Code : Tout sélectionner

Structure pos
  x.i
  y.i
EndStructure
Structure index 
  id.i
  nb.i
EndStructure
Structure Elem Extends pos
  name.s
EndStructure
Global NewList myElem.Elem()
Global Dim index.index(80,60)

Procedure CanvasEvent()
  Protected Xmouse,Ymouse,Time,TimeElapsed,Line,Column,N
  Select EventType()
    Case #PB_EventType_MouseMove
      Xmouse=GetGadgetAttribute(0,#PB_Canvas_MouseY)
      Ymouse=GetGadgetAttribute(0,#PB_Canvas_MouseY)
      Time=ElapsedMilliseconds()
      ; Recherche de l'index
      Line=Abs(Ymouse/10)
      Column=Abs(Xmouse/10)
      SelectElement(myElem(),index(Line,Column)\id)
      Nb+1
      While NextElement(myElem()) And N<=index(Line,Column)\nb
        With myElem()
          If Xmouse>=\x And Xmouse<=(\x+4)
            If Ymouse>=\Y And Ymouse<=(\Y+4)
              TimeElapsed=ElapsedMilliseconds()-Time
              Debug "Temp de recherche: "+Str(TimeElapsed)
              Break
            EndIf
          EndIf
        EndWith
        Nb+1
      Wend
  EndSelect
EndProcedure
Procedure OpenForm()
  Protected x=2,y=2,Line,Column
  OpenWindow(0,0,0,800,600,"Teste",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CanvasGadget(0,0,0,800,600)
  StartDrawing(CanvasOutput(0))
  While y+4<600
    x=2
    While x+4<800
      Box(x,y,4,4,$69230A)
      AddElement(myElem())
      With myElem()
        \x=x
        \y=y
        \name="Element"
      EndWith
      ; Ajoute l'index
      Line=Abs(y/10)
      Column=Abs(x/10)
      If index(Column,Line)\id=0
        index(Column,Line)\id=ListIndex(myElem())        
      EndIf
      index(Column,Line)\nb+1
      x+6
    Wend
    y+6
  Wend
  StopDrawing()
  BindGadgetEvent(0,@CanvasEvent())
EndProcedure

OpenForm()

Repeat:WaitWindowEvent():Until Event()=#PB_Event_CloseWindow
Existe t'il une solution ? Et bien oui on va indexé la liste mais pas n'importe comment.

On va diviser la zone à testé en plusieurs portions dans mon cas 10 portions sur les x et y
on créera pour cela une matrice (tableau) de dans mon cas 80 colonnes sur 60 lignes.

Ensuite quand j'ajoute un élément je calcul sa position en lignes et colonne

Code : Tout sélectionner

Line=Abs(y/10)
Column=Abs(x/10)
Ensuite je vérifie s'il l'index de la liste est déjà renseigné dans la matrice, sinon j'ajoute l'index de la liste

Code : Tout sélectionner

If index(Column,Line)\nb=0
     index(Column,Line)\id=ListIndex(myElem())        
EndIf
J'ajoute après un élément au nombre de liste de la zone

A la recherche je calcul la positon de la souris en ligne et colonne et sélection directement l'élément, je parcours ensuite la liste tant que je ne dépasse pas le nombre d'élément de la liste

Code : Tout sélectionner

; Recherche de l'index
      Line=Abs(Ymouse/10)
      Column=Abs(Xmouse/10)
      SelectElement(myElem(),index(Line,Column)\id)
      Nb+1
      While NextElement(myElem()) And N<=index(Line,Column)\nb
        With myElem()
          If Xmouse>=\x And Xmouse<=(\x+4)
            If Ymouse>=\Y And Ymouse<=(\Y+4)
              TimeElapsed=ElapsedMilliseconds()-Time
              Debug "Temp de recherche: "+Str(TimeElapsed)
              Break
            EndIf
          EndIf
        EndWith
        Nb+1
      Wend
Testez maintenant le code complet et vous ne constaré pratiquement aucune différence de rapidité quelque soit votre position sur le canvas

Code : Tout sélectionner

Structure pos
  x.i
  y.i
EndStructure
Structure index 
  id.i
  nb.i
EndStructure
Structure Elem Extends pos
  name.s
EndStructure
Global NewList myElem.Elem()
Global Dim index.index(80,60)

Procedure CanvasEvent()
  Protected Xmouse,Ymouse,Time,TimeElapsed,Line,Column,N
  Select EventType()
    Case #PB_EventType_MouseMove
      Xmouse=GetGadgetAttribute(0,#PB_Canvas_MouseX)
      Ymouse=GetGadgetAttribute(0,#PB_Canvas_MouseY)
      Time=ElapsedMilliseconds()
      ; Recherche de l'index
      Line=Abs(Ymouse/10)-1
      Column=Abs(Xmouse/10)-1
      SelectElement(myElem(),index(Column,Line)\id)
      Nb+1
      While NextElement(myElem()) And N<=index(Column,Line)\nb
        With myElem()
          If Xmouse>=\x And Xmouse<=(\x+4)
            If Ymouse>=\Y And Ymouse<=(\Y+4)
              TimeElapsed=ElapsedMilliseconds()-Time
              Debug "Temp de recherche: "+Str(TimeElapsed)
              Break
            EndIf
          EndIf
        EndWith
        Nb+1
      Wend
  EndSelect
EndProcedure
Procedure OpenForm()
  Protected x=2,y=2,Line,Column
  OpenWindow(0,0,0,800,600,"Teste",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CanvasGadget(0,0,0,800,600)
  StartDrawing(CanvasOutput(0))
  While y+4<600
    x=2
    While x+4<800
      Box(x,y,4,4,$69230A)
      AddElement(myElem())
      With myElem()
        \x=x
        \y=y
        \name="Element"
      EndWith
      ; Ajoute l'index
      Line=Abs(y/10)
      Column=Abs(x/10)
      If index(Column,Line)\nb=0
        index(Column,Line)\id=ListIndex(myElem())        
      EndIf
      index(Column,Line)\nb+1
      x+6
    Wend
    y+6
  Wend
  StopDrawing()
  BindGadgetEvent(0,@CanvasEvent())
EndProcedure

OpenForm()

Repeat:WaitWindowEvent():Until Event()=#PB_Event_CloseWindow

Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Sélection par positions de souris en mode turbo

Message par falsam »

Difficile de tester le code si la souris est en dehors de la fenetre avant de lancer l'application.
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%
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Sélection par positions de souris en mode turbo

Message par microdevweb »

falsam a écrit :Difficile de tester le code si la souris est en dehors de la fenetre avant de lancer l'application.
:?: Le chrono est calculé à l'événement MouseMove du canvas, Dans mon cas 6 milli-secondes de différences entre le coin supérieure gauche et inférieur droit .

Note: Je n’observe que le temps de parcours de la liste
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Sélection par positions de souris en mode turbo

Message par Zorro »

tu codes avec quelle version de Purebasic ??


beaucoup de tes codes contiennent

Code : Tout sélectionner

Until Event()=#PB_Event_CloseWindow
chez moi Version 5.50 ça plante sur "Event()" , qui n'est pas une fonction répertoriée

ps: suggestion , ajoutes un Cartouche (entete) dans tes codes , pour preciser, ta version de Pb et s'il faut des librairies ...

perso j'utilise souvent ce cartouche (bon....généré automatiquement par mon editeur, mais le principe reste )

Code : Tout sélectionner

;***********************************************
;Titre  :*addition_grand_nombre
;Auteur  : Zorro
;Date  :21/02/2017
;Heure  :20:33:24
;Version Purebasic :  PureBasic 5.50 (Windows - x86)
;Version de l'editeur :EPB V2.64
; Libairies necessaire : Aucune 
;***********************************************
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Sélection par positions de souris en mode turbo

Message par microdevweb »

@Zorro,

5.60, oui c'est vrai pour l'entête, mais je dois reconnaître que j'ai fait ce code un peut à l'arache
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Sélection par positions de souris en mode turbo

Message par Zorro »

microdevweb a écrit :5.60,

ha ... ceci explique cela :)
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Répondre