Seite 1 von 2

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

Verfasst: 27.02.2010 13:34
von mpz
Hallo Leute,

ich habe ein Problem und hoffe Ihr könnt mir helfen. Ich mochte eine Liste in der Liste (kann auch MAP sein) erstellen. Ich habe es mal versucht beispielhaft zu machen. Ich erzeuge variable Partikelemmitter als List Elemente. Diese können auch variable Partikelelemente beinhalten. Derzeit verwende ich für diesen Zweck eine "große" Partikelliste die durch Tricks gesplittet wird. Leider ist die Programmpflege damit sehr schwer, so das ich diese Methode ersetzen will. Irgendwelche Tipps oder Tricks?

Beispielcode wie ich es gerne hätte:

Code: Alles auswählen

Structure Partikel
    MeinPartikel.i
    Textur.i
    pU.f
    pV.f
EndStructure


Structure PartikelEmitter
     MeinPartikelEmitter.i
     NewList Liste.Partikel() ; Ich weiß geht nicht, brauche ich aber
     x.i 
     y.i
EndStructure


NewList Emitter.PartikelEmitter()

; Erstelle einen Emitter 
AddElement(Emitter())

; Erstelle 5 Partikel
AddElement(Emitter()\Liste)
AddElement(Emitter()\Liste)
AddElement(Emitter()\Liste)
AddElement(Emitter()\Liste)
AddElement(Emitter()\Liste)
Gruß Michael

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

Verfasst: 27.02.2010 13:42
von Kaeru Gaman
zur Zeit geht das garnicht.
es gibt Includes die ein eigenes LL-System bauen um das zu bewerkstelligen.
auch in der Lounge hab ich so Code mal rumliegen sehen, die machen ja eh mehr mit OOP in PB.

aber es ist in Planung.
Fred selbst hat gesagt dass er für eine der nächsten Versionen Listen in Strukturen ermöglichen will.

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

Verfasst: 27.02.2010 15:45
von STARGÅTE
das willst du vllt jetzt nicht hören, aber ich sags trotzdem:

Eigentlich reicht eine Partikel-Liste mit allen Partikeln von allen Emittern, wie du ja schon benutzt!

Die Partikel-Structure erhält dann einfach ein Pointer zum zugehörigen Emitter.

Die Partikelliste kann ja nach den Emitter-Pointern geordnet sein.
Jeder Emitter erhält dann eine art Start-Partikel in der Liste der Partike.
Jedes hinzufügen/löschen/anzeigen, findet dann nur genau ab diesem Start-Partikel statt.
Dieses Erreichst du mittels ChangeCurrentElement.

Beim Anziegen der Partikel für ein Emitter, klapperst du dann nur die Liste der Partikel ab:
Von ChangeCurrentElement mit dem Startpartikel bis zum ersten nicht mehr zugehörigen Partikel.

Ich will jetzt einfach mal behaupten das, dass sogar eine bessere Lösung ist als jedem Emitter eine eigene SubList zu geben!

Wenn du das schon eh schon machst, dann vergiss diesen Post ^^

Wenn du n Beispiel brauchst, kann ich gerne eins Posten ...

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

Verfasst: 27.02.2010 16:22
von mpz
Hi,

Wenn Du ein Beipiele hast nur zu, ich kann das sicher brauchen. In meinem System geht manchmal etwas schief und ich weiß dummerweise nicht warum. Da dachte ich das ich das System dann in ein einfacheres System umbaue was man auch später noch versteht. Daher ist eine "unterListe" gar nicht so schlecht. Auf Deine Lösung bin ich gespannt...

Gruß Michael

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

Verfasst: 27.02.2010 16:36
von DrShrek
Also das mit Listen in Structuren...das geht auf jeden Fall schon heute mit den Boardmitteln von PB. Nur eben nicht so einfach wie im ersten Post vom mpz

Allerdings ist es nicht einfach zu verstehen...und erfordert abstraktes Denken.
Ich hatte mal vor über einen Jahr so etwas mit nativen PB Befehlen für Lost Labyrinth gemacht.

Nachdem es aber sehr kompliziert ist haben die aktuellen Entwickler von Lost labyrinth dieses Beispiel bis heute nicht in den aktuelle Lost Labyrinth version eingebaut.

