Autor Beitrag
comes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: Mi 10.12.03 23:23 
ausblenden volle Höhe 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;
      // OnClick handler
      procedure planetClickHandler(Sender: TObject);

    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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;   // Set its parent (Form1)
  Planet.Bild.SetBounds(20+x, 201010);
  planet.Bild.Show;
  Planet.Bild.OnClick := planetClickHandler; // assign onclick handler
  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 user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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!

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
comes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: 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:

ausblenden 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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:
ausblenden volle Höhe 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  tmyImage = class(TImage) //<- das Ganze von TImage ableiten
    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;   // Set its parent (Form1)
  Planet.SetBounds(20+x, 201010);
  planet.Show;
  Planet.OnClick := myImageClickHandler; // assign onclick handler
  x := x+21;
  planet.AnzahlEinwohner := 10;
end;


MfG
Peter

P.S.: Hoffentlich ist meine Lösung nicht auch noch krumm.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
comes Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: Do 11.12.03 00:30 
Titel: jupp...
ausblenden volle Höhe 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;
      // OnClick handler
      procedure planetClickHandler(Sender: TObject);

    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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;   // Set its parent (Form1)
  Planet.Bild.SetBounds(20+x, 201010);
  planet.Bild.Show;
  Planet.bild.OnClick := planet.OnClick; // assign onclick handler
  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 user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: 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?

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: Do 11.12.03 00:42 
du solltest eine Klasse erstellen, die die ganzen Planeten verwaltet.
Also sowas z.B.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
TWorld = class
private
FPlanets : array of TPlanet;

public
procedure onMouseClick(X, Y : Integer); // dort prüfst du ob ein Planet angeklcikt wurde und rufst seine OnClick-methode auf(wenn er überhaupt eine braucht)

procedure addPlanet({irgendwelche Daten, die er haben soll});
procedure tick; // so eine Funktion wird bei jedem Durchgang aufgerufen und steuert die Intelligenz(könnte z.B. eine Tick-und die Draw-Funktion aller Planeten aufrufen)


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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 40



BeitragVerfasst: Do 11.12.03 00:47 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
TWorld = class 
private 
FPlanets : array of TPlanet; 

public 
procedure onMouseClick(X, Y : Integer); // dort prüfst du ob ein Planet angeklcikt wurde und rufst seine OnClick-methode auf(wenn er überhaupt eine braucht) 

procedure addPlanet({irgendwelche Daten, die er haben soll}); 
procedure tick; // so eine Funktion wird bei jedem Durchgang aufgerufen und steuert die Intelligenz(könnte z.B. eine Tick-und die Draw-Funktion aller Planeten aufrufen)

wie meinst das genau? mach ma plz ein grobes bsp. hab noch nich so wirklich mit extra units gearbeitet

Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt (wenn Du so weiter machst, gibt es nichts zu Weihnachten)
Nightmare_82
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 260



BeitragVerfasst: 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


ausblenden 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; // wurde nach dem letzten Tick geklickt?

public 
procedure onMouseClick;// rufst du bei Form1.onClick auf
procedure addPlanet({irgendwelche Daten, die er haben soll}); 
procedure tick; // so eine Funktion wird bei jedem Durchgang aufgerufen und steuert die Intelligenz(könnte z.B. eine Tick-und die Draw-Funktion aller Planeten aufrufen)

{...}
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 ({Mouse über Planet}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.