Help! Mouse control outside of canvas..
BlitzPlus Forums/BlitzPlus Programming/Help! Mouse control outside of canvas..
| ||
MOUSE CONTROL OUTSIDE OF CANVAS Please run the code below. When the mouse pointer exits the canvas, the rectangle doesn't follow the pointer anymore. This is because player\x# and player\y# gets its coordinates from MouseX(canvas)/MouseY(canvas). What I'm after, is when the pointer exits, for example, on the right side, the rectangle stops at the canvas' right edge, no matter how far the pointer goes beyond the canvas, but you'll still be able to control the Y axis, player\y#... I've just started messing with the GUI side of B+, and this problem's been bugging me since sunday! Anyone got the answer to this? Cheers :) winw=320:winh=240 Global window=CreateWindow( "test...",200,ClientHeight(Desktop() )/2-winh/2,winw,winh,Desktop(),3+32 ) Global canvas=CreateCanvas( 0,0,320,240,window ) SetGadgetLayout canvas,1,1,1,1;set canvas attributes to stretch SetGadgetShape window,ClientWidth( Desktop() )/2-400/2,ClientHeight( Desktop() )/2-480/2,400,480;resize canvas, 320x240 to 400x480 ActivateGadget canvas SetBuffer CanvasBuffer( canvas ) Type player1 Field x# Field y# End Type player.player1=New player1 player\x#=160 player\y#=180 MoveMouse 160,120,canvas ;---------------------------------------------------------------------------------------------------- While Not KeyHit( 1 ) Cls id=PeekEvent() If id<>0 Then If id=$803 Then Exit FlushEvents() EndIf Gosub updateplayer FlipCanvas canvas Wend End ;---------------------------------------------------------------------------------------------------- .updateplayer For player.player1=Each player1 player\x# = MouseX(canvas) player\y# = MouseY(canvas) Rect player\x#-8,player\y#-8,16,16 Next Return |
| ||
try inserting desktop() into it, never tried it, but might work |
| ||
MouseXY( desktop ) won't work, since I'm drawing to canvas, and I'd be getting the X/Y coordinates from the desktop. The canvas size is stretched to 400x480, and the desktop size might be 1024x768. Also take GadgetXY( window ) into account. |
| ||
uh, I think uh, just clip your mouse coord-values to the size of your canvas *when drawing* Anyway, I'd use EventX() and EventY() anyway.. |
| ||
Hmm what do you mean CS_TBL? Using MouseX/Y(desktop) and just drawing the player on the canvas at EventX, EventY when WaitEvent(0)=$203 occurs? The coordinates would be way off, since the desktop could be 800x600, 1024x768 or whatever, and the canvas is really 320x240 scaled to 400x480... Also, when outside of the canvas, how would I go about updating the X Y coords? Because I need to be able to, for example, update the player's Y coord if MouseX() isn't inside the canvas.. |
| ||
you will have to similuate mouse x and y when outside canvas area, best bet might be to use x,y coords that doesnt take into consideration of canvas, just mousex() and mousey() |
| ||
norki: Uhm, uh, is this what you want to establish? (hold down the mousebutton and drag the mouse in the canvas) |
| ||
CS_TBL: Yes, I've done something much the same as that, but it seems it can't be done without holding down the left mouse button.. :\ Nicoust: I've tried using MouseXY(desktop), but then I have to use GadgetXY(window) and that includes the window borders, which can vary in size.. |
| ||
ok, I give up :) |
| ||
Hey thanks for the effort CS_TBL, I appreciate it :) |
| ||
Here... http://www.blitzbasic.com/codearcs/codearcs.php?code=1290 |
| ||
Thanks BlitzSupport! Perfect! :D I kind of think I've solved this using the B+ commands, but this userlib seems more robust, so I'll use it. Though, is it safe to use this user32.dll hackery? Below I've posted my solution (doesn't use user32.dll).. hope it's useful to someone. If you make improvements, corrections etc. to the code, please email me. ;CANVAS X/Y by norki. ;The reason I made this is because when you use MouseX/Y(canvas) and the pointer ;leaves the canvas, you lose control of the player in a most horrible way, say if you ;move the mouse really fast to the right, the sprite's last X/Y position might be in the ;middle of the playfield, helpless, and you won't gain control until the pointer reenters ;the canvas. Therefore, I use MouseX/Y(desktop) and CanvasX/Y as an offset to where ;on the canvas to draw the player. ;Formula to find Canvas X and Y below.. ;CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2 ;CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2) ;I've tested this on WinXP and Win98SE using various border widths and resolutions. ;I don't know how it would fare against a desktop that uses skinning applications though.. ;Let me know if it craps on you.. ;Don't worry about seeing GadgetWidth() in the CanvasY calculation, it's only there ;because it's easier to use to find the border size, which is the same on all four sides. ;Of course, the titlebar height is added on the top side. ;NOTE: These calculations won't work if the window's got a status bar, if the window shape isn't ;set to be in client coordinates (32), and if the window is set to be a tool window. ;All other flags are working though. ;Also note that this example was made to work with a stretched canvas, but this can easily be changed. Const winw=320 ;Original game resolution width Const winh=240 ;Original game resolution height Const str_winw=400 ;Stretched width Const str_winh=480 ;Stretched height Global window=CreateWindow("Canvas X/Y by norki",ClientWidth(Desktop())/2-winw,ClientHeight(Desktop())/2-winh/2,winw,winh,Desktop(),3+32) Global canvas=CreateCanvas(0,0,winw,winh,window) SetGadgetLayout canvas,1,1,1,1;Set canvas attributes to stretch SetGadgetShape window,ClientWidth(Desktop())/2-str_winw/2,ClientHeight(Desktop())/2-str_winh/2,str_winw,str_winh; ActivateGadget canvas SetBuffer CanvasBuffer(canvas) Type player1 Field x# Field y# End Type player.player1=New player1 player\x#=winw/2 player\y#=winh/2 CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2 CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2) MoveMouse winw/2,winh/2,canvas ;---------------------------------------------------------------------------------------------------- While Not KeyHit(1) Select WaitEvent(0) Case $803;Window close Exit Case $801;Window move, update CanvasX and CanvasY CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2 CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2) Case $802;Window size, update CanvasX and CanvasY CanvasX=GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2 CanvasY=GadgetY(window)+(GadgetHeight(window)-GadgetHeight(canvas))-((GadgetWidth(window)-GadgetWidth(canvas))/2) End Select Cls Gosub updateplayer FlipCanvas canvas Wend ;Clean up and end For player.player1=Each player1:Delete player:Next FreeGadget canvas:FreeGadget window End ;---------------------------------------------------------------------------------------------------- .updateplayer For player.player1=Each player1 ;Correct the stretched coordinates, and make it the player's coords player\x#=((MouseX(Desktop)-CanvasX)/(Float(GadgetWidth(canvas))/Float(winw))) player\y#=((MouseY(Desktop)-CanvasY)/(Float(GadgetHeight(canvas))/Float(winh))) If player\x#<0 player\x#=0;Bounds checking If player\x#>winw-1 player\x#=winw-1 If player\y#<0 player\y#=0 If player\y#>winh-1 player\y#=winh-1 Color 255,0,255:Rect player\x#-3, player\y#-3,6,6 Color 255,255,255:Text 1,40,"PlayerX/Y in "+winw+"x"+winh+" coords:"+Int(player\x#)+","+Int(player\y#) Text 1,20,"CanvasX/Y relative to screen:"+(GadgetX(window)+(GadgetWidth(window)-GadgetWidth(canvas))/2)+","+(GadgetY(window)+((GadgetHeight(window)-GadgetHeight(canvas))/2)+(((GadgetHeight(window)-GadgetHeight(canvas))/2)/2)+(GadgetWidth(window)-GadgetWidth(canvas))/2) Text 1,30,"MouseX/Y relative to canvas:"+(MouseX(Desktop)-CanvasX)+","+(MouseY(Desktop)-CanvasY) Next Return |