Donnez du mouvement aux sprites.
Publié : dim. 21/déc./2025 10:02
"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"
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"
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