Probleme mit BMax wegen Dateiauslagerung

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

M0rgenstern

Betreff: Probleme mit BMax wegen Dateiauslagerung

BeitragDi, Apr 13, 2010 16:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey Leute.
Ich habe ne kurze Frage zu BMax, da ich auf dieses Problem schon öfter gestoßen bin.
Wenn ich irgendeine Instanz einer Klasse z.b. in meinem Hauptprogramm erstelle und darauf dann in einer anderen Klasse zugreifen will, dann habe ich folgendes Problem, sobald letztere in einer extra Datei ausgelagert ist:
Die Instanz der ersten Klasse wird als nicht deklariert erkannt, bzw ich bekomme den Fehler, dass er den "Identifier" nicht kennt.

Um das mal kongret festzumachen:
In meinem Mapeditor kann ich Objekte (z.b. Häuser) plazieren. Dann setze ich ein bestimmtes Tile im Layer 3 auf 1. Die Lade-und Speicherroutinen sind ausgelagert in einer extra Datei. Wenn ich jetzt eine Map lade will ich für jedes Tile das im Layer 3 auf 1 steht eine INstanz einer Klasse erstellen.
Zuerst habe ich versucht, dies in die Laderoutine einzufügen. Aber: Wenn ich dann im SPiel selbst eine Map geladen habe um sie zu spielen, hat er sich beschwert, dass er eben diese Instanzen nicht kennt.
Das ganze habe ich jetzt so gelöst:

Auszug aus der Hauptdatei:
BlitzMax: [AUSKLAPPEN]
LoadMap(1)

For Local ix:Int = 0 To (iMapwidth - 1)
For Local iy:Int = 0 To (iMapheight - 1)
If iGameMap[ix, iy, 3] = 1 Then
Local Obj:TObject = Tobject.Create((ix), (iy), tiHouse1)
End If
Next
Next


ABER: 1. ist diese Lösung, so finde ich, unschön.
Und zweitens bin ich an ein Problem gestoßen, wo das nicht so einfach geht: Mein Waypont System.
Und zwar habe ich dafür zwei Klassen. EInmal die Waypoint Klasse, die die X und Y Koordinaten enthält. Und dann die Klasse WaypointConnection. Deren Attribute sind jeweils zwei Waypoints, also zwei INstanzen der Waypoint Klasse.
Meine Gegner sollen sich in Abhängigkeit von diesen Waypoints bewegen.
Aber: Sowohl die Gegner als auch die Waypoints werden in einer extra Datei ausgelagert sein.
Die Gegner wissen also nicht, wie viele Instanzen von den Waypoints es gibt etc.

Lässt sich dieses Problem irgendwie umgehen? Wenn ja wie? Bzw. habe ich einen total falschen Ansatz?

Lg, M0rgenstern

DaysShadow

BeitragDi, Apr 13, 2010 17:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Du erstellst Instanzen ins nichts, sogesehen.
Genauer erstellst du Instanzen in ein und dieselbe lokale Variable und die ist nach der Schleife futsch weil du sie als Local definiert hast.

BlitzMax: [AUSKLAPPEN]
LoadMap(1)

For Local ix:Int = 0 To (iMapwidth - 1)
For Local iy:Int = 0 To (iMapheight - 1)
If iGameMap[ix, iy, 3] = 1 Then
GameMapObjects[ deineOrdnungZumVerwalten ] = TObject.Create((ix), (iy), tiHouse1)
End If
Next
Next


GameMapObjects wäre dann vom Typ TObject bzw. ein Array vom Typ TObject wo du auch deine erstellten Instanzen reintun kannst.
Das könnte ein globales Array sein oder auch ein Member eines Typs, z.b. TMap.
Es ist nicht wie in BB, dass jede erstellte Instanz in eine sogesehene Typ-interne Liste mit den Instanzen des Typs kommt.
Du musst schon deine Instanzen in irgendeiner Form für dich in Variablen verwalten, sonst sind sie futsch.

MfG DaysShadow
Blessed is the mind too small for doubt

M0rgenstern

BeitragDi, Apr 13, 2010 17:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, ich glaube ich habe mich ein wenig falsch ausgedrückt.

Das oben war nur ein Beispiel. Das funktioniert auch, weil ich es nur in dieser Datei brauche (PS: Sie sind nicht nach der SChleife futsch. Ich kann sie nämlich in der nächsten Schleife nochmal benutzen, da ich sie nämlich im Konstruktor in eine globale Liste speichern lasse.)

