Page 1 of 1

Missing mouse selection

Posted: Sun Mar 03, 2024 1:38 am
by matty47
I have this partial code

Code: Select all

Function displayGrid()
	For x = 0 To 19
		For y = 0 To 9
			If playGrid[x][y] <>0
				DisplayBrush(playGrid[x][y],(x-1)*40+gapWidth,(y-1)*56+gapWidth)
			EndIf			
		Next
		If sel1.active<>0
			SetLineWidth(5)
			Box((gridX-1)*40+gapWidth,(gridY-1)*56+gapWidth,40,56,#RED)
		EndIf
	Next
EndFunction

Function chkMousePos()
	x=MouseX() /*Get the mouse coords*/ 
	y=MouseY()
	/*find the gri x and y for where the mouse is*/
	gridX = Round((x - gapWidth)/40 + 0.5)
	gridY = Round((y - gapHeight)/56 + 0.55)
	;DebugPrint("x: " .. gridX .. "  y: " .. gridY)
	If playGrid[gridX][gridY]<>0 
		If sel1.active = 0
			sel1.active = 1
		Else
			sel1.active = 0
		EndIf 
	EndIf
	
EndFunction





Repeat
	BeginDoubleBuffer()
	displayGrid()
	;Sleep(100)
	
	If IsLeftMouse() = True
		chkMousePos()	
	EndIf
	Flip()
	EndDoubleBuffer()
	
Forever
What I am finding is that mouse downs (clicks) are sometimes but not always missed. I tried inserting various times in the commented Sleep function with varied success. Is there a better way to not miss mouse clicks. I used the Double Buffer to reduce flickering.
The game has a grid of tiles 18 wide and 8 high and the play is to select two matching tiles - similar to Mahjong. At the moment I am just trying to get the interface working satisfactorily. On Windows 10 64 bit.Thanks for any help.

Re: Missing mouse selection

Posted: Sun Mar 03, 2024 11:20 am
by Flinx
You should not poll the mouse button because there may be parts of the program that take more time than the mouse button is pressed.
The appropriate way is the event library. Replace the If IsLeftMouse() part with an event initialization before entering the main loop. And you need a WaitEvent() or CheckEvent() in the main loop. WaitEvent is the better way, but then you need to move your displayGrid() calls into an interval function initialized by SetInterval(). Then your main loop contains only WaitEvent like in this (unchecked) example:

Code: Select all

Function p_Main()
	BeginDoubleBuffer()
	displayGrid()
	Flip()
	EndDoubleBuffer()
EndFunction

InstallEventHandler({OnMouseDown=chkMousePos})
SetInterval(1, p_Main, 50)
Repeat
	WaitEvent
Forever

Re: Missing mouse selection

Posted: Sun Mar 03, 2024 12:25 pm
by Bugala
Reason for missing mouseclicks could be that your machine is not fast enough.

To explain the point very simply.
When program executes, it basically goes:

Code: Select all

DisplayGrid()
IsLeftMouse()
DisplayGrid()
IsLeftMouse()
DisplayGrid()
IsLeftMouse()
...
Now this leftmouse is checked only when it is executing IsLeftMouse()

By other words, if rest of the stuff, in this case, DisplayGrid() execution takes long, then if you click your mouse and release it up before it ends executing DisplayGrid, it will miss the Click, because when it gets to IsLeftMouse(), Mouse would already be up and therefore it wouldn't react to it.

Instead of using IsLeftMouse, you could use InstallEventHandler to assign Event Handler for Mouse Button being pressed and put WaitEvent() to your program, this way it shouldn't miss a mouse click.

from manual:

Code: Select all

Function p_HandlerFunc(msg)
  Switch(msg.action)
  Case "ActiveWindow":
    DebugPrint("Window has become active again!")
  Case "InactiveWindow":
    DebugPrint("Window has become inactive!")
  Case "MoveWindow":
    DebugPrint("User has moved the window to", msg.x, msg.y)
  Case "OnKeyDown":
    If msg.key = "ESC" Then End
  EndSwitch
EndFunction

InstallEventHandler({ActiveWindow = p_HandlerFunc,
   InactiveWindow = p_HandlerFunc,
   MoveWindow = p_HandlerFunc,
   OnKeyDown = p_HandlerFunc})

Repeat
  WaitEvent
Forever

In your case:

Code: Select all

InstallEventHandler({OnMouseDown=Function() Debugprint("Mouse was put down") EndFunction})

Repeat
 WaitEvent
Forever
Here is example code on how to make a draggable box that you could perhaps use to move your mahjong pieces around:

Code: Select all

MP = {X=100, Y=100, W=100, H=100, MouseXOffSet=0, MouseYOffSet=0} /* MP = Mahjong Piece */


Function UpdateScreen()
	DrawStuff()
	CreateButtons()	
EndFunction

Function DrawStuff()
	Cls(#BLACK)
	SetFillStyle(#FILLCOLOR)
	Box(MP.X, MP.Y, MP.W, MP.H, #RED)
EndFunction

Function CreateButtons()
	DeleteButton(1)
	MakeButton(1, #SIMPLEBUTTON, MP.X, MP.Y, MP.W, MP.H, 
					{OnMouseDown =	Function()
						MP.MouseXOffset = MouseX() - MP.X
						MP.MouseYOffset = MouseY() - MP.Y
						MouseIntervalID = SetInterval(Nil, Function()
							Local EndInterval=False
							If IsLeftMouse() = False Then EndInterval = True
							If EndInterval = False
								MP.X = MouseX() - MP.MouseXOffset
								MP.Y = MouseY() - MP.MouseYOffset
								DrawStuff()
							Else
								ClearInterval(MouseIntervalID)
								UpdateScreen()
							EndIf 						
										   EndFunction, 10
									      )
							EndFunction
					})
									
		
EndFunction

MakeButton(1, #SIMPLEBUTTON, 2, 2, 2, 2, {OnMouseDown=Function() EndFunction}) /* This is here only because I am calling DeleteButton at beginning of CreateButtons function*/

UpdateScreen()

Repeat
	WaitEvent
Forever

Re: Missing mouse selection

Posted: Sun Mar 03, 2024 8:23 pm
by jPV
matty47 wrote: Sun Mar 03, 2024 1:38 am I have this partial code
Just a quick side-note, please use local variables in functions :) Here's a short explanation/example: https://www.hollywood-mal.com/docs/html ... bals_.html

Re: Missing mouse selection

Posted: Sun Mar 03, 2024 10:26 pm
by matty47
Thankyou for taking the time to post the detailed replies. I am off to try this.