Verschiedene Typefields über Array verwalten

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

Krischan

Betreff: Verschiedene Typefields über Array verwalten

BeitragMi, Okt 06, 2010 15:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe ein grosses Typefield, welches ein Sternenfeld mit tausenden Einträgen speichert:

Code: [AUSKLAPPEN]
Type star
   
    Field entity%
    Field x#,y#,z#
   
End Type


Jetzt habe ich mir gedacht das ganze mittels eines dreidimensionalen Arrays zu unterteilen. Die Sterne befinden sich insgesamt in einer Entfernung von 0...50 auf jeder Achse, dann könnte man doch 5x5x5=125 "Sub"types erstellen, die jeweils einen 10x10x10 Units grossen Sektor repräsentieren, der dann über den jeweiligen Arrayeintrag angesprochen und dessen Sterne dann einzeln durchgegangen werden können. Die Sterne werden eingangs alle auf einmal erzeugt und dann mittels der Position den einzelnen Types zugeordnet.

Wenn sich die Kamera dann später bewegt, sollen nur die Typefields in dem Sektor, in dem sich die Kamera befindet durchgegangen werden. Beispiel: Kamera ist in Sektor 2,4,1, dann soll man nur die Sterne des dortigen Types einfach mit For...Each durchgehen können, evt. auch die 8 umliegenden Sektoren.

Wie macht man das? Ich stehe hier gerade auf dem Schlauch.
 

Matthias

BeitragMi, Okt 06, 2010 17:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Hay. Dazu müstest du die Type Handles nummer in einer Bank speichern.
Und dann die einzelnen Banken durch gehen.
Da mann Banken verkleinern oder vegrößern kann können auch alle Sektoren unterschiedlich viele Sterne haben.

Xeres

Moderator

BeitragMi, Okt 06, 2010 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Ausgehend von diesem System:
BlitzBasic: [AUSKLAPPEN]
Type star

Field entity%
Field Sx%,Sy%,Sz%
Field x#,y#,z#

End Type

Dim Sektoren.star(4,4,4)

Erstellst du alle deine Sterne, mit Sx/Sy/Sz den Sektor Koordinaten. Beim erstellen sortierst du die Typeeinträge nach Sektoren, d.h. im Array ist auf Sektoren.star(0,2,0) der erste Eintrag mit den Sektor-Koordinaten 0,2,0 - diese Instanz kannst du direkt ansprechen. Wenn du einen anderen Stern aus dem Sektor brauchst, gehst du mit After weiter, bis die Sektor Koordinaten nicht mehr mit dem gesuchten übereinstimmen.
So hast du Fixpunkte in der Liste und musst nicht alle Instanzen durchgehen.

Nachtrag: In etwa so:
BlitzBasic: [AUSKLAPPEN]
Type TStar

Field Name$
Field Sx%
Field x#

End Type

Const SektorSize = 2
Dim Sektoren.TStar(SektorSize)

CreateStars(SektorSize*5) ;* ~ 5 Sterne per Sektor

ListStarsOfSektor(2)


WaitKey()
End

Function CreateStars(count%)
Local i%, S.TStar
For i=0 To count
S = New TStar
S\Name = Chr(Rand(65,94)) + Chr(Rand(65,94)) + Chr(Rand(65,94)) + Chr(Rand(65,94))
S\x = Rnd(0,SektorSize*10)
S\Sx = Int(S\x / 10)
;Print("'"+S\Name+"' / "+S\x+" / "+S\Sx)
If Sektoren(S\Sx) = Null Then
Sektoren(S\Sx) = S
Print("Neuer Hauptstern in Sektor "+S\Sx+" '"+S\Name+"'")
Else
Insert S After Sektoren(S\Sx)
Print("Neuer Nebenstern in Sektor "+S\Sx+" '"+S\Name+"'")
EndIf
Next
End Function

Function ListStarsOfSektor(sektor%)
Local S.TStar = Sektoren(sektor%)
If S = Null Then
Print("Keine Sterne in Sektor "+sektor+"!")
Return
Else
Repeat
Print("Name: "+S\Name+" Pos: "+S\x+" ("+S\Sx+")")
S = After S
If S = Null Then Return
Until S\Sx <> sektor
EndIf
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Krischan

BeitragFr, Okt 08, 2010 16:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Xeres hat Folgendes geschrieben:
Ausgehend von diesem System

Sei mir net bös, Xeres, aber ich raff es immer noch nicht. Dein Beispiel ist eindimensional, wie sähe das denn mehr/dreidimensional aus? Ich weiss nicht ob das evt. nur im Bmax realisierbar ist, im Pseudocode schwebt mir zumindest so etwas vor (nicht lauffähig und syntaktisch verkehrt, aber so in etwa):

Code: [AUSKLAPPEN]
; type eines sterns
Type star
   
    Field name$,x#,y,z#
   
End Type

Dim Sektoren(10,10,10)

; Aufbau
For i=1 To 10000
   
    x=Rnd(100)
    y=Rnd(100)
    z=Rnd(100)
   
    sx=Int(x/10.0)
    sy=Int(y/10.0)
    sz=Int(z/10.0)
   
    ; Stern zum jeweiligen Sektor hinzufügen (irgendeine Funktion die das macht)
    AddStarToSector(sx,sy,sz,"Stern "+i,x,y,z)
   
Next

; bestimmten Sektor auswählen
temp=GetSector(2,3,6)

