Page 1 of 1

Little Puzzle Game - have fun

Posted: Thu Oct 13, 2016 3:55 pm
by dige
Image

Code: Select all

; by dige 10/2016

InitSprite()
InitMouse()

UsePNGImageDecoder()
UseJPEGImageDecoder()

Structure _PUZZLE
  id.i
  x.i
  y.i
  z.i
  
  cr.i
  cx.i
  cy.i
  
  status.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 Puzzle_Z_Order ()
  Protected n = 0
  
  SortStructuredList( Puzzles(), #PB_Sort_Ascending, OffsetOf(_PUZZLE\z), TypeOf(_PUZZLE\z))
  
  ForEach Puzzles()
    
    
    If Puzzles()\status = 1
      Puzzles()\z = 0
    Else
      n + 1
      Puzzles()\z = n
    EndIf
   
  Next
  
EndProcedure  

Procedure Puzzle_Solved()
  Protected result = 0
  Protected n = 0
  
  ForEach Puzzles()
    If Puzzles()\status = 1
      n + 1
    EndIf
  Next
  
  If n = ListSize(Puzzles())
    result = 1
  EndIf
  
  ProcedureReturn result
EndProcedure


Procedure Puzzle_Home()
  Protected result = 0
  
  If Puzzles()\cr = 0
    If Abs(Puzzles()\x - Puzzles()\cx) < 10 And Abs(Puzzles()\y - Puzzles()\cy) < 10
      Puzzles()\cx = Puzzles()\x
      Puzzles()\cy = Puzzles()\y
      result = 1
    EndIf
  EndIf
  
  ProcedureReturn result
EndProcedure

Procedure DrawPuzzle(bgr = 0)
  
  FlipBuffers()
  ClearScreen(RGB(42,42,42))
  
  If StartDrawing(ScreenOutput())
    If bgr
      DrawAlphaImage(ImageID(0), 0, 0, 100)
    Else
      Box(25, 25, 760, 510, 0)
    EndIf
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText( 300, 560, "Little puzzle game by dige", #White )
    StopDrawing()
  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|#PB_Sprite_PixelCollision)
  If StartDrawing(SpriteOutput(SpriteID))
     DrawingMode(#PB_2DDrawing_AlphaChannel)
     Box(0,0,size,size,128)
     DrawingMode(#PB_2DDrawing_AlphaBlend)
     DrawAlphaImage(ImageID(ImgID), 0, 0 )
     DrawText(50, 50, Str(SpriteID))
     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 - Start with Space key", #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)
  
  
; Mouse Pointer
  CreateSprite(24, 16, 16, #PB_Sprite_PixelCollision|#PB_Sprite_AlphaBlending)
  If StartDrawing(SpriteOutput(24))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0,0,16,16,128)
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    
    Circle(8, 8, 7, RGBA(255, 255, 255, 255))
    Circle(8, 8, 6, RGBA(100, 100, 100, 255))
    StopDrawing()
  EndIf
  
  Puzzle_Z_Order ()
  move = #PB_Any
  
  Repeat
    
    Event = WaitWindowEvent(10) 
    
    If ExamineMouse()
      
      If MouseButton(#PB_MouseButton_Left) Or MouseButton(#PB_MouseButton_Right)
        
        If move = #PB_Any
          n = #PB_Any
          
          ; Find highest machting Sprite
          ForEach Puzzles()
            With Puzzles()
              If SpriteCollision(\id, \cx, \cy, 24, MouseX(), MouseY())
                If SpritePixelCollision(\id, \cx, \cy, 24, MouseX(), MouseY())
                  n = ListIndex(Puzzles())
                EndIf
              EndIf
            EndWith
          Next
          
          If n <> #PB_Any
            SelectElement(Puzzles(), n)
            
            If Puzzles()\status <> 1
              
              Puzzles()\z = 999
              
              If MouseButton(#PB_MouseButton_Right)
                b = Puzzles()\cr
                c = b + 90
                
                For a = b To c Step 10
                  SelectElement(Puzzles(), n)
                  Puzzles()\cr = a
                  DrawPuzzle(0)
                Next
                
                Puzzles()\cr = c
                
                If Puzzles()\cr > 270
                  Puzzles()\cr = 0
                EndIf
                
              Else
                move    = Puzzles()\id
                OffsetX = Puzzles()\cx - MouseX()
                OffsetY = Puzzles()\cy - MouseY()
                
              EndIf
              
              
              Puzzle_Z_Order()

              
            EndIf
          EndIf
          
        Else
          
          ; Still moving..
          ForEach Puzzles()
            If move = Puzzles()\id  
              Puzzles()\cx = MouseX() + OffsetX
              Puzzles()\cy = MouseY() + OffsetY
              
              Puzzle_Home()
              
              Break
            EndIf
          Next
        EndIf
        
      ElseIf move <> #PB_Any
        ; Moving finished
        ForEach Puzzles()
          If move = Puzzles()\id
            If Puzzle_Home()
              Puzzles()\status = 1
              Puzzles()\z      = 0
              
              Puzzle_Z_Order()
              Break
            EndIf
          EndIf
        Next
        
        move = #PB_Any
        OffsetX = 0
        OffsetY = 0
        
        If Puzzle_Solved()
          SetWindowTitle(0, "Start new game with Space Key")  
          MessageRequester( "Congratulations ! :-)", "Time: " + Str(Date() - duration) + " sec.")
        EndIf
        
      EndIf ; MouseButton(#PB_MouseButton_Left)
      
      DrawPuzzle(0)
      DisplayTransparentSprite(24, MouseX(), MouseY())

    EndIf  
    
    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)
          
          \status = 0

        EndWith
      Next
      DrawPuzzle(0)
      
      duration = Date()
      SetWindowTitle(0, "Game is running...")
    EndIf
    
  Until Event = #PB_Event_CloseWindow 

EndIf

Re: Little Puzzle Game - have fun

Posted: Fri Oct 14, 2016 2:42 pm
by Karellen
Nice! Thanks for sharing!