Serpent de boule
Publié : dim. 27/janv./2008 1:00
Salut,
Bon, j'avais fait ceci il y a un fort long bout de temps
Un serpent de boule qui suis la souris, c'est assez rigolo
J'ai réussi à faire un code pour qui se déplace tout seul d'un point à un autre en respectant une vitesse de courbure maximum (en gros, il fait pas de ligne directe, il doit prendre un virage comme une voiture)
On doit pouvoir en faire un écran de veille sympa 
Bon, j'avais fait ceci il y a un fort long bout de temps
Un serpent de boule qui suis la souris, c'est assez rigolo
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 3.90
;
; Explication du programme :
; Dessiner un serpent de boule qui suit la souris
; Dimension du screen
#EcranX = 1024
#EcranY= 768
#NbBoule = 100 ; Nombre de boule
#RayonBoule = 17 ; diamètre des boules
#Vitesse = 0.2 ; Vitesse de déplacement des boules
Structure BouleInfo ; Contient la position de chaque boule
x.f
y.f
EndStructure
Dim Boule.BouleInfo(#NbBoule)
Procedure DessineBoule(id, Couleur)
; ID : Identifiant du sprite
; Couleur : Couleur RGB de la boule
CreateSprite(id, #RayonBoule * 2 + 1, #RayonBoule * 2 + 1)
StartDrawing(SpriteOutput(id))
Circle(#RayonBoule, #RayonBoule, #RayonBoule, Couleur) ; On dessine une boule
StopDrawing()
EndProcedure
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(#EcranX, #EcranY, 32, "")
SetFrameRate(50)
; On crée les sprites qui représentent des boules de couleur de plus en plus claires
For n = 0 To #NbBoule
Coef.f = n / #NbBoule
DessineBoule(n, RGB(255, 165 + (255 - 165) * Coef, 255 * Coef))
Next
; On place la souris au point de départ
MouseLocate(#RayonBoule, #RayonBoule)
Repeat
ExamineMouse()
ExamineKeyboard()
ClearScreen(0) ; On efface l'écran
; Position de la première boule que l'on calcule avec la souris
; Il s'agit de la boule 0
Boule(0)\x = MouseX() - #RayonBoule
Boule(0)\y = MouseY() - #RayonBoule
For n = #NbBoule To 1 Step -1 ; Pour chaque boule
; On part de la fin afin que la dernière boule soit en dessous des autres
; On calcul la vitesse de déplacement en x de la boule à partir de la distance entre cette boule et la précédente
; Le but est de permettre à cette boule de suivre la précédente
; Et plus la distance entre ces 2 boules est grande et plus elle ira vite pour la rattraper
VitesseX.f = (Boule(n - 1)\x - Boule(n)\x) * #Vitesse
; De même sur les y
VitesseY.f = (Boule(n - 1)\y - Boule(n)\y) * #Vitesse
; On détermine la nouvelle position de la boule
Boule(n)\x + VitesseX
Boule(n)\y + VitesseY
; On affiche la boule
DisplayTransparentSprite(n, Boule(n)\x, Boule(n)\y)
Next
DisplayTransparentSprite(0, Boule(0)\x, Boule(0)\y) ; On affiche la boule qui représente la souris
; Elle est affiché en dernier pour être au dessus des autres
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Code : Tout sélectionner
; Auteur : Le Soldat Inconnu
; Version de PB : 3.90
;
; Explication du programme :
; Dessiner un serpent de boule qui suit la souris
; Dimension du screen
#EcranX = 1024
#EcranY= 768
#NbBoule = 100 ; Nombre de boule
#RayonBoule = 17 ; diamètre des boules
#Vitesse = 0.2 ; Vitesse de déplacement des boules
#Tete_Rotation = 2 * #PI / 120 ; Vitesse pour changer de direction de la tete du serpent
#Tete_Vitesse = 10 ; Vitesse maximum de la tete du serpent
Tete_Angle.f = 0
Tete_X.f = 0
Tete_Y.f = 0
Deplacement_X = 0
Deplacement_Y = 0
Structure BouleInfo ; Contient la position de chaque boule
x.f
y.f
EndStructure
Dim Boule.BouleInfo(#NbBoule)
Procedure DessineBoule(id, Couleur)
; ID : Identifiant du sprite
; Couleur : Couleur RGB de la boule
CreateSprite(id, #RayonBoule * 2 + 1, #RayonBoule * 2 + 1)
StartDrawing(SpriteOutput(id))
Circle(#RayonBoule, #RayonBoule, #RayonBoule, Couleur) ; On dessine une boule
StopDrawing()
EndProcedure
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(#EcranX, #EcranY, 32, "")
SetFrameRate(50)
; On crée les sprites qui représentent des boules de couleur de plus en plus claires
For n = 0 To #NbBoule
Coef.f = n / #NbBoule
DessineBoule(n, RGB(255, 165 + (255 - 165) * Coef, 255 * Coef))
Next
Repeat
ExamineMouse()
ExamineKeyboard()
ClearScreen(0) ; On efface l'écran
; Position de la première boule que l'on calcule
; Il s'agit de la boule 0
If Distance.f < #Tete_Vitesse ; Si on est arrivé, on va vers un autre point en aléatoire
Deplacement_X = Random(#EcranX)
Deplacement_Y = Random(#EcranY)
EndIf
If Distance < #Tete_Vitesse * 40 ; Si on arrive pas à atteindre le point au bout d'un moment, on dis qu'on l'a eu
Compteur_Proche + 1
If Compteur_Proche > 200
Deplacement_X = Random(#EcranX)
Deplacement_Y = Random(#EcranY)
EndIf
Else
Compteur_Proche = 0
EndIf
; Distance entre la boule et le point visé
Distance.f = Sqr((Deplacement_X - Tete_X) * (Deplacement_X - Tete_X) + (Deplacement_Y - Tete_Y) * (Deplacement_Y - Tete_Y))
; Angle entre la boule et le point visé
If Deplacement_X >= Tete_X And Deplacement_Y >= Tete_Y ; entre 0 et Pi/2
Angle.f = ACos((Deplacement_X - Tete_X) / Distance)
ElseIf Deplacement_X >= Tete_X And Deplacement_Y <= Tete_Y ; entre 0 et -Pi/2
Angle.f = -ACos((Deplacement_X - Tete_X) / Distance)
ElseIf Deplacement_X <= Tete_X And Deplacement_Y >= Tete_Y ; entre Pi/2 et Pi
Angle.f = #PI - ACos((Tete_X - Deplacement_X) / Distance)
Else ; entre -Pi/2 et -Pi
Angle.f = -#PI + ACos((Tete_X - Deplacement_X) / Distance)
EndIf
If Tete_Angle > #PI ; Si l'angle est plus grand que #Pi ou plus petit que -#Pi, on le ramene est -#pi et #pi
Tete_Angle - 2 * #PI
EndIf
If Tete_Angle < -#PI
Tete_Angle + 2 * #PI
EndIf
If Tete_Angle >= Angle ; on regarde dans quel sens on doit faire évoluer l'angle
If Tete_Angle - Angle > #PI
Tete_Angle + #Tete_Rotation
Else
Tete_Angle - #Tete_Rotation
EndIf
Else
If Angle - Tete_Angle > #PI
Tete_Angle - #Tete_Rotation
Else
Tete_Angle + #Tete_Rotation
EndIf
EndIf
Tete_X + Cos(Tete_Angle) * #Tete_Vitesse ; On déplace suivant l'angle
Tete_Y + Sin(Tete_Angle) * #Tete_Vitesse
Boule(0)\x = Tete_X - #RayonBoule
Boule(0)\y = Tete_Y - #RayonBoule
For n = #NbBoule To 1 Step -1 ; Pour chaque boule
; On part de la fin afin que la dernière boule soit en dessous des autres
; On calcul la vitesse de déplacement en x de la boule à partir de la distance entre cette boule et la précédente
; Le but est de permettre à cette boule de suivre la précédente
; Et plus la distance entre ces 2 boules est grande et plus elle ira vite pour la rattraper
VitesseX.f = (Boule(n - 1)\x - Boule(n)\x) * #Vitesse
; De même sur les y
VitesseY.f = (Boule(n - 1)\y - Boule(n)\y) * #Vitesse
; On détermine la nouvelle position de la boule
Boule(n)\x + VitesseX
Boule(n)\y + VitesseY
; On affiche la boule
DisplayTransparentSprite(n, Boule(n)\x, Boule(n)\y)
Next
DisplayTransparentSprite(0, Boule(0)\x, Boule(0)\y) ; On affiche la boule qui représente la souris
; Elle est affiché en dernier pour être au dessus des autres
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
