2D Puzzelteile erstellen

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

2D Puzzelteile erstellen

Beitrag von dige »

Das soll mal ein kleines Spiel werden. Wie kann man das Sprite unterhalb des Mauszeigers ermitteln?

Bild

Code: Alles auswählen

; Puzzelteile erstellen
; Dige 10/2016
; http://www.purebasic.fr/english/viewtopic.php?f=13&t=66746

InitSprite()
UsePNGImageDecoder()
UseJPEGImageDecoder()

Structure _PUZZLE
  id.i
  x.i
  y.i
  
  cr.i
  cx.i
  cy.i
EndStructure

Global NewList Puzzles._PUZZLE()

If LoadImage(0, "C:\Temp\Endurotraining-original-135.jpg") = 0
  CreateImage(0, 800, 600)
  If StartDrawing(ImageOutput(0))
    DrawingMode(#PB_2DDrawing_Gradient)      
    BackColor($00FFFF)
    FrontColor($FF0000)
    BoxedGradient(0, 0, OutputWidth(), OutputHeight())
    Box(0, 0, OutputWidth(), OutputHeight())
    StopDrawing()
  EndIf
Else
  ResizeImage(0, 800, 600)
EndIf

Procedure DrawPuzzle(bgr = 0)
  
  FlipBuffers()
  ClearScreen(RGB(0,0,0))
  
  If bgr
    If StartDrawing(ScreenOutput())
      Box(0, 0, OutputWidth(), OutputHeight(), RGB(100, 100, 100))
      DrawAlphaImage(ImageID(0), 0, 0, 100)
      StopDrawing()
    EndIf
  EndIf  
  
  ForEach Puzzles()
    With Puzzles()
      RotateSprite(\id, \cr, #PB_Absolute)
      DisplayTransparentSprite(\id, \cx, \cy)
    EndWith
  Next
  
EndProcedure

Procedure CreatePuzzleTile (Size, FillImgID, Pattern.i, SpriteID, x, y)
  
  Protected ImgID = CreateImage(#PB_Any, Size, Size, 32, #PB_Image_Transparent)
  Protected peak.i = (Size * 15) / 100
  Protected gap.i  = (Size * 25) / 100
  Protected length.i = Size - ( 2 * peak )
  
  ; 	       
  ; Pattern: 1-tongue|2-groove Bits from upper to right to bottom to left
  ; Edge Tile upper left = 00011000 (groove right, tongue bottom)
  
  
 If StartVectorDrawing(ImageVectorOutput(ImgID))
   
   ;TranslateCoordinates(peak, peak)
   
   MovePathCursor(peak, peak)
   
   ;{ Check upper side (Cursor Upper Left)
   If Pattern & %11 
     AddPathLine(peak + length/2 - gap/2, peak)
     
     If Pattern & %1 ; tongue
        AddPathCurve(0, 0, size, 0,  peak + length/2 + gap/2, peak)    ; Tongue
       Else
        AddPathCurve(0, 2*peak, size, 2*peak,  peak + length/2 + gap/2, peak)    ; Groove
      EndIf
   EndIf  
   AddPathLine(size-peak, peak)
   ;} 
   
   ;{ Check right side (Cursor Upper Right)
   If Pattern & %1100
     AddPathLine(size-peak, peak + length/2 - gap/2)
     
     If Pattern & %0100 ; tongue
        AddPathCurve(size, 0, size, size, size - peak, peak + length/2 + gap/2)    ; Tongue
       Else
        AddPathCurve(length, 0, length, size, size - peak, peak + length/2 + gap/2)    ; Groove
      EndIf
   EndIf  
   AddPathLine(size-peak, size-peak)
   ;}
   
   ;{ Check bottom side (Cursor bottom Right)
   If Pattern & %110000
     AddPathLine(peak + length/2 + gap/2, size - peak)
     
     If Pattern & %010000 ; tongue
        AddPathCurve(size, size, 0, size, peak + length/2 - gap/2, size - peak)    ; Tongue
       Else
        AddPathCurve(size, size - 2*peak, 0, size - 2*peak, peak + length/2 - gap/2, size - peak)    ; Tongue
      EndIf
   EndIf  
   AddPathLine(peak, size-peak)
   ;}
   
   
   ;{ Check left side (Cursor bottom left)
   If Pattern & %11000000
     AddPathLine(peak, peak + length/2 + gap/2)
     
     If Pattern & %01000000 ; tongue
        AddPathCurve(0, size, 0, 0, peak, peak + length/2 - gap/2)
       Else
        AddPathCurve(2*peak, size, 2*peak, 0, peak, peak + length/2 - gap/2) 
      EndIf
   EndIf  
   AddPathLine(peak, peak)
   ;}
   

   
   ClosePath()
   VectorSourceImage(ImageID(FillImgID), 255, ImageWidth(FillImgID), ImageHeight(FillImgID))
   
   ; Fill the tile shape with the image contents. keep the path
   FillPath(#PB_Path_Preserve)
 
   ; Select a solid color and draw the outline of the tile as well
   VectorSourceColor(RGBA(100, 100, 100, 255))   
   StrokePath(2)   
   StopVectorDrawing()
 EndIf
 
  
  CreateSprite(SpriteID, Size, Size, #PB_Sprite_AlphaBlending)
  If StartDrawing(SpriteOutput(SpriteID))
     DrawingMode(#PB_2DDrawing_AlphaChannel)
     Box(0,0,size,size,128)
     DrawingMode(#PB_2DDrawing_AlphaBlend)
     DrawAlphaImage(ImageID(ImgID), 0, 0 )
     StopDrawing()
   EndIf
   AddElement( Puzzles())
   With Puzzles()
     \id = SpriteID
     \x  = x
     \y  = y
     \cx = x
     \cy = y
     \cr = 0
   EndWith  
  
 FreeImage(ImgID) 
 
 ProcedureReturn length
EndProcedure

  w = 800
  h = 600


If OpenWindow(0, 0, 0, w, h, "Puzzle Game", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, w, h)
  
  tilesize = 180
  x = 0
  y = 0
  l = 0
  
  ; First Row
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %00011000, 0, 0, 0)
  x + l
  
  GrabImage(0, 3, x, 0, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100100, 1, 1*l, 0)
  x + l
  
  GrabImage(0, 3, x, 0, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011000, 2, 2*l, 0)
  x + l
  
  GrabImage(0, 3, x, 0, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100100, 3, 3*l, 0)
  x + l
  
  GrabImage(0, 3, x, 0, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011000, 4, 4*l, 0)
  x + l
  
  GrabImage(0, 3, x, 0, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100000, 5, 5*l, 0)
  
  ; Second Row
  x = 0
  y + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %00100110, 6, 0, l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011001, 7, 1*l, l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100110, 8, 2*l, l)
  x + l

  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011001, 9, 3*l, l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100110, 10, 4*l, l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10010001, 11, 5*l, l)
  
  ; Third Row
  x = 0
  y + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %00011001, 12, 0, 2*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100110, 13, 1*l, 2*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011001, 14, 2*l, 2*l)
  x + l

  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100110, 15, 3*l, 2*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10011001, 16, 4*l, 2*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01100010, 17, 5*l, 2*l)
  
 ; Last Row
  x = 0
  y + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %00000110, 18, 0, 3*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10001001, 19, 1*l, 3*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01000110, 20, 2*l, 3*l)
  x + l

  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10001001, 21, 3*l, 3*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %01000110, 22, 4*l, 3*l)
  x + l
  
  GrabImage(0, 3, x, y, tilesize, tilesize)
  l = CreatePuzzleTile (tilesize, 3, %10000001, 23, 5*l, 3*l)
  
  DrawPuzzle(1)
  
  Repeat
    Event = WaitWindowEvent()   
    
    If Event = #WM_KEYDOWN
      ForEach Puzzles()
        With Puzzles()
          Select Random(3)
            Case 0 : \cr = 0
            Case 1 : \cr = 90
            Case 2 : \cr = 180
            Case 3 : \cr = 270
          EndSelect
          
          \cx = Random(w - tilesize)
          \cy = Random(h - tilesize)

        EndWith
      Next
      DrawPuzzle(0)
    EndIf
    
  Until Event = #PB_Event_CloseWindow 

EndIf
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Benutzeravatar
alter Mann
Beiträge: 201
Registriert: 29.08.2008 09:13
Wohnort: hinterm Mond

Re: 2D Puzzelteile erstellen

Beitrag von alter Mann »

- speichern der Reihenfolge, wie die Sprites gezeichnet wurden (als eine Art z-Buffer)
- Test, ob Mauszeiger innerhalb der Boundingbox des Sprites
- wenn ja, Pixel des Sprites bestimmen - wenn nicht transparent - Sprite gefunden
Win11 64Bit / PB 6.0
Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

Re: 2D Puzzelteile erstellen

Beitrag von dige »

"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Antworten