Type unabhaengig von Typename

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

BladeRunner

Moderator

Betreff: Type unabhaengig von Typename

BeitragFr, Dez 06, 2013 0:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Für Eyes_only erneut eingestellt. MfG BladeRunner
Type unabhängig von Typename an Funktion übergeben

Hallo Community,

ich habe ein Problem. Ich habe zwei verschiedene Types (Spieler und Gegner) mit je einer Instanz. Beide Types haben ein Feld "Energie". Dazu habe ich eine Funktion, die die Energie einfach mittels print ausgeben soll.

Der ganze Code sieht so aus:

BlitzBasic: [AUSKLAPPEN]
Type TSpieler
Field Energie
End Type

Global Spieler.TSpieler = New TSpieler
Spieler\Energie = 54321

Type TGegner
Field Energie
End Type

Global Gegner.TGegner = New TGegner
Gegner\Energie = 12345

EnergieAusgeben(Spieler)

Function EnergieAusgeben (obj.TSpieler)
Print obj\Energie
End Function


Gibt es eine Möglichkeit, dass ich der Funktion "EnergieAusgeben()" einen Type unabhängig vom Typenamen (TSpieler oder TGegner) übergebe, damit ich die Funktion im Laufe des Programms an unterschiedlicher Stelle und mit verschiedenen Types benutzen kann, also an der einen Stelle mal "Spieler" übergeben, an anderer Stelle mal "Gegner". Denn so wie es jetzt ist, erwartet die Funktion ja einen Type vom Typ "TSpieler", sodass "Gegner" nicht an die Funkion übergeben werden kann.

Wichtig ist, dass die beiden verschiedenen Typen (TSpieler und TGegner) bestehen bleiben. Das Ganze auf einen Type (TSpielfigur) runter zu brechen bringt mich nicht weiter.

Vielen Dank für eure Hilfe!
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DAK

BeitragFr, Dez 06, 2013 11:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Was du machen kannst ist sowas:
BlitzBasic: [AUSKLAPPEN]
Type TTest1
Field a%
Field b%
End Type

Type TTest2
Field a%
Field b%
End Type

o.TTest1 = New TTest1
o\a = 1

h = Handle(o)

o2.TTest2 = Object.TTest2(h)
Print((o2=Null))

Delay(1000)


Also nach dem Object.wasauchimmer checken, ob das Ergebnis Null ist. Ist es nicht Null, dann hast du den richtigen Typ erwischt. In der Funktion musst du dann hald alles für beide Typen einzeln schreiben. Von außen kannst du dann die Funktion aber für beide Typen gleich ansteuern.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Eyes_Only

BeitragFr, Dez 06, 2013 13:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm... das bringt mich nicht so richtig weiter. Wenn ich das richtig verstanden habe, zeigen Handle und Object auf einen bestimmten Type Eintrag. Ich will ja aber gar nicht, dass Obj2 auf Obj1 zeigt, sondern möchte die selbständig und unabhängig voneinander haben.

Gibt es denn eine Möglichkeit ohne Handle und Object? Weil die ja auch undokumentiert sind...

Oder kann mir das jemand an meinem obigen Beispiel erklären, wie das funktioniert, dass ich meine Funktion EnergieAusgeben() einmal mit "Spieler" und einmal mit "Gegner" füttere? Vielleicht habe ich ja diese Handel/Object Geschichte nicht ganz verstanden.

Danke

DAK

BeitragFr, Dez 06, 2013 14:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, hab vorhin keine Zeit gehabt, ein schönes Beispiel draus zu machen, hier noch mal richtig:

BlitzBasic: [AUSKLAPPEN]
Type TTest1
Field a%
End Type

Type TTest2
Field a%
End Type

o1.TTest1 = New TTest1
o1\a = 1
o2.TTest2 = New TTest2
o2\a = 2

Print(getA(Handle(o1)))
Print(getA(Handle(o2)))

Delay 1000

Function getA(h%)
o1.TTest1 = Object.TTest1(h)
If (o1<>Null)
Return o1\a
EndIf
o2.TTest2 = Object.TTest2(h)
If (o2<>Null)
Return o2\a
EndIf
Return 0
End Function


