2D Path Editor by fubarpk11th Apr 2018 7:04
|
---|
Summary Creates paths for moving sprites Description Creates paths for moving sprites in a line or using a Bezier curve Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com // 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 #constant horizontalGrid=64 #constant verticalGrid=64 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 closed as integer endtype global testSpr as mySpr testSpr.id=2 testSpr.closed=closed #include "include/Bezier Curve Library.agc" Global dim stuff#[0] global totalLength# = 0 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 loadimage (1,"06.png") CreateSprite (spr,0) SetSpriteSize (spr,10,10) //CreateSprite (testSpr.id,1) CreateSprite (testSpr.id,1) //SetSpriteSize (testSpr.id,200,200) //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) dim path[100] as object SetSpriteVisible(testSpr.id,0) SetSpriteDepth(testSpr.id,9) clearPoints():count=1 SetRenderToImage (renderImg,0) drawCrosshairAndGrid(horizontalGrid,verticalGrid) 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 ////////////////////////////////////////////////// // Added these two lines here ////////////////////////////////////////////////// a=bc_getcurvesegmentpointcount():dim stuff#[a] totalLength# = calculateLength() inc count endif if GetVirtualButtonPressed(clearBtn) clearPoints() count=1 SetRenderToImage (renderImg,0) drawCrosshairAndGrid(horizontalGrid,verticalGrid) endif Update(0) Render() setrendertoscreen () SetSpriteSize(350,1024,768) Update(0) Render() swap() if GetVirtualButtonPressed(closedBtn) if closed=1 closed=0:testSpr.closed=closed SetVirtualButtonText( closedBtn, "Open" ) // else closed=1:testSpr.closed=closed 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) clearPoints() SetRenderToImage (renderImg,0) drawCrosshairAndGrid(horizontalGrid,verticalGrid) count=loadArray() endif until GetVirtualButtonPressed(exitBtn) end function drawCrosshairAndGrid(gridX, gridY) for y=0 to yMax step gridX drawline(0,y,xMax,y,0,255,0) next y for x=0 to xMax step gridY drawline(x,0,x,yMax,0,255,0) next x drawline(0,yMax/2,xMax,yMax/2,255,0,0) drawline(xMax/2,0,xMax/2,yMax,255,0,0) endfunction 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 ////////////////////////////////////////////////// // Constant speed around the bezier curve ////////////////////////////////////////////////// if bc_getcurvesegmentpointcount() > 0 // Simply to control an even time update if timestamp <= getMilliseconds() // A point on the bezier curver lies between 0 and 1. t# = t# + 0.001 // If time goes beyond 1, subtract 1. This will provide // a more even movement. if t# > 1 then t# = t# - 1 // How far from the beginning of the curve are we seg# = totalLength# * t# // Find the point at the beginning of the line segment that we are currently on s = getCurveSegmentPointAtDistance(seg#) // Calculate the length of this line segment segLength# = stuff#[s+1] - stuff#[s] // Calculate how far along this single line segment we are partSegLength# = seg# - stuff#[s] n# = partSegLength# / segLength# print(n#) // Use some linear interpolation to determine the coordinates on this line segment x = bc_getcurvesegmentpointx(s) + (bc_getcurvesegmentpointx(s+1)-bc_getcurvesegmentpointx(s))*n# y = bc_getcurvesegmentpointy(s) + (bc_getcurvesegmentpointy(s+1)-bc_getcurvesegmentpointy(s))*n# // Position the sprite SetSpritePositionByOffset(testSpr.id,bc_getcurvesegmentpointx(i)+testSpr.xOffset,bc_getcurvesegmentpointy(i)+testSpr.yOffset) // Update timer timestamp = getMilliseconds() + 20 endif endif //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) rem move sprite X steps 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 rem move sprite to first point if closed path if testSpr.closed=1 while getDistance(testSpr.x,testSpr.y,path[1].x,path[1].y)>5 angle#=getAngle(testSpr.x,testSpr.y,path[1].x,path[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 endif 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 saveArray(count as integer) write = OpenToWrite("arrayPath.txt" ,0) length=count String$ = Str(length-1) WriteLine (write,String$) WriteLine (write,Str(closed)) for num=1 to length StringX$ = Str(path[num].x-(xMax/2)) StringY$ = Str(path[num].y-(yMax/2)) WriteLine (write,StringX$) WriteLine (write,StringY$) next num Closefile(write) write = OpenToWrite("arrayBezier.txt" ,0) length=bc_getcurvesegmentpointcount()-1 String$ = Str(length-1) WriteLine (write,String$) WriteLine (write,Str(closed)) if bc_getcurvesegmentpointcount()>0 for i=1 to bc_getcurvesegmentpointcount()-2 //normally use -1, but I want to stop 1 early of the end of the array StringX$ = Str((bc_getcurvesegmentpointx(i)+testSpr.xOffset)-(xMax/2)) StringY$ = Str((bc_getcurvesegmentpointy(i)+testSpr.yOffset)-(yMax/2)) WriteLine (write,StringX$) WriteLine (write,StringY$) next i endif Closefile(write) endfunction function loadArray() for t = 0 to 100 path[t].x=0:path[t].y=0 next t If GetFileExists("arrayPath.txt") read = OpenToRead("arrayPath.txt") String1$ = ReadLine(read) length=val(String1$) String2$ = ReadLine(read) closed=val(String2$):testSpr.closed=closed BC_RemoveCurvePoints() //dim path[length] as object for num =1 to length StringX$ = ReadLine(read) StringY$ = ReadLine(read) path[num].x=((xMax/2)+val(StringX$)) path[num].y=((yMax/2)+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 ////////////////////////////////////////////////// // Added these two lines here ////////////////////////////////////////////////// a=bc_getcurvesegmentpointcount() dim stuff#[a] totalLength# = calculateLength() 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 ////////////////////////////////////////////////// // Calculates the distance of each point from the // beginning of the curve. // Returns total length of the curve. ////////////////////////////////////////////////// function calculateLength() total# = 0 if bc_getcurvesegmentpointcount() > 0 for i = 0 to bc_getcurvesegmentpointcount() - 2 x# = (bc_getcurvesegmentpointx(i)-bc_getcurvesegmentpointx(i+1))^2 y# = (bc_getcurvesegmentpointy(i)-bc_getcurvesegmentpointy(i+1))^2 d# = sqrt(x# + y#) total# = total# + d# stuff#[i] = total# next i endif endfunction total# ////////////////////////////////////////////////// // Finds which line segment that 'd#' falls on. // Since this array is technically a sorted list, // it can be modified into a binary search for // improved lookup speeds. ////////////////////////////////////////////////// function getCurveSegmentPointAtDistance(d#) for i = 0 to bc_getcurvesegmentpointcount() - 2 if d# >= stuff#[i] and d# < stuff#[i+1] then exitfunction i next i endfunction 0 |