http://purebasic.hmt-forum.com/viewtopic.php?t=1209
j'ai réalisé une chenille qui se ballade sous windows.
j'ai plusieur solution à proposer.
la première consite à faire une copie d'écran de la zone de l'écran sur laquel la chenille se déplace
en clair, quand je déplace la chenille d'1 pixel vers la droite, je fais une copie d'écran de la bande de 1 px situé à droite de la fenêtre ou je dessine la chenille.
je décale l'image de fond de la fenêtre d'un pixel vers la gauche et je colle la copie d'écran à droite de la fenêtre
ensuite, je déplcae la fenêtre d'un pixel vers la droite
on obtient donc dans le fond de la fenêtre une image correspond à ce qui est sous la chenille (à condition que ce qui est sous la chenille nne change pas d'apparence)
voici le code correspondant : (il n'est pas très commenté alos si vous avez besion d'explication, n'hésitez pas à demandé)
Code : Tout sélectionner
Structure Position
x.l
y.l
a.l
EndStructure
#Pi.f = 3.14159265
#Longueur = 20 ; Longueur de la chenille (Obligatoirement un nombre paire)
#Rayon = 2
#NbImage = 34 ; Nombre d'image de l'animation (Obligatoirement un nombre paire)
#Amplitude.f = #Pi / 180 / #NbImage * 75 ; Amplitude de la chenille, seul le dernier nombre peut-être changé
#Vitesse = 30 ; Vitesse de l'animation
#Tampon = 100 ; Zone en dehors de l'écran dans laquelle la chenille ne fait pas demi-tour
#TailleX = #Longueur * #Rayon + #Rayon ; Largeur de la fenêtre
#TailleY = 16 ; Hauteur de la fenêtre, à ajuster manuellement
#Fond = 0 ; Image de fond de la fenêtre
#Image_Finale = 1 ; Image finale de la chenille
#Fond_Temp = 2
Dim Chenille.Position(#NbImage, #Longueur)
Dim Avance.l(#NbImage)
Global Etat, PosX, PosY, Pas, Sens
Procedure Calcul() ; Calcul des positions de la chenille
Protected Px.f, Py.f, Angle.f, Av.f
; On initialise l'avance à la longeur de départ de la chenille
Av = #Longueur * #Rayon
Debug "_______________"
Debug "La chenille se plie"
; Phase de pliage de la chenille
For Etat = 0 To #NbImage / 2 - 1
Debug "=============="
Px = 0
Py = 0
Angle = 0
For n = 0 To #Longueur / 2 - 1
Chenille(Etat, n)\x = Px
Chenille(Etat, n)\y = Py
Chenille(Etat, n)\a = Int(Angle * 360 / 2 / #Pi / 15) * 15
Angle = Angle + Etat * Sin(n * 4 * #Pi / #Longueur) * #Amplitude
Px = Px + #Rayon * Cos(Angle)
Py = Py + #Rayon * Sin(Angle)
Debug StrF(Px, 1) + " | " + StrF(Py, 1) + " < " + StrF(Angle, 2) + " > " + Str(Chenille(Etat, n)\a)
Next
For n = #Longueur / 2 To #Longueur - 1
Chenille(Etat, n)\x = Px
Chenille(Etat, n)\y = Py
Chenille(Etat, n)\a = Int(Angle * 360 / 2 / #Pi / 15) * 15
Angle = Angle - Etat * Sin(n * 4 * #Pi / #Longueur) * #Amplitude
Px = Px + #Rayon * Cos(Angle)
Py = Py + #Rayon * Sin(Angle)
Debug StrF(Px, 1) + " | " + StrF(Py, 1) + " < " + StrF(Angle, 2) + " > " + Str(Chenille(Etat, n)\a)
Next
Avance(Etat) = Int(Av - Px)
Av = Av - Avance(Etat)
Debug "Avance = " + Str(Avance(Etat))
Next
Debug "_______________"
Debug "La chenille se déplie"
; Phase de dépliage de la chenille
For Etat = #NbImage / 2 To #NbImage
Debug "=============="
Px = 0
Py = 0
Angle = 0
For n = 0 To #Longueur / 2 - 1
Chenille(Etat, n)\x = Px
Chenille(Etat, n)\y = Py
Chenille(Etat, n)\a = Int(Angle * 360 / 2 / #Pi / 15) * 15
Angle = Angle + (#NbImage - Etat) * Sin(n * 4 * #Pi / #Longueur) * #Amplitude
Px = Px + #Rayon * Cos(Angle)
Py = Py + #Rayon * Sin(Angle)
Debug StrF(Px, 1) + " | " + StrF(Py, 1) + " < " + StrF(Angle, 2) + " > " + Str(Chenille(Etat, n)\a)
Next
For n = #Longueur / 2 To #Longueur - 1
Chenille(Etat, n)\x = Px
Chenille(Etat, n)\y = Py
Chenille(Etat, n)\a = Int(Angle * 360 / 2 / #Pi / 15) * 15
Angle = Angle - (#NbImage - Etat) * Sin(n * 4 * #Pi / #Longueur) * #Amplitude
Px = Px + #Rayon * Cos(Angle)
Py = Py + #Rayon * Sin(Angle)
Debug StrF(Px, 1) + " | " + StrF(Py, 1) + " < " + StrF(Angle, 2) + " > " + Str(Chenille(Etat, n)\a)
Next
Avance(Etat) = 0
Next
EndProcedure
Procedure Image_Plafond() ; Création de l'image pour la chenille marchant en haut de l'écran
UseImage(#Image_Finale)
StartDrawing(ImageOutput())
DrawImage(UseImage(#Fond), 0, 0)
; Box(0, 0, #TailleX, #TailleY, 0)
; Dessin de la chenille
For n = 1 To #Longueur - 1
Circle(#Rayon + Chenille(Etat, n)\x, #Rayon + Chenille(Etat, n)\y, #Rayon, $4AD274)
Next
StopDrawing()
EndProcedure
Procedure Image_Plancher() ; Création de l'image pour la chenille marchant en bas de l'écran
UseImage(#Image_Finale)
StartDrawing(ImageOutput())
DrawImage(UseImage(#Fond), 0, 0)
; Dessin de la chenille
For n = 1 To #Longueur - 1
Circle(#Rayon + Chenille(Etat, n)\x, #TailleY - #Rayon - Chenille(Etat, n)\y, #Rayon, $4AD274)
Next
StopDrawing()
EndProcedure
Procedure Deplace_Ecran(x, y)
CopyImage(#Fond, #Fond_Temp)
DC = GetDC_(0)
UseImage(#Fond)
Dessin = StartDrawing(ImageOutput())
Box(0, 0, #TailleX, #TailleY, 0)
BitBlt_(Dessin, 0, 0, #TailleX, #TailleY, DC, WindowX() + x, WindowY() + y, #SRCPAINT)
DrawImage(UseImage(#Fond_Temp), -x, -y)
StopDrawing()
ReleaseDC_(0, DC)
EndProcedure
Procedure Affiche()
Protected x, y
Etat + Pas
If Etat > #NbImage
Etat = 0
ElseIf Etat < 0
Etat = #NbImage
EndIf
x = WindowX()
y = WindowY()
If x > GetSystemMetrics_(#SM_CXSCREEN) + #Tampon Or x < - #TailleX - #Tampon
Pas = -Pas
y = 0
Sens = 0
EndIf
If x >= -#TailleX And x <= GetSystemMetrics_(#SM_CXSCREEN)
If Pas <> 0
x + Avance(Etat) * Pas ; On fait avancer la chenille
If y = 0
; Pour faire tomber la chenille du haut de l'écran
If Etat = 0 And Random(20) = 0
Pas = 0
Sens = 1 ; On charge les images de la chenille qui marche sur le sol
y - #TailleY + 2 * #Rayon + 1 ; On déplace la fen en conséquence
EndIf
Else
; Pour faire tomber la chenille d'une fenêtre
WinID = WindowFromPoint_(x + 2 * #Rayon, y + #TailleY) ; On regarde l'Id de la fenêtre sous la chenille
If GetParent_(WinID) <> 0 ; On regarde si il s'agit d'une fenêtre ou d'un gadget
Pas = 0 ; Si on n'est plus sur une fenêtre, on fait tomber la chenille
EndIf
WinID = WindowFromPoint_(x + #TailleY - 2 * #Rayon, y + #TailleY)
If GetParent_(WinID) <> 0
Pas = 0
EndIf
EndIf
Else
y + 3 ; On fait tomber la chenille
If Etat <> 0
Etat - 1
EndIf
If y >= GetSystemMetrics_(#SM_CYSCREEN) - #TailleY ; On est en bas de l'écran
Pas = Random(1) * 2 - 1 ; On lance la chenille dans un sens au hazard
y = GetSystemMetrics_(#SM_CYSCREEN) - #TailleY
EndIf
WinID = WindowFromPoint_(x + 2 * #Rayon, y + #TailleY)
If GetParent_(WinID) = 0 ; si il y a une fenêtre sous la chenille
GetWindowRect_(WinID, @Pos.RECT)
If y >= Pos\top - #TailleY And y < Pos\top - #TailleY + 3 ; Si la chenille est au dessus du haut de la fenêtre
Pas = Random(1) * 2 - 1
y = Pos\top - #TailleY
EndIf
EndIf
WinID = WindowFromPoint_(x + #TailleX - 2 * #Rayon, y + #TailleY)
If GetParent_(WinID) = 0
GetWindowRect_(WinID, @Pos.RECT)
If y >= Pos\top - #TailleY And y < Pos\top - #TailleY + 3
Pas = Random(1) * 2 - 1
y = Pos\top - #TailleY
EndIf
EndIf
EndIf
Else
x + Avance(Etat) * Pas ; On fait avancer la chenille
EndIf
Deplace_Ecran(x - WindowX(), y - WindowY())
If Sens
Image_Plancher()
Else
Image_Plafond()
EndIf
; On affiche la nouvelle image
StartDrawing(ScreenOutput())
DrawImage(UseImage(#Image_Finale), 0, 0)
StopDrawing()
FlipBuffers()
MoveWindow(x, y) ; On déplace la fenêtre
EndProcedure
;- Debut du programme
OpenWindow(0, -#TailleX, 0, #TailleX, #TailleY, #PB_Window_BorderLess | #WS_SYSMENU, "Chenille")
; CreateGadgetList(WindowID())
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE)
InitSprite()
OpenWindowedScreen(WindowID(), 0, 0, #TailleX, #TailleY, 0, 0, 0)
CreateImage(#Fond, #TailleX, #TailleY)
CreateImage(#Image_Finale, #TailleX, #TailleY)
Calcul()
Pas = 1
; On lance le Timer qui va définir la vitesse de l'animation
Etat = 0
Sens = 0
Timer = SetTimer_(WindowID(), 0, #Vitesse, @Affiche())
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
; On tue le timer
KillTimer_(WindowID(), Timer)