Physique des Fluides ......

Programmation avancée de jeux en PureBasic
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

@wolfjeremy
:lol:
L’eau est gratuite, fallait mettre plus goûtes :D
wolfjeremy
Messages : 1202
Inscription : sam. 31/déc./2005 23:52

Message par wolfjeremy »

Ont peut mettre plus de goute ? MDR :lol:
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

wolfjeremy a écrit :Ont peut mettre plus de goute ? MDR :lol:
J’ai limité le nombre de goûtes à 9999.
Pour plus de débit il suffit de dessiner un réservoir et de le remplir un max.
Puis le troué avec la gomme.
Et hop l’avalanche aquatique :lol:

Image
wolfjeremy
Messages : 1202
Inscription : sam. 31/déc./2005 23:52

Message par wolfjeremy »

Ha oui j'ai pensé à ça, mais là j'ai fait ça à la va vite. :wink:
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Il n'y a pas moyen d'accélérer le débit les gouttes? :)
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Frenchy Pilou a écrit :Il n'y a pas moyen d'accélérer le débit les gouttes? :)
Elles sont déjà à la vitesse max du CPU (delay(1))
Le seul moyen c’est de désactiver l’affichage 1 fois sur 2 ce qui augmentera de 70% la vitesse.
:?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ma variante un peu plus veloce :D
car utilisation d'un rapide_point() ; point () , je vous le rappel est vraiment tres tres lent en purebasic !! , d'ailleurs Fred devrai integrer ce rapide_point() a la place de point() !! :)


ici le liquide est en liste chainée, et j'utilise des sprites , ce qui contribue encore a l'accélération global; en jouant sur le déplacement du sprite on peut vraiment mettre le turbo :D , mais après les collisions sont aléatoires :D


on peu ajouter en cours de visu

de l'eau avec le clique droit
des rampes avec le clique gauche
espace pour creer des trous ou effacer

tout liquide qui sort en bas de l'ecran est renvoyé en haut, ce qui permet
de regarder sa fontaine travailler indefiniment :D

la taille est modifiable dans le code en haut variable : Taille

@ Mityc, Merci pour ton code, il est tres sympath !! :D



  ;-------------
;-By Dobro sur une idée de Mytic ---
;-------------



InitSprite ()
InitMouse ()
InitKeyboard ()
Declare rapide_Point(x,Y)
Declare nouvel_goute(x.l,Y.l)
Declare gravite_collision()

Global taille=4 ; testez un autre chiffre<------------ zoom sur le phenomene



Structure goute
  x.l
  Y.l
  pasy.l
  pasx.l
EndStructure

Global NewList goute.goute()
Global largeur,hauteur

Enumeration
   #crayon
   #goute
   #fond
   #Window
EndEnumeration

