Publié : lun. 21/juil./2008 10:50
numérique ou pavé numérique doit être précisé si on l'utilise.Frenchy Pilou a écrit :hihi
Je m'obstinais sur le clavier numérique alors que c'était les touche numérique du clavier normal
Forums PureBasic - Français
http://forums.purebasic.com/french/
numérique ou pavé numérique doit être précisé si on l'utilise.Frenchy Pilou a écrit :hihi
Je m'obstinais sur le clavier numérique alors que c'était les touche numérique du clavier normal
Le chargement du jeu est des plus laborieux chez moi... mais il mérite l'effort d'attendre, il est très bon, de belles animations bien fluide, et les plate-formes sont tout en courbe... on peux même utiliser la coquille pour réaliser une série de jongle avec la tête !Cpl.Bator a écrit :http://armorgames.com/play/553/the-fanc ... re-world-2
Bel exemple de la physique ! de visu , c'est des courbes de bezier , non ?
Code : Tout sélectionner
;solide guidé motorisé
;auteur Huitbit
;pb v4.20
;-déclarations*********************************
#largeur_ecran=1024
#hauteur_ecran=768
#dim_sprite=32 ;sprite carré de 32*32
Enumeration
#spr_decor
#spr_car_droite
#spr_car_gauche
#chute_libre
#solide_guide
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
sinus.f ; sinus 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_libre_ancien.f
y_libre_ancien.f
x_libre.f
y_libre.f
x_decalage.f
y_decalage.f
angle0_libre.f
t0_libre.w
tx_libre.w
tx_libre_ancien.w
v0s.f
v0x_libre.f
vx_libre.f
vy_libre.f
angle_rotation_libre.w
a_libre.f
b_libre.f
a_courbe.f
b_courbe.f
x_contact.f
y_contact.f
retard_detection.b
acceleration_moteur.f
#acceleration_moteur_max=8
#dt=0.2
#coeff_frot=0.1
spr_car.b
#g=9.8
x_car.f
y_car.f
Macro collision
a_libre= (y_libre- y_libre_ancien)/(x_libre-x_libre_ancien)
b_libre=y_libre-a_libre*x_libre
If tx_libre<>tx_libre_ancien
a_courbe=(courbe(tx_libre)\y-courbe(tx_libre_ancien)\y)/(courbe(tx_libre)\x-courbe(tx_libre_ancien)\x)
b_courbe=courbe(tx_libre)\y-a_courbe*courbe(tx_libre)\x
EndIf
;-zone de la courbe survolée
; StartDrawing(SpriteOutput(#spr_decor))
; LineXY(courbe(tx_libre)\x,courbe(tx_libre)\y,courbe(tx_libre_ancien)\x,courbe(tx_libre_ancien)\y,RGB(255,0,0))
; StopDrawing()
x_contact=(b_courbe-b_libre)/(a_libre-a_courbe)
;y_contact=a_courbe*x_contact+b_courbe
If courbe(tx_libre)\x>courbe(tx_libre_ancien)\x
If x_contact< courbe(tx_libre)\x And x_contact>courbe(tx_libre_ancien)\x
t=tx_libre
s=courbe(tx_libre)\s
vs=Sqr(vx_libre*vx_libre+vy_libre*vy_libre)*Abs(Cos(angle_rotation_libre*#PI/180))
retard_detection=0
modele=#solide_guide
;-tracé du point d'impact
; StartDrawing(SpriteOutput(#spr_decor))
; DrawingMode(#PB_2DDrawing_Outlined )
; Circle(courbe(tx_libre)\x,courbe(tx_libre)\y,8,RGB(0,255,255))
; StopDrawing()
EndIf
EndIf
If courbe(tx_libre)\x<courbe(tx_libre_ancien)\x
If x_contact> courbe(tx_libre)\x And x_contact<courbe(tx_libre_ancien)\x
t=tx_libre
s=courbe(tx_libre)\s
vs=-Sqr(vx_libre*vx_libre+vy_libre*vy_libre)*Abs(Cos(angle_rotation_libre*#PI/180))
retard_detection=0
modele=#solide_guide
;tracé du point d'impact
; StartDrawing(SpriteOutput(#spr_decor))
; DrawingMode(#PB_2DDrawing_Outlined )
; Circle(courbe(tx_libre)\x,courbe(tx_libre)\y,8,RGB(0,255,0))
; StopDrawing()
EndIf
EndIf
EndMacro
;-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
#parametre_creux=0.0004
#hauteur_bosse=64
#profondeur_creux=48
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
rayon.f; rayon de courbure de la trajectoire r=ds/dphi
modele.b=#solide_guide
;-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)\sinus=courbe(t)\dx / 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
;- creux
While courbe(t)\x<3/8*#largeur_ecran
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y+#profondeur_creux*Pow(e,-#parametre_creux*(p-#largeur_ecran/4)*(p-#largeur_ecran/4))
courbe(t)\dx=1
courbe(t)\dy=-#profondeur_creux*2*#parametre_creux*(p-#largeur_ecran/4)*Pow(e,-#parametre_creux*(p-#largeur_ecran/4)*(p-#largeur_ecran/4))
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)\sinus=courbe(t)\dx / 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<5*#largeur_ecran/8
t=t+1
p=p+1
courbe(t)\x=p
courbe(t)\y=courbe(t_max)\y-#hauteur_bosse*Pow(e,-#parametre_bosse*(p-#largeur_ecran/2)*(p-#largeur_ecran/2))
courbe(t)\dx=1
courbe(t)\dy=#hauteur_bosse*2*#parametre_bosse*(p-#largeur_ecran/2)*Pow(e,-#parametre_bosse*(p-#largeur_ecran/2)*(p-#largeur_ecran/2))
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)\sinus=courbe(t)\dx / 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
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)\sinus=courbe(t)\dx / 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)\sinus=courbe(t)\dx / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
; prise en compte des valeurs +INF et -INF dans le calcul de arctangente(phi)
If courbe(t)\dx<>0
courbe(t)\phi_radian =ATan(courbe(t)\dy/courbe(t)\dx)
Else
If courbe(t)\dy>0
courbe(t)\phi_radian=#PI/2
Else
courbe(t)\phi_radian=-#PI/2
EndIf
EndIf
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)\sinus=courbe(t)\dx / 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 <===> t
s_max=Round(longueur_courbe,#PB_Round_Nearest)
Dim t_correspondant_a_s.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_a_s(int_s)=i
EndIf
Next i
Next int_s
For int_s=1 To s_max
If t_correspondant_a_s(int_s)=0
t_correspondant_a_s(int_s)=t_correspondant_a_s(int_s-1)
EndIf
Next int_s
;-PROGRAMME PRINCIPAL
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)
;-sprite décor
CreateSprite(#spr_decor,#largeur_ecran,#hauteur_ecran)
StartDrawing(SpriteOutput(#spr_decor))
For etoile=1 To 500
Plot(5+Random(#largeur_ecran-10),5+Random(#hauteur_ecran-10),RGB(25,255,255))
Next etoile
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()
;-sprite voiture
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)
;-abscisse curviligne initiale
s=1129
t=t_correspondant_a_s(Int(s))
;-BOUCLE PRINCIPALE
;gestion des évènements de la fenêtre
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
;-gestion du clavier
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
If modele=#solide_guide
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_a_s(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
EndIf
If modele=#chute_libre
retard_detection=retard_detection+1
x_libre_ancien=x_libre
y_libre_ancien=y_libre
tx_libre_ancien=tx_libre
vy_libre=vy_libre+#g*#dt
x_libre=x_libre+vx_libre*#dt
y_libre=y_libre+vy_libre*#dt
angle_rotation_libre=ATan(vy_libre/vx_libre)*180/#PI
If courbe(t0_libre)\dx<0
angle_rotation_libre=angle_rotation_libre+180
EndIf
;-reprise de contact avec le sol
;- bosse sens retour
If v0s<0 And v0x_libre<0
For t_test= tx_libre_ancien To 0 Step -1
If courbe(t_test)\x< x_libre
tx_libre=t_test
Break
EndIf
Next t_test
collision
EndIf
;- bosse sens aller
If v0s>0 And v0x_libre>0
For t_test=tx_libre_ancien To t_max
If courbe(t_test)\x>x_libre
tx_libre=t_test
Break
EndIf
Next t_test
collision
EndIf
;-looping sens aller
If v0s>=0 And v0x_libre=<0 And retard_detection>1
For t_test= tx_libre_ancien To 0 Step -1
If courbe(t_test)\x<= x_libre
tx_libre=t_test
Break
EndIf
Next t_test
collision
EndIf
;-looping sens retour
If v0s=<0 And v0x_libre>=0 And retard_detection>1
For t_test=tx_libre_ancien To t_max
If courbe(t_test)\x>=x_libre
tx_libre=t_test
Break
EndIf
Next t_test
collision
EndIf
;réinitialisation en cas de non détection
If y_libre>750
modele=#solide_guide
s=1129
t=t_correspondant_a_s(Int(s))
vs=0
v0s=0
v0x_libre=0
retard_detection=0
EndIf
EndIf
;-gestion de la perte de contact avec le sol
; condition sur la variation d'angle pour empêcher le passage de -90° à +90°
If (courbe(t+1)\phi_radian-courbe(t-1)\phi_radian)<1 And modele=#solide_guide
;calcul du rayon de courbure
rayon=(courbe(t+1)\s-courbe(t-1)\s)/(courbe(t+1)\phi_radian-courbe(t-1)\phi_radian)
;-test du signe du rayon de courbure (nous renseigne sur le sens du vecteur |en>)
; StartDrawing(SpriteOutput(#spr_decor))
; If rayon>0
; Box(courbe(t)\x,courbe(t)\y-20,2,4,RGB(255,0,0))
; Else
; Box(courbe(t)\x,courbe(t)\y-20,2,4,RGB(0,255,0))
; EndIf
; StopDrawing()
;-condition de la perte de contact
If courbe(t)\sinus<vs*vs/(rayon*#g)
;conditions initiales de la chute libre
angle0_libre=courbe(t)\phi_radian
If courbe(t)\dx<0
angle0_libre=angle0_libre+#PI
EndIf
t0_libre=t
tx_libre=t
v0s=vs
v0x_libre=vs*Cos(angle0_libre)
vx_libre=v0x_libre
vy_libre=vs*Sin(angle0_libre)
;léger décalage pour améliorer la détection
If v0s* v0x_libre>0 ;bosse et creux
x_decalage=0
y_decalage=-#dim_sprite*0.2
Else ;looping
x_decalage=0
y_decalage=0
EndIf
x_libre=courbe(t)\x+x_decalage
y_libre=courbe(t)\y+y_decalage
x_libre_ancien=x_libre
y_libre_ancien=y_libre
angle_rotation_libre=angle0_libre*180/#PI
modele=#chute_libre
;-visualisation du point de décollage
; StartDrawing(SpriteOutput(#spr_decor))
; DrawingMode(#PB_2DDrawing_Outlined )
; Circle(courbe(tx_libre)\x,courbe(tx_libre)\y,4,RGB(255,0,0))
; StopDrawing()
EndIf
EndIf
DisplaySprite(#spr_decor,0,0)
If modele=#solide_guide
x_car=courbe(t)\x-16
y_car=courbe(t)\y-16
angle_rotation_car=angle_rotation
ElseIf modele=#chute_libre
x_car=x_libre-16
y_car=y_libre-16
angle_rotation_car=angle_rotation_libre
EndIf
Start3D()
RotateSprite3D(spr_car,angle_rotation_car,0)
DisplaySprite3D(spr_car,x_car,y_car)
Stop3D()
Delay(10)
FlipBuffers()
ForEver
End
Je sais pôhttp://armorgames.com/play/553/the-fanc ... re-world-2
Bel exemple de la physique ! de visu , c'est des courbes de bezier , non ?
Limitations of this Simulation
Unlike the other roller coaster simulations, this one does not have the option to use various tracks. The reason is that having a track that doesn't loop simplified the code considerably. For example, to determine whether there is a collision, we only test whether the ball is below the track. With a looped track there would be more complicated criteria for deciding if the ball has collided with the track, such as checking if it is inside or outside the track. So if you are looking for a programming project, grab the source code and go to work!
Code : Tout sélectionner
Je sais pô Embarassed . En tout cas, il suffit d'avoir les coordonnées du relief pour "s'amuser !"