UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on January 13, 2005, 01:11:00 PM

Title: Infinite Mouse Control
Post by: kevin on January 13, 2005, 01:11:00 PM
[pbcode]

; ===============================
; Custom Mouse Control
; ===============================
; This example gets over the issue of reading the mouse position in
; window mode. As you make have noticed, when teh mouse leaves the
; screen, this makes commands like MouseMoveX to return zero.  
;
;  The code basically Hides the windows mouse pointer, then uses
; a function to find the new position of an object controlled by
; the mouse.  So you pass it a pair of X & Y cords, and it returns
; The position after movement.  Thus movement is infinite
;
; ===============================




; hide the windows mouse
Mouse Off


; create a pointer like shape
createconvexshape 1,10,3
;rotateshape 1,280,1
shiftshape 1,5,5

; get the real mouses position and make it uor starting position
Mx#=mousex()
My#=mouseY()

; Start a Do-Loop
Do
; Clear the Screen
 Cls 0
   ; Display a message
 Print "Controlling an object with the mouse"
 
   ; Read the New position of our custom mouse pointer  
 mx#,my# = Mouse_Control_Object(mx#,my#)


; Click the position to within the bounds of the Window
 w=getScreenWidth()
 H=getScreenWidth()

 if mx#<0 then mx#=0
 if mx#>w-10 then mx#=w-10
 if my#<0 then my#=0
 if my#>(H-10) then my#=H-10
    

   ; Draw our shape as our custom Mouse POinter
 drawshape 1,mx#,my#,2
   

 SYnc   
loop







