|
Post by transdiv on Mar 14, 2007 16:16:54 GMT -5
When running in windowed mode; The function Mouse.X and Mouse.Y keeps reading the mouse position even if it is outside of the program's window.
|
|
|
Post by Guilect on Mar 14, 2007 18:43:22 GMT -5
Is this a bug? Or is it expected windows behavior?
|
|
|
Post by transdiv on Mar 15, 2007 3:04:54 GMT -5
Is this a bug? Or is it expected windows behavior? Well, probably it doesn't qualify like a bug, but its different from at least 3 another game programming languages : Playbasic , Basic4GL and Fenix. I was converting a tiny rts in Fenix to Brutus2D and in that program you scroll the background locating the mouse pointer in the window's edges and the problem is when I get out the mouse pointer from the program's window, the scroll continues. If you have Basic4GL installed, you can try this little example : ' Load texture dim texture texture = LoadTexture ("data\star.bmp") ' Load texture and return handle ' Create sprite dim sprite sprite = NewSprite (texture) ' Create sprite, and assign texture SprSetPos (320, 240) WHILE True SprSetPos (Mouse_X()*640, Mouse_Y()*480) WEND (In Options yu must clear the full screen checkpoint)
|
|
|
Post by Guilect on Mar 15, 2007 6:21:06 GMT -5
I can change the mouse behavior.
I would just be concerned that in doing so it could break other people\'s current/existing code.
However, I would like to hear other\'s opinions as to how the mouse should behave in a windowed environment. Having the behavior either way has its advantages and disadvantages.
|
|
|
Post by u9 on Mar 15, 2007 6:44:44 GMT -5
As you say, both behaviors have advantages and disadvantages. I really really don't know what is better. But thinking about it, currently the x and y values are contained inside the window, which i must say I like... I am wondering if any weird behavior would appear like erratic movement if a game requires changes in the mouse but then one would use mouse dx and dy... I guess transdiv is right, it is a more normal behavior that mouse coordinates don't update when the mouse is outside the window. It is probably also the more "right" way to do it, I mean to the application, when you move the mouse to e.g. the left of the window x becomes 0 and the y was whatever. The coordinates after the mouse leaves the window the coordinates are just not true any more so maybe it is misleading to update them. However, it is probably a bad thing to change the behavior, although I don't think I have made any program that will be affected by this. Ehm... ok, it is fine by me if you change the behavior EDIT: Also the mouse buttons should not update if the mouse is outside the window. I can now see transdiv's (maybe) "frustration" as it was quite annoying sometimes having my game react even though i was in a completely different application. Actually mouse button events really should only be given to the application if the user actually presses the application window. But when doing this you should also maybe add a global mouse button state... or better yet instead of changing too much you could just add local event functions or something similar, i.e. xlocal, or localx and LocalLeftButton or something along those lines...
|
|
|
Post by Guilect on Mar 15, 2007 18:47:57 GMT -5
Hi transdiv,
I tried your example in Basic4GL. And I quickly saw why I don't like the way it works.
Yes the sprite follows the mouse arrow to the edge of the window IF you move the mouse slowly.
But, move the mouse quickly off of the window and the sprite gets placed at some unknown random spot.
This unknow spot is perhaps worse than having the mouse values continuing to be reported as is the current method in B2D.
Thoughts...
|
|
|
Post by transdiv on Mar 15, 2007 20:15:24 GMT -5
Ok, but the main problem there is like U9 said; That you are in a complete different application and the B2D application reacts like you are moving and clicking the mouse in his own window. To be honest it would be the first language I see to do that and definitly not the standart way windows program works.
|
|
|
Post by ptrxyz on Mar 22, 2007 16:29:28 GMT -5
Keep it as it is...if you want other behaviour, change it in your B2D code.
|
|
|
Post by transdiv on Mar 22, 2007 17:21:43 GMT -5
Keep it as it is...if you want other behaviour, change it in your B2D code. Hummm........ Do you know any method I can use to know when the Mouse Pointer is out of his own application window?
|
|
|
Post by Guilect on Mar 23, 2007 6:31:26 GMT -5
If mouse.x >= graphics.GetScreenWidth() then OutOfApp = True ElseIf mouse.y >= graphics.GetScreenHeight() then OutOfApp = True Else OutOfApp = False End If
|
|
|
Post by u9 on Mar 23, 2007 20:00:37 GMT -5
Mouse.x and mouse.y don't get values larger then the windows size. In fact this is a little bug. On a 640x480 window, mouse.x can range from 0 to 640 which is one pixel too much. The range should be 0-639. The same problem is with mouse.y. With this little bug fixed it is, as far as i know, not possible to see if the mouse is out side the window. I don't think it is a good idea to change behavior. It would be better with either new functions/properties that could be used to determine where the mouse is. One solution could be mouse.globalx/y along with graphics.getwindowx/y or maybe just a mouse.relativex which took on negative values and >window values. I don't really know what you should do guilect, but good luck
|
|
|
Post by Guilect on Mar 23, 2007 20:30:32 GMT -5
No bug. 640 is of out of screen indication.
Plan was to do something like:
(psuedo code) If mouse.x >= 640 then mouse.x = mouse.x -1
This would contain the mouse in the window.
Let me consider some alternatives. Maybe a property could be set like: mouse.capture true
|
|
|
Post by transdiv on Mar 23, 2007 21:45:14 GMT -5
If mouse.x >= graphics.GetScreenWidth() then OutOfApp = True ElseIf mouse.y >= graphics.GetScreenHeight() then OutOfApp = True Else OutOfApp = False End If Its Ok when Mouse goes off application's window at the Right and Bottom edges , but not the Top or Left; Maybe Mouse.X, Mouse.Y can return -1 if mouse pointer goes outside from those edges (Like the 640 above) Example :
option explicit
DIM bRunning DIM i DIM Font1 Call Main
SUB Main() IF (Graphics.Initialize(640,480,True) <> True) THEN exit sub graphics.setTitle "Mouse" key.initialize Mouse.initialize Font1 = graphics.CreateFont("system", 14) bRunning = True DO WHILE bRunning = True IF key.pressed(1) or key.pressed(0) = True THEN bRunning = False Call ClearKeyboard Exit Do END IF Graphics.Clear Call PrintMouse ' ------------------------------------------------ ' Print Screen graphics.display System. Pause 1 LOOP Key.terminate Graphics.terminate Mouse.Terminate end sub
SUB PrintMouse Mouse.Update graphics.SetText "X : " + CStr( Mouse.X ), 10,10,Font1,&HFFFFFFFF graphics.SetText "Y : " + CStr( Mouse.Y ), 10,30,Font1,&HFFFFFFFF IF MouseInApp = True THEN graphics.SetText "Mouse in Windows : True " ,10,50,Font1,&HFFFFFFFF ELSE graphics.SetText "Mouse in Windows : False " ,10,50,Font1,&HFFFFFFFF END IF END SUB
SUB ClearKeyboard ' Clear Keyboard buffer DO WHILE (Key.PressedAny ) System.Pause 1 LOOP end sub
FUNCTION MouseInApp Mouse.Update If mouse.x < 0 Or mouse.x >= graphics.GetScreenWidth() then MouseInApp = False ElseIf mouse.y >= graphics.GetScreenHeight() then MouseInApp = False Else MouseInApp = True End If END FUNCTION
[/pre]
|
|
|
Post by u9 on Mar 24, 2007 7:07:57 GMT -5
No bug. 640 is of out of screen indication. I meant that the bug is that either the mouse.x and y coordinates are maintained inside the window, or they should "run free." Since the coordinates cannot go below 0 one would believe that the mouse coordinates are contained inside window. But when the mouse can take a value of 640 which is outside the window (by 1 pixel) then the mouse is not completely contained inside the window. Let me consider some alternatives. Maybe a property could be set like: mouse.capture true You are a genius. At the top of my head, I'm thinking that mouse.capture property would solve everything while maintaining backward compatibility. But with the code below and also mouse.dx and dy being fixed i am really starting to think there is no need to do anything else to the mouse as the wanted behavior can be achieved in software. Btw, 1.71beta has again some error in the mapping of the coordinates. Try e.g mouse.setposxy 0, 480 on a window that is 480 high, and the mouse is positioned far from the edge of the screen. You could also try the below code and move the mouse slowly down to the border of the window in version 1.7 and 1.7.1b. While I am sitting here writing, and trying out my program, I just found the bug with the mouse-hiding issue. Mouse.hide and mouse.show seem to have a count of how many times they are called, also between runs from the IDE. I have seen this behavior before, but I'm not sure it is useful for anything. If you were able to remove this count, I think the issue would be completely resolved. I remember you mentioned you added a mouse.show when a program ended. That one is also contained in the count. This might not be a bug per se, but at least it is a bug that the count is maintained between runs. transdiv, here is an example of how you can do it. I figured that in games one usually changes the mouse pointer anyway, so i just grabbed the real mouse and simulate one when it is inside the window and "set it free" when it goes outside the window. Try the code below If you like it and want to use something like this I can simplify it a lot for you. Just let me know. Another solution, which is very simple actually is just using mouse.dx and mouse.dy to simulate mouse coordinates and you can in a similar way simulate the behavior you want. Mouse.dx and dy don't work in 1.7, but they are fixed in 1.7.1beta. Option explicit
Dim bRunning Dim i Dim Font
' Simulate mouse Dim mouse_x, mouse_y, mouse_in_window
Call Main
Sub Main() If (Graphics.Initialize(640,480,True) = False) Then Exit Sub font = graphics.CreateFont("system", 14) graphics.setTitle "Mouse Simulator" key.initialize ' Initialize mouse Mouse.initialize mouse_x = mouse.x mouse_y = mouse.y mouse_in_window = ( mouse_x>=0 And mouse_x<graphics.getscreenWidth() And mouse_y>=0 And mouse_y<graphics.getscreenHeight() ) ' Boolean algebra If mouse_in_window Then mouse.setposXY graphics.getscreenWidth()/2, graphics.getscreenHeight()/2 mouse.hide End If bRunning = True Do While bRunning = True If key.pressed(1) = True Or key.pressed(0) = True Then bRunning = False Call ClearKeyboard Exit Do End If Graphics.Clear doMouse PrintMouse graphics.setcircle mouse_x, mouse_y, 3, argb(255,55,155,255) graphics.display System. Pause 1 Loop ' Mouse work-around for mouse visibility bug in B2D v1.7 If Not mouse_in_window Then mouse.hide ' Clean up Mouse.Terminate Key.terminate Graphics.terminate End Sub
' Calculate change in mouse movement Sub doMouse Mouse.Update ' If mouse in window take control of mouse If mouse_in_window Then mouse_x = mouse_x + mouse.x - graphics.getscreenWidth()/2 mouse_y = mouse_y + mouse.y - graphics.getscreenHeight()/2 ' If mouse goes out side window then release it If mouse_x < 0 Or mouse_x >= graphics.getscreenWidth() Or mouse_y < 0 Or mouse_y >= graphics.getscreenHeight() Then mouse.setposXY mouse_x, mouse_y ' Keep simulated mouse inside the window mouse_x = min( max( mouse_x, 0), graphics.getscreenWidth()-1 ) mouse_y = min( max( mouse_y, 0), graphics.getscreenHeight()-1 ) ' Release real mouse mouse_in_window = False mouse.show ' Else keep control of mouse Else mouse.setposXY graphics.getscreenWidth()/2, graphics.getscreenHeight()/2 End If ' If mouse off screen Else ' Only change mouse state if it has moved back on window If mouse.x > 0 And mouse.x < graphics.getscreenWidth()-1 And mouse.y > 0 And mouse.y < graphics.getscreenHeight()-1 Then ' Set simulated mouse there where real mouse entered window mouse_x = mouse.x mouse_y = mouse.y ' Grab real mouse mouse.setposXY graphics.getscreenWidth()/2, graphics.getscreenHeight()/2 mouse_in_window = True mouse.hide End If End If End Sub
Sub PrintMouse graphics.SetText "Real x,y: " & CStr( Mouse.X ) & ", " & CStr( Mouse.Y ), 10,10,font,&HFFFFFFFF graphics.SetText "Simulation: " & mouse_x & ", " & mouse_y, 10,30,font,&HFFFFFFFF If mouse_in_window Then graphics.SetText "Mouse in Windows : True " ,10,50,font,&HFFFFFFFF Else graphics.SetText "Mouse in Windows : False " ,10,50,font,&HFFFFFFFF End If End Sub
Sub ClearKeyboard ' Clear Keyboard buffer Do While (Key.PressedAny ) System.Pause 1 Loop End Sub
|
|
|
Post by Guilect on Mar 24, 2007 8:26:00 GMT -5
This is occurring in windowed mode because of the titlebar. The co-ordinates are shifted the height of the titlebar. And depending on what skin or theme or settings a user has this can vary.
And we have had this discussion before. In windowed mode should the window be 640x480 or the non-titlebar and border area be 640x480. We had decided that the entire window should be 640x480. As it is now.
Maybe a note stating thta setmouse is a fullscreen only command is applicable.
|
|