Page 1 sur 2

Cascade d'evenements

Publié : lun. 25/sept./2006 16:41
par SPH
Imaginez une scene spaciale et 2 spheres entrant en collision. De cette collision nait plusieurs autres spheres qui s'eparpillent dans l'espace, entrant elles aussi en collisions.
Bref, de 2, on passe a 10, 100, 1000, etc (ici, des chiffres "ronds" mais qu'importe, on vois une explosion demographique).
Comment gereriez-vous la "naissance" presque infini des nouveaux objets ??
Je pose la question car meme si l'on prevois un tableau de 1000 objets, si les collisions faisait naitre un 1001eme objet, comment le prendriez vous en compte ??
Ce n'est pas que je sois en difficulté avec ce concept mais j'aimerais voir si vous avez des techniques qui me sont etrangeres...

Publié : lun. 25/sept./2006 16:45
par Patrick88
y'a un truc du genre qui existait et qui s'appelait "jeu de la vie"

pat

Publié : lun. 25/sept./2006 17:02
par Frenchy Pilou
Pour le jeu de la vie
http://www.anselm.edu/homepage/dbanach/31life.htm
et charger life32 cela cartonne

Pour les automates cellulaires
http://www.rennard.org/alife/french/ + ses liens !

Pour le reste cela ressemble plus a du system D
suivant que l'on a besoin ou non des états des objets qui sortent de l'écran

Une chose est sûre c'est que pour un écran de 1024* 768 pas la peine de mémoriser plus de 786 432 entités :D

Publié : lun. 25/sept./2006 17:04
par Anonyme
C'est très simple, regarde ca , tu vas comprendre

Code : Tout sélectionner

; Dans cette structure , tu stockes toute les propriétés de tes sphères 
Structure SPHERES
  X.f : Y.f : Z.f    ; La position
  IsExist.b          ; Si la sphere existe
  Size.l              ; Sa taille
;  Etc...
EndStructure    

Global Dim Sphere.SPHERES(1000)



; Voila un test primaire de collision :
If SphereA Collision SphereB

   For i = 1 to 1000

  if Sphere(i)\IsExist=0
    Sphere(i)\IsExist=1
    Sphere(i)\Size=10+Random(100)
    Sphere(i)\x = SphereA\x
    Sphere(i)\y = SphereA\y
    Sphere(i)\z = SphereA\z
    Breack 1
  endif

   next i

endif
ensuite tu gère ton affichage , tu affiches si Sphere(i)IsExist = 1

@++

Publié : lun. 25/sept./2006 17:12
par Dr. Dri
si tu ne connais pas a l'avance le nombre d'éléments regarde du côté des listes chaînées...

Dri

Publié : lun. 25/sept./2006 17:39
par SPH
Frenchy Pilou a écrit :Une chose est sûre c'est que pour un écran de 1024* 768 pas la peine de mémoriser plus de 786 432 entités :D
Pas forcement. Si les objets peuvent se chevaucher, et si en plus le programme gere plusieurs plans spacials, ca peux aller au dela.

Publié : lun. 25/sept./2006 19:37
par Flype
les listes chainees - comme dit dr dri - c'est la voie à suivre.

voici une trame que je me suis amusé à faire vite fait.

à toi d'inventer la vie qui va avec :)

Code : Tout sélectionner

; Gestion des objets

Structure OBJET
  t.l   ; type
  x.l   ; x
  y.l   ; y
  r.l   ; rayon
  c.l   ; couleur
  xd.l  ; delta x
  yd.l  ; delta y
  age.l ; durée de vie
EndStructure   

Global NewList objet.OBJET()

Procedure NouvelObjet()
  
  If AddElement(objet())
    
    objet()\t   = Random(2) 
    objet()\x   = Random(640) 
    objet()\y   = Random(480) 
    objet()\r   = Random(32) + 1
    objet()\xd  = Random(4) + 1 
    objet()\yd  = Random(4) + 1
    objet()\age = Random(1000) + 1000
    objet()\c   = RGB(0, 0, Random(255))
    
    If Random(1) : objet()\xd * -1 : EndIf
    If Random(1) : objet()\yd * -1 : EndIf
    
  EndIf
  
EndProcedure

; Variables

ww.l = 640
wh.l = 480

FPS_Timer.l = 0  ; 
FPS_Frame.l = 0  ; 
FPS_Texte.s = "" ; 

TotalObjet.l = 0 ; Total objet (liste)
TotalAjout.l = 0 ; Total objet ajoutés
TotalSuppr.l = 0 ; Total objet supprimés

; Ouvre une fenêtre

If CreateImage(0, ww, wh) And OpenWindow(0, 0, 0, ww, wh, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Créér une multitude d'objets
  
  For i = 0 To 1000
    NouvelObjet()
  Next
  
  ; Gestion des évênements de la fenêtre
  
  Repeat
    
    Select WindowEvent()
      
      Case #PB_Event_CloseWindow
        Break
        
      Case #Null
        
        ; Ajoute aléatoirement un objet
        
        If Not Random(1) 
          NouvelObjet() : TotalAjout + 1
        EndIf
        
        ; Actualise l'image (buffer)
        
        If StartDrawing(ImageOutput(0))
          
          ; Efface le buffer (image noire)
          
          Box(0, 0, ww, wh, #Black)
          
          ; Parcours chaque objet
          
          TotalAge.l = 0
          
          ForEach objet()
            
            With objet()
              
              ; Algorithme Collision (simpliste)
              
              If \x <  0 : \x =  0 : \xd = -(\xd) : EndIf
              If \x > ww : \x = ww : \xd = -(\xd) : EndIf
              If \y <  0 : \y =  0 : \yd = -(\yd) : EndIf
              If \y > wh : \y = wh : \yd = -(\yd) : EndIf
              
              ; Affiche Objet en fonction de son type
              
              Select \t
                Case 0: Plot  (\x, \y, \c)
                Case 1: Box   (\x, \y, \r, \r, \c)
                Case 2: Circle(\x, \y, \r, \c)
              EndSelect
              
              ; Calcul Nouvelle Position
              
              \x + \xd
              \y + \yd
              
              ; Vérifie l'age de l'objet
              
              \age - 1
              
              If \age = 0
                DeleteElement(objet(), 1) : TotalSuppr + 1
              EndIf
              
              ; Calcul Moyenne d'age
              
              TotalAge + \age
              
            EndWith
            
          Next
          
          StopDrawing()
          
        EndIf
        
        ; Calcul du FPS
        
        If ElapsedMilliseconds() - FPS_Timer > 1000
          FPS_Timer = ElapsedMilliseconds()
          FPS_Texte = Str(FPS_Frame)
          FPS_Frame = 0 
        EndIf
        
        ; Statistique
        
        TotalObjet = CountList(objet())
        
        info$ = "FPS : " + FPS_Texte
        info$ + ", TotalObjet : " + Str(TotalObjet)
        info$ + ", TotalAjout : " + Str(TotalAjout)
        info$ + ", TotalSuppr : " + Str(TotalSuppr)
        info$ + ", Moyenne d'âge : " + StrF(TotalAge / TotalObjet, 2)
        
        ; Actualise la fenetre
        
        SetWindowTitle(0, info$)
        
        If StartDrawing(WindowOutput(0))
          DrawImage(ImageID(0), 0, 0)
          FPS_Frame + 1
          StopDrawing()
        EndIf
        
        ; Delay(1)
        
    EndSelect
    
  ForEver
  
EndIf

Publié : lun. 25/sept./2006 20:02
par SPH
Flype, ton code est tres bien.
Tiens, pour montrer a vitesse grand V ce que ca fait avec des plot :

Code : Tout sélectionner

; Gestion des objets 

Structure OBJET 
  x.f  ; x 
  y.f  ; y 
  c.l  ; couleur 
  xd.f ; delta x 
  yd.f ; delta y 
EndStructure    

Global NewList objet.OBJET() 

Procedure Objet_Ajoute() 
  
  If AddElement(objet()) 
    objet()\x  = Random(102300) /100
    objet()\y  = Random(76700) /100
    objet()\c  = RGB(200+Random(55), 200+Random(55), 200+Random(55)) 
    objet()\xd = ((Random(2000) + 1 )/6000)*((Random(1)*2)-1)
    objet()\yd = ((Random(2000) + 1 )/6000)*((Random(1)*2)-1)
  EndIf 
  
EndProcedure 

; Ouvre une fenêtre 

ww = 1024 
wh = 768

If CreateImage(0, ww, wh) And OpenWindow(0, 0, 0, ww, wh, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  
  ; Gestion des évênements 
  
  Repeat 
    
    Select WindowEvent() 
      
      Case #PB_Event_CloseWindow 
        Break 
        
      Case #Null 
        
        ; Rajoute un objet 

        Objet_Ajoute() 
        
        ; Actualise l'image (buffer) 
        
        If StartDrawing(ImageOutput(0)) 
          
          Box(0, 0, ww, wh, #Black) 
          
          ForEach objet() 
            
            With objet() 
              
              If \x <  0 : \x =  0 : \xd = -(\xd) : EndIf 
              If \x > ww : \x = ww : \xd = -(\xd) : EndIf 
              If \y <  0 : \y =  0 : \yd = -(\yd) : EndIf 
              If \y > wh : \y = wh : \yd = -(\yd) : EndIf 
              
              Plot(\x, \y, \c) 
              
              \x + \xd 
              \y + \yd 
              
            EndWith 
            
          Next 
          
          StopDrawing() 
          
        EndIf 
        
        ; Actualise la fenetre 
        
        SetWindowTitle(0, "Objet : " + Str(CountList(objet()))) 
        
        If StartDrawing(WindowOutput(0)) 
          DrawImage(ImageID(0), 0, 0) 
          StopDrawing() 
        EndIf 
        
        Delay(1) 
        
    EndSelect 
    
  ForEver 
  
EndIf 


Publié : lun. 25/sept./2006 20:11
par Flype
ou comme çà :D [EDIT]
j'ai supprimé le source - voir le précédent.

Publié : lun. 25/sept./2006 20:14
par SPH
Design interessant :lol:
V le laisser tourner 5 minutes pour voir...

PS : en supprimant le Delay, c'est plus puregolo... heu, rigolo...

Publié : lun. 25/sept./2006 20:19
par Flype
j'ai mis à jour le code.

comme çà tu pourrais imaginer que seul les objets de meme type peuvent s'accoupler, et que s'ils sont dans une tranche de couleur proche, par ex.

on peut aussi ajouter facilement la durée de vie d'un objet (age).

Publié : lun. 25/sept./2006 20:25
par SPH
Oui, mais je ne te raconte pas le nombre de test a faire !

ps : tu peux rajouter le nombre de frame par secondes ? (steuplai)

Publié : lun. 25/sept./2006 21:21
par Flype
pour le FPS je suis pas spécialiste :?
mais bon j'ai bricolé un truc - ca semble fonctionné. (voir 1er code)

Publié : lun. 25/sept./2006 22:33
par Frenchy Pilou
Rafraichissant!
C'est comme du Perrier , cela fait des bulles :)
Grosso modo, quelles sont les règles?
Il semble que le quadrant en haut à gauche soit moins peuplé que les 3 autres?

Publié : lun. 25/sept./2006 22:41
par SPH
Frenchy Pilou a écrit :Il semble que le quadrant en haut à gauche soit moins peuplé que les 3 autres?
Bien sur !! et c'est logique... Tu ne devines pas ???