Choc elastique

Programmation avancée de jeux en PureBasic
7dav77
Messages : 14
Inscription : jeu. 14/mai/2009 16:06

Choc elastique

Message par 7dav77 »

Choc élastique de boules de masses éventuellement différentes.

Il faut d'abord tuer les boules roses seulement,
puis les boules bleues,
puis la boule grise.
Ca se joue à la souris.

; Examine les modes graphiques disponible et choisit le meilleur

InitSprite()
ExamineScreenModes()
LargeurEcran.i=0
HauteurEcran.i=0
ProfondeurEcran.i=0
While NextScreenMode()
If LargeurEcran<ScreenModeWidth() Or (LargeurEcran=ScreenModeWidth() And profondeurEcran<ScreenModeDepth() )
LargeurEcran=ScreenModeWidth()
HauteurEcran=ScreenModeHeight()
ProfondeurEcran=ScreenModeDepth()
EndIf
Wend

; Paramètres de base

LargeurEcran_cm= 26.5 ; ici, c'est la largeur en cm, utile pour que la vitesse en cm/s modifie la position (en nb de pixels)
pix_par_cm=LargeurEcran/LargeurEcran_cm
DemiL=LargeurEcran/2
DemiH=HauteurEcran/2
#nb_boules=29
#delai=0.0166 ; c'est le délai théorique entre deux balayages (entre deux passages de boucles
; utilisé pour les déplacements, qui sont modifiés par la vitesse

; Structures de données

Structure Couple
x.f
y.f
EndStructure

Structure Boules
Rayon.w
Couleur.i
Position.couple
Vitesse.couple
Masse.w
Statu.b
EndStructure