Psub Mouse_Control_Object(CurrentX#,CurrentY#)

 W=GetScreenWidth()
 H=GetScreenHeight()
    
 x1=GetScreenXpos()     
   Y1=GetScreenYpos()     
 x2=x1+w
 y2=y1+h     
   
 ` Let the user move the camera around a bit
 ` -----------------------------------------

; Read the Mouse Move Values
    MMX#=MouseMoveX()
    MMY#=MouseMoveY()
    
; Calc the actual X/Y positions in desktop space
    x#=x1+MouseX()     
    y#=y1+MouseY()     
    

; Limit the Real Windows Mouse Pointer inside the PB window
    flag=0      
    If x#=<(x1+75) Then x#=x1+(w/2): flag=1
    If x#=>(x2-75) Then x#=x1+(w/2): flag=1
    If y#=<(y1+75) Then y#=y1+(h/2): flag=1
    If y#=>(y2-75) Then y#=y1+(h/2): flag=1
    

    ; If the Windows mouse has been reposition, we have to
    ; reset the MouseMove values like so, so they don't register
    ; our reposition as a users movement     
    If flag=1
    SetMouse x#,y#
    Useless#=MouseMoveX()
    UseLess#=MouseMoveY()
    SetMouse x#,y#  
    EndIf
    
    ; Calc the New positions
    NewXpos#=CurrentX#+mmX#
    NewYpos#=CurrentY#+mmy#

; return them back to the user     
EndPsub NewXpos#,NEwYpos#




[/pbcode]


Title: Infinite Mouse Control
Post by: tomazmb on January 13, 2005, 01:39:32 PM
Hello Kevin,

Found a small bug in your code (I think  :rolleyes: ).  Look the line:


; Click the position to within the bounds of the Window
w=GetScreenWidth()
H=GetScreenHeight() ` HERE IS THE BUG !!!!!!!!!!!!!!!!!!!!!!!!

If mx#<0 Then mx#=0
If mx#>w-10 Then mx#=w-10
If my#<0 Then my#=0
If my#>(H-10) Then my#=H-10

or the code:

[pbcode]
; ===============================
; Custom Mouse Control
; ===============================
; This example gets over the issue of reading the mouse position in
; window mode. As you make have noticed, when teh mouse leaves the
; screen, this makes commands like MouseMoveX to return zero.  
;
;  The code basically Hides the windows mouse pointer, then uses
; a function to find the new position of an object controlled by
; the mouse.  So you pass it a pair of X & Y cords, and it returns
; The position after movement.  Thus movement is infinite
;
; ===============================




; hide the windows mouse
Mouse Off


; create a pointer like shape
CreateConvexShape 1,10,3
;rotateshape 1,280,1
ShiftShape 1,5,5

; get the real mouses position and make it uor starting position
Mx#=MouseX()
My#=MouseY()

; Start a Do-Loop
Do
; Clear the Screen
Cls 0
 ; Display a message
Print "Controlling an object with the mouse"

 ; Read the New position of our custom mouse pointer  
mx#,my# = Mouse_Control_Object(mx#,my#)


; Click the position to within the bounds of the Window
w=GetScreenWidth()
H=GetScreenHeight() ` HERE IS THE BUG !!!!!!!!!!!!!!!!!!!!!!!!

If mx#<0 Then mx#=0
If mx#>w-15 Then mx#=w-15 ` Changed from 10 to 15 to see more clearly !!
If my#<0 Then my#=0
If my#>(H-20) Then my#=H-20 ` Changed from 10 to 20 to see more clearly !!
 

 ; Draw our shape as our custom Mouse POinter
DrawShape 1,mx#,my#,2
 

Sync
Loop







Psub Mouse_Control_Object(CurrentX#,CurrentY#)

W=GetScreenWidth()
H=GetScreenHeight()
 
x1=GetScreenXpos()  
  Y1=GetScreenYpos()  
x2=x1+w
y2=y1+h  
 
` Let the user move the camera around a bit
` -----------------------------------------

; Read the Mouse Move Values
 MMX#=MouseMoveX()
 MMY#=MouseMoveY()
 
; Calc the actual X/Y positions in desktop space
 x#=x1+MouseX()  
 y#=y1+MouseY()  
 

; Limit the Real Windows Mouse Pointer inside the PB window
 flag=0      
 If x#=<(x1+75) Then x#=x1+(w/2): flag=1
 If x#=>(x2-75) Then x#=x1+(w/2): flag=1
 If y#=<(y1+75) Then y#=y1+(h/2): flag=1
 If y#=>(y2-75) Then y#=y1+(h/2): flag=1
 

 ; If the Windows mouse has been reposition, we have to
 ; reset the MouseMove values like so, so they don't register
 ; our reposition as a users movement  
 If flag=1
   SetMouse x#,y#
   Useless#=MouseMoveX()
   UseLess#=MouseMoveY()
   SetMouse x#,y#  
 EndIf
 
 ; Calc the New positions
 NewXpos#=CurrentX#+mmX#
 NewYpos#=CurrentY#+mmy#

; return them back to the user  
EndPsub NewXpos#,NEwYpos#
[/pbcode]

Am I correct Kevin ? And thank you for source code.

Have a nice day,

Tomaz
Title: Re: Infinite Mouse Control
Post by: Alex on January 02, 2008, 06:02:18 PM
this code doesnt work in latest version.. well it runs, but it doesn't do what it is suppose to do.
I've been trying to control an object based upon the mouse movement, but it always stops when the mouse goes off the window.
I was searching to see if there's any way to check if you mouse is off the window, but i haven't found anything yet since the mousex() etc only updates when your mouse is in the window area. so when the mouse is off the window, it just stays in the previous position.
Title: Re: Infinite Mouse Control
Post by: Alex on January 02, 2008, 07:16:17 PM
ok, did some experimenting, and managed to get something somewhat suitable in regards to moving an object with the mouse going out of the window:
[pbcode]
Function update_mcursor()
   Static flag
   Static counter
   fx = MouseMoveX()
   fy = MouseMoveY()
   If fx = 0 And fy = 0
      SetMouse GetScreenWidth()/2,GetScreenHeight()/2
      mmx = MouseMoveX()
      mmy = MouseMoveY()
      mmx = 0
      mmy = 0
      flag = 1

   Else
      mmx = fx
      mmy = fy
      If flag <> 1
         mcursor(0).x =mcursor(0).x+ mmx
         mcursor(0).y =mcursor(0).y+ mmy

      Else
         flag = 0
      EndIf   
   EndIf

   
   
   PositionSprite mcursor(0).image,mcursor(0).x,mcursor(0).y
EndFunction[/pbcode]


Title: Re: Infinite Mouse Control
Post by: AdeN on February 18, 2008, 06:06:42 PM
Here is one way that I use...

[pbcode]
LinkDll "user32.dll"
   GetWindowRect(hwnd, lpRect) alias "GetWindowRect" as integer
   GetCursorPos(pointMemBlock) alias "GetCursorPos" as integer
EndlinkDll

memBankId = GetFreeBank()
createbank memBankId, 100
memBankPtr = GetBankPTR(memBankId)

; this gets the cursor screen position (not the position within the game window)
GetCursorPos(memBankPtr)
mx = PeekInt(memBankPtr)
my = PeekInt(memBankPtr + 4)
   
; this gets the game window co-ordinates
hwnd = GetScreenHandle()
GetWindowRect(hwnd, memBankPtr)
wl = PeekBankInt(memBankId,  0) ; left
wt = PeekBankInt(memBankId,  4) ; top
wr = PeekBankInt(memBankId,  8) ; right
wb = PeekBankInt(memBankId, 12) ; bottom      

; now check if the mouse is within the game window
inWindow = 0
if mx >= wl
   if mx < wr
       if my >= wt
           if my < wb
              inWindow = 1
           endif
       endif
   endif
endif         

DeleteBank memBankId
[/pbcode]

inWindow is 0 if outside of the game window and 1 within. Obviously you wouldn't create and delete the memory block each time round the game loop but you would create it before the loop and delete it afterwards.

Only one gotcha... if the mouse is over the title bar it is still within the game window rectangle and therefore still counted as being in the game window... but this is good enough for my use as when the mouse leaves the window I just want to stop some animation that was based on the mouse position.

Hope that helps!