Grafic: How to create puzzle tiles?
Posted: Tue Oct 11, 2016 2:06 pm
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
; Define
#X=800
#Y=600
Enumeration
#Image
#Tile
EndEnumeration
CreateImage(#Image,#X,#Y,32)
CreateImage(#Tile,#X,#Y,32)
StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_Gradient)
GradientColor(0.4,$00FFFF)
GradientColor(0.6,$FFFF00)
FrontColor($FF0000)
LinearGradient(0,0,#X,#Y)
Box(0,0,#X,#Y,$FFFFFF)
DrawingMode(#PB_2DDrawing_AlphaBlend)
For i=0 To #Y>>2
Circle(Random(#X),Random(#Y),Random(#X>>4),$80000000|Random(#White))
Next i
StopDrawing()
Structure SetType
TilesX.i
TilesY.i
SizeX.i
SizeY.i
HalfX.i
HalfY.i
Radius.i
Back.i
EndStructure
Global Set.SetType
; EndDefine
Procedure ClearBoard()
StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,ImageWidth(#Image),ImageHeight(#Image),0)
StopDrawing()
EndProcedure
Procedure ShowTile(x,y)
Protected color
#DrawDark= $80000000
#DrawOpaque= $FF000000
With Set
For i=0 To 1
If i=0
color=#DrawDark
\Radius+1
resize=1
StartDrawing(ImageOutput(#Tile))
Box(0,0,#X,#Y,#White)
DrawingMode(#PB_2DDrawing_AlphaBlend)
Else
color=#DrawOpaque
\Radius-1
resize=0
StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_AlphaChannel)
EndIf
Box(x*\SizeX-resize,y*\SizeY-resize,\SizeX+resize<<1,\SizeY+resize<<1,color)
If (x+y)&1
Circle(x*\SizeX+\HalfY,y*\SizeY-\Back,\Radius,color)
Circle(x*\SizeX-\Back,y*\SizeY+\HalfY,\Radius,color)
If x<\TilesX-1
Circle((x+1)*\SizeX+\Back,y*\SizeY+\HalfY,\Radius,color)
EndIf
If y<\TilesY-1
Circle(x*\SizeX+\HalfY,(y+1)*\SizeY+\Back,\Radius,color)
EndIf
Else
Circle(x*\SizeX-\Back,y*\SizeY+\HalfY,\Radius,color)
Circle(x*\SizeX+\HalfY,y*\SizeY-\Back,\Radius,color)
If x<\TilesX-1
Circle((x+1)*\SizeX+\Back,y*\SizeY+\HalfY,\Radius,color)
EndIf
If y<\TilesY-1
Circle(x*\SizeX+\HalfY,(y+1)*\SizeY+\Back,\Radius,color)
EndIf
EndIf
StopDrawing()
Next i
EndWith
EndProcedure
Procedure ShowBoard()
StartDrawing(ImageOutput(#Tile))
DrawAlphaImage(ImageID(#Image),0,0)
StopDrawing()
;CopyImage(#Image,#Tile)
SetGadgetState(0,ImageID(#Tile))
EndProcedure
Procedure PuzzleInit(Image,TilesX,TilesY)
Protected x,y
With Set
\TilesX=TilesX
\TilesY=TilesY
\SizeX=ImageWidth(Image)/\TilesX
\SizeY=ImageHeight(Image)/\TilesY
\HalfX=\SizeX>>1
\HalfY=\SizeY>>1
\Back=\HalfY/3
\Radius=\Back+5
EndWith
EndProcedure
OpenWindow(0,0,0,#X,#Y,"Image Demo",#PB_Window_SystemMenu|#PB_Window_TitleBar)
PuzzleInit(#Image,8,6)
ImageGadget(0,0,0,#X,#Y,ImageID(#Image))
AddWindowTimer(0,0,250)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
z+1
If z>10
ClearBoard()
ShowTile(Random(7),Random(5))
ShowBoard()
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Code: Select all
LoadImage(0, #PB_Compiler_Home + "Examples\Sources\Data\PureBasicLogo.bmp")
If OpenWindow(0, 0, 0, 800, 600, "Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 800, 600)
If StartVectorDrawing(CanvasVectorOutput(0))
; First move the origin of our coordinate system to somewhere in the middle of the canvas.
; You can use this to keep the code that defines the shapes independent from where the actual tile will be drawn.
TranslateCoordinates(100, 100)
; Create a path that defines the tile shape
MovePathCursor(0, 0)
AddPathLine(80, 0)
AddPathLine(80, 20)
AddPathCurve(120, 0, 120, 80, 80, 60)
AddPathLine(80, 80)
AddPathLine(60, 80)
AddPathCurve(80, 120, 0, 120, 20, 80)
AddPathLine(0, 80)
ClosePath()
; Move the origin of the "source" coordinate system. Basically, this moves the image we will use for drawing
; in relation to the path we just defined. This way the tile shows a part from the middle of the source image
; which is more interesting than the edge
TranslateCoordinates(-200, 0, #PB_Coordinate_Source)
; Select the image as the source for drawing operations
VectorSourceImage(ImageID(0), 255, ImageWidth(0) * 2, ImageHeight(0) * 2)
; 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($FF000000)
StrokePath(2)
StopVectorDrawing()
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Code: Select all
InitSprite()
; UsePNGImageDecoder()
; LoadImage(0, "C:\Temp\Puzzle_Vorlage.png")
CreateImage(0, 866, 579)
If StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_Gradient)
BackColor($00FFFF)
FrontColor($FF0000)
BoxedGradient(0, 0, OutputWidth(), OutputHeight())
Box(0, 0, OutputWidth(), OutputHeight())
StopDrawing()
EndIf
Procedure CreatePuzzleTile (Size, FillImgID, Pattern.i, SpriteID = #PB_Ignore)
Protected ImgID = CreateImage(#PB_Any, Size, Size, 32, #PB_Image_Transparent)
Protected peak.d = (Size * 15) / 100
Protected gap.d = (Size * 25) / 100
Protected length.d = 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, 255, 255))
StrokePath(2)
StopVectorDrawing()
EndIf
If SpriteID <> #PB_Ignore
CreateSprite(SpriteID, Size, Size, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(SpriteID))
DrawAlphaImage(ImageID(ImgID), 0, 0 )
StopDrawing()
EndIf
EndIf
FreeImage(ImgID)
ProcedureReturn peak
EndProcedure
If OpenWindow(0, 0, 0, 800, 600, "Example", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)
If StartDrawing(ScreenOutput())
Box(0, 0, OutputWidth(), OutputHeight(), RGB(100, 100, 100))
DrawAlphaImage(ImageID(0), 0, 0, 100)
StopDrawing()
EndIf
tilesize = 180
x = 0
y = 0
GrabImage(0, 3, x, y, tilesize, tilesize)
x = x + tilesize - 2 * CreatePuzzleTile (tilesize, 3, %00011000, 0)
GrabImage(0, 3, x, 0, tilesize, tilesize)
x = x + tilesize - 2 * CreatePuzzleTile (tilesize, 3, %01100100, 1)
GrabImage(0, 3, x, 0, tilesize, tilesize)
x = x + tilesize - 2 * CreatePuzzleTile (tilesize, 3, %10011000, 2)
GrabImage(0, 3, x, 0, tilesize, tilesize)
x = x + tilesize - 2 * CreatePuzzleTile (tilesize, 3, %01100000, 3)
DisplayTransparentSprite(0, 0, 0)
DisplayTransparentSprite(1, 190 - 2*offset, 0)
DisplayTransparentSprite(2, 380 - 2*offset, 0)
DisplayTransparentSprite(3, 580 - 2*offset, 0)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Code: Select all
If SpriteID <> #PB_Ignore
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
EndIf
Code: Select all
; Puzzle Creator
; 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
Code: Select all
; Define
#BoardMaxX=50
#BoardMaxY=40
#TileFill= 1
Enumeration
#SideTop
#SideLeft
#SideBottom
#SideRight
EndEnumeration
EnumerationBinary
#BorderTop
#BorderLeft
#BorderBottom
#BorderRight
EndEnumeration
Enumeration
#FlagHole
#FlagNose
#FlagLine
#FlagFilter
EndEnumeration
Structure Tile
x.i
y.i
type.i
fixed.i
EndStructure
Global Dim Curve.Point(#SideRight,1,18)
Global Dim Board.Tile(#BoardMaxX,#BoardMaxY)
; EndDefine
Procedure InitShapes()
Protected BirdsTail.s
Protected *Mem
Protected i,j,k
#BirdTailDots=9
#BirdSize=28
BirdsTail="@VDVETEREOANDLFKJMNN"; (c) 2016 by Michael Vogel
*Mem=@BirdsTail
For i=0 To #BirdTailDots
Curve(#SideBottom,#FlagNose,#BirdTailDots+i)\x=PeekB(*Mem)-'@'
Curve(#SideBottom,#FlagNose,#BirdTailDots-i)\x=-Curve(#SideBottom,#FlagNose,#BirdTailDots+i)\x
*Mem+1
Curve(#SideBottom,#FlagNose,#BirdTailDots+i)\y=PeekB(*Mem)-'@'
Curve(#SideBottom,#FlagNose,#BirdTailDots-i)\y=Curve(#SideBottom,#FlagNose,#BirdTailDots+i)\y
*Mem+1
Next i
For i=0 To #BirdTailDots<<1
Curve(#SideTop,#FlagNose,i)\x=-Curve(#SideBottom,#FlagNose,i)\x
Curve(#SideTop,#FlagNose,i)\y=-Curve(#SideBottom,#FlagNose,i)\y
Curve(#SideLeft,#FlagNose,i)\x=-Curve(#SideBottom,#FlagNose,i)\y
Curve(#SideLeft,#FlagNose,i)\y=Curve(#SideBottom,#FlagNose,i)\x
Curve(#SideRight,#FlagNose,i)\x=Curve(#SideBottom,#FlagNose,i)\y
Curve(#SideRight,#FlagNose,i)\y=-Curve(#SideBottom,#FlagNose,i)\x
Next i
For j=0 To #SideRight
For i=0 To #BirdTailDots<<1
k=(1-(j&1)<<1)
Curve(j,#FlagHole,i)\x=Curve(j,#FlagNose,i)\x*k+#BirdSize*(j-2)*(j&1)
Curve(j,#FlagHole,i)\y=-Curve(j,#FlagNose,i)\y*k+#BirdSize*(j-1)*(j&1)!1
Next i
Next j
EndProcedure
Procedure DrawSide(x,y,side,type)
Protected i,pos
If side=#SideTop
MovePathCursor(x+Curve(side,#Null,pos)\x,y+Curve(side,#Null,pos)\y)
EndIf
If type&#FlagLine
AddPathLine(x+Curve(side,#Null,#BirdTailDots<<1)\x,y+Curve(side,#Null,#BirdTailDots<<1)\y)
Else
pos=0
For i=0 To 5
AddPathCurve(x+Curve(side,type,pos+1)\x,y+Curve(side,type,pos+1)\y,x+Curve(side,type,pos+2)\x,y+Curve(side,type,pos+2)\y,x+Curve(side,type,pos+3)\x,y+Curve(side,type,pos+3)\y)
pos+3
Next i
EndIf
If side=#SideRight
ClosePath()
EndIf
EndProcedure
Procedure DrawTile(x,y,type)
If #TileFill
DrawSide(x,y,#SideTop, type>>0&#FlagFilter)
DrawSide(x,y,#SideLeft, type>>2&#FlagFilter)
DrawSide(x,y,#SideBottom,type>>4&#FlagFilter)
DrawSide(x,y,#SideRight, type>>6&#FlagFilter)
VectorSourceColor($ffC0C0C0|(Random(#White)))
FillPath()
StrokePath(0.1)
EndIf
DrawSide(x,y,#SideTop, type>>0&#FlagFilter)
DrawSide(x,y,#SideLeft, type>>2&#FlagFilter)
DrawSide(x,y,#SideBottom,type>>4&#FlagFilter)
DrawSide(x,y,#SideRight, type>>6&#FlagFilter)
VectorSourceColor($FF000000)
StrokePath(0.5,#PB_Path_RoundCorner)
EndProcedure
Procedure InitBoard(x,y,size,special)
Protected i,j,z
If x>#BoardMaxX Or y>#BoardMaxY
End
EndIf
For i=1 To x
For j=1 To y
With Board(i,j)
\x=i*size
\y=j*size
\type=%10001<<(((i+j)&1)<<1)
If j=1
\type|%10
EndIf
If i=1
\type|%1000
EndIf
If j=y
\type|%100000
EndIf
If i=x
\type|%10000000
EndIf
EndWith
Next j
Next i
z=x*y*special/100
While z
z-1
i=Random(x-1)
j=Random(y-1)
If Random(1)
Board(i,j)\type!%10000
Board(i,j+1)\type!%1
Else
Board(i,j)\type!%1000000
Board(i+1,j)\type!%100
EndIf
Wend
EndProcedure
#X= 8
#Y= 5
#Chi= 25; (0 to 100)
#Rho= 2
InitShapes()
InitBoard(#X,#Y,#BirdSize+#Rho,#Chi)
If OpenWindow(0,0,0,900,600,"Jigsaw tiles created by Michael Vogel", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0,0,0,900,600)
If StartVectorDrawing(CanvasVectorOutput(0))
ScaleCoordinates(3.6,3.6)
TranslateCoordinates(-10,-8)
For i=1 To #X
For j=1 To #Y
With Board(i,j)
DrawTile(\x,\y,\type)
If i>1 And j>1 And i<#X And j<#y And \type<>%10001 And \type<>%1000100
VectorSourceColor($FF0000FF)
AddPathCircle(\x,\y,3)
FillPath()
StrokePath(0.1); mark special tile
EndIf
EndWith
Next j
Next i
StopVectorDrawing()
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf