Clonklex's Bevier Curve Library is great a great find blinkok
if you use Bezier Curve Library.agc
found here at the start of Clonkex thread
https://forum.thegamecreators.com/thread/210460
and then with the following changes to my above code
This now allows you to design a path save it and then load
it using an offset means you could for example have a particular alien
movement and then using the offset position anwhere on screen
main.agc
// Project: Path Editor
// Created: 2017-10-30
// show all errors
SetErrorMode(2)
#constant clearBtn=1
#constant test1Btn=2
#constant test2Btn=3
#constant closedBtn=4
#constant loadBtn=5
#constant saveBtn=6
#constant exitBtn=7
#constant spr=1
#constant xMax=1024
#constant yMax=768
global renderImg=100
global closed=1 //whether or not to draw as open or closed curve
type object
x as float
y as float
endtype
type mySpr
id as integer
x as float
y as float
xOffset as float
yOffset as float
endtype
global testSpr as mySpr
testSpr.id=2
#include "include/Bezier Curve Library.agc"
gosub _bc_setup //this has to be called before any BC command, preferably before anything at all
// set window properties
SetWindowTitle( "Path Editor" )
SetWindowSize( xMax, yMax, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
CreateSprite (spr,0)
SetSpriteSize (spr,10,10)
CreateSprite (testSpr.id,0)
SetSpriteSize (testSpr.id,10,10)
SetSpriteColor (testSpr.id,0,255,0,255)
SetSpritePositionByOffset(testSpr.id,xMax/2,yMax/2)
AddVirtualButton(clearBtn,40,30,60) //make a button
SetVirtualButtonText( clearBtn, "Clear" ) //set to exit text
SetVirtualButtonColor( clearBtn,200,200,200) //grey colour
AddVirtualButton(test1Btn,40,90,60) //make a button
SetVirtualButtonText( test1Btn, "Test Points" ) //set to music text
SetVirtualButtonColor( test1Btn,200,200,200) //grey colour
AddVirtualButton(test2Btn,40,150,60) //make a button
SetVirtualButtonText( test2Btn, "Test Bezier" ) //set to music text
SetVirtualButtonColor( test2Btn,200,200,200) //grey colour
AddVirtualButton(closedBtn,40,210,60) //make a button
if closed=1
SetVirtualButtonText( closedBtn, "Closed" ) //set to music text
else
SetVirtualButtonText( closedBtn, "Open" ) //set to music text
endif
SetVirtualButtonColor( closedBtn,200,200,200) //grey colour
AddVirtualButton(saveBtn,40,270,60) //make a button
SetVirtualButtonText( saveBtn, "Save" ) //set to music text
SetVirtualButtonColor( saveBtn,200,200,200) //grey colour
AddVirtualButton(loadBtn,40,330,60) //make a button
SetVirtualButtonText( loadBtn, "Load" ) //set to music text
SetVirtualButtonColor( loadBtn,200,200,200) //grey colour
AddVirtualButton(exitBtn,40,390,60) //make a button
SetVirtualButtonText( exitBtn, "Exit" ) //set to sound text
SetVirtualButtonColor( exitBtn,200,200,200) //grey colour
CreateRenderImage (renderImg,xMax,yMax,0,0)
CreateSprite(350,renderImg)
count=1
dim path[100] as object
SetSpriteVisible(testSpr.id,0)
SetSpriteDepth(testSpr.id,9)
repeat
mx#=GetPointerX()
my#=GetPointerY()
SetSpritePositionByOffset(spr,mx#,my#)
if GetRawMouseLeftPressed()
path[count].x=mx#:path[count].y=my#
SetRenderToImage (renderImg,0)
drawSprite(spr)
bc_addcurvepoint(getrawmousex(),getrawmousey())
if closed=0
bc_calculateopencurvesegmentpoints()
else
bc_calculateclosedcurvesegmentpoints()
endif
inc count
endif
if GetVirtualButtonPressed(clearBtn)
clearPoints()
count=1
endif
Update(0)
Render()
setrendertoscreen ()
SetSpriteSize(350,1024,768)
Update(0)
Render()
swap()
if GetVirtualButtonPressed(closedBtn)
if closed=1
closed=0
SetVirtualButtonText( closedBtn, "Open" ) //
else
closed=1
SetVirtualButtonText( closedBtn, "Closed" ) //
endif
endif
if GetVirtualButtonPressed(test1Btn)
testPaths()
endif
if GetVirtualButtonPressed(test2Btn)
drawBezier()
testBezierCurve()
//Bezier2()
endif
if GetVirtualButtonPressed(saveBtn)
saveArray(count)
endif
if GetVirtualButtonPressed(loadBtn)
count=loadArray()
endif
until GetVirtualButtonPressed(exitBtn)
end
function clearPoints ()
for t = 0 to 100
path[t].x=0:path[t].y=0
next t
BC_RemoveCurvePoints()
DeleteSprite(350):DeleteImage(renderImg)
renderImg=CreateRenderImage (xMax,yMax,0,0)
CreateSprite(350,renderImg)
endfunction
function drawBezier()
if bc_getcurvesegmentpointcount()>0
SetRenderToImage (renderImg,0)
for i=0 to bc_getcurvesegmentpointcount()-2 //normally use -1, but I want to stop 1 early of the end of the array
drawline(bc_getcurvesegmentpointx(i),bc_getcurvesegmentpointy(i),bc_getcurvesegmentpointx(i+1),bc_getcurvesegmentpointy(i+1),255,0,0)
next i
endif
Update(0)
Render()
setrendertoscreen ()
Update(0)
Render()
swap()
endfunction
function testBezierCurve()
testSpr.xOffset=0:testSpr.yOffset=0
SetSpriteVisible(testSpr.id,1)
if bc_getcurvesegmentpointcount()>0
for i=0 to bc_getcurvesegmentpointcount()-1 //normally use -1, but I want to stop 1 early of the end of the array
SetSpritePositionByOffset(testSpr.id,bc_getcurvesegmentpointx(i)+testSpr.xOffset,bc_getcurvesegmentpointy(i)+testSpr.yOffset)
//add following to point to centre
angle#=getAngle(bc_getcurvesegmentpointx(i),bc_getcurvesegmentpointy(i),bc_getcurvesegmentpointx(i+1),bc_getcurvesegmentpointy(i+1))
SetSpriteAngle(testSpr.id,getAngle(GetSpriteXByOffset(testSpr.id),GetSpriteYByOffset(testSpr.id),xMax/2,yMax/2)):rem point to middle of screen
sync()
next i
endif
SetSpriteVisible(350,1)
SetSpriteVisible(testSpr.id,0)
endfunction
function testPaths()
//testSpr.x=xMax/2:testSpr.y=yMax/2
testSpr.xOffset=0:testSpr.yOffset=0
testSpr.x=path[1].x+testSpr.xOffset:testSpr.y=path[1].y+testSpr.yOffset
count=1:speed#=5
//SetSpriteVisible(350,0)
SetSpriteVisible(testSpr.id,1)
repeat
SetSpritePositionByOffset(testSpr.id,testSpr.x,testSpr.y)
//SetSpriteSize(testspr,200,200)
while getDistance(testSpr.x,testSpr.y,path[count+1].x,path[count+1].y)>5
angle#=getAngle(testSpr.x,testSpr.y,path[count+1].x,path[count+1].y)
testSpr.x=testSpr.x-sin(angle#)*speed#:testSpr.y=testSpr.y+cos(angle#)*speed#
SetSpritePositionByOffset(testSpr.id,testSpr.x+testSpr.xOffset,testSpr.y+testSpr.yOffset)
SetSpriteAngle(testSpr.id,getAngle(GetSpriteXByOffset(testSpr.id),GetSpriteYByOffset(testSpr.id),xMax/2,yMax/2)):rem point to middle of screen
//SetSpriteAngle(testspr,angle#):rem point to way point
print( getDistance(testSpr.x,testSpr.y,path[count+1].x,path[count+1].y))
sync()
endwhile
//x=path[count+1].x:y=path[count+1].y
inc count
until path[count+1].x=0 and path[count+1].y=0
SetSpriteVisible(350,1)
SetSpriteVisible(testSpr.id,0)
endfunction
function getAngle(x1#, y1#, x2#, y2#)
result# = ATanFull(x1# - x2#, y1# - y2#)
endfunction result#
function getDistance (x1#,y1#,x2#,y2#)
dx#=x1#-x2#
dy#=y1#-y2#
distance#=sqrt((dx#*dx#)+(dy#*dy#)):rem distance object to path point
endfunction distance#
function difference(x as float ,y as float)
diff as float
diff = (x-y)
endfunction diff
//Function Bezier4(p:TV2D Var,p1:TV2D,p2:TV2D,p3:TV2D,p4:TV2D,mu:Float)
function Bezier2()
//MR 01.07.2005
//Four control point Bezier interpolation
//mu ranges from 0 To 1, start To End of curve
mu as float
mum1 as float
mum13 as float
mu3 as float
count as integer
SetSpriteVisible(testSpr.id,1)
for mu=0 to 1 step .025
mum1 = 1.0 - mu
mum13 = mum1 * mum1 * mum1
mu3 = mu * mu * mu
testSpr.x = mum13*path[1].x + (3.0*mu*mum1*mum1*path[2].x) + (3.0*mu*mu*mum1*path[3].x) + (mu3*path[4].x)
testSpr.y = mum13*path[1].y + (3.0*mu*mum1*mum1*path[2].y) + (3.0*mu*mu*mum1*path[3].y) + (mu3*path[4].y)
//p.z = mum13*p1.z + 3.0*mu*mum1*mum1*p2.z + 3.0*mu*mu*mum1*p3.z + mu3*p4.z
SetSpritePositionByOffset(testSpr.id,testSpr.x,testSpr.y)
Print(testSpr.x)
sync()
next mu
//SetSpriteVisible(testSpr.id,0)
EndFunction
function saveArray(count as integer)
write = OpenToWrite("array.txt" ,0)
length=count
String$ = Str(length)
WriteLine (write,String$)
WriteLine (write,Str(closed))
for num=0 to length
StringX$ = Str(path[num].x)
StringY$ = Str(path[num].y)
WriteLine (write,StringX$)
WriteLine (write,StringY$)
next num
Closefile(write)
endfunction
function loadArray()
for t = 0 to 100
path[t].x=0:path[t].y=0
next t
If GetFileExists("array.txt")
read = OpenToRead("array.txt")
String1$ = ReadLine(read)
length=val(String1$):length=3
String2$ = ReadLine(read)
closed=val(String2$)
BC_RemoveCurvePoints()
//dim path[length] as object
for num =1 to length
StringX$ = ReadLine(read)
StringY$ = ReadLine(read)
path[num].x=val(StringX$)
path[num].y=val(StringY$)
SetRenderToImage (renderImg,0)
SetSpritePosition(spr,path[num].x,path[num].y)
drawSprite(spr)
bc_addcurvepoint(path[num].x,path[num].y)
if closed=0
bc_calculateopencurvesegmentpoints()
else
bc_calculateclosedcurvesegmentpoints()
endif
Update(0)
Render()
setrendertoscreen ()
SetSpriteSize(350,1024,768)
Update(0)
Render()
swap()
next num
Closefile(read)
if closed=1
SetVirtualButtonText( closedBtn, "Closed" ) //set to music text
else
SetVirtualButtonText( closedBtn, "Open" ) //set to music text
endif
count=length
endif
endfunction count
Clonklex's Bevier Curve Library
/*
---------------------------------------------------------
---- Bezier Curve Library v1.21 (BASIC) ----
---- By Clonkex aka David Hynd ----
---- Created 12/03/14 - 11/04/14 ----
---------------------------------------------------------
Legal:
Do what you want with it. Have fun! xD
Changes:
[20/03/14] 1.0 - Public release
[21/03/14] 1.1 - Fixed closed curves (so they actually work and all that)
[22/03/14] 1.11 - Tiny eency little fix (forgot to change an X to a Y)
[22/03/14] 1.2 - Fixed some floats not being floats and wrote the C++ version of the library
[11/04/14] 1.21 - Fixed some bugs in the C++ version related to for-loops
Usage:
Coming soon (i.e. when I feel like writing it). For now look at the example.
Function list:
BC_AddCurvePoint(posx#,posy#) -- Adds a new point to the curve at the specified position
BC_RemoveCurvePoints() -- Removes all points from the curve
BC_CalculatePointOnOpenCurve(t#) -- Finds a point on the curve from distance along it in a range of 0-1; calculates an open-ended curve
BC_CalculatePointOnClosedCurve(t#) -- Finds a point on the curve from distance along it in a range of 0-1; calculates a closed curve
BC_GetCurvePointCount() -- Returns the number of points currently making up the curve
BC_GetCurvePointX() -- Returns the last calculated position from BC_CalculatePointOnXXXCurve()
BC_GetCurvePointY() -- Returns the last calculated position from BC_CalculatePointOnXXXCurve()
BC_CalculateClosestPointToCurve(x#,y#) -- Finds the closest point on the curve to the position; call BC_CalculateXXXCurveSegmentPoints() first!
BC_GetClosestPointX() -- Returns the last calculated closest position from BC_CalculateClosestPointToCurve()
BC_GetClosestPointY() -- Returns the last calculated closest position from BC_CalculateClosestPointToCurve()
BC_GetClosestPointDistance() -- Returns the distance to the last calculated closest position from BC_CalculateClosestPointToCurve()
BC_GetClosestPointIndex() -- Returns the index of the last calculated segment point from BC_CalculateClosestPointToCurve()
BC_SetCurveSegmentPointCount(count) -- Sets how many segment points should be created from the curve
BC_GetCurveSegmentPointCount() -- Returns the number generated of segment points
BC_GetCurveSegmentPointX(index) -- Returns the position of a specific segment point
BC_GetCurveSegmentPointY(index) -- Returns the position of a specific segment point
BC_CalculateOpenCurveSegmentPoints() -- Cuts up a curve into a set number of points (segment points) making straight lines
BC_CalculateClosedCurveSegmentPoints() -- Cuts up a curve into a set number of points (segment points) making straight lines
BC_Distance(x1#,y1#,x2#,y2#) -- Used internally; calculates the distance between two 2D points
BC_PointOnLineX(x1#,y1#,x2#,y2#,percent#) -- Used internally; calculates a position based on a distance along a 2D line
BC_PointOnLineY(x1#,y1#,x2#,y2#,percent#) -- Used internally; calculates a position based on a distance along a 2D line
*/
_BC_Setup:
global bc_lastcurvepointx#=0.0
global bc_lastcurvepointy#=0.0
global bc_curvepointcount=0
global bc_distanceiterations=50
global bc_closestdistance#=0.0
global bc_closestpointx#=0.0
global bc_closestpointy#=0.0
global bc_closestindex=0
global bc_curvesegmentpointcount=0
type bc_curvepointinfo
posx# as float
posy# as float
endtype
type bc_curvesegmentpointinfo
posx# as float
posy# as float
endtype
dim bc_curvepoint[0] as bc_curvepointinfo
dim bc_curvesegmentpoint[0] as bc_curvesegmentpointinfo
return
function BC_AddCurvePoint(posx#,posy#)
bc_curvepointcount=bc_curvepointcount+1
dim bc_curvepoint[bc_curvepointcount] as bc_curvepointinfo
bc_curvepoint[bc_curvepointcount-1].posx#=posx#
bc_curvepoint[bc_curvepointcount-1].posy#=posy#
endfunction
function BC_RemoveCurvePoints()
bc_curvepointcount=0
dim bc_curvepoint[bc_curvepointcount] as bc_curvepointinfo
bc_curvesegmentpointcount=0
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
endfunction
function BC_CalculatePointOnOpenCurve(t#) //t# is the percentage of the way along the line in a range of 0-1
if bc_curvepointcount>1
totalt#=t#*(bc_curvepointcount-1)
i=trunc(totalt#)
realt#=totalt#-i
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,0.3333)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,0.3333)
p2posx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
p2posy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
if i=0
p0posx#=bc_curvepoint[i].posx#
p0posy#=bc_curvepoint[i].posy#
else
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,0.3333)
p0posx#=bc_pointonlinex(tempx#,tempy#,p1posx#,p1posy#,0.5)
p0posy#=bc_pointonliney(tempx#,tempy#,p1posx#,p1posy#,0.5)
endif
if i=bc_curvepointcount-2
p3posx#=bc_curvepoint[i+1].posx#
p3posy#=bc_curvepoint[i+1].posy#
else
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,tempx#,tempy#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,tempx#,tempy#,0.5)
endif
//begin calculations (conveniently adapted from http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/):
u#=1-realt#
tt#=realt#*realt#
uu#=u#*u#
uuu#=uu#*u#
ttt#=tt#*realt#
bc_lastcurvepointx#=uuu#*p0posx# //first term
bc_lastcurvepointy#=uuu#*p0posy# //first term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*uu#*realt#*p1posx# //second term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*uu#*realt#*p1posy# //second term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*u#*tt#*p2posx# //third term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*u#*tt#*p2posy# //third term
bc_lastcurvepointx#=bc_lastcurvepointx#+ttt#*p3posx# //fourth term
bc_lastcurvepointy#=bc_lastcurvepointy#+ttt#*p3posy# //fourth term
else
if bc_curvepointcount>0
bc_lastcurvepointx#=bc_curvepoint[0].posx#
bc_lastcurvepointy#=bc_curvepoint[0].posy#
else
message("Bezier Curve Library: Tried to calculate a curve with no points! You douchebag!")
end
endif
endif
endfunction
function BC_CalculatePointOnClosedCurve(t#) //t# is the percentage of the way along the line in a range of 0-1
if bc_curvepointcount>1
totalt#=t#*bc_curvepointcount
i=trunc(totalt#)
realt#=totalt#-i
if i=bc_curvepointcount-1
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,0.3333)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,0.3333)
p2posx#=bc_pointonlinex(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
p2posy#=bc_pointonliney(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
else
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,0.3333)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,0.3333)
p2posx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
p2posy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,0.3333)
endif
if i=0
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[bc_curvepointcount-1].posx#,bc_curvepoint[bc_curvepointcount-1].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[bc_curvepointcount-1].posx#,bc_curvepoint[bc_curvepointcount-1].posy#,0.3333)
p0posx#=bc_pointonlinex(tempx#,tempy#,p1posx#,p1posy#,0.5)
p0posy#=bc_pointonliney(tempx#,tempy#,p1posx#,p1posy#,0.5)
else
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,0.3333)
p0posx#=bc_pointonlinex(tempx#,tempy#,p1posx#,p1posy#,0.5)
p0posy#=bc_pointonliney(tempx#,tempy#,p1posx#,p1posy#,0.5)
endif
if i=bc_curvepointcount-2
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,tempx#,tempy#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,tempx#,tempy#,0.5)
else
if i=bc_curvepointcount-1
tempx#=bc_pointonlinex(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[1].posx#,bc_curvepoint[1].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[1].posx#,bc_curvepoint[1].posy#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,tempx#,tempy#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,tempx#,tempy#,0.5)
else
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,tempx#,tempy#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,tempx#,tempy#,0.5)
endif
endif
//begin calculations (conveniently adapted from http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/):
u#=1-realt#
tt#=realt#*realt#
uu#=u#*u#
uuu#=uu#*u#
ttt#=tt#*realt#
bc_lastcurvepointx#=uuu#*p0posx# //first term
bc_lastcurvepointy#=uuu#*p0posy# //first term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*uu#*realt#*p1posx# //second term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*uu#*realt#*p1posy# //second term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*u#*tt#*p2posx# //third term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*u#*tt#*p2posy# //third term
bc_lastcurvepointx#=bc_lastcurvepointx#+ttt#*p3posx# //fourth term
bc_lastcurvepointy#=bc_lastcurvepointy#+ttt#*p3posy# //fourth term
else
if bc_curvepointcount>0
bc_lastcurvepointx#=bc_curvepoint[0].posx#
bc_lastcurvepointy#=bc_curvepoint[0].posy#
else
message("Bezier Curve Library: Tried to calculate a curve with no points! You douchebag!")
end
endif
endif
endfunction
function BC_GetCurvePointCount()
endfunction bc_curvepointcount
function BC_GetCurvePointX()
endfunction bc_lastcurvepointx#
function BC_GetCurvePointY()
endfunction bc_lastcurvepointy#
function BC_CalculateClosestPointToCurve(posx#,posy#) //x# and y# are the point from which we're searching
bc_closestdistance#=1000000 //hack, but basically could never be larger than this anyway
if bc_curvepointcount>0
bc_closestpointx#=0
bc_closestpointy#=0
for i=0 to bc_distanceiterations-1
distance#=bc_distance(posx#,posy#,bc_curvesegmentpoint[i].posx#,bc_curvesegmentpoint[i].posy#)
if distance#<bc_closestdistance#
bc_closestdistance#=distance#
bc_closestpointx#=bc_curvesegmentpoint[i].posx#
bc_closestpointy#=bc_curvesegmentpoint[i].posy#
bc_closestindex=i
endif
next i
else
bc_closestpointx#=0
bc_closestpointy#=0
endif
endfunction
function BC_GetClosestPointX()
endfunction bc_closestpointx#
function BC_GetClosestPointY()
endfunction bc_closestpointy#
function BC_GetClosestPointDistance()
endfunction bc_closestdistance#
function BC_GetClosestPointIndex()
endfunction bc_closestindex
function BC_SetCurveSegmentPointCount(count)
bc_distanceiterations=count
endfunction
function BC_GetCurveSegmentPointCount()
endfunction bc_curvesegmentpointcount
function BC_GetCurveSegmentPointX(index)
x#=bc_curvesegmentpoint[index].posx#
endfunction x#
function BC_GetCurveSegmentPointY(index)
y#=bc_curvesegmentpoint[index].posy#
endfunction y#
function BC_CalculateOpenCurveSegmentPoints()
bc_curvesegmentpointcount=bc_distanceiterations
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
if bc_curvepointcount>0
add#=1.0/bc_distanceiterations
t#=0
for i=0 to bc_curvesegmentpointcount-1
bc_calculatepointonopencurve(t#)
bc_curvesegmentpoint[i].posx#=bc_lastcurvepointx#
bc_curvesegmentpoint[i].posy#=bc_lastcurvepointy#
t#=t#+add#
next i
endif
endfunction
function BC_CalculateClosedCurveSegmentPoints()
bc_curvesegmentpointcount=bc_distanceiterations
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
if bc_curvepointcount>0
add#=1.0/bc_distanceiterations
t#=0
for i=0 to bc_curvesegmentpointcount-1
if i=bc_distanceiterations-1 then t#=0.9999999
bc_calculatepointonclosedcurve(t#)
bc_curvesegmentpoint[i].posx#=bc_lastcurvepointx#
bc_curvesegmentpoint[i].posy#=bc_lastcurvepointy#
t#=t#+add#
next i
endif
endfunction
function BC_Distance(x1#,y1#,x2#,y2#)
dx#=x1#-x2#
dy#=y1#-y2#
distance#=sqrt(dx#*dx#+dy#*dy#)
endfunction distance#
function BC_PointOnLineX(x1#,y1#,x2#,y2#,percent#)
px#=x1#+((x2#-x1#)*percent#)
endfunction px#
function BC_PointOnLineY(x1#,y1#,x2#,y2#,percent#)
py#=y1#+((y2#-y1#)*percent#)
endfunction py#
Plotting three points and selecting the Bezier curve option mimmicks your video
If you want to try the waypoints option ive added an offset testSpr.xOffset and testSpr.yOffset
they can be calculated by getting the difference from where you want the sprite and the location
they was first plotted and putting it in the offset variables arcs work with closed=0
If you wish to change closed to open or visa versa remember to clear after
Work to do make it so as you can have many different paths saved and load each one for
individual alien movements
fubar