Mir ist sonst nichts bekannt, wie man in BB einer Funktion eine Variable beliebigen Typs übergeben kann. In jeder Sprache, die Objektorientierung richtig umsetzt wäre Vererbung das was du brauchst. Leider gibt es das in BB nicht, soweit ich weiß. Das ist leider alles was mir einfällt, um in BB die statische Typisierung zu umgehen.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Eyes_Only

BeitragFr, Dez 06, 2013 15:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey super, vielen Dank!
Das hilft mir jedenfalls weiter. Jetzt werde ich mal schauen, dass ich das in mein Spiel eingebaut bekomme.

Schade, dass BB eine andere Möglichkeit nicht unterstützt.

BladeRunner

Moderator

BeitragFr, Dez 06, 2013 15:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein Hack wäre jedem Objekt ein internes ID-Feld zu geben, die eindeutig zu vergeben und dann alle in frage kommenden Types zu prüfen ob sie ein Objekt mir der passenden ID haben. Ist aber ein Dirty workaround und unter Umständen recht langsam.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

Eyes_Only

BeitragFr, Dez 06, 2013 17:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, das klingt recht - naja, sagen wir mal unsauber... Very Happy

Aber auf jeden Fall auch eine Möglichkeit. Danke!

Xeres

Moderator

BeitragFr, Dez 06, 2013 18:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Da es keine Vererbung in BB gibt, kann man das nicht wirklich schön lösen...
Was mir noch einfällt:
1. Man könnte für Spieler und Gegner den selben Type benutzen.
2. Vielleicht macht es Sinn, die Energie-Eigenschaften (basiswert, bonus, aktueller Wert, Maximalwert) in einen Sub-Type zusammen zu fassen. Dann kann man immerhin EnergieAusgeben(Spieler\Energie) und EnergieAusgeben(Gegner\Energie) schreiben.
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)
 

Eyes_Only

BeitragFr, Dez 06, 2013 19:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit dem gleichen Type für beide hatte ich schonmal gemacht, zB Spieler.TSpielfigur und Gegner.TSpielfigur.

Dann hatte ich jedoch ein Problem, wenn ich mit

Code: [AUSKLAPPEN]
For Gegner.TSpielfigur to Each TSpielfigur


meine Gegner Objekte durchlaufen habe, weil er dann "Spieler" auch als Objekt von "TSpielfigur" mit überprüft hat und die Werte für "Spieler.TSpielfigur" alles auf 0 gesetzt hat, weil ich da ja nichts initialisiert hatte.

Ich hatte glaube ich noch eine Überprüfung anhand einer ID mit drin, das hat es aber auch nicht besser gemacht.

Xeres

Moderator

BeitragFr, Dez 06, 2013 20:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Klar, da muss man eine Bedingung herum bauen - IDs sind bei Types meistens Kontraproduktiv: Man kann Instanzen sehr gut auf Gleichheit prüfen und sehr schlecht wirklich eindeutige IDs erzeugen, die man dann nochmal extra abfragen müsste...

BlitzBasic: [AUSKLAPPEN]
Type TChar
Field name$
End Type

Global Player.TChar = New TChar
Player\name = "Spieler"
Local char.TChar, i%
For i=0 To 10
char = New TChar
char\name = "Gegner"
Next

For char = Each TChar
If char <> Player Then ;IDs nicht nötig
Print(char\name)
EndIf
Next
Print(Player\name)

WaitKey()
End
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)

DAK

BeitragFr, Dez 06, 2013 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Falls dir das was hilft, könntest du es so machen:

BlitzBasic: [AUSKLAPPEN]
Type TShared
Field a%
End Type

Type TTest1
Field s.TShared
End Type

Type TTest2
Field s.TShared
End Type

o1.TTest1 = New TTest1
o1\s = New TShared
o1\s\a = 1
o2.TTest2 = New TTest2
o2\s = New TShared
o2\s\a = 2

Print(getA(o1\s))
Print(getA(o2\s))

Delay 1000

Function getA(s.TShared)
Return s\a
End Function


