Le problème c'est que ton "path" est trop lié à ton mobs , c'est pas souple , et pas facile d'emploi.
Pour ce genre de "problème" , j'utilise l'interpolation linéaire entre 2 points, dans l'exemple que je vais te donner, c'est basé sur des clé de temps ( comme un logiciel d'animation avec des keyFrame ) , tu rajoutes des positions à atteindre à un temps T , et tu laisse faire les fonctions , il y a 2 modes de déplacement , linéaire & cosine , Dans un logiciel d'animation cela correspondrais à l'icone "ligne droite" pour les déplacement linéaire, et ligne courbe pour les déplacement cosine, pour ce dernier , les virage sont donc moins brute , le point ralentit à l'arrivé , puis accélère ensuite en fonction du temps qui lui reste à atteindre le prochain point.
Tu peu utilisé aussi cette base de code pour animé n'importe quoi avec du temps & des clé ( des rotations , la mise a l'echelle , le pitch d'un son , etc..... )
Amuse toi bien
Code : Tout sélectionner
;
; HELPER FUNCTION
;
Procedure.f Min(a.f,b.f)
If a<b
ProcedureReturn a
EndIf
ProcedureReturn b
EndProcedure
;
; HELPER FUNCTION
;
Procedure.f Max(a.f,b.f)
If a>b
ProcedureReturn a
EndIf
ProcedureReturn b
EndProcedure
; Structure représentant un point dans l'espace
;
;
Structure vector2d
x.d
y.d
EndStructure
Procedure.b vector2dAreClose(*A.vector2d , *B.vector2d)
tolerance.f = 0.01
If (Abs(*A\x - *B\x) < tolerance) And (Abs(*A\y - *B\y) < tolerance)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;
; HELPER MACRO
;
Macro linearInterpolation(a,b,t)
(a*(1-t)+b*t)
EndMacro
;
; HELPER MACRO
;
Macro t2(t)
((1-Cos(t*#PI))/2)
EndMacro
;
; HELPER MACRO
;
Macro CosineInterpolation(a,b,t)
a * (1-t2(t))+b*t2(t)
EndMacro
Enumeration
#LINEAR_INTERPOLATION
#COSINE_INTERPOLATION
EndEnumeration
Procedure Interpolation1D(*value, min.d, max.d ,t.d, mode.l = #LINEAR_INTERPOLATION)
Select mode
Case #LINEAR_INTERPOLATION
PokeD(*value, linearInterpolation(min,max,t))
Case #COSINE_INTERPOLATION
PokeD(*value, CosineInterpolation(min,max,t))
EndSelect
EndProcedure
Procedure Interpolation2D(*vector.vector2d, *min.vector2d, *max.vector2d ,t.d, mode.l = #LINEAR_INTERPOLATION)
Select mode
Case #LINEAR_INTERPOLATION
*vector\x = linearInterpolation(*min\x,*max\x,t)
*vector\y = linearInterpolation(*min\y,*max\y,t)
Case #COSINE_INTERPOLATION
*vector\x = CosineInterpolation(*min\x,*max\x,t)
*vector\y = CosineInterpolation(*min\y,*max\y,t)
EndSelect
EndProcedure
;
;
;
Structure waypoint
position.vector2d
time.d
EndStructure
Structure path
List point.waypoint()
EndStructure
;
;
;
Procedure.i CreateWayPath()
*p.path = AllocateMemory(SizeOf(path))
If *p
InitializeStructure(*p,path)
ProcedureReturn *p
EndIf
ProcedureReturn #Null
EndProcedure
;
;
;
Procedure AddWayPoint(*p.path, x.d, y.d, time.d)
If *p
AddElement(*p\Point())
*p\Point()\position\x = x
*p\Point()\position\y = y
*p\Point()\time = time
EndIf
EndProcedure
;
;
;
Procedure.d GetWayPointX(*p.path,index.l)
If *p
PushListPosition(*p\Point())
SelectElement(*p\Point(),index)
result.f = *p\Point()\position\x
PopListPosition(*p\Point())
ProcedureReturn result
EndIf
EndProcedure
;
;
;
Procedure.d GetWayPointY(*p.path,index.l)
If *p
PushListPosition(*p\Point())
SelectElement(*p\Point(),index)
result.f = *p\Point()\position\y
PopListPosition(*p\Point())
ProcedureReturn result
EndIf
EndProcedure
; Structure representant un "suiveur"
; de path
;
Structure pathFollower
*follow.path
position.vector2d
moveTo.vector2d
index.l
timer.l
EndStructure
;
;
;
Procedure.i createFollower(*follow.path)
*f.pathFollower = AllocateMemory(SizeOf(*f))
If *f
FirstElement(*follow\Point())
*f\position\x = *follow\Point()\position\x
*f\position\y = *follow\Point()\position\y
NextElement(*follow\Point())
*f\moveTo\x = *follow\Point()\position\x
*f\moveTo\y = *follow\Point()\position\y
*f\timer = 0
*f\follow = *follow
*f\index = 0
FirstElement(*f\follow\Point())
ProcedureReturn *f
EndIf
ProcedureReturn #Null
EndProcedure
;
;
;
Procedure moveFollower(*follower.pathFollower, time.i)
If *follower
With *follower
; update time
;
\timer = time
nextTime.i = 0
While \timer >= nextTime
PushListPosition(*follower\follow\Point())
If NextElement(*follower\follow\Point()) = 0
ProcedureReturn 0
EndIf
nextTime = *follower\follow\Point()\time
*Follower\moveTo\x = *Follower\follow\Point()\position\x
*Follower\moveTo\y = *Follower\follow\Point()\position\y
PopListPosition(*follower\follow\Point())
If \timer >= nextTime
\index + 1
EndIf
SelectElement(*follower\follow\Point(),\index)
Wend
A.i = *follower\follow\Point()\time
B.i = nextTime
t.f = (\timer - Min(A,B)) / (Max(A,B)-Min(A,B))
Interpolation2D(@\position,@*follower\follow\Point()\position,@\moveTo,t, #LINEAR_INTERPOLATION) ; Change avec #COSINE_INTERPOLATION
EndWith
EndIf
EndProcedure
Procedure resetFollower(*f.pathFollower)
If *f
FirstElement(*f\follow\Point())
*f\position\x = *f\follow\Point()\position\x
*f\position\y = *f\follow\Point()\position\y
NextElement(*f\follow\Point())
*f\moveTo\x = *f\follow\Point()\position\x
*f\moveTo\y = *f\follow\Point()\position\y
*f\timer = 0
*f\index = 0
FirstElement(*f\follow\Point())
EndIf
EndProcedure
Procedure.f GetFollowerX(*f.pathFollower)
If *f
ProcedureReturn *f\position\x
EndIf
EndProcedure
Procedure.f GetFollowerY(*f.pathFollower)
If *f
ProcedureReturn *f\position\y
EndIf
EndProcedure
;-test
OpenWindow(0,0,0,1024,768,"")
CanvasGadget(0,0,0,1024,768)
*MyPath = CreateWayPath()
AddWayPoint(*MyPath,100,500,0) ; 100x100 au temp 0ms
AddWayPoint(*MyPath,200,200,500) ; 200x200 au temp 2000ms
AddWayPoint(*MyPath,400,400,1000) ; 200x200 au temp 2000ms
AddWayPoint(*MyPath,800,300,1500) ; 200x200 au temp 2000ms
AddWayPoint(*MyPath,900,600,2000) ; 200x200 au temp 2000ms
*Follower = createFollower(*MyPath)
simulatedTime.f = 0
While #True
If WindowEvent() = #PB_Event_CloseWindow
Break
EndIf
StartDrawing(CanvasOutput(0))
Box(0,0,OutputWidth(), OutputHeight(), $FFFFFF)
For p = 0 To 4
x.f = GetWayPointX(*MyPath,p)
y.f = GetWayPointY(*MyPath,p)
Circle(x,y,4,$999999)
Next
moveFollower(*Follower,simulatedTime)
Circle( GetFollowerX(*Follower),GetFollowerY(*Follower),4,$FF)
simulatedTime + 10
If simulatedTime => 2000
simulatedTime=0
resetFollower(*Follower)
EndIf
StopDrawing()
Wend