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!