Also: Für jede Klasse die ich habe, habe ich auch eine globale Liste als Klassenattribut.
Im Konstruktor jeder Klasse sorge ich dafür, dass die neue Instanz der Liste hinzugefügt wird.
Das Problem ist aber, dass ich in ausgelagerten Dateien nicht auf eben diese Listen (TList) zugreifen kann.

Hoffe, dass es jetzt klarer ist, was ich meine.

Lg, M0rgenstern

DaysShadow

BeitragDi, Apr 13, 2010 17:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Was meinst du mit "in ausgelagerten Dateien nicht auf eben diese Listen (TList) zugreifen"? Includes?
Mit Type.GlobaleListe kommst du doch immer an die Liste ran...vielleicht verstehe ich dich einfach falsch, k.a..

MfG DaysShadow
Blessed is the mind too small for doubt

M0rgenstern

BeitragDi, Apr 13, 2010 17:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja ich meinte Include Dateien, die ich mit "Import" einbinde.
Dann habe ich eine Datei in der die Klassen TWaypoints und TWaypointConnections gespeichert sind. Und eine Datei in der die Klasse TEnemy gespeichert ist.
Jetzt will ich in einer Methode von TEnemy auf einige Attribute der vorher genannten Klasse zugreifen.
Beide Klassen werden mit Import ind die Hauptdatei eingebunden.
Das ist das ganze.

Lg, M0rgenstern

mpmxyz

BeitragDi, Apr 13, 2010 17:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Du möchtest jedes Objekt in einer globalen Liste abspeichern, hast diese Liste in der Hauptdatei, nutzt "Import" und möchtest aus den importieren Dateien auf die Liste zugreifen?
(Meine Diagnose)
"Import" funktioniert nur in eine Richtung, kann dir aber beim Kompilieren viel Wartezeit ersparen und ist meiner Meinung nach auch ordentlicher als "Include".
Hast du schon eine Hauptklasse, von der alle anderen, wichtigen Klassen erben?
Dann solltest du dort die Liste einführen.
Auf alle Fälle musst du die Liste auslagern und überall dort, wo sie gebraucht wird, importieren.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragDi, Apr 13, 2010 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
ALso.
Hier mal eine Beispielklasse:
BlitzMax: [AUSKLAPPEN]
Type TShoot
Global TLAllShoots:TList = New TList
Field fx:Float, fy:Float
Field fAngle:Float
Field fSpeed:Float
Field sFraction:String
Field tiImage:TImage
Field iDamage:Int

'Methoden etc
End Type


Jetzt habe ich den Hauptordner "Alien Shooter 2D", in diesem liegt die Main.bmx wo meien Hauptschleife etc drin ist. Außerdem liegt in diesem Ordner der Unterordner "Includes". In ebendiesem liegt obige Klasse in der Datei "WeaponAndPlayerClasses.bmx"
Im selben Ordner liegt in der Datei "Waypoints.bmx" folgende Klasse:
BlitzMax: [AUSKLAPPEN]
Type TWaypoint
Global TLAllWaypoints:TList = New TList
Field fx:Float
Field fy:Float

'Methoden
End Type


In der MainDatei im Hauptordner mache ich folgendes:

BlitzMax: [AUSKLAPPEN]
Import brl.PNGLoader
Import "Includes/PlayerAndWeaponClass.bmx"
Import "Includes/MapSaveAndLoad.bmx"
Import "Includes/MapVariables.bmx"
Import "Images.bmx"
Import "Includes/Waypoints.bmx"
SuperStrict


Jetzt will ich in einer Methode von, sagen wir einfach TShoot auf die Waypoint Klasse zugreifen.

Die globalen Listen könnt ihr jetzt besser erkennen und ich hoffe, dass es jetz besser verständlich ist, was gemeint ist.

Nein, ich habe übrigens keine Hauptklasse.
Sollte ich sowas haben? Bzw wäre das besser?
Lg, M0rgenstern

mpmxyz

