@Cpl. Bator
Un petit écran, ça fait moins de pixels à gérer.
Code : Tout sélectionner
;solide guidé motorisé
;pb v4.20
;auteur Huitbit
;*********************************
#largeur_ecran=1024
#hauteur_ecran=768
#dim_sprite=32
Enumeration
#spr_decor
#spr_car_droite
#spr_car_gauche
EndEnumeration
Structure donnees
x.f
y.f
dx.f
dy.f
s.f ; abscisse curviligne s(t)
cosinus.f; cosinus de l'angle vecteur poids |P> et le vecteur tangent à la courbe
phi_radian.f ;angle correspondant à la pente locale de la courbe, en radians
EndStructure
x_car.f=100
y_car.f=480
vx_car.f
vy_car.f
acceleration_moteur.f
#acceleration_moteur_max=8
#dt=0.2
#coeff_frot=0.1
spr_car.b
#g=9.8
;création de la piste
Dim courbe.donnees(5000)
#y_depart=64
e.f=2.718281828 ; valeur de exp(1)
#parametre_gaussienne=0.001
#parametre_bosse=0.0004
#hauteur_bosse=64
t.w = 0 ;paramètre pour les fonctions x(t), y(t) et s(t) sur tout le parcours
t_max.w ; dernière valeur de t
p.w = 0 ; paramètre provisoire pour chaque portion de courbes
x_point_precedent.f=0
y_point_precedent.f=#y_depart
angle.w
#rayon=100
longueur_courbe.f = 0
s.f ; abscisse curviligne s(t)
s_max.w ; abscisse curviligne s(t) maximale
int_s.w; valeur entière de s(t)
vs.f ; vitesse curviligne
angle_rotation.w
;première demi-gaussienne
While courbe(t)\x<#largeur_ecran/8
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=#y_depart+(#hauteur_ecran*2/3-#y_depart)*(1-Pow(e,-#parametre_gaussienne*p*p))
courbe(t)\dx=1
courbe(t)\dy=(#hauteur_ecran*2/3-#y_depart)*#parametre_gaussienne*2*p*Pow(e,-#parametre_gaussienne*p*p)
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Wend
t_max=t
; portion horizontale n°1
While courbe(t)\x<0.25*#largeur_ecran
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y
courbe(t)\dx=1
courbe(t)\dy=0
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Wend
t_max=t
;bosse
While courbe(t)\x<#largeur_ecran/2
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y-#hauteur_bosse*Pow(e,-#parametre_bosse*(p-3*#largeur_ecran/8)*(p-3*#largeur_ecran/8))
courbe(t)\dx=1
courbe(t)\dy=#hauteur_bosse*2*#parametre_bosse*(p-3*#largeur_ecran/8)*Pow(e,-#parametre_bosse*(p-3*#largeur_ecran/8)*(p-3*#largeur_ecran/8))
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Wend
t_max=t
; portion horizontale n°2
While courbe(t)\x<0.75*#largeur_ecran
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y
courbe(t)\dx=1
courbe(t)\dy=0
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Wend
t_max=t
;cercle
For angle=0 To 360
t=t+1
courbe(t)\x=courbe(t_max)\x+#rayon*Cos(#PI*(-angle+90)/180); décalage de 90° pour partir du bon endroit sur l'ellipse !
courbe(t)\y=courbe(t_max)\y-#rayon+#rayon*Sin(#PI*(-angle+90)/180)
courbe(t)\dx=#rayon*#PI/180*Sin(#PI*(-angle+90)/180)
courbe(t)\dy=-#rayon*#PI/180*Cos(#PI*(-angle+90)/180)
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Next angle
t_max=t
;deuxième demi-gaussienne
While courbe(t)\x<#largeur_ecran-1
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y-(#hauteur_ecran*2/3-#y_depart)*Pow(e,-#parametre_gaussienne*(p -#largeur_ecran)*(p -#largeur_ecran))
courbe(t)\dx=1
courbe(t)\dy=(#hauteur_ecran*2/3-#y_depart)*2*#parametre_gaussienne*(p -#largeur_ecran)*Pow(e,-#parametre_gaussienne*(p -#largeur_ecran)*(p -#largeur_ecran))
longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\s=longueur_courbe
courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Wend
t_max=t
;correspondance s<===>(x,y)
s_max=Round(longueur_courbe,#PB_Round_Nearest)
Dim t_correspondant.l(s_max);tableau qui va permettre de faire le lien entre abscisse curviligne s et coordonnées cartésiennes x,y par le biais du paramètre t
; à chaque valeur de s on va faire correspondre une valeur t
For int_s=1 To s_max
For i=1 To t_max
If int_s=Round(courbe(i)\s,#PB_Round_Nearest)
t_correspondant(int_s)=i
EndIf
Next i
Next int_s
For int_s=1 To s_max
If t_correspondant(int_s)=0
t_correspondant(int_s)=t_correspondant(int_s-1)
EndIf
Next int_s
InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0,0,0,#largeur_ecran,#hauteur_ecran,"solide guidé motorisé | <= et => pour se déplacer !",#PB_Window_ScreenCentered|#PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0),0,0,#largeur_ecran,#hauteur_ecran,0,0,0)
CreateSprite(#spr_decor,1024,768)
StartDrawing(SpriteOutput(#spr_decor))
For t=1 To t_max
LineXY(x_point_precedent, y_point_precedent, courbe(t)\x, courbe(t)\y,RGB(0,255,255))
x_point_precedent.f=courbe(t)\x
y_point_precedent.f=courbe(t)\y
Next t
FillArea(10,600,RGB(0,255,255),RGB(0,55,55))
StopDrawing()
CreateSprite(#spr_car_droite,32,32,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr_car_droite))
Box(0,4,16,12,RGB(75, 241, 75))
Ellipse(16,16,16,12,RGB(248, 241, 7))
Circle(8,24,8,RGB(15, 109, 240))
Circle(24,26,6,RGB(15, 109, 240))
Box(20,11,6,5,RGB(174, 192, 248))
StopDrawing()
CreateSprite3D(#spr_car_droite, #spr_car_droite)
CreateSprite(#spr_car_gauche,32,32,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr_car_gauche))
Box(16,4,16,12,RGB(75, 241, 75))
Ellipse(16,16,16,12,RGB(248, 241, 7))
Circle(24,24,8,RGB(15, 109, 240))
Circle(8,26,6,RGB(15, 109, 240))
Box(6,11,6,5,RGB(174, 192, 248))
StopDrawing()
CreateSprite3D(#spr_car_gauche, #spr_car_gauche)
s=600
t=t_correspondant(Int(s))
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
acceleration_moteur=acceleration_moteur-2
If acceleration_moteur<-#acceleration_moteur_max
acceleration_moteur=-#acceleration_moteur_max
EndIf
ElseIf KeyboardPushed(#PB_Key_Right)
acceleration_moteur=acceleration_moteur+2
If acceleration_moteur>#acceleration_moteur_max
acceleration_moteur=#acceleration_moteur_max
EndIf
Else
acceleration_moteur=0
EndIf
;-équations du mouvement
vs=vs+(#g*courbe(t)\cosinus-#coeff_frot*vs+acceleration_moteur)*#dt
s=s+vs*#dt
If s<1
s=1
EndIf
If s>s_max
s=s_max
EndIf
;recherche de la valeur de t
t=t_correspondant(Int(s))
angle_rotation=180*courbe(t)\phi_radian /#PI
If courbe(t)\dx<0
angle_rotation=angle_rotation+180
EndIf
;choix du sprite en fonction du sens de parcours
If vs >=0
spr_car=#spr_car_droite
Else
spr_car=#spr_car_gauche
EndIf
DisplaySprite(#spr_decor,0,0)
Start3D()
RotateSprite3D(spr_car,angle_rotation,0)
DisplaySprite3D(spr_car,courbe(t)\x-16,courbe(t)\y-16)
Stop3D()
Delay(1)
FlipBuffers()
ForEver