Von einem Type auf andere Types zugreifen ?

Previous topic - Next topic

Trabant 500

Hi.

Ich bin gerade dabei mich in die GLBasic-Typestrukturen einzuarbeiten und habe es auch soweit verstanden. Ein Problem habe ich allerdings noch, welches bissl schlecht zu erklären ist. Ich versuche es mal am beliebten Beispiel eines Weltraumshooters(Multiplayer).

Nehmen wir an wir haben eine Typestruktur namens 'Player'. Darin befinden sich die Daten für alle Spielerobjekte.
Code (glbasic) Select
Type Player
    PosX
    PosY
    usw...
End Type


Gehen wir weiterhin davon aus, daß wir 4 Spieler-Raumschiffe erstellt haben. Es sind also 4 Einträge vorhanden.
Jedem der zwei Teams sollen nun jeweils 2 Raumschiffe zugeteilt werden. Dafür gibt es eine weitere Typestruktur namens 'Teams'. Darin wird festgelegt welche Raumschiffe zu welchem Team gehören.
Es sollen zum Beispiel die Raumschiffe mit der Nummer 0 und 1 dem Team Rot und die Raumschiffe 2 und 3 dem Team Blau zugeteilt werden.
Wenn man jetzt in einer Schleife die Teams abfragt, aber nur die Blauen berechnen will, so müsste man in der Struktur 'Teams' abfragen welche 'Player'-Nummern zum blauen Team gehören und dessen PosX, PosY etc. aktualisieren. Wie kann man dies bewerkstelligen ? Also wie kann man von einer Typestruktur aus auf eine andere zugreifen ?

Es ist ein bissl blöd zu erklären, aber ich hoffe das es trotzdem halbwegs verständlich ist. ;)


PS:
Ich programmiere mittlerweile seit über 22 Jahren und eigentlich durchgängig im Basic-Dialekt (Html, PHP, etc. mal ausgenommen). Dadurch habe ich schon viele Typestrukturen kennengelernt und frage mich wieso das bei GLBasic so extrem kompliziert gemacht wurde !? Wenn man mal die Umsetzung bei Blitzbasic betrachtet, so erkennt man, daß es da um einiges einfacher, aber dennoch sehr effektiv ist. Wieso ist das bei GLBasic denn so umständlich mit den Types ?
IF was <> passt
   was = passt
ENDIF

Schranz0r

Code (glbasic) Select
TYPE TPlayer
x;y
blablabla...
ENDTYPE


TYPE TTeam
bla...
players[] AS TPlayer
ENDTYPE
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

Danke Schranz0r, aber kannst Du das eventuell kurz erläutern ?
IF was <> passt
   was = passt
ENDIF

Quentin

Die Zuweisung kannst du folgendermaßen vornehmen. Mit verschachtelten TYPEs wirds aber sehr schnell unübersichtlich meiner Meinung nach. Nur was ist daran komplizierter als in anderen Basic-Dialekten? Der Zugriff erfolgt dort doch ebenso.

Code (glbasic) Select

TYPE TPlayer
x
y
ENDTYPE

TYPE TTeam
player[2] AS TPlayer
ENDTYPE

GLOBAL teams[] AS TTeam
DIM teams[2]

// 1. Spieler des 1. Teams Werte zuweisen
teams[0].player[0].x = 10
teams[0].player[0].y = 20

// 2. Spieler des 1. Teams Werte zuweisen
teams[0].player[1].x = 50
teams[0].player[1].y = 40

// 1. Spieler des 2. Teams Werte zuweisen
teams[1].player[0].x = 70
teams[1].player[0].y = 10

// 2. Spieler des 2. Teams Werte zuweisen
teams[1].player[1].x = 15
teams[1].player[1].y = 16

Schranz0r

Also du musst als erstes das TPlayer machen damit GLB weiß, dass es TPlayer gibt.

