![]() |
Spielfeld mit Klassen als Felder
Hallo :hi:,
ich möchte einen Bomberman-Klon programmieren, allerdings steh ich jetzt vor einem Problem. Ich möchte ein Spielfeld erstellen mit verschiedenen Klassen als Feldern. In einem Array kann man ja nur gleiche Klassen verwalten. Wie kann ich das also anders anstellen? MfG freak |
Re: Spielfeld mit Klassen als Felder
Zitat:
Wie wäre es mit:
Delphi-Quellcode:
Frank :coder:type TFeldtyp = (nix,Wand, Kirsche, Taler, Bombe); var Feld : array[0..80,0..200] of TFeldtyp; |
Re: Spielfeld mit Klassen als Felder
Delphi-Quellcode:
type
TFeld = class end; TWand = class (TFeld) end; TSpielfeld = array[0..1,0..1] of TFeld; var S: TSpielFeld; S[0,0] := TWand.Create; //etc. |
Re: Spielfeld mit Klassen als Felder
Hi,
wenn du tatsächlich Klassen im OOP-Sinne meinst, dann könntest du sie sehr wohl in einem Array verwalten, wenn sie -entweder von einer gemeinsamen Oberklasse (abstrakte "Feld"-Klasse) abstammen -oder ein gemeinsames Interface implementieren. Gruß Christian //edit: Ja, kam ein roter Kasten. :) Ich lass es trotzdem mal stehen--Interface hat schließlich noch keiner gesagt :mrgreen: |
Re: Spielfeld mit Klassen als Felder
Zitat:
MfG greak |
Re: Spielfeld mit Klassen als Felder
Nein TFeld ist "nur" eine Dummy Klasse...
Die braucht garnix.. Frank |
Re: Spielfeld mit Klassen als Felder
Du kannst auch ein zweistufiges Veerebungsschema für die Steine entwerfen, wobei die übergeordnete Klasse die Eigenschaften des Spielsteins nicht haben. In diesem fall kannst du aber auf diesen Aufwand veruchten, da sich die Anzhal der Eigenschaften wohl im Rahemn hält.
|
Re: Spielfeld mit Klassen als Felder
Zitat:
ICh hab leider kein Delphi hier um das zu testen. :( MfG freak |
Re: Spielfeld mit Klassen als Felder
Delphi-Quellcode:
if S[0,0] is TBomb then TBomb(S[0,0]).ExploTime := 5;
|
Re: Spielfeld mit Klassen als Felder
Das geht tatsächlich. :) Aber da ergibt sich ein neues Problem. Wenn ich das Spielfeld erstelle sind ja noch keine Bomben auf dem Feld. Wenn ich dann das Feld mit TFeld erstellt hab und dann ein TBomb draus mache, muss ich ja erst das Feld zerstören, das neue Feld erstellen und dann die Bumbenzeit setzen. Wenn die Bombe explodiert muss das wieder alles rückgängig gemacht werden. Geht das nicht einfacher? Ich bin für alle Ideen offen.
Danke euch schonmal. :D MfG ein ratloser freak |
Re: Spielfeld mit Klassen als Felder
Ich würde es über eine Klasse machen, der ich eine Eigenschaft spendieren würde, über die man ermitteln kann ob Bombe oder nicht.
|
Re: Spielfeld mit Klassen als Felder
Moin,
ich würde in TFeld einen neuen Constructor einführen, dem du als Parameter den Feldplatz übergibts. Sollte auf dem Feld schon was sein, löst er einfach den Destructor aus, so dass bei der Zuweisung das Feld dann wieder frei ist. Durch die Ableitung der TBomb von TFeld erbt TBomb den Constructor einfach.
Delphi-Quellcode:
type
TFeld = class Position: TPoint; public Constructor Create(PFeld: TFeld); override; // oder reintroduce; (je nach Vorfahr) end; TBomb = class (TFeld) ExploTime: Integer; end; TSpielfeld = array[0..1,0..1] of TFeld; var S: TSpielFeld; Constructor TFeld.Create(PFeld: TFeld); begin inherited; if assigned(PFeld) then FreeAndNil(PFeld); end; // Der Constructor entfernt ein evtl. vorhandenes Feld für uns automatisch S[0,0] := TBomb.Create(S[0,0]); //etc. |
Re: Spielfeld mit Klassen als Felder
Die meiste Arbeit davon könntest du in einer Methode des Spielfeldes machen, dass ein Feld zu einem bestimmten Typ macht:
Delphi-Quellcode:
Alle vorzunehmenden Einstellungen, wie z.B. ExplodeTime etc., gehören sowieso in den Konstruktor der entsprechenden Unterklasse (in diesem Fall TBomb.Create)
type TFeld = class
... TFeldClass = class of TFeld; TBomb = class(TFeld) ... end; TBombClass = class(TBomb); // usw. type TSpielfeld = class private const FELDGROESSE = 10; FFelder = array[0..FELDGROESSE-1, 0..FELDGROESSE-1] of TFeld; public SetFieldTo(i,j: byte; NewClass: TFeldClass); end; procedure TSpielfeld.SetFieldTo(i,j: byte; NewClass: TFeldClass); begin if not (FFelder[i,j] is NewClass) then begin // Veränderung? FFelder[i,j].Free; FFelder[i,j] := NewClass.Create; end; end; Jetzt ließe sich mit Spielfeld.SetFieldTo(0,0, TBomb) das linke obere Feld zu einer Bombe machen, ein anschließender Aufruf Spielfeld.SetFieldTo(0,0, TWall) verwandelt die Bombe in eine Wand. Nachteil: Alle alten Objektreferenzen verlieren dabei ihre Gültigkeit, wenn du dir also im Spielerfigur-Objekt ein die TFeld-Instanz abspeicherst, auf der sich die Figur gerade befindet, kann es dir passieren, dass diese ihre Gültigkeit verliert. Um das zu vermeiden müsstest du halt grundsätzlich immer über Zeilen- und Spaltenindex auf die Felder zugreifen. //edit: @McLane: Konstruktoren sind automatisch virtuell (wär ja sonst auch wenig sinnvoll)...das override braucht (darf?) da also nicht hin. Reintroduce ist falsch, verdecken willst du hier ja nicht. |
Re: Spielfeld mit Klassen als Felder
Warum machst Du es nicht so:
Delphi-Quellcode:
Wenn Du normales Feld
TFeld = class
end; TBomb = class (TFeld) end; TFeldRec = record Inhalt: Word; FObject: TFeld; end; TFeldArray = array[0..9,0..9 of TFeldRec];
Delphi-Quellcode:
oder Mauer
Inhalt := coFeld;
Delphi-Quellcode:
hast, dann steht dies über Inhalt bereit, und wenn Du die Bombe setzt, machst Du
Inhalt := coMauer;
Delphi-Quellcode:
Inhalt := coBombe;
FObject := TBombe.Create; |
Re: Spielfeld mit Klassen als Felder
also die Lösung von Tigerman gefällt mir richtig. Ich würde aber noch testen ob an der Stelle im Array schon ein Feld existiert, sonst rennst du evtl. beim FFelder[i,j].Free in eine Exception.
Wegen dem override; bzw. reintroduce; Das Override sollte man nehmen, damit eben nicht verdeckt wird. Und das Reintroduce brauchste wenn du mehrere gleichnamige Constructoren hast, also nen overload; mit bei hast aber trotzdem per inherited auf den Vorfahren zugreifen willst. Lass mich da aber auch gerne belehren (Mein Einsatzgebiet ist Fehlersuche und Korrektur, da hab ich mit Constructodefinitionen sogut wie nie was am Hut) |
Re: Spielfeld mit Klassen als Felder
Free testet automatisch ob dort überhaupt eine Referenz steht. Noch besser wäre es, FreeAndNil zu nehmen, sonst kann das was du angesprochen hast (AccessViolation) doch noch passieren.
Ein Constructor muss (implizit) virtuell sein und wird deswegen auch immer überschrieben, nie verdeckt. Es ist ja gerade erforderlich, eine Instanz gerade der spezifischen Klasse zu erzeugen, und nicht irgendeiner Vorfahrklasse. |
Re: Spielfeld mit Klassen als Felder
Danke euch allen! Ich werd nun mal sehen, was ich davon umsetzen kann. :)
MfG freak |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz