Page 1 sur 1

Donnez du mouvement aux sprites.

Publié : dim. 21/déc./2025 10:02
par plabouro472
"Obj Trajet.pbi" : objet POO

Donne une trajectoire aux sprites.
On commence par initialiser l'objet avec ses coordonnées de départ, d'arrivée et sa vitesse.
Peut être dans une variable, table, map ou liste pourvu quelle soit typée .NewTrajet
On ajoute des points supplémentaire si besoin.
On défini le mode de déplacement.
On récupère les coordonnées x et y puis l'angle que l'on affecte à un sprite.
La vitesse et le mode de déplacement peuvent être modifiées en cours de fonctionnement.
C'est tout.

Initialisation :
MonObjet .NewTrajet = Trajet_Init ( x1.w , y1.w , x2.w , y2.w, speed.f )

Les commandes :
MonObjet\Free ( ) ; Libere la mémoire.
MonObjet\AddPoint ( x.w , y.w ) ; Ajoute un nouveau point de passage.
MonObjet\Refresh ( ) ; Calcule la nouvelle position.

MonObjet\SetSpeed ( sp.f ) ; Définit la vitesse de déplacement
MonObjet\SetModeOff ( ) ; En fin de parcours, le déplacement s'arrête sur le dernier point
MonObjet\SetModeWrap ( ) ; En fin de parcours, le déplacement reprend sur le premier point
MonObjet\SetModeBounce ( ) ; En fin de parcours, le déplacement reprend en sens inverse

PosX = MonObjet\GetX ( ) ; Retourne la coordonnée X
PosY = MonObjet\GetY ( ) ; Retourne la coordonnée Y
Vit = MonObjet\GetSpeed ( ) ; Retourne la vitesse
AngleRad = MonObjet\GetAngleRad ( ) ; Retourne l'angle en radian
AngleDeg = MonObjet\GetAngleDeg ( ) ; Retourne l'angle en degré ( utile pour orienter les sprites )

If MonObjet\IsModeOff ( ) ; Retourne TRUE si le mode est ModeOff
If MonObjet\IsModeWrap ( ) ; Retourne TRUE si le mode est ModeWrap
If MonObjet\IsModeBounce ( ) ; Retourne TRUE si le mode est ModeBounce

If MonObjet\IsEndOfLine ( ) ; Fin de ligne atteint ( ModeOff ModeBounce ModeWrap)
If MonObjet\IsEndOfCycle ( ) ; Fin de cycle atteint ( ------- ModeBounce ModeWrap)
If MonObjet\IsEndOfRoad ( ) ; Fin de parcours atteint ( ModeOff ModeBounce ModeWrap)


le code "Obj Trajet.pbi"

Code : Tout sélectionner

 

; ****************************************
; Obj Trajet.pbi
; PB 6.21
; Windows 11
; ****************************************


#ModeOff = 1 ; Mode 0 = Arret en fin de ligne
#ModeBounce = 2 ; Mode 1 = Mouvement inversé après le dernier point.
#ModeWrap = 3 ; Mode 2 = Retourne directement au point de départ après le dernier point.

