So im wanting to write my own custom buttons for my game, but im not certain the best way to detect when one is pressed. Is there are info out there about the different methods, i need to be able to have oddly shaped buttons, like be able to have a .png image that only triggers when i click a non-alpha part.
programming buttons
BlitzMax Forums/BlitzMax Programming/programming buttons Probably not the most efficient way to do it, but this works:
Graphics 640, 480, 0 ,0 TButton.Create("button.png", 100, 100, clicky) While Not KeyDown(KEY_ESCAPE) Cls TButton.UpdateAll() TButton.DrawAll() Flip Wend End Function clicky() Print "clicked "+MouseX()+" : "+MouseY() End Function Type TButton Field image:TImage Field X:Float Field Y:Float Global list:TList Field onClick() Field _mouseOver:Int = False Field _pixmap:TPixmap Method Draw() DrawImage(image, X, Y) End Method Method Update() If ( MouseX() >= X And MouseX() <= X + image.width ) Then If ( MouseY() >= Y And MouseY() <= Y+image.height ) Then _mouseOver = True Else _mouseOver = False EndIf Else _mouseOver = False EndIf If ( MouseHit(1) ) Then If (_mouseOver) Then If HitTest(MouseX()-X, MouseY()-Y) Then If (onClick <> Null) Then onClick() EndIf EndIf EndIf FlushMouse() EndIf End Method Method HitTest:Int(hitX:Float, hitY:Float) Local pix:Int = ReadPixel(_pixmap, hitX, hitY) If pix & $FF000000 Then Return True End Method Function DrawAll() For Local button:TButton = EachIn TButton.list button.Draw() Next End Function Function UpdateAll() For Local button:TButton = EachIn TButton.list button.Update() Next End Function Function Create:TButton(imagePath:String, X:Float, Y:Float, clickHandler()) Local temp:TButton = New TButton If (TButton.list = Null) Then TButton.list = New TList temp.image = LoadImage(imagePath) If (temp.image = Null) Then RuntimeError("Unable to load image "+imagePath) End EndIf temp._pixmap = LoadPixmap(imagePath) temp.X = X temp.Y = Y temp.onClick = clickHandler TButton.list.addLast(temp) Return temp End Function End Type
Thanks man, i get whats going on there i thought there pretty much what i was thinking. but this line
I got some of this, but just so i understand could you explain how the hit test works?
Method HitTest:Int(hitX:Float, hitY:Float) Local pix:Int = ReadPixel(_pixmap, hitX, hitY) If pix & $FF000000 Then Return True End Method
I got some of this, but just so i understand could you explain how the hit test works?
the $FF000000 represents an AARRGGBB integer, the $FF portion being full opacity, doing a bitwise AND between it and the pixel we are checking will return a boolean true when the pixel has full opacity
Technically, that line could be changed to:
in fact a further optimisation could be:
And if further optimised could be something like:
I'm not sure I'm explaining it as well as I could, my brain understands it better than I do.
Technically, that line could be changed to:
Return pix & $FF000000
in fact a further optimisation could be:
Method HitTest:Int(hitX:Float, hitY:Float) Return ReadPixel(_pixmap, hitX, hitY) & $FF000000 End Method
And if further optimised could be something like:
If ReadPixel(_pixmap, MouseX()-X, MouseY()-Y) & $FF000000 Then If (onClick <> Null) Then onClick() EndIf EndIf
I'm not sure I'm explaining it as well as I could, my brain understands it better than I do.
DING DING DING! i had no idea i could check for opacity :) hit the nail on the head there, thanks so much!