This is a small collection of mostly game example source codes. These source codes are made available to help PlayBasic programmers kick start their game programming journey.
Looking for more source code / tutorials & media, then remember to visit the PlayBasic Resource board on our forums.
This function takes a base path and then computes the absolute path from this base from an assumed relative path in the file name
PlayBasic Code:
BasePath$="D:\MyProjectFolder\Gfx\_examples"ink$ff0000print BasePath$
ink-1print""print GetAbsolutePathToFile(BasePath$, "Stuff.txt")print GetAbsolutePathToFile(BasePath$, "subfolder/Stuff.txt")print GetAbsolutePathToFile(BasePath$, "../Stuff.txt")print GetAbsolutePathToFile(BasePath$, "../../Stuff.txt")print GetAbsolutePathToFile(BasePath$, "subfolder/../../Stuff.txt")SyncwaitkeyFunction GetAbsolutePathToFile(BasePath$, Filename$)
BasePath$=replace$(BasePath$,"/","\")
Filename$=replace$(Filename$,"/","\")
Filename$=trim$(Filename$)
BasePath$=trimright$(BasePath$,"\")+"\"local Device$=GetDevicename$(Filename$)iflen(Device$)=0// if the Filename is relative, we'll try and// build an absolute path from BASE to this Filenamelocal Path$=GetFolderName$(Filename$)
FileName$=BasePath$+Filename$
// Check for "..\" in pathifinstring(Path$,"..\")Dim FolderChunks$(50)local Count=splittoarray(filename$,"\",FolderChunks$())local lp,s$
local Output=0for lp =0to count-1
s$=FolderChunks$(lp)if s$<>".."if output>=0then FolderChunks$(Output)=s$
Output++else
output--endifnext// Put it back together
Filename$=""for lp =0to output-1
Filename$+=FolderChunks$(lp)if lp<output-1then Filename$+="\"nextendifendifEndFunction Filename$
This code is a function that determines if two lines intersect and returns the intersection point as the coordinates (x,y). The function takes in the starting and ending x and y coordinates for each line as arguments. The function first calculates the slope and length of each line. It then uses these values to determine if the lines intersect and, if they do, calculates the intersection point. The function returns a boolean value indicating whether the lines intersect, as well as the x and y coordinates of the intersection point. The function is called in a loop that clears the screen, draws the two lines with the mouse coordinates as one of the endpoints, and prints the intersection point (if the lines intersect).
PlayBasic Code:
Do// Clear the screenCls// Set line1StartX, line1StartY, line1EndX, and line1EndY to variables
line1StartX=100
line1StartY=100
line1EndX =mousex()
line1EndY =mousey()// Set line2StartX, line2StartY, line2EndX, and line2EndY to variables
line2StartX=20
line2StartY=200
line2EndX=1000
line2EndY=700// Draw line1 in blacklinec line1StartX, line1StartY, line1EndX, line1EndY,-1// Draw line2 in greenlinec line2StartX, line2StartY, line2EndX, line2EndY,$00ff00// Check if lines intersect
State,x#,y#=Lines_Intersect(line1StartX, line1StartY, line1EndX, line1EndY,_
line2StartX, line2StartY, line2EndX, line2EndY)// Print intersect stateprint State
// If lines intersect, draw a red circle at intersect pointif State
Circlec X#,y#,10,true,$ff0000endif// Display the screensyncloopspacekey()endFunction Lines_Intersect(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY)// Initialize variables
intersects =False
intersectX =0
intersectY =0
s1_x# = line1EndX - line1StartX
s1_y# = line1EndY - line1StartY
s2_x# = line2EndX - line2StartX
s2_y# = line2EndY - line2StartY
// Calculate s and t
s# =(-s1_y# *(line1StartX - line2StartX)+ s1_x# *(line1StartY - line2StartY))/(-s2_x# * s1_y# + s1_x# * s2_y#)
t# =( s2_x# *(line1StartY - line2StartY)- s2_y# *(line1StartX - line2StartX))/(-s2_x# * s1_y# + s1_x# * s2_y#)// Check if s and t are within valid rangeif s# >=0and s# <=1and t# >=0and t# <=1// Set intersects to true and calculate intersectX and intersectY
intersects =True
intersectX# = line1StartX +(t# * s1_x#)
intersectY# = line1StartY +(t# * s1_y#)EndIf// Return intersects, intersectX, and intersectYEndFunction intersects, intersectX#, intersectY#
This function takes two two sorted Integer (Numeric) and merged them into a new array.
PlayBasic Code:
Size=100Dim Test1(Size)Dim Test2(Size); fill both arrays with some random integers between 0 and 1000for lp =0to Size
Test1(lp)=rnd(1000)
Test2(lp)=rnd(1000)next; Place a couple of value at the end of our arrays to check we're; getting all the values in the merged output
test1(Size)=5000
test2(Size)=9999; Sort the Arrays SortArray Test1(),0,Size
SortArray Test2(),0,Size
Dim Result(0)
Result()=MergeSortedArrays(Test1(), Test2())SyncwaitkeyFunction MergeSortedArrays(a(), b()); dim our arrat C() to hold both merged arrays
A_Size =getarrayelements(a())
B_Size =getarrayelements(b()); output array total size
C_Size = A_Size+B_Size+1Dim c(C_Size); Initialize variables to track the current position in each array
i =0
j =0for LP=0to C_Size
; Check if the value in array A is; smaller than the value in array Bif a(i)< b(j); Add the value from array A to the merged array
c(lp)= a(i)
i++; Move to the next element in array A; Check if we're out of values in array A if i>A_Size
; If so, we copy the rest of B() to C()For CopyLP = j to B_Size
LP++
c(LP)=b(CopyLP)nextendifElse; Otherwise, the value in array B is smaller; Add the value from array B to the merged array
c(lp)= b(j)
j++; Move to the next element in array B; Check if we're out of values in array B if j>B_Size
; if so, we can copy the rest of A() to C()For CopyLP = i to A_Size
LP++
c(lp)=a(CopyLP)nextendifEndifnext lp
; Return the merged arrayEndFunction c()
Learn To Code How it Works:
The function called MergeSortedArrays takes two sorted arrays, a and b, as input and returns a new array containing the merged and sorted values from both input arrays.
The function starts by declaring a new array, c, to hold the merged values of the two input arrays. It then initializes three variables, i, j, and lp, which will be used to track the current position in each of the input arrays and to loop through the elements of the output array.
The function then enters a FOR loop which will iterate lp from 0 to the size of the output array. Inside the loop, the function compares the current element of array a to the current element of array b. If the element from array a is smaller, it is added to the merged array and the i variable is incremented to move to the next element in array a. If the element from array b is smaller, it is added to the merged array and the j variable is incremented to move to the next element in array b.
If the end of either array a or b is reached, the rest of the values in the other array are added to the output array in a separate FOR loop. Finally, the function returns the merged array c.
This example rendering spinning gouraud shaded torus in 3D, purely in software. The code is translation of an old Blitz BASIC program that was converted and tweaked to run in PlayBasic.
Note: Download attachment for the FULL code it's too big for a snippet
GetWindowRect is a function in the Windows API that retrieves the dimensions of the bounding rectangle of a window. It takes a handle to the window as an input parameter and returns the dimensions of the window in a RECT structure, which contains the left, top, right, and bottom coordinates of the rectangle.
GetClientRect is a similar function that retrieves the dimensions of the client area of a window. The client area is the part of the window where the application can draw and is typically smaller than the full window because it excludes the title bar and other non-client elements. Like GetWindowRect, GetClientRect takes a handle to the window as an input parameter and returns the dimensions of the client area in a RECT structure.
Both functions are useful for getting the dimensions of a window or client area, which can be used to position controls within the window or to resize the window to fit its contents. They can be called from any application that has a handle to the window, whether it is the application that created the window or another application.
PlayBasic Code:
// Scale OpenScreen1600,960,32,1; open screen in 'window' mode
ScaleWindowToDeskTop()loadfont"ariel",1, 45docls
ShowClientArea()print"Mouse POsition:"printMouseX()printMouseY()Syncloopspacekey()=truetype tWindow_RECT
X1,Y1
X2,Y2
endtypelinkdll"user32.dll"
SetWindowPos(hwnd,hWndInsertAfter,x,y,cx,cy,wFlags)alias"SetWindowPos"Asinteger
GetWindowRect(hwnd,RectPointer)alias"GetWindowRect"Asinteger
GetClientRect(hwnd,RectPointer)alias"GetClientRect"AsintegerEndlinkdllFunction ScaleWindowToDeskTop()// Get the Desk top width/height
dtw=GetDesktopWidth()
dth=GetDesktopHeight()*0.96// Get the PB screens size; w=GetScreenWidth(); h=GetScreenHeight()// Get the PB screens window Handle
hwnd=GetScreenHandle(); Stretch the window to the size users display size
SetWindowPos(hwnd,hWndInsertAfter,0,0,dtw,dth,wFlags); Resize PB's GFX viewport to screens (the window) new client areaStretchGFXscreenEndfunctionFunction ShowClientArea()Local Xpos =GetScreenXpos()Local Ypos =GetScreenYpos()Local Width =GetScreenWidth()Local Height=GetScreenHeight()local Handle=GetSCreenHandle()dim Rect as TWindow_REct pointer
Rect =new tWindow_RECT
print"SCREEN SIZE:"print Width
print Height
print""local Status= GetWindowREct(Handle, int(RECT))if Status
print"Window RECT"print Rect.X1
print Rect.Y1
print Rect.X2
print Rect.Y2
print""endiflocal Status= GetClientREct(Handle, int(RECT))if Status
print"Client RECT - area inside of window"print Rect.X1
print Rect.Y1
print Rect.X2
print Rect.Y2
print""endiffree Rect
EndFunction X,Y
While tinkering last night, I wrote a simple menu library that lets the programmer define a list of text options that can have a key and mousing bindings as well. The library is more a starting point than a end product, but it shows a way how we can wrap a system into library that help us separate that functionality from the main program. The user can tag a function (by name) that is called when any option is clicked or the key binding is pressed.
This library provides a set of functions for working with 2D vectors. A 2D vector is a geometric object that has both magnitude (length) and direction and can be represented by an ordered pair of real numbers (x, y).
The functions in this library allow you to create, manipulate, and perform calculations with 2D vectors. Some of the things you can do with these functions include:
- Set the x and y components of a 2D vector using SetVector2D
- Convert polar coordinates (angle and radius) to Cartesian coordinates (x and y) using SetPolar2D
- Copy the values of one 2D vector to another using CopyVector2D
- Add or subtract two 2D vectors using AddVectors2D or SubVectors2D
- Multiply or divide two 2D vectors component-wise using MultVectors2D or DivVectors2D
- Multiply or divide a 2D vector by a scalar value using MultVector2D or DivVector2D
- Linearly interpolate between two 2D vectors using LerpVector2D
- Normalize a 2D vector (i.e., set its magnitude to 1) using GetVectorNormal2D
- Calculate the length or squared length of a 2D vector using GetVectorLength2D or GetVectorSquaredLength2D
- Check if two 2D vectors are equal using AreVectorsEqual2D
- Calculate the dot product or cross product of two 2D vectors using DotProduct2D or CrossProduct2D
PlayBasic Code:
; PROJECT : Vector Library; AUTHOR : Kevin Picone - PlayBasic Tutor - https://PlayBasic.com; CREATED : 12/05/2022; EDITED : 28/05/2022; ---------------------------------------------------------------------// Use a typed array to hold all the vectors we'll be usingDim vectors(100)as vector2d
for lp =0togetArrayElements(vectors())
vectors(lp)=new vector2D
next// declare some pointers of type vector for use in the examples Dim N as vector2d pointerDim V1 as vector2d pointerDim V2 as vector2d pointerDim OldPoint as vector2D pointer// Get pointers to some pre--alloated vectors in our cache array
n = Vectors(0).vector2d
V1 = Vectors(1).vector2d
V2 = Vectors(2).vector2d
Dim CurrentPoint as vector2D pointer
CurrentPOint = Vectors(3).vector2d
Dim OldPoint as vector2D pointer
OldPOint = Vectors(4).vector2d
Dim Lerp1 as vector2D pointer
Lerp1 = Vectors(10).vector2d
Dim Lerp2 as vector2D pointer
Lerp2 = Vectors(11).vector2d
SetVector2d lerp1, 500,100
SetPolar2d lerp2, Rnd(36),rndrange(10,100)
Addvectors2d Lerp2, Lerp2, Lerp1
// Set up this vector
Setvector2d OldPOint,Mousex(),MouseY()Flushmouse// -----------------------------------------------------------// -----------------------------------------------------------// -----------------------------------------------------------Do// -----------------------------------------------------------// -----------------------------------------------------------// -----------------------------------------------------------CLS// Set up this vecor
Setvector2d CurrentPoint,Mousex(),MouseY()circlec OldPoint.X,OldPoint.Y, 50,true, $00ff00circle CurrentPoint.X,CurrentPOint.Y, 50,true// Subtract target from current N = Old - Current
Subvectors2d(N , oldPoint,CurrentPoint)
ypos=50text10,Ypos, "Delta:"+StrVector2d$(N)// Get the length of this delta vector
Dist#=GetVectorLenght2D(N)// normalize N = and store it back in N
GetVectorNormal2D(N , N)text10,Ypos+30, "Normalized:"+StrVector2d$(N)// Scale Normal by Dist#
Multvector2d(N , N, Dist#)text10,Ypos+60, "Scaled Normalized:"+StrVector2d$(N)// Add origin (current point) back on.
Addvectors2d(N , N, CurrentPoint)text10,Ypos+90, "Result:"+StrVector2d$(N)// Scale it so we can draw line between themline CurrentPOint.x,CurrentPOint.y,n.x,n.y
ifMousebutton()=1
CopyVector2d OldPoint,CurrentPOint
endif// test lerpLinec Lerp1.x,Lerp1.y,Lerp2.x,Lerp2.y, $ff00ff//
LerpFrame =mod(LerpFrame+1,100)
LerpScale# =LerpFrame/100.0
LerpVector2d N,Lerp1,Lerp2,LerpScale#
Circlec n.x , n.y, 5, true ,$ff00ff// Curve Lerp vector to the one between
LerpVector2d V1,Lerp1,Lerp2,LerpScale#
LerpVector2d V2,CurrentPoint,OldPoint,LerpScale#
LerpVector2d V1,V2,V1,LerpScale#
Circlec v1.x , v1.y, 5, true ,$ff00ff
LerpVector2d V1,Lerp1,Oldpoint,LerpScale#
LerpVector2d V2,lerp2,CurrentPoint,LerpScale#
LerpVector2d V1,V2,V1,LerpScale#
Circlec v1.x , v1.y, 5, true ,$ff00ffSyncloopSpacekey()
This tiny source code snippet uses PlayBasic's shapes to draw batches of line fragments. The fragments are all connected in a circle were each vertex is waving and rotating. On their own the effect is really simple; but when you overlay (rotate and scale) a bunch of them on top of each other it creates a sort of button effect similar to the robotic voice in the classic science function movie 2001 A Space Odyssey. Excuse my poor impressions of Hal in this video.. It's just for laughs
Release Type:
The source code & tutorials found on this site are released as license ware for PlayBasic Users. No Person or Company may redistribute any file (tutorial / source code or media files) from this site, without explicit written permission.