In TShared kommt alles, was beide gemeinsam haben. TTest1 und TTest2 sind dann dafür da, dass es zwei getrennte Listen gibt für die verschiedenen Objekte gibt. Auch können in TTest1 und TTest2 alle Variablen gesteckt werden, die sie nicht teilen.
Damit kann man Vererbung teilweise nachbasteln.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Eyes_Only

BeitragFr, Dez 06, 2013 23:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Das sind in der Tat zwei schöne Varianten.
Ich schaue mal, ob ich davon etwas in meinem Programm umsetzen kann.

Dankeschön!

Tankbuster

BeitragSa, Dez 07, 2013 2:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde auch sagen, es ist am Sinnvollsten für Spieler und Gegner einen Type zu benutzen. Den Spieler erkennst du dann an der ID.

Natürlich kannst du den Gegnern auchnoch eine ID geben um eventuelle Typen der Gegner festzulegen, die dann mit einer Funktion individuell bewegt werden oder halt auch anderes Zeugs machen .. ID=1 z.b. langsam ID=2 z.b. schnell, ect
Damit spart man eine Variable \o/

Code: [AUSKLAPPEN]
For P.Player=Each Player

    If P/ID$=Spielername$ Then  ;natürlich muss es kein String sein :3

        ;Spielerzeug If KeyHit then move undso.

    Else

        ;Künstliche unintelligenz Zeug
        ;jagespieler() undso.

    Endif

    DrawEnergiebalken()
    DrawPlayer()

Next



Und sonst einfach die Funktion kopieren und den Type verändern *hust*
Twitter
Download Jewel Snake!
Windows|Android
 

Silbersurfer

Betreff: mit sub Types

BeitragSo, Dez 08, 2013 8:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde es auch so machen wie DAK
Es kann ja sein das Eyes_Only mehr als einen Spieler haben möchte dann finde Ich die aufteilungen
in mehren Types sinnvoll !

wie Xeres schon meinte mit sub Types geht das wunderbar

hier mal mein kleines Beispiel Eyes_Only

Code: [AUSKLAPPEN]
Graphics 1024,768,32,2
SetBuffer BackBuffer()

Type dev
   Field Energie
   Field waffen
   Field panzerung
End Type

Type spieler
   Field x,y
   Field sub.dev
End Type

Type gegner
   Field x,y
   Field sub.dev
End Type

tod=neuerSpieler(100,50)
alien=neuerGegner()
Repeat
   datenauslesen (tod)
   Flip
   Cls
Until KeyHit(1)

Function neuerSpieler(x=0,y=0,energie=1000)
   sp.spieler=New spieler
   sp\x=X
   sp\y=y
   sp\sub.dev=New dev
   sp\sub\Energie=energie
   Return Handle(sp)
End Function

Function neuerGegner(x=0,y=0,energie=500)
   ge.gegner=New gegner
   ge\x=X
   ge\y=y
   ge\sub.dev=New dev
   ge\sub\Energie=energie
   Return Handle(ge)
End Function

Function datenAuslesen (id,x=0,y=0)
   sp.spieler=Object.spieler(id)
   If sp<>Null
      Text x,y,"X pos "+sp\x+" Y pos "+sp\y
      Text x,y+16,"Energie "+sp\sub\Energie
   EndIf
   ge.gegner=Object.gegner(id)
   If ge<>Null
      Text x,y,"X pos "+ge\x+" Y pos "+ge\y
      Text x,y+16,"Energie "+ge\sub\Energie
   EndIf
 End Function   
-------------------------------------------------------
XP 2000+ 512DDR Radeon 9800 XL 340GB HD
Hompage : http://home.arcor.de/silbersurfer01/
Is Bob engine http://home.arcor.de/silbersur.../Isbob.zip
 

Eyes_Only

BeitragSo, Dez 08, 2013 11:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah, das ist ja mal cool.
Das mit den Subtypes finde ich gut. Muss ich mal schauen, ob und wie ich das bei mir umsetzen kann. Die Abfrage mit den IDs ist auch gut. Das kann ich ja unter Umständen falls erforderlich auch kombinieren.

