Page 1 of 1
point and click
Posted: Wed Dec 07, 2022 3:13 pm
by TheAutomator
how would you guys go about clicking on a non rectangular object in a 2D game?
let's say I want the mouse arrow to change only when I hover above a pixel of a partially transparant image..
2D array with pixel coordinates?
Getting the pixel color of a separate bitmap that's black and white? (no idea how to do that)
I have no clue :/
Re: point and click
Posted: Wed Dec 07, 2022 3:44 pm
by Bitblazer
I would create a simple bitmask where a clickable point is 1 and a nonclickable point is 0. It is simple and straight forward and can be used with minimal implementation overhead - so it is easy to implement and debug. The mask can be created by a complex calculation during creation of the data libraries of the game and stored along each of the animation images of an object. The memory overhead should be neglectable nowadays and that way it can handle even complex animation sequences pixel exact.
If you want to size optimze it later, add the creation routine of the mask into the data library handler and let the mask be created on the fly during loading, to save storage memory / download time

But that is likely overkill.
Re: point and click
Posted: Wed Dec 07, 2022 3:48 pm
by STARGĂ…TE
You are probably looking for:
SpritePixelCollision
Re: point and click
Posted: Wed Dec 07, 2022 4:07 pm
by Mijikai
PixelCollision
Example PureBasic:
Code: Select all
EnableExplicit
Procedure.i GenerateSprite(Radius.i,Color.i)
Protected sprite.i
sprite = CreateSprite(#PB_Any,Radius << 1,Radius << 1,#PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending);<- enable PixelCollision!
If sprite
If StartDrawing(SpriteOutput(sprite))
DrawingMode(#PB_2DDrawing_AllChannels)
Circle(Radius,Radius,Radius - 1,Color)
StopDrawing()
ProcedureReturn sprite
EndIf
FreeSprite(sprite)
EndIf
ProcedureReturn #Null
EndProcedure
Procedure.i Main()
Protected exit.i
Protected s1.i
Protected s2.i
Protected mx.i
Protected my.i
If InitSprite()
If OpenWindow(0,0,0,960,600,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
If OpenWindowedScreen(WindowID(0),0,0,960,600)
s1 = GenerateSprite(128,$FFAFFF97)
s2 = GenerateSprite(16,$FFFFFFFF)
SetFrameRate(60)
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
exit = #True
Case #PB_Event_None
Break
EndSelect
ForEver
mx = WindowMouseX(0)
my = WindowMouseY(0)
ClearScreen($0)
If SpritePixelCollision(s1,360,160,s2,mx - 16,my - 16);<- check for collision
DisplayTransparentSprite(s1,360,160,255,$FF00FF)
Else
DisplayTransparentSprite(s1,360,160)
EndIf
DisplayTransparentSprite(s2,mx - 16,my - 16)
FlipBuffers()
Until exit
CloseScreen()
EndIf
CloseWindow(0)
EndIf
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
Example RPix (
viewtopic.php?t=80083):
Code: Select all
EnableExplicit
XIncludeFile "rpix.pbi";alpha 11
Procedure.i Main()
Protected *rpix.RPIX
Protected *s1.RPIX_SURFACE
Protected *s2.RPIX_SURFACE
Protected mx.i
Protected my.i
*rpix = rpixWindowOpen(#RPIX_WINDOW_NORMAL,960,600)
If *rpix
*rpix\PaletteSet(1,$FF97FFAF)
*rpix\PaletteSet(2,$FFFF00FF)
*rpix\PaletteSet(3,$FFFFFFFF)
*s1 = *rpix\SurfaceCreate(256,256)
*s2 = *rpix\SurfaceCreate(32,32)
*rpix\DrawCircle(*s1,128,128,128,-1,1)
*rpix\DrawCircle(*s2,16,16,16,-1,3)
Repeat
*rpix\InputUpdate()
*rpix\InputMousePosition(@mx,@my)
*rpix\BufferFill()
*s1\DrawTint(0,360,160,0,1 + *s2\Test(*s1,mx - 360,my - 160,0,1,1))
*s2\DrawMask(0,mx,my,0,1)
*rpix\BufferDrawEvent()
Until rpixWindowExit(*rpix)
rpixWindowClose(*rpix)
EndIf
ProcedureReturn #Null
EndProcedure
Main()
End
Re: point and click
Posted: Fri Dec 09, 2022 12:03 pm
by TheAutomator
Nice ideas! Thanks everyone :)
I'm gonna check those out this weekend!