Der Main-Entwickler von Lost Labyrinth (Markus Döbele) hat mir dazu erst vor einer Woche eine erste Mail geschrieben.

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

Verfasst: 27.02.2010 17:24
von STARGÅTE
So hier mal eine der möglichen Varianten.

Ich weiß nicht genau ob du die "Index-Schreibweise" wie es bei den PB-Sachen ist lieber willst, oder mit Pointern arbeitest, oder jetzt neu mit Namen:
A: CreatePartikelEmitter(#PartikelEmitter1, x.f, y.f) ; LinkedList/Array Konbination
B: *PartikelEmitter1 = CreatePartikelEmitter(x.f, y.f) ; LinkedList
C: CreatePartikelEmitter("PartikelEmitter1", x.f, y.f) ; Map
Hier n Variante mit Pointern:

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 DisplayPartikel(*PartikelEmitter.PartikelEmitter=0)
  If *PartikelEmitter And *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
  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()
Erst werden 5 Emitter erzeugt, dessen IDs in einem Array gespeichert werden.
Hier kann man auch mit einer Map arbeiten.

Danach werden zufällig Partikel in zufälligen Emittern erstellt.
Beim erstellen (CreatePartikel), wird dabei auf die "Ordnung" in der Liste geachtet.

Bein darstellen/auslesen, wird dann das StartPartikel angesprungen, und solange weiter gemacht bis ein anderes kommt:

Code: Alles auswählen

ChangeCurrentElement(Partikel(), *PartikelEmitter\StartPartikel)
 Repeat : Until Not NextElement(Partikel()) Or Partikel()\PartikelEmitter <> *PartikelEmitter
Diese Art der Listen-Bearbeitung kannst du nun überall da verwenden wo du nun zugriff auf Partikel eines bestimmten Emitters brauchst.

Der Vorteil hier ist, das du aber auch komplett alle Partikel durchlaufen kannst (mit nur einer Schleife).

Verfasst: 27.02.2010 17:35
von Kaeru Gaman
nette idee.
wenn man jetzt noch die Reihenfolge sektoriell einteilt, kann man alle Emmitter in einem Sektor der Karte durchlaufen.
... weil man ja normalerweise nicht alle Emitter in der World anzeigen will sondern nur die in der Nähe der Cam.
eventuell wäre ein Dummy-Element was den Sektor beginnt ganz praktisch, damit man den Anfang der Sektorenliste auch suchen kann.

Re:

Verfasst: 27.02.2010 17:47
von STARGÅTE
Kaeru Gaman hat geschrieben:wenn man jetzt noch die Reihenfolge sektoriell einteilt, kann man alle Emmitter in einem Sektor der Karte durchlaufen.
Reihenfolgen gibt es aber nur im Eindimensionalen, eine Karte ist aber meist 2-Dimensional, gar 3-Dim.
Da kann man höchsten die "Sektoren" du du meinst Nummerieren, und diese Nummerierung wäre dann wieder Eindimensionalen und somit "reihenfolg-bar" gibs das Wort überhaupt ?
Wenn man dort zeilenweise vorgeht, gibs n Algo. mit dem man von einem Sektorfeld alle 8 Nachbarn bekommt, ohne suche, und diese dann anläuft, wenn du das meinst ...

Verfasst: 27.02.2010 17:53
von Kaeru Gaman
ich dachte jetzt erstmal nur an einzelne Sektoren, aber klar, die 8 Nachbarn wäre ein wichtiger Punkt.

nur dass es bei einer Liste doch keinen Algo gibt um die oberen und unteren Nachbarn zu ermitteln?
bei einem Array geht das, weil die Zeilenlänge fix ist, aber wenn beliebig viele Elemente in einer Zeile stehen können, muss ich zwangsweise suchen.

das Dummy-Element das den Sektoren-Header bildet könnte natürlich auch Pointer zu seinen Nachbarn tragen...
genaugenommen braucht es nur drei: den linken, den links oben und den links unten.
... nee ... da muss man noch was anders machen ...

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

Verfasst: 28.02.2010 17:46
von mpz
Hi Stargate,

Dein Code sieht schon sehr vielversprechend aus. Ich glaube ich habe Ihn auch verstanden. Der einzige kleine Nachteil ist das ich die Anzahl der Elemente einzeln zählen muss, da bei einem Partikelemmitter dieses immens wichtig ist.

Gruß Michael