Page 1 sur 1

Sélection par positions de souris en mode turbo

Publié : jeu. 23/févr./2017 18:16
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


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

Publié : jeu. 23/févr./2017 23:48
par falsam
Difficile de tester le code si la souris est en dehors de la fenetre avant de lancer l'application.

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

Publié : ven. 24/févr./2017 5:46
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

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

Publié : ven. 24/févr./2017 9:04
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 
;***********************************************

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

Publié : ven. 24/févr./2017 18:41
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

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

Publié : ven. 24/févr./2017 18:49
par Zorro
microdevweb a écrit :5.60,

ha ... ceci explique cela :)