PB : 6.30
Os : Windows 11
Après leurs avoir donnés des trajectoires à suivre, nous allons leurs donner de l'animation et un point de référence.
Il peut être positionner n'importe ou à l'intérieure du sprite mais aussi à l'extérieur.
Les opérations de positionnement, Zooms et Rotations se feront par rapport à ce point de référence ou HotSpot.
La rotation se fait dans le sens trigo contrairement à l'instruction "RotateSprite" qui tourne dans le sens horaire.
Le zoom se mesure en pourcentage de la taille d'origine du Sprite.
L'animation peut revenir en arrière ou reprendre au début après la dernière image, ceci dans les deux sens.
l'image de départ peut être n'importe laquelle des images de la palette.
Les propriétés de chacun des Sprites seront stockés dans une variable structurée.
Structure PointFloat
x.f
y.f
EndStructure
Structure Spr
IdSprite .i ; Identifiant du Sptire ( chargé/créé )
SprTaille .PointFloat ; Taille du Sprite ( Largeur,Hauteur )
HotSpot .PointFloat ; Points de référence du Sprite ( X,Y )
SprPos .PointFloat ; Position du Sprite à l'écran ( X,Y )
VitPos .PointFloat ; Vitesse de déplacement ( X,Y )
SprZoom .f ; Zoom du Sprite ( 1 = 100% de sa taille)
VitZoom .f ; Vitesse de Zoom ( +-0.02 = +-2% )
SprAngle .f ; Angle du Sprite en degré
VitAngle .f ; Vitesse angulaire en degré ( Positif = sens trigo )
AnimNo .b ; N° du Sprite à Clipper, dans la palette
AnimInc .b ; Incrémentation de position dans la palette ( +1/-1 )
AnimNoMax .b ; N° du dernier Sprite dans la palette
AnimRaz .a ; Reprend au 1er Sprite ( #True/#False )
EndStructure
Pour la démo, deux hélicoptères ( vraiment trééééééés..... basic ), se déplacent en sens inverse avec rotation et zoom.
Le point de référence du sprite 1 est centré horizontalement et verticalement.
Le point de référence du sprite 2 est positionné en bas et au milieu.
Le point de référence des sprites sera positionné sur la position d'affichage de celui-ci, materialisée par un axe traversant l'écran.
Une boite de dialogue temporise pour un affichage pas à pas.
Code : Tout sélectionner
; ******************************
; Animation de Sprites
; PB : 6.30
; Os : Windows 11
; ******************************
; ******************************
; ** Palette animation helico **
; ** **
; 20 pixels de large
; 22 Pixels de haut
; 10 images alignées horizontalement ( N° de 0 à 9 )
DataSection
DataPalette_Helico_20x22:
Data .a 6 ; Palette de 6 couleurs
Data .l $00000000 , $00FEF0F0 , $00FF8000 , $00FFF000 , $00FF8072 , $00150088
DataImage_Helico_20x22:
Data .a 05 , 11 ; Nombre de données de la table ( X , Y )
Data .a 04 , 02 ; Dimension des pixels ( X , Y )
Data_Helico: ; Données de l"hélico
Data .a $01,$01,$01,$01,$01
Data .a $00,$00,$01,$00,$00
Data .a $00,$00,$01,$00,$00
Data .a $00,$02,$02,$02,$00
Data .a $02,$02,$02,$02,$02
Data .a $02,$03,$03,$03,$02
Data .a $02,$03,$01,$03,$02
Data .a $02,$03,$01,$03,$02
Data .a $02,$03,$03,$03,$02
Data .a $04,$04,$02,$04,$04
Data .a $00,$04,$04,$04,$00
EndDataSection
Dim MesCouleurs .l ( 1 )
Restore DataPalette_Helico_20x22 ; Chargement de la palette de couleurs
Read .a N
ReDim MesCouleurs( N - 1 )
For I = 0 To N -1
Read .l MesCouleurs( I )
Next
Restore DataImage_Helico_20x22 ; Dessin de l'hélico
Read .a Larg
Read .a Haut
Read .a LargPix
Read .a HautPix
PaletteHelico = CreateImage( #PB_Any , Larg * LargPix * 10 , Haut * HautPix , 32 )
StartDrawing ( ImageOutput( PaletteHelico ) )
For N = 0 To 9 ; 10 images alignées horizontalement
Restore Data_Helico:
For Y = 0 To Haut - 1
For X = 0 To Larg - 1
Read .a C
Box( N*20 + X*LargPix , Y*HautPix , LargPix , HautPix , MesCouleurs( C ) )
Next
Next
Box( N*20 , 0 , N , HautPix , #Black ) ; Les pales
Box( N*20 + 20 - N , 0 , N , HautPix , #Black )
Next
StopDrawing()
FreeArray( MesCouleurs() )
; Sauvegarde sur disque
; SaveImage( PaletteHelico , GetCurrentDirectory() + "Palette_Helico_20x22.bmp" , #PB_ImagePlugin_BMP )
Structure PointFloat
x.f
y.f
EndStructure
Structure Spr
IdSprite .i ; Identifiant du Sptire ( chargé/créé )
SprTaille .PointFloat ; Taille du Sprite ( Largeur/Hauteur )
HotSpot .PointFloat ; Points de référence du Sprite ( X,Y )
SprPos .PointFloat ; Position du Sprite à l'écran ( X,Y )
VitPos .PointFloat ; Vitesse de déplacement ( X,Y )
SprZoom .f ; Zoom du Sprite ( 1 = 100% de sa taille)
VitZoom .f ; Vitesse de Zoom ( +-0.02 = +-2% )
SprAngle .f ; Angle du Sprite en degré
VitAngle .f ; Vitesse angulaire en degré ( Positif = sens horaire )
AnimNo .b ; N° du Sprite à Cliper dans la palette
AnimInc .b ; Incrémentation de position dans la palette ( +1/-1 )
AnimNoMax .b ; N° du dernier Sprite dans la palette
AnimRaz .a ; Reprend au 1er Sprite ( #True/#False )
EndStructure
#ScreenWidth = 800
#ScreenHeight = 600
#Tempo = 25
Attente.i = 5000
Procedure AfficheAxes ( *This.Spr , _C.l ) ; Dessin de l'axe
With *This\SprPos
StartDrawing ( ScreenOutput() )
Line ( \x , 0 , 1 , #ScreenHeight , _C )
Line ( 0 , \y , #ScreenWidth , 1 , _C )
Circle ( \x , \y , 2 , _C )
StopDrawing()
EndWith
EndProcedure
Procedure CalculePositionSuivante ( *This.Spr )
With *This
\SprPos\x + \VitPos\x
\SprPos\y + \VitPos\y
\SprZoom + \VitZoom
If \SprZoom < 1 : \SprZoom = 1: EndIf
\SprAngle + \VitAngle
If \SprAngle > 360 : \SprAngle - 360 : EndIf
If \SprAngle < 0 : \SprAngle + 360 : EndIf
\AnimNo + \AnimInc
If \AnimRaz ; L'animation reprend au début
If \AnimNo > \AnimNoMax : \AnimNo = 0 : EndIf
If \AnimNo < 0 : \AnimNo = \AnimNoMax : EndIf
Else ; L'animation reprend en arrière
If \AnimNo = \AnimNoMax Or \AnimNo = 0 : \AnimInc = -\AnimInc : EndIf
EndIf
EndWith
EndProcedure
Procedure AfficheSptite ( *This.Spr )
Protected .f TmpHotSpotx , TmpHotSpoty
Protected .f HotSpotLong , HotSpotAngle
Protected .f DeltaX , DeltaY
Protected .f DemiX , DemiY
With *This
; Calcule du HotSpot en tenant compte de la rotation ( Sens Trigo )
DemiX = \SprTaille\x / 2
DemiY = \SprTaille\y / 2
DeltaX = \HotSpot\x - DemiX
DeltaY = - ( \HotSpot\y - DemiY )
HotSpotLong = Sqr( ( DeltaX * DeltaX ) + (DeltaY * DeltaY ) )
HotSpotAngle = ATan2( DeltaX , DeltaY ) + Radian( \SprAngle )
TmpHotSpotx = ( DemiX + ( Cos( HotSpotAngle ) * HotSpotLong ) ) * \SprZoom
TmpHotSpoty = ( DemiY - ( Sin( HotSpotAngle ) * HotSpotLong ) ) * \SprZoom
ClipSprite ( \IdSprite , \AnimNo * \SprTaille\x , 0 , \SprTaille\x , \SprTaille\y )
ZoomSprite ( \IdSprite , \SprTaille\x * \SprZoom , \SprTaille\y * \SprZoom )
RotateSprite ( \IdSprite , -\SprAngle , #PB_Absolute )
DisplayTransparentSprite( \IdSprite , \SprPos\x - TmpHotSpotx , \SprPos\y - TmpHotSpoty )
EndWith
EndProcedure
InitSprite()
OpenWindow ( 0 , 100 , 100 , #ScreenWidth , #ScreenHeight , "Sprite..." , #PB_Window_SystemMenu )
OpenWindowedScreen ( WindowID(0) , 0 , 0 , #ScreenWidth , #ScreenHeight , #True , 0 , 0 )
#SpriteWidth = 20
#SpriteHeight = 22
#SpriteNoMax = 9 ; Numéro du dernier sprite dans la palette
; ********************************
; *** Initialise le Sprite N°1 ***
; ********************************
MonSprite1 .Spr
; ; Chargement depuis le disque
; MonSprite1\IdSprite = LoadSprite( #PB_Any , GetCurrentDirectory() + "Palette_Helico_20x22.bmp" , #PB_Sprite_AlphaBlending )
; ou Chargement depuis une image
MonSprite1\IdSprite = CreateSprite( #PB_Any , 10 * #SpriteWidth , #SpriteHeight , #PB_Sprite_AlphaBlending )
StartDrawing ( SpriteOutput( MonSprite1\IdSprite ) )
DrawingMode ( #PB_2DDrawing_AllChannels )
DrawImage ( ImageID( PaletteHelico ) , 0 , 0 )
StopDrawing ( )
TransparentSpriteColor( MonSprite1\IdSprite , RGB( 0,0,0 ) )
; Les propriétées
MonSprite1\SprTaille\x = #SpriteWidth
MonSprite1\SprTaille\y = #SpriteHeight
MonSprite1\HotSpot\x = #SpriteWidth / 2
MonSprite1\HotSpot\y = #SpriteHeight / 2
MonSprite1\SprPos\x = 200
MonSprite1\SprPos\y = 200
MonSprite1\VitPos\x = 2
MonSprite1\VitPos\y = 0
MonSprite1\SprZoom = 5.00 ; 5 fois sa taille ( 500% )
MonSprite1\VitZoom = -0.02 ; réduit sa taille de 2%
MonSprite1\SprAngle = 0
MonSprite1\VitAngle = -1 ; <0 = Sens Trigo
MonSprite1\AnimNo = 5 ; Image de départ
MonSprite1\AnimInc = 1
MonSprite1\AnimNoMax = #SpriteNoMax
MonSprite1\AnimRaz = #False
; ********************************
; *** Initialise le Sprite N°2 ***
; ********************************
MonSprite2 .Spr
; ; Chargement depuis le disque
; MonSprite2\IdSprite = LoadSprite( #PB_Any , GetCurrentDirectory() + "Palette_Helico_20x22.bmp" , #PB_Sprite_AlphaBlending )
; ou Chargement depuis une image
MonSprite2\IdSprite = CreateSprite( #PB_Any , 10 * #SpriteWidth , #SpriteHeight , #PB_Sprite_AlphaBlending )
StartDrawing ( SpriteOutput( MonSprite2\IdSprite ) )
DrawingMode ( #PB_2DDrawing_AllChannels )
DrawImage ( ImageID( PaletteHelico ) , 0 , 0 )
StopDrawing ( )
TransparentSpriteColor( MonSprite2\IdSprite , RGB( 0,0,0 ) )
; Les propriétées
MonSprite2\SprTaille\x = #SpriteWidth
MonSprite2\SprTaille\y = #SpriteHeight
MonSprite2\HotSpot\x = #SpriteWidth / 2
MonSprite2\HotSpot\y = #SpriteHeight
MonSprite2\SprPos\x = 480
MonSprite2\SprPos\y = 300
MonSprite2\VitPos\x = -2
MonSprite2\VitPos\y = 0
MonSprite2\SprZoom = 1.50
MonSprite2\VitZoom = 0.03
MonSprite2\SprAngle = 45
MonSprite2\VitAngle = 2 ; >0 = Sens Horaire
MonSprite2\AnimNo = 0 ; Image de départ
MonSprite2\AnimInc = 1
MonSprite2\AnimNoMax = #SpriteNoMax
MonSprite2\AnimRaz = #True
; ********************************
; *** Boucle d'animation ***
; ********************************
For j= 0 To 180
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
If MessageRequester( "" , "Poursuivre ?" , #PB_MessageRequester_YesNo ) = #PB_MessageRequester_No
Attente = 1
Break
EndIf
ClearScreen ( RGB( 127 , 127 , 127 ) )
AfficheSptite ( @MonSprite1 )
AfficheSptite ( @MonSprite2 )
AfficheAxes ( @MonSprite1 , RGB( 255 , 0 , 0 ) )
AfficheAxes ( @MonSprite2 , RGB( 0 , 255 , 0 ) )
CalculePositionSuivante ( @MonSprite1 )
CalculePositionSuivante ( @MonSprite2 )
FlipBuffers ( )
Delay ( #Tempo )
Next
Delay ( Attente )
FreeSprite ( #PB_All )
CloseScreen ( )