PureBasic modules step-by-step by example (triangles!)
Posted: Wed Oct 02, 2019 4:08 am
Analyzing issues with PureBasic and how to improve it
Lets start with something simple. We'll create a window and draw a triangle.
Great. But there is a problem. The points are hard-coded. And worse, we've had to type them twice (one for the end of one line and again for the start of another. So now if we want to move a point we have to analyze it closely. We can also forget moving the entire triangle around.
Great! Variables to the rescue!
Now we have a bunch of variables that we can modify and the triangle line drawing will automatically update. But why have 6 variables when we only need one? This code can be further improved by using structures.
This is better. But what if we want multiple triangles? We'll need a procedure to both allocate and free the memory for the triangles. We'll have it return the structure so we can manipulate it just as easily as before.
And while we're at it, lets make a procedure to draw it as well.
It looks like we have a lot of procedures now that have to do with triangles like Triangle_new(), Triangle_delete(), and Triangle_draw(). Lets put them into a module. I've also created an additional procedure and added a button to the window for creating random triangles when pressed.
You can see now how everything is self-contained in a module:
Lets start with something simple. We'll create a window and draw a triangle.
Code: Select all
Define window.i
window=OpenWindow(#PB_Any,0,0,132,103,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StartDrawing(WindowOutput(window))
FrontColor(#Black)
LineXY(65,7,113,91)
LineXY(113,91,17,91)
LineXY(17,91,65,7)
StopDrawing()
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Great! Variables to the rescue!
Code: Select all
Define x1.l, y1.l, x2.l, y2.l, x3.l, y3.l
x1=65
y1=7
x2=113
y2=91
x3=17
y3=91
LineXY(x1,y1,x2,y2)
LineXY(x2,y2,x3,y3)
LineXY(x3,y3,x1,y1)
Code: Select all
Structure Triangle
x1.l
y1.l
x2.l
y2.l
x3.l
y3.l
EndStructure
Define triangle.Triangle
triangle\x1=65
triangle\y1=7
triangle\x2=113
triangle\y2=91
triangle\x3=17
triangle\y3=91
LineXY(triangle\x1,triangle\y1,triangle\x2,triangle\y2)
LineXY(triangle\x2,triangle\y2,triangle\x3,triangle\y3)
LineXY(triangle\x3,triangle\y3,triangle\x1,triangle\y1)
And while we're at it, lets make a procedure to draw it as well.
Code: Select all
;-- Triangle
Structure Triangle
x1.l
y1.l
x2.l
y2.l
x3.l
y3.l
EndStructure
Procedure Triangle_new(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l)
Protected *triangle.Triangle=AllocateStructure(Triangle)
*triangle\x1=x1
*triangle\y1=y1
*triangle\x2=x2
*triangle\y2=y2
*triangle\x3=x3
*triangle\y3=y3
ProcedureReturn *triangle
EndProcedure
Procedure Triangle_delete(*triangle.Triangle)
FreeStructure(*triangle)
EndProcedure
Procedure Triangle_draw(*triangle.Triangle)
LineXY(*triangle\x1,*triangle\y1,*triangle\x2,*triangle\y2)
LineXY(*triangle\x2,*triangle\y2,*triangle\x3,*triangle\y3)
LineXY(*triangle\x3,*triangle\y3,*triangle\x1,*triangle\y1)
EndProcedure
;--
Define window.i
window=OpenWindow(#PB_Any,0,0,132,103,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
Define *triangle.Triangle
*triangle=Triangle_new(65,7, 113,91, 17,91)
StartDrawing(WindowOutput(window))
FrontColor(#Black)
Triangle_draw(*triangle)
StopDrawing()
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Code: Select all
;-- Triangle
DeclareModule Triangle
Structure Triangle
x1.l
y1.l
x2.l
y2.l
x3.l
y3.l
EndStructure
Declare new(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l)
Declare delete(*triangle.Triangle)
Declare draw(*triangle.Triangle)
Declare fromRandom(min.l, max.l)
EndDeclareModule
Module Triangle
Procedure new(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l)
Protected *triangle.Triangle=AllocateStructure(Triangle)
*triangle\x1=x1
*triangle\y1=y1
*triangle\x2=x2
*triangle\y2=y2
*triangle\x3=x3
*triangle\y3=y3
ProcedureReturn *triangle
EndProcedure
Procedure delete(*triangle.Triangle)
FreeStructure(*triangle)
EndProcedure
Procedure draw(*triangle.Triangle)
LineXY(*triangle\x1,*triangle\y1,*triangle\x2,*triangle\y2)
LineXY(*triangle\x2,*triangle\y2,*triangle\x3,*triangle\y3)
LineXY(*triangle\x3,*triangle\y3,*triangle\x1,*triangle\y1)
EndProcedure
Procedure fromRandom(min.l, max.l)
ProcedureReturn new(Random(max,min),Random(max,min),Random(max,min),Random(max,min),Random(max,min),Random(max,min))
EndProcedure
EndModule
;--
Procedure drawRandomTriangle(*oldTriangle, image)
Protected *triangle.Triangle::Triangle
Triangle::delete(*oldTriangle)
*triangle=Triangle::fromRandom(10,92)
FreeImage(image)
DisableDebugger
CreateImage(image,132,103,32,#PB_Image_Transparent)
EnableDebugger
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels)
FrontColor(RGBA(0,0,0,255))
Triangle::draw(*triangle)
StopDrawing()
EndProcedure
Define window.i
Define image.i
Define imageGadget.i
Define buttonGadget.i
Define event.i
window=OpenWindow(#PB_Any,0,0,132,136,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
image=CreateImage(#PB_Any,132,103,32,#PB_Image_Transparent)
imageGadget=ImageGadget(#PB_Any,0,0,132,103,ImageID(image))
buttonGadget=ButtonGadget(#PB_Any,5,109,122,23,"Random")
Define *triangle.Triangle::Triangle
*triangle=Triangle::new(65,7, 113,91, 17,91)
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels)
FrontColor(RGBA(0,0,0,255))
Triangle::draw(*triangle)
StopDrawing()
SetGadgetState(imageGadget,ImageID(image))
Repeat
event=WaitWindowEvent()
If event=#PB_Event_Gadget And EventGadget()=buttonGadget
drawRandomTriangle(*triangle,image)
SetGadgetState(imageGadget,ImageID(image))
EndIf
Until event=#PB_Event_CloseWindow
Code: Select all
Triangle::new(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l)
Triangle::delete(*triangle.Triangle)
Triangle::draw(*triangle.Triangle)
Triangle::fromRandom(min.l, max.l)