excuse me for my bad english. I would like to share with you my code to move on map with Catmullrom spline
I hope you will like this code
regards
Code: Select all
Procedure CatmullRomSpline(t.f,*result.POINT,*p0.Point,*p1.Point,*p2.point,*p3.point)
t2.f = t * t
t3.f = t2 * t
*result\x= 0.5 * ( ( 2.0 * *p1\x ) + ( -*p0\x + *p2\x ) * t + ( 2.0 * *p0\x - 5.0 * *p1\x + 4 * *p2\x - *p3\x ) * t2 + ( -*p0\x + 3.0 * *p1\x - 3.0 * *p2\x + *p3\x ) * t3 )
*result\y= 0.5 * ( ( 2.0 * *p1\y ) + ( -*p0\y + *p2\y ) * t + ( 2.0 * *p0\y - 5.0 * *p1\y + 4 * *p2\y - *p3\y ) * t2 + ( -*p0\y + 3.0 * *p1\y - 3.0 * *p2\y + *p3\y ) * t3 )
EndProcedure
#tileWidth=48
;-Characters
Structure chara
;reel chara coord
worldPixelX.l
worldPixelY.l
;the target where you want to go
ToWorldPixelX.l
ToWorldPixelY.l
pathSize.l;tile number in path
num.l ; pointer on path
startTime.l ; time to move
startWorldPixelX.l; to save the start coord
startWorldPixelY.l
EndStructure
chara.chara
;init characters position
chara\worldPixelX=10
chara\worldPixelY=10
;je fais comme si on voulait aller a un autre endroit
;c'est pas tres loin du point de depart, mais le faux pathfinding
;un peu plus loin fera un detour
chara\ToWorldPixelX=10
chara\ToWorldPixelY=42
;-Le path
Structure path
x.l
y.l
EndStructure
NewList path.path()
If InitSprite() = 0
MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
End
EndIf
If OpenWindow(0, 0, 0, 800, 600, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(320)
If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 1, 0, 20)
Repeat
; It's very important to process all the events remaining in the queue at each frame
;
Repeat
Event = WaitWindowEvent(10)
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
;-Deplacement
;if current coord <> targ pos you must found a path
If (chara\ToWorldPixelX<>chara\worldPixelX Or chara\ToWorldPixelY<>chara\worldPixelY) And chara\pathSize=0
;ici on utilise un pathfinding normalement
tileX=Int(chara\worldPixelX/#tileWidth)
tileY=Int(chara\worldPixelY/#tileWidth)
toTileX=Int(chara\ToWorldPixelX/#tileWidth)
toTileY=Int(chara\ToWorldPixelY/#tileWidth)
;pathfinding simulation
AddElement(path()):path()\x=1:path()\y=0
AddElement(path()):path()\x=1:path()\y=1
AddElement(path()):path()\x=2:path()\y=1
AddElement(path()):path()\x=3:path()\y=1
AddElement(path()):path()\x=4:path()\y=1
AddElement(path()):path()\x=5:path()\y=2
AddElement(path()):path()\x=6:path()\y=3
AddElement(path()):path()\x=6:path()\y=4
AddElement(path()):path()\x=6:path()\y=5
AddElement(path()):path()\x=6:path()\y=6
AddElement(path()):path()\x=7:path()\y=6
AddElement(path()):path()\x=8:path()\y=6
AddElement(path()):path()\x=9:path()\y=7
AddElement(path()):path()\x=9:path()\y=8
AddElement(path()):path()\x=8:path()\y=9
AddElement(path()):path()\x=7:path()\y=10
AddElement(path()):path()\x=6:path()\y=10
AddElement(path()):path()\x=5:path()\y=10
AddElement(path()):path()\x=5:path()\y=9
AddElement(path()):path()\x=4:path()\y=8
AddElement(path()):path()\x=3:path()\y=7
AddElement(path()):path()\x=3:path()\y=6
AddElement(path()):path()\x=3:path()\y=5
AddElement(path()):path()\x=3:path()\y=4
AddElement(path()):path()\x=3:path()\y=3
AddElement(path()):path()\x=2:path()\y=2
AddElement(path()):path()\x=1:path()\y=1
AddElement(path()):path()\x=0:path()\y=1
chara\pathSize=ListSize(path()) ;tile number in the path
chara\startTime=ElapsedMilliseconds() ;time to move
chara\num=-1 ; init my path pointer
chara\startWorldPixelX=chara\worldPixelX ; save the start coord
chara\startWorldPixelY=chara\worldPixelY ;
;End
EndIf
;si on a un path alors hop on avance
If chara\pathSize>0
t.f=(ElapsedMilliseconds()-chara\startTime)/1000 ;t= 0 last tile => 1 next tile
move=1 ;we move
;if next tile
If t>=1
t=1
If chara\num>chara\pathSize-2 ;the end
Debug "end";
;clear the path
ClearList(path())
move=0 ;no move
chara\pathSize=0
chara\num=0
chara\worldPixelX=chara\ToWorldPixelX ;on est bien arrivé au point qu'on voulait
chara\worldPixelY=chara\ToWorldPixelY
EndIf
chara\startTime=ElapsedMilliseconds(): ;je memorise le temps
EndIf
EndIf
If move=1 ; if we must move
Dim p.point(3) ;to know position on a catmull rom, i must know 4 points
For z=0 To 3
num=chara\num+z-1
If num<0:
num=-1
EndIf
If num>chara\pathSize-1
num=chara\pathSize-1
EndIf
Select num
Case -1
p(z)\x=chara\startWorldPixelX
p(z)\y=chara\startWorldPixelY
Case chara\pathSize-1
p(z)\x= chara\ToWorldPixelX
p(z)\y= chara\ToWorldPixelY
Default
SelectElement(path(),num)
p(z)\x=path()\x*#tileWidth+#tileWidth/2
p(z)\y=path()\y*#tileWidth+#tileWidth/2
EndSelect
Next
result.point
CatmullRomSpline(t,result,p(0),p(1),p(2),p(3))
If t>=1 ;if next tile
chara\num+1:;next path tile
EndIf
;new coord to to caracters
chara\worldPixelX=result\x
chara\worldPixelY=result\y
EndIf
FlipBuffers()
ClearScreen(0) ; A blue background
StartDrawing(ScreenOutput())
For x=1 To 20
LineXY(x*#tileWidth,0,x*#tileWidth,600,#White)
Next
For y=0 To 20
LineXY(0,y*#tileWidth,800,y*#tileWidth,#White)
Next
ForEach path()
Box(path()\x*#tileWidth,path()\y*#tileWidth,#tileWidth,#tileWidth,RGB(50,50,50))
Next
Circle(chara\worldPixelX,chara\worldPixelY,5,#Red)
StopDrawing()
ForEver
Else
MessageRequester("Error", "Can't open windowed screen!", 0)
EndIf
EndIf