BeitragDi, Apr 13, 2010 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Es gibt mehrere Lösungen.
a) Du importierst TWaypoint in die TShoot-Datei, falls du keine zyklischen Abhängigkeiten hast.
b) Du nutzt "Include". (nicht so gut; kein Import/SuperStrict in den eingebundenen Dateien schreibbar, da das in der Hauptdatei stehen soll.)
c) Du verbesserst das Design, sodass es eine gemeinsam genutzte Basis gibt.
Da kommt erst einmal die Basisklasse "Object" ins Spiel:
Sie bietet eine Methode, mit denen man mit jedem Objekt kommunizieren kann.
Das ist die Methode "SendMessage:Object( message:Object,context:Object )".
Mit dieser Methode sendest du dann ein spezielles Message-Objekt zu einem Objekt und bekommst eventuell auch eine Rückgabe. (Ideen, die ich gerade habe: TGetPropertyMessage, THitMessage ...)
Du musst diese Methode nur geeignet überschreiben.
Die einzelnen Message-Klassen müssen nur Informationen tragen und können so relativ einfach von den anderen Klassen unabhängig gemacht werden.
Mit eigenen Basisklassen kannst du weitere gemeinsame Methoden, wie "CheckCollision(Obj2:TGameObject)" für Schüsse und Gegner oder "Save(Stream:TStream)" für alle spielrelevanten Objekte, hinzufügen.
Ob man eine eigene Basisklasse aber wirklich gebrauchen kann, kommt auf den Fall an.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragDi, Apr 13, 2010 19:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Also, was würdest du mir denn raten?
Soll ich eine große ParentKlasse machen?
Das Problem ist einfach, dass ich so viele verschiedene Dinge habe: Die Schüsse, der Spieler, die Waffen, die Gegner, die Waypoints, die Umgebungsobjekte.

Also, ich wollte das ganze schon so OOP wie möglich machen.

Achso, frage ich habe hier was gelesen:
https://www.blitzforum.de/foru...ght=pixmap

UNdzwar der Beitrag von klepto2.
Wäre das auch eine Lösung? Bzw wie genau ist das zu verstehen?

Lg, M0rgenstern

mpmxyz

BeitragDi, Apr 13, 2010 19:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Beitrag von klepto2 ist hier nicht hilfreich.
Mit seiner Entdeckung kann man nur aus dem Type springen. Man bleibt aber immer noch in der selben Datei.
OOP pur? -> Nehme die Möglichkeit c. Dies ist meiner Meinung nach auch die eleganteste Lösung, auch wenn es in deinem Fall Mehrarbeit erfordert.
mfG
mpmxyz
P.S.: Links neben dem Erstellungsdatum jedes Beitrages gibt es ein kleines Icon. Mit Hilfe dieses Icons hättest du mich direkt zu dem Beitrag von klepto2 geschickt. Wink
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragDi, Apr 13, 2010 20:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay. Sieht dann doch nach mehr Arbeit aus.
Ganz doofe frage: Wie stell ich das dann am besten an?

Also, welche Dinge nehm ich da am besten mit rein etc?

Es ist einfach wirklich ein etwas größeres Projekt und das ganze soll relativ dynamisch sein.
Ich möchte halt verschiedene Waypointarten (Startpunkte für Gegner, normale Wegpunkte), unterschiedliche Gegnertypen etc.
Das Problem ist, dass ich vorher mit BB gearbeitet habe, was ja jetzt nicht wirklich SOOO objektorientiertist. Und in der Schule arbeite ich mit Pascal, was wirklich richtig objektorientiertist (mit Private und public und protected und mit diesen tollen IST/KENNT/HAT Beziehungen) ist irgendwie schade, dass BMAx nicht ganz so objektorientiert ist.

Also, ich weiß nicht genau wie ich es erklären soll, aber ich möchte schon ne schöne Dynamik drin haben, damit das einfach erweitbar und auch wartbar ist.

Lg, M0rgenstern

mpmxyz

BeitragDi, Apr 13, 2010 20:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Um dieses Prinzip strikt durchzusetzen, muss jede Abhängigkeit vermieden/umgewandelt werden.
Aber: Ich glaube, dass du dieses Prinzip hier nicht brauchst und es nur für Mehrarbeit sorgen würde.
(Ich hätte mal weiterdenken sollen. Rolling Eyes)
Es ist nur absolut notwendig, wenn man zyklische Abhängigkeiten hat und diese nicht auflösen kann, da man nicht zyklisch importieren kann. (auflösbares Beispiel: Waypoints erstellen Gegner mit einer Methode/Gegner folgt Waypoints)
Du musst nur die Waypoint-Datei importieren. (So einfach können gute Lösungen sein. Smile)
Ist das Problem nun gelöst?
mfG
mpmxyz
Edit: Meine Meinung zu Private, Protected & Co.:
An sich ist die Idee ganz nett.
Aber wenn man einen großen Workaround machen muss, nur weil eine nützliche Funktion/Methode als "private" gekennzeichnet ist und man die Kompatibilität zu diesen fremden Code erhalten möchte, lernt man es zu hassen. (Es handelt sich um eine GLMax2D-Erweiterung.)
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

M0rgenstern

BeitragDi, Apr 13, 2010 20:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey vielen Dank.
Wie gesagt, ich wusste es halt nicht.
Vielen Dank nochmal, ist dann wohl die beste Lösung.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group