Seite 2 von 2

Re: Wie kann man Liste in Liste oder Map in Map erstellen?

Verfasst: 28.02.2010 22:16
von STARGÅTE
ListSize() zählt auch "einzeln" durch, jedoch speichert PB diesen Wert im Header der LinkedList, sodass bei einem AddElement +1 und bei DeleteElement -1 gemacht wird.
Das kannst du für jeden Emitter auch einbauen.

Da du ja eh eigene Proceduren schreiben musst/willst, kannst du das Prima einbauen.
und bei CreatePartikel(*PartikelEmitter.PartikelEmitter)
dann zB: *PartikelEmitter\Elements + 1

und wenn du dann immer ordentlich Hinzufügst und Entfernst, sollte die Synkronität bestehen bleiben.


Aber warum ist "die Anzahl der Elemente [..] dieses immens wichtig ist." so wichtig ?
Ein Emitter bekomme eine Emissionsrate in der er Partikel ausspuckt.
Die Partikel eine LebensZeit aus diesen Daten kann die durchschnittliche Anzahl der existierenden Partikel berechnen.
Damit erhält man ein Überblick, mir fällt jetzt kein Grund ein die Anzahl genau zu kennen ...

Re: Wie kann man Liste in Liste oder Map in Map erstellen?

Verfasst: 01.03.2010 00:16
von mpz
Hi Stargate,

ein Problem habe ich aber vermutlich noch beim Löschen eines Partikels. Wenn der "Startpartikel" gelöscht wird knallts furchtbar. Vermutlich muss man das den Wert "umpatchen". Hast Du da schon einen fertigen Code?

Meine Lösung sieht im Prinzip so aus (die Schleife muss man sich denken...)

Code: Alles auswählen

   
*pointer.PartikelEmitter = *Partikel\PartikelEmitter
   If *pointer\StartPartikel = *Partikel
      DeleteElement(Partikel())
      If NextElement(Partikel())
         If Partikellist()\PartikelEmitter = *pointer
            *pointer\StartPartikel = Partikel()
         Else
            *pointer\StartPartikel = #False
         EndIf
      Else
            *pointer\StartPartikel = #False
      EndIf
  Else
     DeleteElement(Partikel())
  EndIf
Die einzelnen Partikel werden eh jedesmal neu berechnet, daher kann ich die anzahl der Elemente gut berechnen. Wichtig, ja , damit weiß ich ob mein Maximum der Elementen erreicht ist. Hier zu schätzen hätte noch langer Zeit unangenehme Nebenwirkungen

Gruß Michael

Re: Wie kann man Liste in Liste oder Map in Map erstellen?

Verfasst: 01.03.2010 01:53
von STARGÅTE
JO da hast du recht, dein LösungsCode ist auch soweit richtig, ich habe auch noch die DisplayProcedure verbessert, dort gabs n kleinen BUG ...

Code: Alles auswählen

Structure Partikel
  *PartikelEmitter.PartikelEmitter
  x.f
  y.f
EndStructure

Structure PartikelEmitter
  *StartPartikel.Partikel
  x.f
  y.f
EndStructure


Global NewList Partikel.Partikel()

Global NewList PartikelEmitter.PartikelEmitter()


Procedure CreatePartikelEmitter(x.f, y.f)
  If AddElement(PartikelEmitter())
    PartikelEmitter()\x = x
    PartikelEmitter()\y = y
    PartikelEmitter()\StartPartikel = #False
    ProcedureReturn PartikelEmitter()
  EndIf
EndProcedure

Procedure CreatePartikel(*PartikelEmitter.PartikelEmitter)
  If *PartikelEmitter\StartPartikel
    ChangeCurrentElement(Partikel(), *PartikelEmitter\StartPartikel)
    AddElement(Partikel())
  Else
    LastElement(Partikel())
    *PartikelEmitter\StartPartikel = AddElement(Partikel())
  EndIf
  Partikel()\x = *PartikelEmitter\x
  Partikel()\y = *PartikelEmitter\y
  Partikel()\PartikelEmitter = *PartikelEmitter
EndProcedure

Procedure DeletePartikel(*Partikel.Partikel)
  ChangeCurrentElement(Partikel(), *Partikel)
  If *Partikel = *Partikel\PartikelEmitter\StartPartikel
    If NextElement(Partikel()) And Partikel()\PartikelEmitter = *Partikel\PartikelEmitter
      *Partikel\PartikelEmitter\StartPartikel = Partikel()
    Else
      *Partikel\PartikelEmitter\StartPartikel = #False
    EndIf
    DeletePartikel(*Partikel)
  Else
    DeleteElement(Partikel())
  EndIf
EndProcedure

