News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Infinite Mouse Control

Started by kevin, January 13, 2005, 01:11:00 PM

Previous topic - Next topic

kevin

PlayBASIC Code: [Select]
; ===============================
; 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#









tomazmb

#1
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:

PlayBASIC Code: [Select]
; ===============================
; 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#



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

Have a nice day,

Tomaz
My computer specification:

AMD Athlon 64 2800+
MB ASUS K8V Socket 754 VIA K8T800
SB Audigy 2
3 GB RAM DDR 400 MHz PQI
AGP NVIDIA GeForce 7600GT 256 MB-Club 3D
Windows XP Pro SP2
DirectX 9.0c

Alex

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.

Alex

#3
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:
PlayBASIC Code: [Select]
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




AdeN

#4
Here is one way that I use...

PlayBASIC Code: [Select]
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



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!