Code (glbasic) Select
TYPE TTeam
    bla...
    players[] AS TPlayer
ENDTYPE


das erstellt ein Array für Spieler in einem Team.

also erstellt du als erstes ein Team:

Code (glbasic) Select
LOCAL Team1 AS TTeam

nun einen Spieler:

Code (glbasic) Select
LOCAL player1 AS TPlayer

jetzt kannst du den Team1 den Player1 zuweisen

Code (glbasic) Select
DIMPUSH Team1.players[], Player1


Jetzt könntest du sogar noch auf die Playerwerte zugreifen z.B x und y mit;

Code (glbasic) Select
Team1.players[0].x
Team.player[0].y


wenn du jetzt aber am Player1 was änderst musst du das an Team1 übergeben!
Sprich:

Team1.players[0] = Player1

I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

Vielen Dank für die Erklärungen. Dennoch bin ich trotz intensiven Rumprobierens noch nicht ganz hinter die Logik des Ganzen gekommen.
Ich denke ich habe mir auch ein zu kompliziertes Beispiel ausgedacht. Mittlerweile ist mir ein einfacheres eingefallen. Ich hoffe ich verstehs dann. :D

Nehmen wir einfach an wir haben in einer Typestruktur ein paar Punkte (X;Y):
Code (glbasic) Select

TYPE Punkte
    x
    y
ENDTYPE


Und in der zweiten Typestruktur steht, welche Punkte zusammengehören. Also Beispielsweise soll Punkt 1 und Punkt 2 mit einer Linie verbunden werden. Das Gleiche mit den Punkten 2 und 3, aber nicht Punkt 1 und 3.

Kann mir das vielleicht jemand erklären ? Ich hoffe dann steig ich besser hinter das Geheimnis von Types in GLBasic. :)
IF was <> passt
   was = passt
ENDIF

Schranz0r

#6
Ich mach dir mal ein Beispiel ;)

Also ne "art Drawline" nur das man mit mehrern Punkten arbeiten kann, um eine Krümmung zu erzeugen.
Easy to do xD

EDIT:
Mal sehen ob du selber daraus schlauer wirst :P

Code (glbasic) Select
// --------------------------------- //
// Project: Lines Type
// Start: Monday, January 18, 2010
// IDE Version: 7.237

TYPE TVector
x%; y% // position
ENDTYPE

TYPE TLine
vec[] AS TVector // vector-array
color% // linecolor
ENDTYPE

GLOBAL _TLine[] AS TLine // Line-array



LOCAL Line1 AS TLine
Line1 =  CreateLine(RGB(0xff, 0x00, 0x00))

AddPointToLine(Line1,10,10)
AddPointToLine(Line1,20,20)
AddPointToLine(Line1,30,10)
AddPointToLine(Line1,40,20)
AddPointToLine(Line1,50,10)


LOCAL Line2 AS TLine
Line2 =  CreateLine(RGB(0x00, 0xff, 0x00))

AddPointToLine(Line2,100,100)
AddPointToLine(Line2,200,100)
AddPointToLine(Line2,200,200)
AddPointToLine(Line2,100,200)


WHILE TRUE

DrawPointLine(Line1)
DrawPointLine(Line2)

SHOWSCREEN
WEND
END

FUNCTION CreateLine AS TLine: color%
LOCAL L AS TLine

L.color = color

DIMPUSH _TLine[], L
RETURN L
ENDFUNCTION

FUNCTION AddPointToLine: L AS TLine, x%, y%
LOCAL V AS TVector

V.x = x
V.y = y

DIMPUSH L.vec[], V


ENDFUNCTION


FUNCTION DrawPointLine: L AS TLine

FOR i = 0 TO LEN(L.vec[])-1
IF i < LEN(L.vec[])-1
DRAWLINE L.vec[i].x, L.vec[i].y, L.vec[i+1].x, L.vec[i+1].y, L.color
ENDIF
NEXT