; nur die Sterne des Sektors ausgeben
For t.temp = Each temp
   
    Print t\name+": "+t\x+","+t\y+","+t\z
   
Next

Xeres

Moderator

BeitragFr, Okt 08, 2010 16:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
wie sähe das denn mehr/dreidimensional aus?
Nun - fast genauso. Der Pseudocode geht ja schon in die richtige Richtung.

BlitzBasic: [AUSKLAPPEN]
; bestimmten Sektor auswählen
temp=GetSector(2,3,6)

; nur die Sterne des Sektors ausgeben
For t.temp = Each temp

Print t\name+": "+t\x+","+t\y+","+t\z

Next

Das kann so mit BB nicht gehen - Du hast ein Type "star" und jeder Stern den du erstellst, wird in dessen Globale liste eingetragen.
Darum muss man beim erstellen die Sterne gleich die passenden Sektoren zusammen sortieren. Den ersten Stern im Sektor kann man direkt aus dem Array bekommen, den Rest muss man per After weiterschalten, und aufhören, wenn die Koordinaten eines anderen Sektors erreicht wurden (oder das ende der Type-Liste erreicht wurde: NULL).

Nachtrag:
Selbes Beispiel in 3D
BlitzBasic: [AUSKLAPPEN]
Type TStar

Field Name$
Field x#, y#, z#

End Type

Const SektorSize = 10
Dim Sektoren.TStar(SektorSize, SektorSize, SektorSize)

CreateStars(10000)

ListStarsOfSektor(2,3,6)


WaitKey()
End

Function CreateStars(count%)
Local i%, S.TStar
For i=0 To count
S = New TStar
S\Name = Chr(Rand(65,94)) + Chr(Rand(65,94)) + Chr(Rand(65,94)) + Chr(Rand(65,94))
S\x = Rnd(0,100)
S\y = Rnd(0,100)
S\z = Rnd(0,100)
Local Sx% = Int(S\x / 10)
Local Sy% = Int(S\y / 10)
Local Sz% = Int(S\z / 10)


If Sektoren(Sx, Sy, Sz) = Null Then
Sektoren(Sx, Sy, Sz) = S ;** Verlinken
Else
Insert S After Sektoren(Sx, Sy, Sz) ;** Neuen Stern hinter diesen Stern setzen
EndIf
Next
End Function

Function ListStarsOfSektor(sektorX%, sektorY%, sektorZ%)
Local S.TStar = Sektoren(sektorX%, sektorY%, sektorZ%) ;*** Ersten Stern des Sektors finden.
If S = Null Then
Print("Keine Sterne in Sektor ("+sektorX%+", "+ sektorY%+", "+ sektorZ%+") !")
Return
Else
Repeat ;*** Ersatz für eine For...Each Schleife!
Print("Name: "+S\Name+" Pos: "+S\x+", "+S\y+", "+S\z)
S = After S ;*** Per hand in der Type-Liste weitergehen (Next)
If S = Null Then Return ;*** Ende der Liste abfangen
;*** wenn der nächste Stern in einem anderen Sektor ist, wird aufgehört...
Until Int(S\x / 10) <> sektorX Or Int(S\y / 10) <> sektorY Or Int(S\z / 10) <> sektorZ
EndIf
End Function

ListStarsOfSektor kann etwas mit den Sternen eines bestimmten Sektors anstellen - aber es ist nicht möglich, eine Separate liste für Sektoren o.ä. zu erstellen.

Nachtrag2:
Okay - man könnte auch einen solchen Workaround verwenden, wenn man unbedingt eine Type Liste mit Speziellen Sternen braucht:
BlitzBasic: [AUSKLAPPEN]
Type TStar

Field Name$
Field x#, y#, z#

End Type

Type TStar_Copy

Field Star.TStar

End Type

Dim Sektoren.TStar(SektorSize, SektorSize, SektorSize)

Function WorkingCopy(sektorX%, sektorY%, sektorZ%)
Delete Each TStar_Copy ;*** Aktuelle Liste Löschen... Kein TStar-Objekt geht dabei verloren!
Local C.TStar_Copy, S.TStar = Sektoren(sektorX%, sektorY%, sektorZ%) ;*** Ersten Stern des Sektors finden.
If S = Null Then
Print("Keine Sterne in Sektor ("+sektorX%+", "+ sektorY%+", "+ sektorZ%+") !")
Return
Else
Repeat ;*** Ersatz für eine For...Each Schleife!

;*** Sterne in verlinken.
C = New TStar_Copy
C\Star = S

S = After S ;*** Per hand in der Type-Liste weitergehen (Next)
If S = Null Then Return ;*** Ende der Liste abfangen
;*** wenn der nächste Stern in einem anderen Sektor ist, wird aufgehört...
Until Int(S\x / 10) <> sektorX Or Int(S\y / 10) <> sektorY Or Int(S\z / 10) <> sektorZ
EndIf
End Function

Ich bezweifle aber, dass das besonders effizient oder flexibel ist...
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Krischan

BeitragFr, Okt 08, 2010 17:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Ahhhh das erste Beispiel sieht gut aus - damit kann ich weiter herumspielen, danke! Ist auch sehr schnell, der zieht die Liste quasi in Echtzeit aus dem Typefield, hab mal 10.000.000 Sterne ohne Textausgabe versucht, höchstens 1ms, wow Shocked

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group