Dim Boule.boules(#nb_boules)
Dim Pret_pour_choc(#nb_boules,#nb_boules) ; Je rajoute ça, c'est pour que deux boules ne se rechoquent pas avant de s'être éloignées.

; Initialisations

UseOGGSoundDecoder()
InitSound()
; Les sons doivent être dans le répertoire "courant". Utiliser SetCurrentDirectory sinon
;LoadSound(0,"SuiteFrançaise1.ogg")
;LoadSound(1,"ChocBoules.wav")
;LoadSound(2,"Bouchon-Champagne.wav")
;LoadSound(3,"Applaudissements.wav")
;LoadSound(4,"Tir billard.wav")
LoadFont(1, "Time New Roman", 300)
Global px1.f,py1.f,px2.f,py2.f,x1.f,x2.f,y1.f,y2.f,m1,m2,distance.f
Declare Choc_Elastique()

;PlaySound(0, #PB_Sound_Loop)
InitKeyboard()
InitMouse()
OpenScreen(LargeurEcran,HauteurEcran,ProfondeurEcran,"Hop")

Repeat


For i=1 To #nb_boules
For j=1 To #nb_boules
Pret_pour_choc(i,j)=0
Next j
Next i

; Valeurs initiales des variables

Rayon=50
a.f=DemiL-51
b.f=0
score=0
ligne=0
colonne=0
statu=2
For i=2 To #nb_boules
boule(i)\rayon=50
If statu=1: boule(i)\couleur=RGB(255,100,100):EndIf
If statu=2: boule(i)\couleur=RGB(0,200,200):EndIf
boule(i)\position\x=-300+ligne*((Sqr(3)/2)*100+1)
boule(i)\position\y=(colonne-ligne/2)*101
colonne=colonne+1
If colonne>ligne : colonne=0:ligne=ligne+1:EndIf
boule(i)\vitesse\x=0
boule(i)\vitesse\y=0
boule(i)\masse=5
boule(i)\statu=statu
If statu=2: statu=1: Else: statu=2:EndIf

Next i

i=1
boule(i)\rayon=100
boule(i)\couleur=RGB(100,100,100)
boule(i)\position\x=-DemiL+100
boule(i)\position\y=0
boule(i)\vitesse\x=5
boule(i)\vitesse\y=Random(1000)/1000
boule(i)\masse=110
boule(i)\statu=2
If statu=2: statu=1: Else: statu=2:EndIf

; Comptage des boules de chaque catégorie
nb_boules_statu1=0
nb_boules_statu2=0
nb_boules_statu3=0

For i=1 To #nb_boules
If boule(i)\statu=1:nb_boules_statu1=nb_boules_statu1+1:EndIf
If boule(i)\statu=2:nb_boules_statu2=nb_boules_statu2+1:EndIf
If boule(i)\statu=3:nb_boules_statu3=nb_boules_statu3+1:EndIf
Next i
nb_boules_vivantes=nb_boules_statu1+nb_boules_statu2+nb_boules_statu3

ClearScreen(RGB(0,0,0))

; Dessin

StartDrawing(ScreenOutput())
Circle(DemiL+a,DemiH+b,Rayon,RGB(255, 0,0))
Circle(DemiL+a,DemiH+b,Rayon-10,RGB(100, 100,100))
For i=1 To #Nb_Boules
If boule(i)\statu>0
Circle(DemiL+boule(i)\position\x,DemiH+boule(i)\position\y,boule(i)\rayon,boule(i)\couleur)
EndIf
Next i
StopDrawing()
FlipBuffers(#PB_Screen_WaitSynchronization )
Delay(1000)
;PlaySound(4, #PB_Sound_MultiChannel)

Repeat ; Début de la boucle principale du jeu

ClearScreen(RGB(0,0,0))

; Dessin

StartDrawing(ScreenOutput())

; Score

DrawingFont(FontID(1))
If score >0
If score>9 : DrawText(DemiL-300,DemiH-300,StrF(score,0),RGB(0,0,200),RGB(0,0,0) )
Else : DrawText(DemiL-150,DemiH-300,StrF(score,0),RGB(0,0,200),RGB(0,0,0) )
EndIf
EndIf
Circle(DemiL+a,DemiH+b,Rayon,RGB(255, 255,0))
Circle(DemiL+a,DemiH+b,Rayon-10,RGB(100, 100,100))
For i=1 To #Nb_Boules
If boule(i)\statu>0
Circle(DemiL+boule(i)\position\x,DemiH+boule(i)\position\y,boule(i)\rayon,boule(i)\couleur)
EndIf
Next i
StopDrawing()
FlipBuffers(#PB_Screen_WaitSynchronization )

; Intervention souris
ExamineMouse()
da=MouseDeltaX()
db=MouseDeltaY()
mb1=MouseButton(1)
mb2=MouseButton(2)

; Intervention clavier
ExamineKeyboard()

; Déplacements

a=a+da/2
b=b+db/2
For i=1 To #Nb_Boules
If boule(i)\statu>0
boule(i)\position\x= boule(i)\position\x + boule(i)\vitesse\x*#delai*pix_par_cm
boule(i)\position\y= boule(i)\position\y + boule(i)\vitesse\y*#delai*pix_par_cm
boule(i)\vitesse\y=boule(i)\vitesse\y
EndIf
Next i

; Chocs

For i=1 To #nb_boules
For j=i+1 To #nb_boules
If boule(i)\statu>0 And boule(j)\statu>0
px1=boule(i)\position\x
py1=boule(i)\position\y
px2=boule(j)\position\x
py2=boule(j)\position\y
distance = Sqr( (px2-px1)*(px2-px1) + (py2-py1)*(py2-py1) )

If distance < ( boule(i)\rayon + boule(j)\rayon )
If Pret_pour_choc(i,j)=0
Pret_pour_choc(i,j)=1
x1=boule(i)\vitesse\x ; Il aurait été plus élégant de transmetre les valeurs à la procédure par pointeur
y1=boule(i)\vitesse\y ; plutôt que d'utiliser des variables globales, je sais.
x2=boule(j)\vitesse\x ; en Pascal,on pouvait transmettre les valeurs à une procédure par paramètre ou
y2=boule(j)\vitesse\y ; "par variable". C'était plus simple, je trouve.
m1=boule(i)\masse
m2=boule(j)\masse

Choc_Elastique()
;PlaySound(1, #PB_Sound_MultiChannel)

boule(i)\vitesse\x = xx1.f
boule(i)\vitesse\y = yy1.f
boule(j)\vitesse\x =xx2.f
boule(j)\vitesse\y = yy2.f
EndIf
Else
Pret_pour_choc(i,j)=0
EndIf

EndIf
Next j
Next i

; Disparition de boules
px1=a
py1=b
For i=1 To #nb_boules
If boule(i)\statu>0
px2=boule(i)\position\x
py2=boule(i)\position\y
distance = Sqr( (px2-px1)*(px2-px1) + (py2-py1)*(py2-py1) )

If distance < ( boule(i)\rayon + rayon )

If boule(i)\statu=1
nb_boules_statu1=nb_boules_statu1-1
nb_boules_vivantes=nb_boules_vivantes-1
score=score+1 ;PlaySound(2, #PB_Sound_MultiChannel)
boule(i)\statu=-1
EndIf

If boule(i)\statu=2
nb_boules_statu2=nb_boules_statu2-1
nb_boules_vivantes=nb_boules_vivantes-1
If nb_boules_statu1=0:score=score+1
;PlaySound(2, #PB_Sound_MultiChannel)
boule(i)\statu=-2
Else: boule(i)\statu=0
EndIf
EndIf

If boule(i)\statu=3
nb_boules_statu3=nb_boules_statu3-1
nb_boules_vivantes=nb_boules_vivantes-1
If nb_boules_statu2=0:score=score+1:PlaySound(2, #PB_Sound_MultiChannel): Boule(i)\statu=-3
Else: Boule(i)\statu=0
EndIf
EndIf

EndIf
EndIf
Next i

If mb1<>0 : rayon = rayon - 5 : EndIf
If mb2<>0 : rayon = rayon +5 : EndIf

; Limitations écran

If a>DemiL-(rayon+1) : a=DemiL-(rayon+1) : EndIf
If a<-DemiL+(rayon+1) : a=-DemiL+(rayon+1):EndIf
If b>DemiH-(rayon+1) : b=DemiH-(rayon+1) : EndIf
If b<-DemiH+(rayon+1) : b=-DemiH+(rayon+1):EndIf
If rayon > 255: rayon=255:EndIf
If rayon < 50: rayon=50:EndIf

For i=1 To #Nb_Boules

If boule(i)\statu<>0

If boule(i)\position\x > DemiL-(boule(i)\rayon+1)
boule(i)\position\x = DemiL-(boule(i)\rayon+1)
boule(i)\vitesse\x = - Abs(boule(i)\vitesse\x)
EndIf

If boule(i)\position\x < -DemiL +(boule(i)\rayon+1)
boule(i)\position\x = -DemiL+(boule(i)\rayon+1)
boule(i)\vitesse\x = Abs(boule(i)\vitesse\x)
EndIf

If boule(i)\position\y > DemiH-(boule(i)\rayon+1)
boule(i)\position\y = DemiH-(boule(i)\rayon+1)
boule(i)\vitesse\y = - Abs(boule(i)\vitesse\y)
EndIf

If boule(i)\position\y < -DemiH+(boule(i)\rayon+1)
boule(i)\position\y = -DemiH+(boule(i)\rayon+1)
boule(i)\vitesse\y = Abs(boule(i)\vitesse\y)
EndIf

EndIf

Next i

Until KeyboardPushed(#PB_Key_Escape) Or nb_boules_vivantes=0; Fin de la boucle principale du jeu

ClearScreen(RGB(0,0,0))

; Dessin

StartDrawing(ScreenOutput())

; Score

Circle(DemiL+a,DemiH+b,Rayon,RGB(255, 255,0))
Circle(DemiL+a,DemiH+b,Rayon-10,RGB(100, 100,100))
For i=1 To #Nb_Boules
If boule(i)\statu<0
Circle(DemiL+boule(i)\position\x,DemiH+boule(i)\position\y,boule(i)\rayon,boule(i)\couleur)
EndIf
Next i
DrawingFont(FontID(1))
DrawingMode(#PB_2DDrawing_Transparent)
If score>9 : DrawText(DemiL-300,DemiH-300,StrF(score,0),RGB(0,0,200),RGB(0,0,0) )
Else : DrawText(DemiL-150,DemiH-300,StrF(score,0),RGB(0,0,200),RGB(0,0,0) )
EndIf
If score=#nb_boules
DrawText(DemiL-500,DemiH-300,"WIN",RGB(200,0,200),RGB(0,0,0) )
;PlaySound(3)
EndIf
StopDrawing()
FlipBuffers(#PB_Screen_WaitSynchronization )
Delay (500)

Repeat
ExamineKeyboard():
ExamineMouse()
reponse1=KeyboardPushed(#PB_Key_Space)
reponse2=KeyboardPushed(#PB_Key_Escape)
Until reponse1 Or reponse2
Until reponse2

End

Procedure Choc_Elastique()
Protected alphax.f,alphay.f,betax.f,betay.f,a1.f,a2.f,b1.f,b2.f,aa1.f,bb1.f,aa2.f,bb2.f
Shared xx1,xx2,yy1,yy2
alphax=(px2-px1)/distance
alphay=(py2-py1)/distance
betax=alphay
betay=-alphax
a1= x1*alphax + y1*alphay
b1= x1*betax + y1*betay
a2= x2*alphax + y2*alphay
b2= x2*betax + y2*betay
aa1= ((m1-m2)/(m1+m2))*a1 + ((2*m2)/(m1+m2))*a2
bb1= b1
aa2= ((2*m1)/(m1+m2))*a1 + ((m2-m1)/(m1+m2))*a2
bb2= b2
xx1= aa1*alphax + bb1*betax
yy1= aa1*alphay + bb1*betay
xx2= aa2*alphax + bb2*betax
yy2= aa2*alphay + bb2*betay
EndProcedure
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Message par Cool Dji »

Joli, meilleur score 27 !!!
J'aime bien :D
Only PureBasic makes it possible
Avatar de l’utilisateur
Ar-S
Messages : 9478
Inscription : dim. 09/oct./2005 16:51
Contact :

Message par Ar-S »

Cool Dji a écrit :Joli, meilleur score 27 !!!
J'aime bien :D
27 aussi :) au 2eme essai
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
7dav77
Messages : 14
Inscription : jeu. 14/mai/2009 16:06

Message par 7dav77 »

Félicitations.
Faut maintenant remplacer
#nb_boules=29
par #nb_boules=37

J'ai une question :
Peut-on insérer les fichiers son dans l'executable, à la compilation ?

Par ailleurs, dans la partie "débutant" du forum, j'ai posté un message sur un "bug" avec l'instruction plot. J'ai mis à jour mon pilote de carte graphique, mais ça n'arrange rien. Si quelqu'un était dans mon cas, je me sentirais moins seul.
Avatar de l’utilisateur
Droopy
Messages : 1151
Inscription : lun. 19/juil./2004 22:31

Message par Droopy »

Sympa :wink:
7dav77
Messages : 14
Inscription : jeu. 14/mai/2009 16:06

Message par 7dav77 »

Avec le son, c'est mieux:

[URL=http://www.terafiles.net/v-3471.html]

[/url]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

je suis à 29. Mais il faut un écran géant pour faciliter la tache. Sur un 17", c'est intordable

36 avec plus de boule
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

excellent ! :)
7dav77
Messages : 14
Inscription : jeu. 14/mai/2009 16:06

Message par 7dav77 »

Le Soldat Inconnu a écrit :je suis à 29. Mais il faut un écran géant pour faciliter la tache. Sur un 17", c'est intordable

36 avec plus de boule
Exact, j'aurais dû rendre les tailles des boules proportionnelles aux dimensions de l'écran. Le miens est un 1920*1200 en 17'' (merci Dell). En tout cas, ça me fait bien plaisir de vous faire jouer à mon KillerBall. Je l'avais fait pour ma plus jeune fille, qui aime bien manipuler l'ordinateur. Et quand je lui demande ce qu'elle veut faire, elle dit: "pas le jeu des boules". :?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

7dav77 a écrit : Et quand je lui demande ce qu'elle veut faire, elle dit: "pas le jeu des boules". :?
je suis pas sur que ce soit une bonne education pour une fille :lol: :lol: :lol:

(ok! je sort)
jbernard13
Messages : 1501
Inscription : dim. 18/avr./2004 15:04
Localisation : sud de la france

Message par jbernard13 »

pour la resolution utilise l'api suivant :
GetSystemMetrics_(#SM_CXSCREEN)
GetSystemMetrics_(#SM_CYSCREEN)
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

C'est ludique! Concept original!
Félicitation!

Ollivier
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

7dav77 a écrit :Félicitations.
Faut maintenant remplacer
#nb_boules=29
par #nb_boules=37

J'ai une question :
Peut-on insérer les fichiers son dans l'executable, à la compilation ?

Par ailleurs, dans la partie "débutant" du forum, j'ai posté un message sur un "bug" avec l'instruction plot. J'ai mis à jour mon pilote de carte graphique, mais ça n'arrange rien. Si quelqu'un était dans mon cas, je me sentirais moins seul.
avec directx9 plot pose probléme
http://www.purebasic.fr/french/viewtopic.php?t=9268
remplace le donc par la commande box

Huit bit a fait une application sympa concernant l'intégration de son midi, là:http://www.purebasic.fr/french/viewtopic.php?t=9220

petite suggestion:
boule bleu prise en l'absence de rose: +10
boule grise pris à la fin = +100
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Message par Cool Dji »

beauregard a écrit :petite suggestion:
boule bleu prise en l'absence de rose: +10
boule grise pris à la fin = +100
yes, + boule bleu prise alors qu'il reste des boules roses = -5
Only PureBasic makes it possible
7dav77
Messages : 14
Inscription : jeu. 14/mai/2009 16:06

Message par 7dav77 »

Merci pour tes réponses, Beauregard.
avec directx9 plot pose probléme
http://www.purebasic.fr/french/viewtopic.php?t=9268
remplace le donc par la commande box
J'ai essayé avec box, ça bug aussi.
Huit bit a fait une application sympa concernant l'intégration de son midi, là:http://www.purebasic.fr/french/viewtopic.php?t=9220
En effet, c'est top. Je m'en servirai sûrement.
petite suggestion:
boule bleu prise en l'absence de rose: +10
boule grise pris à la fin = +100
Je suis pas complètement d'accord. En effet, à la fin, toutes les boules ont été niquées, dont les roses. Donc de toutes façons, les points des roses, c'est pour décorer, ça translate juste le score final. Par conséquent, la valeur d'une boule bleue, relativement à une rose, n'a pas d'importance.
De même, si la boule grise est touchée à la fin, c'est qu'on a le score maximal, dans les deux façons de noter. Bref, il me semble que ton échelle des scores et la mienne organisent les résultats dans le même ordre. Cela dit, je veux bien admettre l'aspect psychologique des choses. :wink:
Répondre