Procedure DisplayPartikel(*PartikelEmitter.PartikelEmitter=0)
  If *PartikelEmitter 
    If *PartikelEmitter\StartPartikel
      ChangeCurrentElement(Partikel(), *PartikelEmitter\StartPartikel)
      Repeat
        Debug "Emitter: "+Str(Partikel()\PartikelEmitter)+"  :: ("+Str(Partikel()\x)+"|"+Str(Partikel()\y)+")"
      Until Not NextElement(Partikel()) Or Partikel()\PartikelEmitter <> *PartikelEmitter
    EndIf
  Else
    ForEach Partikel()
      Debug "Emitter: "+Str(Partikel()\PartikelEmitter)+"  :: ("+Str(Partikel()\x)+"|"+Str(Partikel()\y)+")" 
    Next
  EndIf
EndProcedure


Dim *PartikelEmitter(4)
Debug "EmitterIDs:"
For n = 0 To 4
  *PartikelEmitter(n) = CreatePartikelEmitter(Random(100),Random(100))
  Debug Str(n)+"  "+Str(*PartikelEmitter(n))
Next

Debug "---"
RandomSeed(1)
For n = 1 To 16
  CreatePartikel(*PartikelEmitter(Random(4)))
Next

Debug "Display 2:"
DisplayPartikel(*PartikelEmitter(2))
Debug "Display All:"
DisplayPartikel()

DeletePartikel(FirstElement(Partikel()))
DeletePartikel(FirstElement(Partikel()))
Debug "Display 3:"
DisplayPartikel(*PartikelEmitter(3))

DeletePartikel(FirstElement(Partikel()))
DeletePartikel(FirstElement(Partikel()))
DeletePartikel(FirstElement(Partikel()))
Debug "Display 3:"
DisplayPartikel(*PartikelEmitter(3))
Die DeleteFunktion hat folgendes Funktionsprinzip:

Code: Alles auswählen

Procedure DeletePartikel(*Partikel.Partikel)
  ChangeCurrentElement(Partikel(), *Partikel)
  If *Partikel = *Partikel\PartikelEmitter\StartPartikel
    If NextElement(Partikel()) And Partikel()\PartikelEmitter = *Partikel\PartikelEmitter
      *Partikel\PartikelEmitter\StartPartikel = Partikel()
    Else
      *Partikel\PartikelEmitter\StartPartikel = #False
    EndIf
    DeletePartikel(*Partikel)
  Else
    DeleteElement(Partikel())
  EndIf
EndProcedure

Code: Alles auswählen

-> StartPartikel ?
  -> NEIN
    -> Löschen
  -> JA
    -> Gehört nächstes Partikel dazu?
      -> JA -> StartPartikel darauf legen
      -> NEIN -> StartPartikel auf #False
    -> Partikel erneut versuchen zu Löschen
Ist n bisschen kürzer.

Wegen dem Zählen, ja eben, einfach beim Displayen einfach mitzählen und dem Emitter übergeben...

Re: Wie kann man Liste in Liste oder Map in Map erstellen?

Verfasst: 02.03.2010 17:30
von mpz
Hi Stargate,

über ein kleines Problem bin ich noch gestolpert und möchte es nun einbringen. Wenn ich in einer Schleife bin würde Deine Routine nicht funktionieren. Durch NextElement schaltet die Prozedur meiner Meinung nach einfach ein Element weiter

Code: Alles auswählen

count = 0
ForEach Partikel()
       count + 1
         if count > 2
             DeletePartikel(Partikel())
         endif
next
Ich glaube auch das in der DeletePartikel(*Partikel.Partikel) Routine noch ein Bug ist. Durch NextElement(Partikel())
schaltet die Routine doch zum nächsten Partikel und löscht diesen und nicht den aktuellen. Oder irre ich mich ?

Code: Alles auswählen

   If NextElement(Partikel()) And Partikel()\PartikelEmitter = *Partikel\PartikelEmitter
      *Partikel\PartikelEmitter\StartPartikel = Partikel()
    Else
      *Partikel\PartikelEmitter\StartPartikel = #False
    EndIf
    DeletePartikel(*Partikel)
Sollte nicht vor DeletePartikel(*Partikel) ein PreviousElement(Partikel()) eingefügt werden?

Ich habe es etwas anders gelöst indem ich meine vorhergehende Routine angepasst habe...

Gruß Michael

Re: Wie kann man Liste in Liste oder Map in Map erstellen?

Verfasst: 02.03.2010 18:40
von STARGÅTE
Sollte nicht vor DeletePartikel(*Partikel) ein PreviousElement(Partikel()) eingefügt werden?
nein, muss nicht, da *Partikel bereits der Pointer von dem Element ist/war welches ich zuvor übergeben habe.
Dieser ändert sich ja nicht wenn ich NextElement() machen.

Bei dieser Variante mit der gesplitteten Liste muss man aufpassen mit was man gerade Arbeitet.
Mit einem temporären aktuellen Element : Partikel()
Oder mit einem festen aktuellen Element : *Partikel

würde es DeletePartikel(Partikel()) heiße, müsse ein PreviousElement rein, aber bei mir nicht.

In der angesprochenen Schleife hast du recht! deswegen muss dort noch ein PreviousElement rein !