ENDFUNCTION
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

Danke Schranz0r.
Also Dein Beispiel habe ich soweit verstanden. Allerdings löst es nicht mein Verständnisproblem. Man kann ja mit einer FOREACH-Schleife jeden Eintrag einer Typestruktur durchgehen, aber wie kann man auf einen bestimmten Eintrag zugreifen ? Also wenn ich zum Beispiel 20 Einträge habe und den Eintrag 15 auslesen möchte, aber eben ohne alle Einträge durchgehen zu müssen. Wie mach ich das ?
IF was <> passt
   was = passt
ENDIF

Kitty Hello


Schranz0r

Mit LEN(_TLine[]) bekommst du die Anzahl der Einträge

Wenn du weißt wieviele Einträge du hast, kannst du auch _TLine[2].color oder _TLine[2].vec[0].x  usw verwenden!
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

Oh man...Da hab ich mal wieder den Wald vor lauter Bäumen nicht gesehen und viel komplizierter gedacht als es eigentlich ist.  ;/ :whistle:
Jetzt wo ich es verstanden habe, nehm ich auch meine Behauptung zurück, daß es komplizierter wäre als bei Blitzbasic und behaupte das Gegenteil.  =D

Eine Frage habe ich allerdings noch. ;)
Kann man in einer FOREACH-Schleife abfragen welcher Eintrag gerade abgefragt wird ? Also man kann das natürlich mit einer fortlaufenden Variable machen, aber gibt es vielleicht auch einen Befehl der eben diese Nummer ausgibt ?
IF was <> passt
   was = passt
ENDIF

Schranz0r

Ne gibts nicht, ich mach sowas über eine ID-Nummer im Type :D
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

#12
Das ist natürlich auch eine Möglichkeit, aber ist die nicht um einiges uneffektiver ?  :blink:
Wenn man eine ID-Nummer anlegt, dann kostet das ja Speicher und je mehr Einträge in der Typestruktur vorhanden sind, desto mehr Speicher wird benötigt. Außerdem braucht man dafür ja trotzdem eine fortlaufende Variable um den Wert der ID zu bestimmen. Wenn man allerdings nur bei der Ausgabe eine fortlaufende Variable hat, so ist das Ganze doch speicherschonender und somit effizienter, oder !?
IF was <> passt
   was = passt
ENDIF

Schranz0r

#13
Bei heutigen PC's wohl kein Problem mehr :D
Wenn ich beim programmieren schon auf sowas achten müsste, würde ich sofort aufhören ;)

Ne ich mach das eh nur, um einen festen Bezug auf den Eintrag im Typearray zu haben, falls ich es benötige, wenn nicht, dann braach ich das auch net ;)

aber naja du kannst machen:

Code (glbasic) Select
TYPE Test
    id
    x
    y
ENDTYPE

GLOBAL _Test[] AS Test

LOCAL bla AS Test

bla.id = LEN(_Test[])  // Hier geht man einfach von der Arraygröße aus :)

usw...
I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

Trabant 500

#14
Mag sein das heutige Computer kein Problem damit haben, aber wieso unnötig Speicher verschenken, wenn es doch gar nicht nötig wäre ? Und was ist mit den Usern die nicht für den PC compilieren ? Ich zum Beispiel bin WIZ-User und auch wenn der WIZ ausreichend Speicher hat, so stößt man auch da irgendwann an seine Grenzen. ;) Deswegen finde ich meine Version effektiver.

Hier mal ein Pseudobeispiel wie ich das meine:

Code (glbasic) Select
TYPE WERT
  Wert1
  Wert2
  ...
END TYPE

Werte eintragen usw...
blablablubb...

FUNCTION Auslesen:
  LOCAL ID=0
    FOREACH W IN Wert[]
      Print Wert[ID],0,ID*20
      ID=ID+1
    NEXT
ENDFUNCTION
IF was <> passt
   was = passt
ENDIF