Interface NewTrajet
 Free ( ) ; Libere la mémoire
 AddPoint ( _x.w , _y.w ) ; Ajoute un nouveau point
 Refresh ( ) ; Calcule la nouvelle position
 
 SetSpeed ( _sp.f ) ; Vitesse de déplacement
 SetModeOff ( ) ; En fin de parcours, le déplacement s'arrête sur le dernier point
 SetModeWrap ( ) ; En fin de parcours, le déplacement reprend sur le premier point
 SetModeBounce ( ) ; En fin de parcours, le déplacement reprend en sens inverse
 
 GetX .w ( ) ; Retourne la coordonnée X
 GetY .w ( ) ; Retourne la coordonnée Y
 GetSpeed .f ( ) ; Retourne la vitesse
 GetAngleRad .f ( ) ; Retourne l'angle en radian
 GetAngleDeg .f ( ) ; Retourne l'angle en degré
 
 IsModeOff .a ( ) ; Retourne TRUE si le mode est ModeOff
 IsModeWrap .a ( ) ; Retourne TRUE si le mode est ModeWrap
 IsModeBounce .a ( ) ; Retourne TRUE si le mode est ModeBounce
 
 IsEndOfLine .a ( ) ; EndOfLine Fin de ligne atteint ( #ModeOff #ModeBounce #ModeWrap )
 IsEndOfCycle .a ( ) ; EndOfCycle Fin de cycle atteint ( -------- #ModeBounce #ModeWrap )
 IsEndOfRoad .a ( ) ; EndOfRoad Fin de parcours atteint ( #ModeOff ----------- --------- )
 
EndInterface

Structure TypLine
 X1 .w
 Y1 .w
 X2 .w
 Y2 .w
EndStructure

Structure Trajet_Typ
 *DSVT
 LigneX0 .w ; Point d'origine X
 LigneY0 .w ; Point d'origine Y
 LigneX1 .w ; Point de départ X
 LigneY1 .w ; Point de départ Y
 LigneX2 .w ; Point d'arrivée X
 LigneY2 .w ; Point d'arrivée Y
 PointX .f ; Coordonnées de l'objet X
 PointY .f ; Coordonnées de l'objet Y
 Angle .f ; Angle de la ligne
 Vitesse .f ; Vitesse de déplacement
 Sens .b ; Sens de déplacement +1 -1
 Mode .a ; Mode de déplacement #ModeOff = 1 #ModeBounce = 2 #ModeWrap = 3
 FinDeLigne .a ; Fin de ligne atteinte ( #ModeOff #ModeBounce #ModeWrap )
 FinDeCycle .a ; Fin de cycle atteint ( #ModeBounce #ModeWrap )
 FinDeParcours .a ; Fin de parcourt atteint ( #ModeOff )
 
 Angle90 .f
 Angle180 .f
 Angle270 .f
 Angle360 .f
 
 List ListLine .TypLine ( )
EndStructure



; Procedures Privees
Procedure .a Trajet_Out ( *This.Trajet_Typ )
 With *This
 If \PointX > \LigneX1 And \PointX > \LigneX2 : ProcedureReturn #True : EndIf
 If \PointX < \LigneX1 And \PointX < \LigneX2 : ProcedureReturn #True : EndIf
 
 If \PointY > \LigneY1 And \PointY > \LigneY2 : ProcedureReturn #True : EndIf
 If \PointY < \LigneY1 And \PointY < \LigneY2 : ProcedureReturn #True : EndIf
 ProcedureReturn #False
 EndWith
EndProcedure



; Procedures Publiques ( Methode )
Procedure Trajet_Free ( *This.Trajet_Typ )
 FreeMemory( *This )
EndProcedure
Procedure Trajet_AddPoint ( *This.Trajet_Typ , _x.w , _y.w )
 Protected .w TmpX , TmpY
 With *This
 LastElement( \ListLine() )
 TmpX = \ListLine()\X2
 TmpY = \ListLine()\Y2
 
 AddElement( \ListLine ( ) )
 \ListLine()\X1 = TmpX ; Le point précédent
 \ListLine()\Y1 = TmpY
 \ListLine()\X2 = _x ; Le nouveau point
 \ListLine()\Y2 = _y
 
 FirstElement( \ListLine() )
 \LigneX1 = \ListLine()\X1
 \LigneY1 = \ListLine()\Y1
 \LigneX2 = \ListLine()\X2
 \LigneY2 = \ListLine()\Y2
 
 \PointX = \ListLine()\X1
 \PointY = \ListLine()\Y1
 \Sens = 1
 \Angle = ATan2( \LigneX2 - \LigneX1 , \LigneY2 - \LigneY1 )
 
 EndWith
EndProcedure
Procedure Trajet_Refresh ( *This.Trajet_Typ )
 With *This
 \FinDeLigne = #False ; Fin de ligne atteinte
 \FinDeCycle = #False ; Fin de cycle atteint
 \FinDeParcours = #False
 
 \PointX + \Vitesse * Cos( \Angle ) ; Position suivante
 \PointY + \Vitesse * Sin( \Angle )
 
 If Trajet_Out ( *This ) ; Si Position suivante sort de la ligne
 \FinDeLigne = #True
 Select \Mode
 Case #ModeBounce ; Mouvement inversé après le dernier point.
 If \sens > 0 ; Si sens de déplacement positif
 If Not NextElement( \ListLine() ) ; Si on a pas de ligne suivante
 \sens = -1 ; changement de sens de déplacement 
 LastElement( \ListLine() ) ; On pointe sur le dernier élément puique l'on revient en arrière
 \FinDeParcours = #True
 EndIf
 
 ElseIf \sens < 0 ; Si sens de déplacement negatif
 If Not PreviousElement( \ListLine() ) ; Si on a pas de ligne precedente
 \sens = 1 ; changement de sens de déplacement 
 FirstElement( \ListLine() ) ; On pointe sur le premier élément puique l'on repart en avant
 \FinDeParcours = #True
 EndIf
 
 EndIf
 ;CaseEnd
 
 Case #ModeWrap ; Retourne au point de départ après le dernier point.
 
 If \sens > 0 ; Si sens de déplacement positif
 If Not NextElement( \ListLine() ) ; Si on a pas de ligne suivante
 FirstElement( \ListLine() ) ; On pointe sur le premier élément
 \FinDeParcours = #True
 EndIf
 
 ElseIf \sens < 0 ; Si sens de déplacement negatif
 If Not PreviousElement( \ListLine() ) ; Si on a pas de ligne precedente
 LastElement( \ListLine() ) ; On pointe sur le dernier élément
 \FinDeParcours = #True
 EndIf
 EndIf
 ;CaseEnd
 
 Case #ModeOff ; Arret du parcourt après le dernier point.
 If \sens > 0 ; Si sens de déplacement positif
 If Not NextElement( \ListLine() ) ; Si on a pas de ligne suivante
 \FinDeParcours = #True
 \PointX = \LigneX2
 \PointY = \LigneY2
 ProcedureReturn
 EndIf
 
 ElseIf \sens < 0 ; Si sens de déplacement negatif
 If Not PreviousElement( \ListLine() ) ; Si on a pas de ligne precedente
 \FinDeParcours = #True
 \PointX = \LigneX2
 \PointY = \LigneY2
 ProcedureReturn
 EndIf
 
 EndIf
 ;CaseEnd
 
 EndSelect
 
 ; Traitement de la ligne suivante
 \LigneX1 = \ListLine()\X1 ; Point de depart
 \LigneY1 = \ListLine()\Y1
 \LigneX2 = \ListLine()\X2 ; Point d'arrivee
 \LigneY2 = \ListLine()\Y2
 If \sens < 0 ; Si sens negatif on inverse le point de départ avec le point d'arrivé
 Swap \LigneX1 , \LigneX2
 Swap \LigneY1 , \LigneY2
 EndIf
 \PointX = \LigneX1 ; Recalcule les points et l'angle avec les nouvelles valeurs
 \PointY = \LigneY1
 \Angle = ATan2( \LigneX2 - \LigneX1 , \LigneY2 - \LigneY1 )
 If \Angle < 0 : \Angle + \Angle360 : EndIf
 \Angle = Mod( \Angle , \Angle360 )
 
 If \LigneX1 = \LigneX0 And \LigneY1 = \LigneY0
 \FinDeCycle = #True ; Fin de cycle lorsque les coordonnées correspondent celles du point de départ
 EndIf
 
 
 EndIf
 
 EndWith
EndProcedure

Procedure Trajet_SetSpeed ( *This.Trajet_Typ , _sp.f )
 With *This
 \Vitesse = Abs ( _sp )
 EndWith
EndProcedure
Procedure Trajet_SetModeOff ( *This.Trajet_Typ )
 With *This
 \Mode = #ModeOff ; Arret après le dernier point.
 \FinDeLigne = #False ; Fin de ligne atteinte
 \FinDeCycle = #False ; Fin de cycle atteint
 \FinDeParcours = #False ; Fin de parcours atteint ( #ModeOff uniquement)
 EndWith
EndProcedure
Procedure Trajet_SetModeWrap ( *This.Trajet_Typ )
 With *This
 \Mode = #ModeWrap ; Retourne directement au point de départ après le dernier point.
 \FinDeLigne = #False ; Fin de ligne atteinte
 \FinDeCycle = #False ; Fin de cycle atteint
 \FinDeParcours = #False ; Fin de parcours atteint ( #ModeOff uniquement)
 EndWith
EndProcedure
Procedure Trajet_SetModeBounce ( *This.Trajet_Typ )
 With *This
 \Mode = #ModeBounce ; Mouvement inversé après le dernier point.
 \FinDeLigne = #False ; Fin de ligne atteinte
 \FinDeCycle = #False ; Fin de cycle atteint
 \FinDeParcours = #False ; Fin de parcours atteint ( #ModeOff uniquement)
 EndWith
EndProcedure

Procedure .w Trajet_GetX ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \PointX
 EndWith
EndProcedure
Procedure .w Trajet_GetY ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \PointY
 EndWith
EndProcedure
Procedure .f Trajet_GetSpeed ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \Vitesse
 EndWith
EndProcedure
Procedure .f Trajet_GetAngleRad ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \Angle
 EndWith
EndProcedure
Procedure .f Trajet_GetAngleDeg ( *This.Trajet_Typ )
 With *This
 ProcedureReturn Degree( \Angle )
 EndWith
EndProcedure

Procedure .a Trajet_IsModeOff ( *This.Trajet_Typ )
 With *This
 ProcedureReturn Bool( \Mode = #ModeOff )
 EndWith
EndProcedure
Procedure .a Trajet_IsModeWrap ( *This.Trajet_Typ )
 With *This
 ProcedureReturn Bool( \Mode = #ModeWrap )
 EndWith
EndProcedure
Procedure .a Trajet_IsModeBounce ( *This.Trajet_Typ )
 With *This
 ProcedureReturn Bool( \Mode = #ModeBounce )
 EndWith
EndProcedure

Procedure .a Trajet_IsEndOfLine ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \FinDeLigne
 EndWith
EndProcedure
Procedure .a Trajet_IsEndOfCycle ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \FinDeCycle
 EndWith
EndProcedure
Procedure .a Trajet_IsEndOfRoad ( *This.Trajet_Typ )
 With *This
 ProcedureReturn \FinDeParcours
 EndWith
EndProcedure

Procedure .i Trajet_Init ( _x1.w , _y1.w , _x2.w , _y2.w, _sp.f )
 Protected *Object.Trajet_Typ
 *Object = AllocateMemory( SizeOf( Trajet_Typ ) )
 If *Object
 With *Object
 \DSVT = ?Trajet_Class
 NewList \ListLine ( )
 AddElement( \ListLine ( ) )
 \ListLine()\X1 = _x1
 \ListLine()\Y1 = _y1
 \ListLine()\X2 = _x2
 \ListLine()\Y2 = _y2
 
 \LigneX0 = \ListLine()\X1
 \LigneY0 = \ListLine()\Y1
 \LigneX1 = \ListLine()\X1
 \LigneY1 = \ListLine()\Y1
 \LigneX2 = \ListLine()\X2
 \LigneY2 = \ListLine()\Y2
 
 \PointX = \ListLine()\X1
 \PointY = \ListLine()\Y1
 \Vitesse = Abs( _sp )
 \Sens = 1
 \Mode = #ModeOff ; Mode 1 = Arret après le dernier point.
 ; Mode 2 = Mouvement inversé après le dernier point.
 ; Mode 3 = Retourne directement au point de départ après le dernier point.
 \FinDeLigne = #False ; Fin de ligne atteinte
 \FinDeCycle = #False ; Fin de cycle atteint
 \FinDeParcours = #False ; Fin de parcours atteint ( #ModeOff uniquement)
 
 \Angle90 = #PI / 2
 \Angle180 = #PI 
 \Angle270 = #PI * 3 / 4
 \Angle360 = #PI * 2
 
 \Angle = ATan2( \LigneX2 - \LigneX1 , \LigneY2 - \LigneY1 )
 
 If \Angle < 0 : \Angle + \Angle360 : EndIf
 
 \Angle = Mod( \Angle , \Angle360 )
 
 EndWith
 EndIf
 ProcedureReturn *object
EndProcedure

DataSection
 Trajet_Class:
 Data.i @Trajet_Free ( )
 Data.i @Trajet_AddPoint ( )
 Data.i @Trajet_Refresh ( )
 
 Data.i @Trajet_SetSpeed ( )
 Data.i @Trajet_SetModeOff ( )
 Data.i @Trajet_SetModeWrap ( )
 Data.i @Trajet_SetModeBounce ( )
 
 Data.i @Trajet_GetX ( )
 Data.i @Trajet_GetY ( )
 Data.i @Trajet_GetSpeed ( )
 Data.i @Trajet_GetAngleRad ( )
 Data.i @Trajet_GetAngleDeg ( )
 
 Data.i @Trajet_IsModeOff ( )
 Data.i @Trajet_IsModeWrap ( )
 Data.i @Trajet_IsModeBounce ( )
 Data.i @Trajet_IsEndOfLine ( )
 Data.i @Trajet_IsEndOfCycle ( )
 Data.i @Trajet_IsEndOfRoad ( )
EndDataSection






La démo regroupe l'ensemble des commandes disponibles.
le sprite orange et rouge modifie le comportement du sprite bleu.

Le code "Obj Trajet Démo.pb"

Code : Tout sélectionner

 

; ****************************************
; Trajet Démo
; PB 6.21
; Windows 11
; ****************************************

DataSection
 DataImage_Spr:
 Data .l %11111000000000000000000000000000
 Data .l %00001110000000000000000000000000
 Data .l %00000001100000000000000000000000
 Data .l %00000000111000000000000000000000
 Data .l %00000000001110000000000000000000
 Data .l %00000000000111000000000000000000
 Data .l %00000000000011110000000000000000
 Data .l %00000000000011111100000000000000
 Data .l %00000000000001111111000000000000
 Data .l %00000000000000111111110000000000
 Data .l %00000000000000111111111000000000
 Data .l %00000000000000111111111110000000
 Data .l %00000000000000011111111111100000
 Data .l %00000000000000011111111111111000
 Data .l %00000000000000011111111111111110
 Data .l %00000000000000011111111111111111
 Data .l %00000000000000011111111111111111
 Data .l %00000000000000011111111111111110
 Data .l %00000000000000011111111111111000
 Data .l %00000000000000011111111111100000
 Data .l %00000000000000111111111110000000
 Data .l %00000000000000111111111000000000
 Data .l %00000000000000111111110000000000
 Data .l %00000000000001111111000000000000
 Data .l %00000000000011111100000000000000
 Data .l %00000000000011110000000000000000
 Data .l %00000000000111000000000000000000
 Data .l %00000000001110000000000000000000
 Data .l %00000000111000000000000000000000
 Data .l %00000001100000000000000000000000
 Data .l %00001110000000000000000000000000
 Data .l %11111000000000000000000000000000
EndDataSection

Procedure .i NewSprite ( Color.l = #White )
 Protected .i SprTmp
 Protected .i Mask 
 Protected .i Valeur 
 SprTmp = CreateSprite( #PB_Any , 32 , 32 , #PB_Sprite_AlphaBlending | #PB_Sprite_Transparent )
 If StartDrawing( SpriteOutput( SprTmp ) )
 DrawingMode( #PB_2DDrawing_AllChannels )
 Restore DataImage_Spr
 For y = 0 To 31
 Mask = $80000000
 Read .l Valeur
 For x = 0 To 31
 If Valeur & Mask
 Plot( x , y , RGBA( Red( Color ) , Green( Color ) , Blue( Color ) , $FF ) )
 Else
 Plot( x , y , RGBA( $00, $00, $00, $00 ) )
 EndIf
 Mask = ( Mask >> 1 ) & $7FFFFFFF
 Next
 Next
 StopDrawing()
 EndIf
 ProcedureReturn SprTmp
EndProcedure

If Not InitSprite()
 MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran & l'environnement nécessaire aux ImageSprites !" , 0 )
 End
EndIf

Global MaWin .i = OpenWindow ( #PB_Any , 0 , 0 , 800 , 600 , "Teste de trajets" , #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
OpenWindowedScreen ( WindowID( MaWin ) , 0 , 0 , 800 , 600 )
SpriteQuality ( #PB_Sprite_BilinearFiltering )



XIncludeFile "Obj Trajet.pbi" ; Inclusion de l'objet POO
; Initialisation :
; MonObjet .NewTrajet = Trajet_Init ( _x1.w , _y1.w , _x2.w , _y2.w, _sp.f )
;
; Les commandes :
; MonObjet\Free ( ) ; Libere la mémoire
; MonObjet\AddPoint ( _x.w , _y.w ) ; Ajoute un nouveau point
; MonObjet\Refresh ( ) ; Calcule la nouvelle position
;
; MonObjet\SetSpeed ( _sp.f ) ; Vitesse de déplacement
; MonObjet\SetModeOff ( ) ; En fin de parcours, le déplacement s'arrête sur le dernier point
; MonObjet\SetModeWrap ( ) ; En fin de parcours, le déplacement reprend sur le premier point
; MonObjet\SetModeBounce ( ) ; En fin de parcours, le déplacement reprend en sens inverse
;
; PosX = MonObjet\GetX ( ) ; Retourne la coordonnée X
; PosY = MonObjet\GetY ( ) ; Retourne la coordonnée Y
; Vit = MonObjet\GetSpeed ( ) ; Retourne la vitesse
; AngleRad = MonObjet\GetAngleRad ( ) ; Retourne l'angle en radian
; AngleDeg = MonObjet\GetAngleDeg ( ) ; Retourne l'angle en degré
;
; If MonObjet\IsModeOff ( ) ; Retourne TRUE si le mode est ModeOff
; If MonObjet\IsModeWrap ( ) ; Retourne TRUE si le mode est ModeWrap
; If MonObjet\IsModeBounce ( ) ; Retourne TRUE si le mode est ModeBounce
;
; If MonObjet\IsEndOfLine ( ) ; EndOfLine Fin de ligne atteint ( ModeOff ModeBounce ModeWrap )
; If MonObjet\IsEndOfCycle ( ) ; EndOfCycle Fin de cycle atteint ( ------- ModeBounce ModeWrap )
; If MonObjet\IsEndOfRoad ( ) ; EndOfRoad Fin de parcours atteint ( ModeOff ModeBounce ModeWrap )
;




Global ImageDeFond .i = CreateImage ( #PB_Any , 800, 600 , 24 , #Black )

Global TraceOn .a = #True ; Visualise le parcours, si pas de visu, remplacez #True par #False


Structure Objet_Typ
 Objet .NewTrajet ; L'objet POO
 ImageSpr .i ; Image du sprite
 ColFond .l ; Couleur du traçage
 Nom .s ; Nom de l'objet pour identification
EndStructure

; Une liste pour les differents mouvements des sprites
NewList Mouvement .Objet_Typ ( ) ; La liste a une structure 


; *******************************************
; Routine d'affichage des sprites à l'écran *
Procedure Trace ( List Aff.Objet_Typ() )
 If TraceOn ; Affichage du tracé sur l'image de fond
 StartDrawing( ImageOutput( ImageDeFond ) )
 ForEach Aff()
 Plot ( Aff()\Objet\GetX( ) , Aff()\Objet\GetY( ) , Aff()\ColFond ) 
 Next
 StopDrawing() 
 EndIf
 
 StartDrawing( ScreenOutput( ) )
 DrawImage( ImageID( ImageDeFond ) , 0 , 0 ) ; Plaque l'image de fond
 StopDrawing() 
 
 ForEach Aff() ; Affiche le sprite aux coordonnées avec son angle
 RotateSprite ( Aff()\ImageSpr , Aff()\Objet\GetAngleDeg() , #PB_Absolute )
 DisplayTransparentSprite ( Aff()\ImageSpr , Aff()\Objet\GetX( ) - 16 , Aff()\Objet\GetY( ) - 16 , 255 )
 Next
EndProcedure


; *********************************************
; Initialisation des sprites et leurs trajets *
AddElement( Mouvement() ) ;{ Ajoute un sprite bleu avec les propriétés suivantes
Mouvement()\Nom = "SprBleu" ; Nom du sprite
Mouvement()\ColFond = $ffaaaa ; Couleur du tracé
Mouvement()\ImageSpr = NewSprite( #Blue ) ; création de l' image du sprite 
;Mouvement()\ImageSpr = LoadSprite( #PB_Any , "SprBleu.bmp" , #PB_Sprite_AlphaBlending ) ; Image du sprite sur disque

; ( x1.w , y1.w , x2.w , y2.w , speed.f )
Mouvement()\Objet = Trajet_Init ( 032 , 192 , 288 , 160 , 1.4 )
Mouvement()\Objet\AddPoint ( 288 , 192 )
Mouvement()\Objet\AddPoint ( 128 , 192 )
Mouvement()\Objet\AddPoint ( 064 , 320 )
Mouvement()\Objet\AddPoint ( 224 , 320 )
Mouvement()\Objet\AddPoint ( 112 , 432 )
Mouvement()\Objet\AddPoint ( 352 , 496 )
Mouvement()\Objet\AddPoint ( 352 , 448 )
Mouvement()\Objet\AddPoint ( 448 , 448 )
Mouvement()\Objet\AddPoint ( 528 , 512 )
Mouvement()\Objet\AddPoint ( 624 , 512 )
Mouvement()\Objet\AddPoint ( 544 , 352 )
Mouvement()\Objet\AddPoint ( 512 , 352 )
Mouvement()\Objet\AddPoint ( 512 , 320 )
Mouvement()\Objet\AddPoint ( 640 , 288 )
Mouvement()\Objet\AddPoint ( 608 , 192 )
Mouvement()\Objet\AddPoint ( 480 , 192 )
Mouvement()\Objet\AddPoint ( 480 , 160 )
Mouvement()\Objet\AddPoint ( 608 , 128 )
Mouvement()\Objet\SetModeOff ( ) ;}

AddElement( Mouvement() ) ;{ Ajoute un sprite vert avec les propriétés suivantes
Mouvement()\Nom = "SprVert"
Mouvement()\ColFond = $aaffaa
Mouvement()\ImageSpr = NewSprite( #Green )
Mouvement()\Objet = Trajet_Init ( 352 , 288 , 576 , 224 , 1.5 )
Mouvement()\Objet\AddPoint ( 432 , 192 )
Mouvement()\Objet\AddPoint ( 384 , 096 )
Mouvement()\Objet\AddPoint ( 272 , 128 )
Mouvement()\Objet\AddPoint ( 192 , 224 )
Mouvement()\Objet\AddPoint ( 176 , 352 )
Mouvement()\Objet\AddPoint ( 272 , 448 )
Mouvement()\Objet\AddPoint ( 400 , 480 )
Mouvement()\Objet\AddPoint ( 512 , 448 )
Mouvement()\Objet\AddPoint ( 480 , 320 )
Mouvement()\Objet\AddPoint ( 576 , 244 )
Mouvement()\Objet\AddPoint ( 676 , 224 )
Mouvement()\Objet\SetModeBounce ( ) ;}

AddElement( Mouvement() ) ;{ Ajoute un sprite rouge avec les propriétés suivantes
Mouvement()\Nom = "SprRouge"
Mouvement()\ColFond = $aaaaff
Mouvement()\ImageSpr = NewSprite( #Red )
Mouvement()\Objet = Trajet_Init ( 000 , 032 , 736 , 032 , 2 )
Mouvement()\Objet\AddPoint ( 768 , 064 )
Mouvement()\Objet\AddPoint ( 768 , 512 )
Mouvement()\Objet\AddPoint ( 736 , 544 )
Mouvement()\Objet\AddPoint ( 000 , 544 )
Mouvement()\Objet\SetModeWrap ( ) ;}

AddElement( Mouvement() ) ;{ Ajoute un sprite orange avec les propriétés suivantes
Mouvement()\Nom = "SprOrange"
Mouvement()\ColFond = $60b0ff
Mouvement()\ImageSpr = NewSprite( $0080FF )
Mouvement()\Objet = Trajet_Init ( 032 , 096 , 704 , 096 , 1 )
Mouvement()\Objet\AddPoint ( 704 , 480 )
Mouvement()\Objet\AddPoint ( 064 , 480 )
Mouvement()\Objet\AddPoint ( 064 , 160 )
Mouvement()\Objet\AddPoint ( 640 , 160 )
Mouvement()\Objet\SetModeOff ( ) ;}



FlagPauseBleu .a = #False
FlagFiniOrange .a = #False
FlagFini .a = #False
ComptRouge .a = 0
Repeat
 Trace ( Mouvement() ) ; Affichage de tous les sprites
 FlipBuffers ( )
 
 ForEach Mouvement() ; On gère les sprites un par un
 Mouvement()\Objet\Refresh( ) ; Calcule la prochaine position du sprite
 
 Select Mouvement()\Nom
 Case "SprBleu" ; Gestion du sprite bleu
 If Mouvement()\Objet\IsEndOfRoad() And Mouvement()\Objet\IsModeOff( ) And Not FlagPauseBleu ; Le sprite est en fin de parcours
 Debug Mouvement()\Nom + " fin de parcours"
 FlagPauseBleu = #True
 EndIf
 If Not Mouvement()\Objet\IsModeOff( ) ; Bascule en ModeOff si ce n'est pas le cas
 Mouvement()\Objet\SetModeOff( )
 Debug "* ObjetBleu\SetModeOff( ) , Mode aller simple."
 EndIf
 ; Fait repartir le sprite bleu en sens inverse lorsque le sprite orange a terminé son parcours
 If FlagPauseBleu And FlagFiniOrange 
 Mouvement()\Objet\SetModeBounce( )
 Debug "* ObjetBleu\SetModeBounce( ) , repart en sens inverse."
 FlagFiniOrange = #False
 FlagPauseBleu = #False
 ; Fait repartir le sprite bleu depuis le départ lorsque le sprite rouge a terminé 5 boucles
 ElseIf FlagPauseBleu And ComptRouge = 5
 Mouvement()\Objet\SetModeWrap( )
 Mouvement()\Objet\SetSpeed( Mouvement()\Objet\GetSpeed( ) + 0.6 )
 Debug "* ObjetBleu\SetModeWrap( ) , repart depuis le début, vitesse " + StrF( Mouvement()\Objet\GetSpeed( ) , 2 )
 FlagPauseBleu = #False
 ; Fait repartir le sprite bleu en sens inverse lorsque le sprite rouge a terminé 7 boucles
 ElseIf FlagPauseBleu And ComptRouge = 7 And Not FlagFini
 Mouvement()\Objet\SetModeBounce( )
 Mouvement()\Objet\SetSpeed( Mouvement()\Objet\GetSpeed( ) - 1 )
 Debug "* ObjetBleu\SetModeBounce( ) , repart en sens inverse, vitesse " + StrF( Mouvement()\Objet\GetSpeed( ) , 2 )
 FlagPauseBleu = #False
 FlagFini = #True
 EndIf
 ;CaseEnd
 
 Case "SprVert" ; Gestion du sprite vert
 If Mouvement()\Objet\IsEndOfRoad() And Not FlagFini ; Le sprite est en fin de parcours
 Debug Mouvement()\Nom + " fin de parcours"
 EndIf
 If Mouvement()\Objet\IsEndOfCycle() And Not FlagFini ; Le sprite est en fin de cycle
 Debug Mouvement()\Nom + " fin de cycle"
 EndIf
 If FlagFini
 Mouvement()\Objet\SetModeOff( )
 EndIf
 ;CaseEnd
 
 Case "SprRouge" ; Gestion du sprite rouge
 If Mouvement()\Objet\IsEndOfCycle() ; Le sprite est en fin de cycle
 ComptRouge + 1
 Debug Mouvement()\Nom + " fin de cycle n° " + Str( ComptRouge )
 EndIf
 If FlagFini
 Mouvement()\Objet\SetModeOff( )
 EndIf
 ;CaseEnd
 
 Case "SprOrange" ; Gestion du sprite orange
 If Mouvement()\Objet\IsEndOfRoad() ; Le sprite est en fin de parcours
 Debug Mouvement()\Nom + " fin de parcours, sprite détruit."
 Mouvement()\Objet\Free() ; Destruction du déplacement
 DeleteElement( Mouvement() , 1 ) ; Destruction du sprite
 FlagFiniOrange = #True
 EndIf
 ;CaseEnd
 
 EndSelect
 
 Next
 
 Event = WindowEvent()
 Delay( 10 )
 
Until Event = #PB_Event_CloseWindow

ForEach Mouvement()
 Mouvement()\Objet\Free( )
Next