;OpenWindow ( #Window ,1,1,1024,768, "ecran" , #PB_Window_BorderLess )
;OpenWindowedScreen ( WindowID ( #Window ),1,1,1024,768,1,0,0)
OpenScreen (1024,768,16, "Eau" )
;OpenScreen(1024,768,32,"Eau")
largeur = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
hauteur = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
  
   ; ********** Fond ****************
   CreateSprite ( #fond ,1024,768 )
   ; ********************************
   ; ********** crayon ****************
   CreateSprite ( #crayon ,taille*2,taille*2)
   StartDrawing ( SpriteOutput ( #crayon ))
   Box (0,0,taille,taille, RGB (0,255,0))
   StopDrawing ()
   ; ********************************
  
   ; ********** goute d'eau ****************
   CreateSprite ( #goute ,taille,taille)
   StartDrawing ( SpriteOutput ( #goute ))
   For i = 0 To 5
     DrawingMode ( #PB_2DDrawing_Outlined )
     Circle (taille/2,taille/2,i, RGB ( Random (160), Random (160),220 + Random (30)))
   Next i
   DrawingMode ( #PB_2DDrawing_Default )
   StopDrawing ()
   ; ********************************
  
  
   Repeat
   ; Event = WindowEvent () ; mode fenetre
     ExamineKeyboard ()
     ExamineMouse ()
     ClearScreen (0)
     If KeyboardPushed ( #PB_Key_Escape )
       End
     EndIf
    
     DisplaySprite ( #fond ,0,0)
    x = MouseX ()
    Y = MouseY ()
     DisplaySprite ( #crayon ,x,Y)
    
     If MouseButton ( #PB_MouseButton_Left )
       StartDrawing ( SpriteOutput ( #fond ))
       Circle (x,Y,taille, RGB (255,0,0))
       StopDrawing ()
     EndIf
    
     If KeyboardPushed ( #PB_Key_Space )
       StartDrawing ( SpriteOutput ( #fond ))
       Circle (x,Y,taille, RGB (0,0,0))
       StopDrawing ()
     EndIf
    
     If MouseButton ( #PB_MouseButton_Right )
       ;Y=0
       ; x=Random(largeur)
      G=G+1
       ;Debug CountList (goute())
      nouvel_goute(x,Y)
       If G>1000 ; < ------------- seuil maximum
         ClearList (goute())
        G=0
       EndIf
      
      
     EndIf
    gravite_collision()
     Delay (1)
     FlipBuffers ()
  ForEver
   End
  
  
  
   Procedure nouvel_goute(x.l,Y.l)
     AddElement (goute())
    goute()\x=x
    goute()\Y=Y
     DisplaySprite ( #goute ,x,Y)
   EndProcedure
  
   Procedure gravite_collision()
     ResetList (goute() )
    
     While NextElement (goute())
      
       StartDrawing ( ScreenOutput ())
      
       If rapide_Point (goute()\x,goute()\Y+taille) = 0
        goute()\Y+taille
       Else
        p = Random (1)
         If p = 1
           If rapide_Point (goute()\x+taille,goute()\Y)= 0
            goute()\x+taille
           Else
             If rapide_Point (goute()\x-1,goute()\Y)= 0 :goute()\x-taille: EndIf
           EndIf
         Else
           If rapide_Point (goute()\x-1,goute()\Y)=0
            goute()\x-taille
           Else
             If rapide_Point (goute()\x+taille,goute()\Y)= 0 :goute()\x+taille: EndIf
           EndIf
         EndIf
       EndIf
       StopDrawing ()
      
       ; ******** test sorti en bas on remet en haut ! ************
       If goute()\Y>= (hauteur-10)
        goute()\Y=0
       EndIf
       ; *******************************
      
       ; ******** test sorti a droite et gauche************
       If (goute()\x>= (largeur-taille) Or goute()\x<=0)
        goute()\pasx=0
        goute()\pasy=0
       EndIf
       ; *******************************
      
       DisplayTransparentSprite ( #goute ,goute()\x,goute()\Y)
     Wend
    
   EndProcedure
  
  
  
   Procedure rapide_Point(x,Y)
     Select DrawingBufferPixelFormat ()
       Case #PB_PixelFormat_16Bits : PF=2
         color= PeekW ( DrawingBuffer () + (x * PF) + DrawingBufferPitch ()* ( Y ) )
       Case #PB_PixelFormat_32Bits_RGB : PF=4
        color= PeekL ( DrawingBuffer () + (x * PF) + DrawingBufferPitch ()* ( Y ) )
       Case #PB_PixelFormat_32Bits_BGR : PF=4
        color= PeekL ( DrawingBuffer () + (x * PF) + DrawingBufferPitch ()* ( Y ) )
        Rouge= Red (color)
        Vert= Green (color)
        Bleu= Blue (color)
        color= RGB (Bleu,Vert,Rouge)
     EndSelect
     ProcedureReturn color
   EndProcedure
  
Dernière modification par Backup le dim. 30/sept./2007 17:41, modifié 4 fois.
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

@Dobro
Bravo…très belle Variante.
J’ai rajouté quelques détails à ton code : (L’eau rond, et la transparence)

Code : Tout sélectionner

 ;-------------
;-By Dobro sur une idée de Mytic ---
;-------------



InitSprite ()
InitMouse ()
InitKeyboard ()
Declare rapide_Point(x,Y)
Declare nouvel_goute(x.l,Y.l)
Declare gravite_collision()

Global taille=10 ; testez un autre chiffre<------------ zoom sur le phenomene



Structure goute
  x.l
  Y.l
  pasy.l
  pasx.l
EndStructure

Global NewList goute.goute()
Global largeur,hauteur

Enumeration
   #crayon
   #goute
   #fond
   #Window
EndEnumeration

OpenWindow ( #Window ,1,1,1024,768, "ecran" , #PB_Window_BorderLess )
OpenWindowedScreen ( WindowID ( #Window ),1,1,1024,768,1,0,0)
;OpenScreen(1024,768,32,"Eau")
largeur = GetSystemMetrics_ ( #SM_CXSCREEN ): ;=largeur de l'ecran
hauteur = GetSystemMetrics_ ( #SM_CYSCREEN ): ;=hauteur de l'ecran
  
   ; ********** Fond ****************
   CreateSprite ( #fond ,1024,768 )
   ; ********************************
   ; ********** crayon ****************
   CreateSprite ( #crayon ,taille*2,taille*2)
   StartDrawing ( SpriteOutput ( #crayon ))
   Box (0,0,taille,taille, RGB (0,255,0))
   StopDrawing ()
   ; ********************************
  
   ; ********** goute d'eau ****************
   CreateSprite ( #goute ,taille,taille)
   StartDrawing ( SpriteOutput ( #goute ))
For i = 0 To 5
DrawingMode(#PB_2DDrawing_Outlined)
Circle(taille/2,taille/2,i,RGB(Random(160),Random(160),220 + Random(30)))
Next i
DrawingMode(#PB_2DDrawing_Default)
   StopDrawing ()
   ; ********************************
  
  
   Repeat
    Event = WindowEvent ()
     ExamineKeyboard ()
     ExamineMouse ()
     ClearScreen (0)
     If KeyboardPushed ( #PB_Key_Escape )
       End
     EndIf
    
     DisplaySprite ( #fond ,0,0)
    x = MouseX ()
    Y = MouseY ()
     DisplaySprite ( #crayon ,x,Y)
    
     If MouseButton ( #PB_MouseButton_Left )
       StartDrawing ( SpriteOutput ( #fond ))
       Circle (x,Y,taille, RGB (255,0,0))
       StopDrawing ()
     EndIf
    
     If KeyboardPushed ( #PB_Key_Space )
       StartDrawing ( SpriteOutput ( #fond ))
       Circle (x,Y,taille, RGB (0,0,0))
       StopDrawing ()
     EndIf
    
     If MouseButton ( #PB_MouseButton_Right )
       ;Y=0
       ; x=Random(largeur)
      G=G+1
       ;Debug CountList (goute())
      nouvel_goute(x,Y)
       If G>1000 ; < ------------- seuil maximum
         ClearList (goute())
        G=0
       EndIf
      
      
     EndIf
    gravite_collision()
     Delay (1)
     FlipBuffers ()
  ForEver
   End
  
  
  
   Procedure nouvel_goute(x.l,Y.l)
     AddElement (goute())
    goute()\x=x
    goute()\Y=Y
     DisplaySprite ( #goute ,x,Y)
   EndProcedure
  
   Procedure gravite_collision()
     ResetList (goute() )
    
     While NextElement (goute())
      
       StartDrawing ( ScreenOutput ())
      
       If rapide_Point (goute()\x,goute()\Y+taille) = 0
        goute()\Y+taille
       Else
        p = Random (1)
         If p = 1
           If rapide_Point (goute()\x+taille,goute()\Y)= 0
            goute()\x+taille
           Else
             If rapide_Point (goute()\x-1,goute()\Y)= 0 :goute()\x-taille: EndIf
           EndIf
         Else
           If rapide_Point (goute()\x-1,goute()\Y)=0
            goute()\x-taille
           Else
             If rapide_Point (goute()\x+taille,goute()\Y)= 0 :goute()\x+taille: EndIf
           EndIf
         EndIf
       EndIf
       StopDrawing ()
      
       ; ******** test sorti en bas on remet en haut ! ************
       If goute()\Y>= (hauteur)
        goute()\Y=0
       EndIf
       ; *******************************
      
       ; ******** test sorti a droite et gauche************
       If (goute()\x>= (largeur-taille) Or goute()\x<=0)
        goute()\pasx=0
        goute()\pasy=0
       EndIf
       ; *******************************
 
       DisplayTransparentSprite(#goute ,goute()\x,goute()\Y)
     Wend
    
   EndProcedure
  
  
  
   Procedure rapide_Point(x,Y)
     ; de cpl Bator
     If (x > 0) And (x < largeur) And (Y > 0) And (Y < hauteur)
       Select DrawingBufferPixelFormat ()
         Case #PB_PixelFormat_8Bits : PF=1:t=0
         Case #PB_PixelFormat_15Bits : PF=2:t=0
         Case #PB_PixelFormat_16Bits : PF=2:t=0
         Case #PB_PixelFormat_24Bits_RGB : PF=3:t=0
         Case #PB_PixelFormat_24Bits_BGR : PF=3:t=1
         Case #PB_PixelFormat_32Bits_RGB : PF=4:t=0
         Case #PB_PixelFormat_32Bits_BGR : PF=4:t=1
       EndSelect
      color= PeekL ( DrawingBuffer () + (x * PF) + DrawingBufferPitch ()* ( Y ) )
       If t=1
        Rouge= Red (color)
        Vert= Green (color)
        Bleu= Blue (color)
        color= RGB (Bleu,Vert,Rouge)
       EndIf
       ProcedureReturn color
     Else
      color= RGB (0,0,0)
       ProcedureReturn color
     EndIf
   EndProcedure
   
Dernière modification par Mytic le sam. 29/sept./2007 15:45, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ouaip, ça rend bien .. :D

par contre tu n'aurai pas du toucher au masque noir derriere le crayon vert
parcequ'il permettait en positionant le crayon sur une goute d'eau de décoincer celle-ci sans avoir a faire de trous !!! :D

en clair remplace

Code : Tout sélectionner

DisplayTransparentSprite ( #crayon ,x,Y) 
par

Code : Tout sélectionner

DisplaySprite ( #crayon ,x,Y) 
Dernière modification par Backup le sam. 29/sept./2007 15:26, modifié 1 fois.
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Ah, Dsl… :oops:
Au fait, la collision ne se fait pas au centre de sprite ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Mytic a écrit :Ah, Dsl… :oops:
Au fait, la collision ne se fait pas au centre de sprite ?
non !!

elle se fait par rapport a la coordonée (0,0) en haut a gauche du sprite !!
sur certains basic, on a une instruction d'offset pour modifier la position du "point chaud" (la point de collision)

en pure il faut tenir compte de la taille du sprite

s'il fait 16 de large il faut faire point(x+16,y) :D pour detecter a droite du sprite :)

le tout c'est de le savoir :D
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Il suffit de faire ça Point(x+tailleX/2,y+tailleY/2) :idea:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Mytic a écrit :Il suffit de faire ça Point(x+tailleX/2,y+tailleY/2) :idea:
ben non :D

ce que tu fait te donne la couleur du point au centre du sprite !!
c'est a dire la couleur du pixel se trouvant au centre du sprite !! :?


il faut faire :

Code : Tout sélectionner

couleur_gauche = point(x-1,(y+taille/2))
couleur_ haut = point(x+(taille/2),y-1)
couleur_droite =point(x+taille,y+(taille/2))
couleur_bas=point(x+(taille/2),y+taille)
comme ceci on obtient le point a 9 heure, a midi, a 15 heure, a 30 , du "carre" representant un sprite !! :)

bien sur on peut aussi obtenir la couleur des points se trouvant dans l'axe des angle du carre !! :D

il faudrai faire :

Code : Tout sélectionner

couleur_angle_haut_gauche = point(x-1,y-1)
couleur_ angle_haut_droite = point(x+(taille+1),y-1)
couleur_angle_bas_gauche =point(x-1,y+(taille+1))
couleur_angle_bas_droite=point(x+(taille+1),y+(taille+1))
pour obtenir la couleur du point se trouvant
entre 10h et 11 heure
entre 13h et 14 heure
entre 16h et 17 heure
entre 19h et 20 heure


:)
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

Tu scannes la couleur avant l’affichage du sprite !
Comme ça le Point te renverra la couleur du Fond ?
:?
Mytic
Messages : 466
Inscription : mer. 25/juil./2007 0:13

Message par Mytic »

J’ai rajouté l’accélération aux goûtes d’eau et quadrupler leurs tailles, maintenant c’est plus rapide et plus réaliste.
(Posté sur le premier post)
:idea:
Répondre