An die Subtypes habe ich mich nicht so richtig ran getraut, weil ich das bisher etwas verwirrend und komliziert fande mit der ganzen Verschachtelung, aber anhand der Beispiele kann ich mir das langsam entschlüsseln.

Was ich noch nicht so richtig kapiert habe sind handle und object. Ich habe das so verstanden, dass mir handle eine Art Referenz/Bezugspunkt gibt und mit object kann ich später wieder auf diese Referenz zugreifen, also im Prinzip so als würde ich den Type in eine neue Variable speichern um ihn später weiter benutzen zu können. Stimmt das so in etwa?

Xeres

Moderator

BeitragSo, Dez 08, 2013 13:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit handle wandelst du eine Type-Instanz aka. Objekt in einen eindeutigen Integer-Wert um. object macht das Gegenteil und findet das richtige Objekt zu diesem Wert.
Ich kann keinen all zu großen Sinn darin sehen; Wenn du eine Funktion hast, um mehrere Arten Types zu verarbeiten, kann man mit handle einen Int wert übergeben und damit verschiedene Types in eine Funktion füttern. Allerdings muss man dann jeden Type wieder zurück casten: Ist das handle ein Y Type? Dann mache X. Ist das Objekt ein B Type? Dann mache A... usw. usf. Man hat damit nichts erreicht als alle Funktionen für verschiedene Types in eine zusammen zu fassen. Das kann man auch sein lassen, meiner Meinung nach.
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)
 

Eyes_Only

BeitragSo, Dez 08, 2013 13:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm... unter diesem Aspekt hast du Recht. Ist mir auch schon aufgefallen, dass man dann innerhalb der einen Funktion dann einen Menge Schreibarbeit hat.

Mein Ziel ist es, eine Funktion zu haben, die ich immer wieder für verschiedene Objekte einsetzen kann, z.B.:

Function move_obj (obj,dirx,diry)

Dieser will ich dann immer das jeweilige Objekt übergeben, z.B. Spieler, Gegner, Rakete etc., also alles, was sich irgendwie auf dem Bildschrim bewegen kann.

Ich wollte nicht für jeden Type eine eigene Funktion schreiben, weil ich dachte, dass das zu Lasten der Performance geht. Aber ich komme wohl nicht drum herum.

Ich habe schon mal das umgesetzt, was du (Xeres) geschrieben hast hinsichtlich des Vergleichs der Objekte (x<>y). Aber jedesmal wenn ich ein neues Objekt hinzufüge, wird diese Abfrage komplexer.

Vielleicht schreibe ich doch lieber mehrere einzelne Funktionen für jeden Type...

BladeRunner

Moderator

BeitragSo, Dez 08, 2013 13:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Du könntest auf BMax umsteigen und echte OOP geniessen.
Würde einiege deiner Probleme lösen Smile
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Xeres

Moderator

BeitragSo, Dez 08, 2013 13:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie gesagt: Da BB nur sehr rudimentär Objekt Orientiert ist (= gar nicht) gibt es gar keine schöne Möglichkeit das zu lösen.
Viele Verschiedene Funktionen beeinträchtigen nicht die Performance - Types herum zu casten und ewig viele Bedingungen ab zu arbeiten bis man zu dem Code kommt, der das richtige macht schon eher.

Mit BlitzMax/c#/Java oder was die feschen Sprachen gerade sind, könntest du OOP benutzen und hübscheren Code haben. Vielleicht bist du BB einfach schon entwachsen Wink
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)
 

Eyes_Only

BeitragSo, Dez 08, 2013 13:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Hehe, danke der netten Worte. Very Happy

Ich denke ich mach das Projekt jetzt erstmal mit BB fertig und wähle doch den Weg über mehrere Funktionen. Das ist zwar ein bisschen mehr Schreibarbeit, macht mir das Leben aber leichter, weil ich nicht ständig irgendwo drehen muss, um das richtige Ergebnis zu erhalten.

Wenn ich mal wieder etwas mehr Zeit habe, schaue ich mir mal BMax an. Im Moment bleibt das Programmieren etwas auf der Strecke... Sad


Vielen Dank für eure tolle Hilfe!!!

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group