Screen et Mouse "Bloquée"

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Screen et Mouse "Bloquée"

Message par blendman »

Salut

Lorsqu'on utilise le screen et examinemouse(), la souris est bloquée dans le screen (pas glup).

Du coup, pour éviter ça, on peut utiliser cette technique :

Code : Tout sélectionner

;{ init
If InitSprite() <> 0: EndIf
If InitKeyboard() <> 0: EndIf
If InitMouse() <> 0: EndIf
;}


flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget

If OpenWindow(0,0,0,800,600, "menu jeu", Flag) <> 0
    
    If OpenWindowedScreen(WindowID(0), 0,0,600,400,1,0,0) <> 0
        
        ScreenW = ScreenWidth()
        ScreenH = ScreenHeight() 
        WinW = WindowWidth(0)
        WinH = WindowHeight(0)
    EndIf
    ShowCursor_(1)
    
EndIf


Repeat
    
    Repeat        
        EventID  = WaitWindowEvent(1)        
        Select EventID                
            Case #PB_Event_CloseWindow 
                End                
        EndSelect        
    Until event = 0
    
    If ExamineKeyboard()
        If KeyboardPushed(#PB_Key_Escape)
            End
        EndIf
    EndIf
    
    ; en décommentant ces lignes, ça ne résoud pas le soucis
    ; screenW = WinW
    ; screenH = WinH
    
    If ExamineMouse()
        mx = MouseX()
        my = MouseY()
        
        If MouseButton(#PB_MouseButton_Left)
            clic = 1
        Else
           clic = 0 
        EndIf
        
        If InScreen = 1 
            If WindowMouseX(0)> ScreenW-2 Or WindowMouseX(0)<1 Or WindowMouseY(0)<1 Or WindowMouseY(0)>ScreenH-2
                ReleaseMouse(1)
                InScreen = 0
            EndIf
        EndIf
        
    EndIf
    
    If InScreen = 0 
        If WindowMouseX(0)>=1 And WindowMouseX(0)<=ScreenW-2 And WindowMouseY(0)>=1 And WindowMouseY(0)<=ScreenH-2
            InScreen = 1
            ReleaseMouse(0)
            MouseLocate(WindowMouseX(0),WindowMouseY(0))
        EndIf
    EndIf
    
    If StartDrawing(ScreenOutput())
        DrawText(0,0,"Allez au delà de 600 X 400 et la souris ne réagit plus")
        DrawText(0,20,Str(mx)+"/"+Str(my))
        DrawText(0,40,"Clic : "+Str(clic))
        StopDrawing()
    EndIf
        
    FlipBuffers()
    ClearScreen(RGB(200,200,200))

Until Quit = 1
Cependant, vous constaterez que ça crée un problème si l'écran n'est pas de la taille de la fenêtre et si on a activé l'auto(redimensionnement.

D'où ma question :
savez-vous comment on gère ça avec un écran plus petit que la fenêtre et l'auto-redimensionnement de l'écran ?

Merci :)
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Screen et Mouse "Bloquée"

Message par Mesa »

Je pense que c'est le même principe que les sprites.

On ne peut pas changer la taille du screen tant qu'il existe (en pb).
Les sprites et les screens sont des objets qui doivent avoir une relation particulière avec la mémoire de la carte graphique. On peut les zoomer ou les stretcher mais pas changer leur taille.

Il faut donc détruire puis reconstruire le screen (il y a du scintillement):

Code : Tout sélectionner

;{ init
If InitSprite() <> 0: EndIf
If InitKeyboard() <> 0: EndIf
If InitMouse() <> 0: EndIf
;}


flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget

If OpenWindow(0,0,0,800,600, "menu jeu", Flag) <> 0
  
  If OpenWindowedScreen(WindowID(0), 0,0,600,400,1,0,0) <> 0
    
    ScreenW = ScreenWidth()
    ScreenH = ScreenHeight() 
    WinW = WindowWidth(0)
    WinH = WindowHeight(0)
  EndIf
  ShowCursor_(1)
  
EndIf


Repeat
  
  Repeat        
    EventID  = WaitWindowEvent(1)        
    Select EventID                
      Case #PB_Event_CloseWindow 
        End
        
      Case #PB_Event_SizeWindow      
        ;récupérer tous les sprites en vue de les réafficher sur le nouveau screen
        ; puis
        WinW = WindowWidth(0)
        WinH = WindowHeight(0)
        
        ExamineMouse()
        mx=MouseX() 
        my= MouseY()
        
        CloseScreen()
        
        screenW = WinW
        screenH = WinH
        OpenWindowedScreen(WindowID(0), 0,0,screenW,screenH,1,0,0)
        MouseLocate(mx,my)
        
    EndSelect        
  Until event = 0
  
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      End
    EndIf
  EndIf
  
  ; en décommentant ces lignes, ça ne résoud pas le soucis
  ; screenW = WinW
  ; screenH = WinH
  
  If ExamineMouse()
    mx = MouseX()
    my = MouseY()
    
    If MouseButton(#PB_MouseButton_Left)
      clic = 1
    Else
      clic = 0 
    EndIf
    
    If InScreen = 1 
      If WindowMouseX(0)> ScreenW-2 Or WindowMouseX(0)<1 Or WindowMouseY(0)<1 Or WindowMouseY(0)>ScreenH-2
        ReleaseMouse(1)
        InScreen = 0
      EndIf
    EndIf
    
  EndIf
  
  If InScreen = 0 
    If WindowMouseX(0)>=1 And WindowMouseX(0)<=ScreenW-2 And WindowMouseY(0)>=1 And WindowMouseY(0)<=ScreenH-2
      InScreen = 1
      ReleaseMouse(0)
      MouseLocate(WindowMouseX(0),WindowMouseY(0))
    EndIf
  EndIf
  
  If StartDrawing(ScreenOutput())
    DrawText(0,0,"Allez au delà de 600 X 400 et la souris ne réagit plus")
    DrawText(0,20,Str(mx)+"/"+Str(my))
    DrawText(0,40,"Clic : "+Str(clic))
    StopDrawing()
  EndIf
  
  FlipBuffers()
  ClearScreen(RGB(200,200,200))
  
Until Quit = 1
M.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

Ton code ne résout pas le soucis ^^.
Je veux avoir une fenêtre dont la taille est différente de la taille de l'écran, là, tu recrées un écran de la taille de la fenêtre (je dois prévoir tous les cas de figure), donc ce n'est pas ce que je cherche à obtenir.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Screen et Mouse "Bloquée"

Message par Mesa »

J'avoue que je ne comprends pas bien.

Pourquoi utiliser l'auto-redimensionnement ?
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

Pourquoi utiliser l'auto-redimensionnement ?
Pour afficher un jeu dans une fenêtre plus grande que l'écran, en redimensionnant l'écran tout simplement. C'est utilisé dans énormément de jeux 2D, y compris de très nombreux jeux professionnels.

Comme je disais, je dois prévoir tous les cas de figure car je fais une lib pour la création de jeu vidéo.

Il arrive qu'on ait besoin/envie de créer un jeu avec des sprites assez petits (pixels arts ou autre), affichés dans un écran qui sera "auto-redimensionné" (zoomé) dans une fenêtre plus grande ensuite. C'est un peu le principe du plein écran, mais en mode fenêtré en quelque sorte ^^.
- tes sprites font 32*32 par exemple.
- tu prévois un écran de 640*480 par exemple. Tu as conçu tes level comme ça (il font 20x la taille de tes tiles en X).
- tu veux qu'en mode fenêtré ce ne soit pas minuscule, mais affiché dans une fenêtre plus grande, par exemple du 1024*768, ce qui "zoome" la taille de l'écran de jeu en 1.6X.

Résultat : tu as un jeu avec une taille de fenêtre de 1024*768, et tu as un gain de place car tes sprites sont plus petits que si tu avais prévu directement ton jeu pour du 1024*768 (tu gagnes 1.6 fois X le poids de tes sprites, ce n'est pas négligeable ;)).

Ce genre de chose est visible dans de très nombreux jeux, y compris des jeux professionnels (Dofus par exemple fonctionne de cette manière pour les sprites de décor, ainsi que trickster, Mixmaster, goonzu, etc..).
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

En fait, j'ai beaucoup testé et je pense que c'est un bug.
Lorsqu'on utilise le redimensionnementauto, la souris n'est pas capturée dans l'écran zoomé (comme cela devrait être le cas), mais dans l'ancienne taille avant ce redimensionnementauto, comme on le voit sur ce code :

Code : Tout sélectionner

;{ init
If InitSprite() <> 0 : EndIf
If InitKeyboard() <> 0 : EndIf
If InitMouse() <> 0 : EndIf
;}

flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
If OpenWindow(0,0,0,1200,800, "Game, screen Autoresized", Flag) <> 0   
    If OpenWindowedScreen(WindowID(0), 0,0,600,400,1,0,0) <> 0       
        ScreenW = ScreenWidth()
        ScreenH = ScreenHeight()
        WinW = WindowWidth(0)
        WinH = WindowHeight(0)
    EndIf
    ShowCursor_(1)
 EndIf

Repeat
   
    Repeat       
        EventID  = WaitWindowEvent(1)       
        Select EventID               
            Case #PB_Event_CloseWindow
                End               
        EndSelect       
    Until event = 0
   
    If ExamineKeyboard()
        If KeyboardPushed(#PB_Key_Escape)
            End
        EndIf
    EndIf
     
     RatioX = WindowMouseX(0) / (WinW/ScreenW)
     RatioY = WindowMouseY(0) / (WinH/ScreenH)
       
    If ExamineMouse()
        mx = MouseX()
        my = MouseY()
       
        If MouseButton(#PB_MouseButton_Left)
            clic = 1
        Else
           clic = 0
        EndIf
             
    EndIf
 
    If StartDrawing(ScreenOutput())
        u=0
        DrawText(0,0,"Try to go over "+Str(ScreenW)+" x "+Str(ScreenH)) : u+20
        DrawText(0,u,Str(mx)+"/"+Str(my)) : u+20
        ; DrawText(0,u,Str(RatioX)+"/"+Str(RatioY)) : u+20
        DrawText(0,u,Str(WindowMouseX(0))+"/"+Str(WindowMouseY(0))) : u+20
        DrawText(0,u,"Clic : "+Str(clic))
        StopDrawing()
    EndIf
       
    FlipBuffers()
    ClearScreen(RGB(200,200,200))

ForEver
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Screen et Mouse "Bloquée"

Message par Ar-S »

Je confirme que c'est bien étrange et que les 600 devraient s'afficher à droite du screen. Dans ce cas c'est le screen non zoomé qui est pris en compte (alors qu'il est zoomé).

P.S : Idem en 5.40 x86 beta10
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

Oui Spock, c'est super cool ;), mais hélas, ce n'est pas compatible avec Linux et Mac il me semble.

Et c'est vrai que c'est un bug qui existe depuis quand même très longtemps je pense ^^. Je pense que peu d'utilisateurs font du jeu avec purebasic (avec redimensionnement automatique), c'est pour ça que personne ne l'a vu avant ^^.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Screen et Mouse "Bloquée"

Message par Mesa »

Pour ceux que ça interesse, demivec sur le forum uk semble donner la solution.

http://www.purebasic.fr/english/viewtop ... =4&t=63719

Son code

Code : Tout sélectionner

;{ init
If InitSprite() <> 0 : EndIf
If InitKeyboard() <> 0 : EndIf
If InitMouse() <> 0 : EndIf
;}

flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
If OpenWindow(0,0,0,1200,800, "Game, screen Autoresized", Flag) <> 0   
		If OpenWindowedScreen(WindowID(0), 0,0,600,400,1,0,0) <> 0       
				ScreenW = ScreenWidth() 
				ScreenH = ScreenHeight()
				WinW = WindowWidth(0)
				WinH = WindowHeight(0)
			EndIf
			If CreateSprite(0, 10, 10) And StartDrawing(SpriteOutput(0)): Box(0,0, 10, 10, RGB(0,255,0)): StopDrawing(): EndIf ;<<< create screen mouse pointer
		ShowCursor_(1)
	EndIf

Repeat
		
		Repeat       
				EventID  = WaitWindowEvent(1)       
				Select EventID               
						Case #PB_Event_CloseWindow
								End               
				EndSelect       
		Until event = 0
		
		If ExamineKeyboard()
				If KeyboardPushed(#PB_Key_Escape)
						End
				EndIf
		EndIf
			
			RatioX = WindowMouseX(0) / (WinW/ScreenW)
			RatioY = WindowMouseY(0) / (WinH/ScreenH)
				
		If ExamineMouse()
				mx = MouseX()
				my = MouseY()
				
				DisplaySprite(0, mx, my)      ; <<< show screen mouse pointer
				If MouseButton(#PB_MouseButton_Left)
						clic = 1
				Else
						clic = 0
				EndIf
							
		EndIf
	
		If StartDrawing(ScreenOutput())
				u=0
				DrawText(0,0,"Try to go over "+Str(ScreenW)+" x "+Str(ScreenH)) : u+20
				DrawText(0,u,Str(mx)+"/"+Str(my)) : u+20
				; DrawText(0,u,Str(RatioX)+"/"+Str(RatioY)) : u+20
				DrawText(0,u,Str(WindowMouseX(0))+"/"+Str(WindowMouseY(0))) : u+20
				DrawText(0,u,"Clic : "+Str(clic))
				StopDrawing()
		EndIf
				
		FlipBuffers()
		ClearScreen(RGB(200,200,200))

ForEver
M.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

En fait, demivec ne poste pas vraiment de solution, il explique pourquoi ça ne marche pas comme convenu (en montrant que les coordonnées de la souris et de la windowmouse() sont différent avec un écran streched), c'est différent ^^.

J'ai ensuite posté un code qui permet à peu près d'avoir un code fonctionnel, mais c'est windows uniquement, ce qui n'est pas terrible pour le cross-platform.
Dans la doc, il est indiqué que le screen est cross-platform, mais à moins d'avoir un équivalent à SetCursorPos_() sous mac et linux, je ne vois pas comment faire pour que cette solution fonctionne (avec l'auto-redimensionnement).

Code : Tout sélectionner

;{ init
If InitSprite() <> 0 : EndIf
If InitKeyboard() <> 0 : EndIf
If InitMouse() <> 0 : EndIf
;}

flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
If OpenWindow(0,0,0,1200,800, "Game, screen Autoresized", Flag) <> 0   
    If OpenWindowedScreen(WindowID(0), 0,0,600,400,1,0,0) <> 0       
        ScreenW = ScreenWidth()
        ScreenH = ScreenHeight()
        WinW = WindowWidth(0)
        WinH = WindowHeight(0)
      EndIf
      If CreateSprite(0, 10, 10) And StartDrawing(SpriteOutput(0)): Box(0,0, 10, 10, RGB(0,255,0)): StopDrawing(): EndIf ;<<< create screen mouse pointer
    ;ShowCursor_(1)
 EndIf
 
Repeat
   
    Repeat       
        EventID  = WaitWindowEvent(1)       
        Select EventID               
            Case #PB_Event_SizeWindow
                ScreenW = ScreenWidth()
                ScreenH = ScreenHeight()
                WinW = WindowWidth(0)
                WinH = WindowHeight(0)
               
            Case #PB_Event_CloseWindow
                End               
        EndSelect       
    Until event = 0
   
    If ExamineKeyboard()
        If KeyboardPushed(#PB_Key_Escape)
            End
        EndIf
    EndIf
     
     RatioX = WindowMouseX(0) ;/ (WinW/ScreenW)
     RatioY = WindowMouseY(0) ;/ (WinH/ScreenH)
     
     If inscreen = 1
         If ExamineMouse()
             
             mx = MouseX()
             my = MouseY()
             
             If mx<=1 Or my<=1 Or mx>=screenW-2 Or my>=screenH-2
                 inscreen = 0
                 ReleaseMouse(1)
                 
                 If mx <=1
                     x = 0+WindowX(0)
                 ElseIf mx >=screenW-2
                     x = winW+2+WindowX(0)
                 Else
                     x = mx *(WinW/ScreenW)+WindowX(0)
                 EndIf
                 If my<=1
                     y = 0+WindowY(0)
                 ElseIf my>=screenH-2
                     y =winH+2+WindowY(0)                     
                 Else
                     y = my*(WinH/ScreenH)+WindowY(0)
                 EndIf                 
                 SetCursorPos_(mx *(WinW/ScreenW)+WindowX(0),my *(WinH/ScreenH)+WindowY(0)+25)
             EndIf
         EndIf
     Else
         If RatioX>1 And RatioX<winw-2 And RatioY>1 And RatioY<winh-2
             inscreen = 1
             ReleaseMouse(0)
             rx.d = WinW/ScreenW
             ry.d = WinH/ScreenH
             MouseLocate(RatioX/rx,RatioY/ry)
         EndIf         
     EndIf
     
     
     DisplaySprite(0, mx, my)      ; <<< show screen mouse pointer
     If MouseButton(#PB_MouseButton_Left)
         clic = 1
     Else
         clic = 0
     EndIf
     
   
 
    If StartDrawing(ScreenOutput())
        u=0
        DrawText(0,0,"Try to go over "+Str(ScreenW)+" x "+Str(ScreenH)) : u+20
        DrawText(0,u,Str(mx)+"/"+Str(my)) : u+20
        ; DrawText(0,u,Str(RatioX)+"/"+Str(RatioY)) : u+20
        DrawText(0,u,Str(WindowMouseX(0))+"/"+Str(WindowMouseY(0))) : u+20
        DrawText(0,u,"Clic : "+Str(clic))
        StopDrawing()
    EndIf
       
    FlipBuffers()
    ClearScreen(RGB(200,200,200))

ForEver
@Spock : le soucis avec ton exemple, c'est qu'on n'a plus aucune gestion de la souris et le container ne gère aucun event souris.
Mettre l'écran dans un canvas ne fonctionne pas sous linux (G-rom l'avait fait remarqué), et j'ai des doutes sous mac aussi. Alors, je pense que mettre un écran dans un container risque de ne pas fonctionner sous Linux et mac.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: Screen et Mouse "Bloquée"

Message par Mesa »

@spock, tu ne vois pas le carré vert ?
C'est le curseur de la souris dans le screen.
Les coordonnées affichées correspondent à la position du carré.
Donc "ça marche" en pure pb, sans rien faire de spécial, c'est le ShowCursor_(1) qui n'est pas une solution.

@blendman: En fait Damivec sous entend que l'utilisation des fonction de winapi comme ShowCursor_(1) ne peuvent pas être une solution à ton problème car le screen, sauf erreur, n'utilise pas ces apis là mais l'api DirectX. On ne s'en sortira pas en mélangeant des apis différentes, sauf à faire de la "tembouille" :)
A mon avis, il ne faut pas que tu t'écartes des fonctions des lib screen et mouse

L'exemple de la doc de la fonction release, fonctionne bien et sans api.
Je le remets dessous, ici

Code : Tout sélectionner

; Quelques variables
  MargeG = 20 
  MargeH = 20 
  LargeurEcran = 440 
  HauteurEcran = 440 

  ; Initialisation du monde 2D
  InitSprite()
  InitMouse() 
  
  ; Ouverture de la fenêtre et de l'écran
  OpenWindow(0,0,0,650,480,"Capture/Libération de la souris",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
  ButtonGadget(1,500,440,120,24,"Cliquez !") 
  OpenWindowedScreen(WindowID(0),20,20,LargeurEcran,HauteurEcran,0,0,0) 

  ; Gestion de la fenêtre et de l'écran
  Repeat
    
    Repeat ; Gestion de la fenêtre
      Event  = WindowEvent()  
      Select Event 
        Case #PB_Event_Gadget 
          If EventGadget() = 1     ; Si Clic sur le Bouton "Cliquez !"
            MessageRequester("Attention","Bouton cliqué !") 
          EndIf 
        Case #PB_Event_CloseWindow ; Si fermeture de la fenêtre
          End
      EndSelect
      
      ; Affichage de la position de la souris dans la fenêtre
      SetWindowTitle(0, "Capture/Libération de la souris X= " + Str(mx) + " Y= "+ Str(my))
    Until Event =  0 
    
    ; Gestion de la capture de la souris dans l'écran noir
      If inScreen = #True       ; Si la souris est dans l'écran noir...
        If MouseX() > LargeurEcran-2 Or MouseY() > HauteurEcran-2 Or MouseX() < 1 Or MouseY() <1 
              ReleaseMouse(#True)   ; ...et si elle s'approche des bords de l'écran alors on libère la souris
              inScreen = #False 
          EndIf  
      Else                      
        mx = WindowMouseX(0)      ; Sinon, si la souris entre dans l'écran noir...
        my = WindowMouseY(0)
        If mx < LargeurEcran + MargeG And mx > MargeG And my > MargeH And my < MargeH + HauteurEcran                         
          ReleaseMouse(#False)    ; ... alors on capture la souris 
            MouseLocate(mx-MargeG,my-MargeH) 
            inScreen = #True 
        EndIf 
    EndIf 
    
    ; Affichage de l'écran noir
    ClearScreen(0) 
    StartDrawing(ScreenOutput()) 
        DrawText(150,200,"Souris relachée") 
        DrawText(180,230,"X= ")
        DrawText(180,260,"Y= ")
    StopDrawing()  
    If inScreen  ; Si la souris est dans l'écran noir... 
        ExamineMouse() 
        StartDrawing(ScreenOutput())
        FrontColor(RGB(255,255,0))
        DrawText(150,200,"Souris capturée" ) 
        DrawText(180,230,"X= "+ Str(MouseX())) 
        DrawText(180,260,"Y= "+ Str(MouseY()))
        DrawText(MouseX(), MouseY(), "["+Chr(164)+"]")
        StopDrawing() 
    EndIf 
    FlipBuffers() 
 ForEver
M.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen et Mouse "Bloquée"

Message par blendman »

@mesa : oui, les exemples qui n'utilisent pas l'auto-redimensionnement du screen ne posent pas de soucis avec ... l'auto-redimensionnement, ça c'est certain :mrgreen:

Voici donc le même exemple avec l'auto-redimensionnement, et ça ne marche plus vraiment (essaye de sortir de l'écran pas le bas ou va vers la droite, tu verra sun sacré décalage avec la souris).

Code : Tout sélectionner

; Quelques variables
  MargeG = 20
  MargeH = 20
  LargeurEcran = 440
  HauteurEcran = 440

  ; Initialisation du monde 2D
  InitSprite()
  InitMouse()
 
  ; Ouverture de la fenêtre et de l'écran
  OpenWindow(0,0,0,650,480,"Capture/Libération de la souris",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  ButtonGadget(1,500,440,120,24,"Cliquez !")
  OpenWindowedScreen(WindowID(0),0,0,LargeurEcran,HauteurEcran,1,0,0)

  ; Gestion de la fenêtre et de l'écran
  Repeat
   
    Repeat ; Gestion de la fenêtre
      Event  = WindowEvent() 
      Select Event
        Case #PB_Event_Gadget
          If EventGadget() = 1     ; Si Clic sur le Bouton "Cliquez !"
            MessageRequester("Attention","Bouton cliqué !")
          EndIf
        Case #PB_Event_CloseWindow ; Si fermeture de la fenêtre
          End
      EndSelect
     
      ; Affichage de la position de la souris dans la fenêtre
      SetWindowTitle(0, "Capture/Libération de la souris X= " + Str(mx) + " Y= "+ Str(my))
    Until Event =  0
   
    ; Gestion de la capture de la souris dans l'écran noir
      If inScreen = #True       ; Si la souris est dans l'écran noir...
        If MouseX() > LargeurEcran-2 Or MouseY() > HauteurEcran-2 Or MouseX() < 1 Or MouseY() <1
              ReleaseMouse(#True)   ; ...et si elle s'approche des bords de l'écran alors on libère la souris
              inScreen = #False
          EndIf 
      Else                     
        mx = WindowMouseX(0)      ; Sinon, si la souris entre dans l'écran noir...
        my = WindowMouseY(0)
        If mx < LargeurEcran + MargeG And mx > MargeG And my > MargeH And my < MargeH + HauteurEcran                         
          ReleaseMouse(#False)    ; ... alors on capture la souris
            MouseLocate(mx-MargeG,my-MargeH)
            inScreen = #True
        EndIf
    EndIf
   
    ; Affichage de l'écran noir
    ClearScreen(0)
    StartDrawing(ScreenOutput())
        DrawText(150,200,"Souris relachée")
        DrawText(180,230,"X= ")
        DrawText(180,260,"Y= ")
    StopDrawing() 
    If inScreen  ; Si la souris est dans l'écran noir...
        ExamineMouse()
        StartDrawing(ScreenOutput())
        FrontColor(RGB(255,255,0))
        DrawText(150,200,"Souris capturée" )
        DrawText(180,230,"X= "+ Str(MouseX()))
        DrawText(180,260,"Y= "+ Str(MouseY()))
        DrawText(MouseX(), MouseY(), "["+Chr(164)+"]")
        StopDrawing()
    EndIf
    FlipBuffers()
ForEver
Donc, pour moi, ça ne marche pas complètement, seul le code que j'ai posté juste au dessus fonctionne à peu près (faute de mieux) avec un screen auto-redimensionné, mais on est obligé d'utiliser l'api setCursorPos_() lorsqu'on sort de l'écran pour positionner la souris, puisque la souris capturée dans le screen est décalée par rapport à windowmouseX(0).
En fait, il manque une fonction à purebasic, un LocateWindowMouse(x,y) (équivalent de SetCursorPos_(x,y), mais multiplateforme.) ou un truc du genre. Ou tout simplement, il ne faudrait plus que la souris soit capturée dans l'écran, ce serait plus simple. Je ne vois d'ailleurs pas l'intérêt qu'elle soit capturée dans l'écran.

Pour le moment, je vais être obligé d'utiliser setCursorPos_() avec windows et mouselocate() pour linux et macos (je fais une lib pour créer des jeux, donc j'aimerai que ce soit compatible).
Répondre