Page 1 sur 2

Choc elastique

Publié : sam. 16/mai/2009 0:17
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

Publié : sam. 16/mai/2009 10:58
par Cool Dji
Joli, meilleur score 27 !!!
J'aime bien :D

Publié : sam. 16/mai/2009 11:08
par Ar-S
Cool Dji a écrit :Joli, meilleur score 27 !!!
J'aime bien :D
27 aussi :) au 2eme essai

Publié : sam. 16/mai/2009 15:04
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.

Publié : sam. 16/mai/2009 22:38
par Droopy
Sympa :wink:

Publié : dim. 17/mai/2009 0:53
par 7dav77
Avec le son, c'est mieux:

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

[/url]

Publié : lun. 18/mai/2009 13:55
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

Publié : lun. 18/mai/2009 14:32
par Backup
excellent ! :)

Publié : mar. 19/mai/2009 17:57
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". :?

Publié : mar. 19/mai/2009 18:03
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)

Publié : mar. 19/mai/2009 18:13
par jbernard13
pour la resolution utilise l'api suivant :
GetSystemMetrics_(#SM_CXSCREEN)
GetSystemMetrics_(#SM_CYSCREEN)

Publié : mar. 19/mai/2009 21:35
par Ollivier
C'est ludique! Concept original!
Félicitation!

Ollivier

Publié : mer. 20/mai/2009 12:20
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

Publié : mer. 20/mai/2009 14:21
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

Publié : mer. 20/mai/2009 14:26
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: