Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Variablen ändern bei zur Laufzeiterzeugten Objecten
comes - Mi 10.12.03 23:23
Titel: Variablen ändern bei zur Laufzeiterzeugten Objecten
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92:
| unit main;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type TRohstoffe = record Uran : boolean; cryptonid : boolean; end;
type TStationierteSchiffe = record FrachterKlein : Integer; FrachterGross : Integer; Kriegsschiffklein : Integer; Kriegsschiffgross : Integer; end;
type TVolk = record Krieger : boolean; Handelsvolk : boolean; Mischvolk : boolean; end;
type TGebaeude = record Kraftwerk : boolean; Werft : boolean; Schutzschild : boolean; Waffensysteme : boolean; Forschungsstation : boolean; Depot : boolean; end;
type TPlanet = class Bild : TImage; Bezeichnung : String; AnzahlEinwohner : Integer; maxEineohner : Integer; Besitzer : String; Volk : TVolk; Rohstoffe : TRohstoffe; StationierteSchiffe : TStationierteSchiffe; Gebaeude : TGebaeude; neutral : boolean; end;
type TForm1 = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private planet: Tplanet; procedure planetClickHandler(Sender: TObject);
public end;
var Form1: TForm1; x : integer = 0; implementation
{$R *.dfm} procedure TForm1.planetClickHandler(Sender: TObject); begin ShowMessage(inttostr(TPlanet(Sender).AnzahlEinwohner)); end; procedure TForm1.Button1Click(Sender: TObject); begin Planet := TPlanet.Create; Planet.Bild := TImage.Create(Self); planet.bild.Picture.LoadFromFile('c:\test.bmp'); Planet.Bild.Parent := Form1; Planet.Bild.SetBounds(20+x, 20, 10, 10); planet.Bild.Show; Planet.Bild.OnClick := planetClickHandler; x := x+21; planet.AnzahlEinwohner := 10; end;
end. |
In der letzten Zeile wird zwar planet.AnzahlEinwohner auf 10 gesetzt, wenn ich aber den planeten im clickhandler auslese, ist anzahleinwohner = 0. Warum ist das so?
kann mir das mal plz jemand erklären?
Moderiert von
Peter Lustig: Code- durch Delphi-Tags ersetzt
Nightmare_82 - Mi 10.12.03 23:43
du weist das Click-Event von planet.bild zu, das heißt meines Wissens wird als sender planet.bild übergeben.
Das castest du dann zu TPlanet(dann müßte aber eigentlich eine Fehlermeldun kommen :shock: )
guck mal was passiert, wenn du planet direkt verwendest.
Ansonsten solltest du Planet nur einmal erzeugen in Form1create, sonst verursachst du Memory-Leaks.
Christian S. - Mi 10.12.03 23:49
Es ist ja schon spät, also sagt mir, wenn ich was blödes von mir gebe:
Wo wird der planetClickHandler denn aufgerufen? Ich sehe da nur Zuweisungen! Und erst bei einem Aufruf wird doch der Sender festgelegt!
comes - Mi 10.12.03 23:50
Titel: das soll ja allles...
das soll ja alles dynamisch werden, wie sich hoffentlich erkennen lässt.
ich möchte dann wärend der laufzeit 100 oder 2 oder 1000 dieser objekte erstellen. da kann ich nicht planet nehmen, weil das ja dann nur auf DIESES Eine object bezogen ist. (LEIDER)
comes - Mi 10.12.03 23:54
Titel: eigene onclick?
wenn ich für die classe TPlanet nen eigenes onclick handler benutze sollte dass doch auch gehn, oder?
also nicht plant.bild.onclick sonder planet.onclick? geht das irgendwie zu realisieren?
kann mir da jemand bitte helfen?
merci
Christian S. - Do 11.12.03 00:04
Hallo!
Ich weiß nicht, ob Du meine Frage nicht gesehen hast. Aber wie wird planetClickHandler aufgerufen. Und welcher Parameter wird dort als Sender übergeben?
MfG
Peter
Nightmare_82 - Do 11.12.03 00:07
er erstellt ein Bild und weist das OnClick-Event seiner Funktion zu.
Das ist doch dasselbe, wie wenn man ein Image auf eine Form zieht und auf OnClick doppelklickt?! Und dann wird doch als Sender das Image übergeben *denk*
Aber wie dem auch sei, eine Lösung für dein Problem:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| TPlanet procedure Click(Sender : TObject);
planet.bild.onClick:= planet.click;
procedure TPlanet.click(Sender : TObject) begin form1.planetClickHandler(self); end; |
Christian S. - Do 11.12.03 00:27
| Zitat: |
er erstellt ein Bild und weist das OnClick-Event seiner Funktion zu.
Das ist doch dasselbe, wie wenn man ein Image auf eine Form zieht und auf OnClick doppelklickt?! Und dann wird doch als Sender das Image übergeben *denk* |
Du hast recht. Irgendwie denke ich heute krumm. :?
Aber hier habe ich noch eine Lösung. Ist nicht schön, aber geht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| type TForm1 = class(TForm) Button1: TButton; procedure myImageClickHandler(Sender: TObject); procedure Button1Click(Sender: TObject); private public end;
type tmyImage = class(TImage) private public anzahleinwohner : Integer; end;
var Form1: TForm1; planet : TMyImage;
implementation
{$R *.dfm}
procedure TForm1.myImageClickHandler(Sender: TObject); begin if Sender is TmyImage then ShowMessage(IntToStr(TMyImage(sender).anzahleinwohner)); end;
procedure TForm1.Button1Click(Sender: TObject); VAR x : INTEGER; begin x := 20; Planet := TmyImage.Create(self); planet.Picture.LoadFromFile('c:\test.bmp'); Planet.Parent := Form1; Planet.SetBounds(20+x, 20, 10, 10); planet.Show; Planet.OnClick := myImageClickHandler; x := x+21; planet.AnzahlEinwohner := 10; end; |
MfG
Peter
P.S.: Hoffentlich ist meine Lösung nicht auch noch krumm.
comes - Do 11.12.03 00:30
Titel: jupp...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99:
| unit main;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type TRohstoffe = record Uran : boolean; cryptonid : boolean; end;
type TStationierteSchiffe = record FrachterKlein : Integer; FrachterGross : Integer; Kriegsschiffklein : Integer; Kriegsschiffgross : Integer; end;
type TVolk = record Krieger : boolean; Handelsvolk : boolean; Mischvolk : boolean; end;
type TGebaeude = record Kraftwerk : boolean; Werft : boolean; Schutzschild : boolean; Waffensysteme : boolean; Forschungsstation : boolean; Depot : boolean; end;
type TPlanet = class Bild : TImage; Bezeichnung : String; AnzahlEinwohner : Integer; maxEineohner : Integer; Besitzer : String; Volk : TVolk; Rohstoffe : TRohstoffe; StationierteSchiffe : TStationierteSchiffe; Gebaeude : TGebaeude; neutral : boolean; procedure OnClick(Sender: TObject); end;
type TForm1 = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private planet: Tplanet; procedure planetClickHandler(Sender: TObject);
public end;
var Form1: TForm1; x : integer = 0; implementation
{$R *.dfm} procedure TPlanet.OnClick(Sender: TObject); begin form1.planetclickhandler(self); end;
procedure TForm1.planetClickHandler(Sender: TObject); begin ShowMessage(inttostr(TPlanet(Sender).AnzahlEinwohner)); end; procedure TForm1.Button1Click(Sender: TObject); begin Planet := TPlanet.Create; Planet.Bild := TImage.Create(Self); planet.bild.Picture.LoadFromFile('c:\test.bmp'); Planet.Bild.Parent := Form1; Planet.Bild.SetBounds(20+x, 20, 10, 10); planet.Bild.Show; Planet.bild.OnClick := planet.OnClick; x := x+21; randomize; planet.AnzahlEinwohner := random(10); end;
end. |
jupp, genauso nightmare...
@Peter Lustig, hab es gelöst wie nightmare vorgeschlagen hat.... das is zwar bissl verwurschtelt aber es geht!
aber mal noch so ne frage, wäre es besser das teil als komponente auszulagern oder was wäre dann im gesamt konzept das beste...
plz helped mich mal...
Moderiert von
Peter Lustig: Code- durch Delphi-Tags ersetzt
Christian S. - Do 11.12.03 00:35
(1) Bitte nutze demnächst die Delphi-Tags!
(2) Randomize sollte nur beim Start des Programmes aufgerufen werden
(3) Wie sieht Dein Gesamtkonzept bisher aus?
Nightmare_82 - Do 11.12.03 00:42
du solltest eine Klasse erstellen, die die ganzen Planeten verwaltet.
Also sowas z.B.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| TWorld = class private FPlanets : array of TPlanet;
public procedure onMouseClick(X, Y : Integer); procedure addPlanet(); procedure tick; |
Was willst du denn genau machen? Es kommt immer darauf an, was du alles vorhast? Für mich sieht das nach einem Weltraum-Spiel aus oder?
Also Komponenten brauchst du dafür nicht und statt Images würd ich Bitmaps nehmen und deinen Planeten eine eigene draw-Funktion schreiben.
Die Prüfung, ob ein Planet angeklickt wurde kannst du auh selbst erstellen, da du ja die Größe der Bitmaps kenst. Wenn du ein richtiges Spiel machen willst, wirst du schnell feststellen, daß Images saulahm sind wenn man zu viele davon hat.
comes - Do 11.12.03 00:44
Titel: -
Also, das gesamtkonzept wird ein strategiespiel, welches rundenbasierend wird. es wird sobald es aus der probierphase raus ist, auf delphiX bzw. directX exportiert.
Man hat also ein paar planeten, die stück für stück vom spieler besetzt werden, wenn alle planeten vergeben sind, bekriegt man sich gegenseitig, bis alle planeten im eigenen besitz sind. und so weiter und sofort, das konzept sollte klar sein.
okay, delphi tags werd ich in zukunft verwenden und die sache mit dem randomize war nur zu test zwecken...
frohe weihnachten, mfg,comes
comes - Do 11.12.03 00:47
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| TWorld = class private FPlanets : array of TPlanet;
public procedure onMouseClick(X, Y : Integer); procedure addPlanet(); procedure tick; |
wie meinst das genau? mach ma plz ein grobes bsp. hab noch nich so wirklich mit extra units gearbeitet
Moderiert von
Peter Lustig: Code- durch Delphi-Tags ersetzt (wenn Du so weiter machst, gibt es nichts zu Weihnachten)
Nightmare_82 - Do 11.12.03 01:04
OK, also wenn du so ein relativ komplexes Spiel machst, sit es wichtig, daß du die Klassen gut gliederst. Du solltest eine Manager-Klasse haben, die alle wichtigen Objekte verwaltet und zur Kommunikation der verschiedenen Objekte dient.
Du brauchst einen Main-Loop(kannst bei DelphiX einfach den Timer nehmen), der sollte einfach die Tick-Funktion des Manager-Objektes aufrufen.
Dieser Tick des manager könnte so aussehen:
- alle Ticks der Planeten aufrufen
- alle Ticks der Schiffe aufrufen
- wenn ein Planet angeklickt wurde, Click-Procedure des Planeten aufrufen
- alles zeichnen, was auf dem Bildschirm sichtbar ist
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| TWorld = class private FPlanets : array of TPlanet; FClicked : Boolean; public procedure onMouseClick;procedure addPlanet(); procedure tick;
procedure TWorld.tick; VAR i : Integer; Mouse : TPoint; begin getCursorPos(Mouse); for i:= 0 to high(FPlanets) do begin FPlanets[i].tick; if (Clicked) and () then FPlanets[i].onClick(Mouse.X, Mouse.Y); FPlanets[i].draw; end; Clicked:= false; end; |
In deiner Form1 werden dann nur die Events an TWorld weitergeleitet und im Timer wird die Tick-Funktion von TWorld aufgerufen.
Wenn du das so machst kannst du dem Planeten als Owner TWorld übergeben. Dann kann jeder Planet z.B. über eine Funktion
GetNearestPlanetAt(X, Y : Integer) : PPlanet; die Welt fragen, welcher Planet am nächsten liegt etc.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!