Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Images per Array erstellen, aber wie. Meine Variante geht...


Xearox - Mo 15.03.10 07:11
Titel: Images per Array erstellen, aber wie. Meine Variante geht...
...nicht

Ich habe vor, mir ein kleines 2D spiel komplett ohne Engine zu Programmieren.
Klapp auch alles Soweit Super, nur stehe ich jetzt vor dem Problem, das ich mehrere Objekte Erstellen möchte, ohne hunderte von TImage Objekte zu erstellen.
Ich wollte das mit hilfe eines Array machen, jedoch bekomme ich das nicht hin...
Kann sich jemand hier den Code mal anschauen, und mir sagen, wie ich das am Besten bewerkstelligen kann?
wäre echt super, ich weiß mir keinen Rat mehr...

Kurz noch zu dem Programm, die Objekte sollen innerhalb eines Panels dargestellt werden, mit einem Bild, ohne den Array hat das auch supergeklappt.
Das Objekt soll mit Hilfe eines Timers, immer um einen Bestimmten Schritt weiter nach unten gehen.

Hier mein bisheriger Code:

Hoffe der ist nicht zu unübersichtlich, habe so gut wie es geht, alles Kommentiert.

Und das mit dem Array, ist das überhaupt möglich?


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:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, pngimage;

type
  Ship1ArrayType = Array [1..200of TImage;

  TForm1 = class(TForm)
    Timer1: TTimer;
    BGameStart: TButton;
    Panel2: TPanel;
    BClose: TButton;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BGameStartClick(Sender: TObject);
    procedure VariableInit;
    procedure ObjekteInit;
    procedure CollisionAbfrage;
    procedure BCloseClick(Sender: TObject);
    procedure Ship1Init;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Ship1Typ : Ship1ArrayType;
  ShipProRunde:integer;
  Ship1:integer;
  count:integer;
  Form1: TForm1;
  stepX,stepY,Countdown:integer;
  FBreite,FHoehe:integer;
  PosX:integer;
  RandR,RandU:integer;
  ButtonKlick:boolean;

implementation

{$R *.dfm}

procedure TForm1.Ship1Init;

begin
  for Ship1 := 0  to ShipProRunde +1 do
  begin
    count:=count+1;
    Ship1Typ[Ship1]:=Image1;
  end;

end;

procedure TForm1.CollisionAbfrage;//Hier wird die Postion des Objectes überprüft
begin                             //Falls der Rand erreicht wird, wird das Obj.
  if (Image1.Top>=RandU) then     //wieder zurückgesetzt
    begin
      Ship1Typ[Ship1].Top:=10;
      StepX:=0;
    end;

  if (Ship1Typ[Ship1].Left>=RandR) then
    begin
      Ship1Typ[Ship1].Left:=56;
    end;

end;


procedure TForm1.VariableInit;//Hier werden die Variablen initialisiert
begin
  Count:=0;
  stepX:=10;
  stepY:=10;
  Countdown:=5;  //Spielgeschwindigkeit
//Form Größe Anpassen
  FBreite:=1024;
  FHoehe:=768;
//Form Position Anpassen
  Form1.Top:=50;
  Form1.Left:=50;
//Ränder für Collisions Abfrage
  RandR:=950;
  RandU:=600;
  PosX:=0;
//Schiff Anzahl
  ShipProRunde:=2;
end;

procedure TForm1.ObjekteInit;//Hier werden die Objecte initialisiert
begin
  Panel2.Height:=FHoehe-100;
  Panel2.Width:=FBreite-100;
  BGameStart.Left:=FBreite-90;
  BGameStart.Top:=FHoehe-750;
  BClose.Left:=FBreite-90;
  BClose.Top:=FHoehe-720;
  ButtonKlick:=true;
  for count := 0 to ShipProRunde + 1 do
    begin
      Ship1Typ[Ship1].Top:=stepX;
      Ship1Typ[Ship1].Left:=stepY
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);//hier wird die Formerstellt und
begin                                        //die Grunddaten initialisert
//intitialsierung
 VariableInit;
 Ship1Init;
 ObjekteInit;
//Timer Deaktivieren
 timer1.Enabled:=false;//timer Deaktiviern
//Form Größe Anpassen
 Form1.Width:=FBreite;
 Form1.Height:=FHoehe;
end;

procedure TForm1.BCloseClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.BGameStartClick(Sender: TObject); //Hier wird das Spiel gestartet
begin                                           //oder auch gestoppt
  if ButtonKlick=true then
    begin
      timer1.Interval:=Countdown;// 1 sekunde.
      timer1.Enabled :=true;//Timer starten
      BGameStart.Caption:=('Stopp');
    end;

  if ButtonKlick=false then
    begin
      BGameStart.Caption:=('Spiel Starten');
      Timer1.Enabled:=False;
      ButtonKlick:=true;
    end;


end;

procedure TForm1.Timer1Timer(Sender: TObject);

begin
  ButtonKlick:=false;
  timer1.Enabled:=false;
  stepX:=stepX+8;
  timer1.Interval:=Countdown;
  timer1.Enabled:=true;
  CollisionAbfrage;

end;

end.


arj - Mo 15.03.10 09:57

Du erstellst keine 200 Images, sondern weißt den 200 Images im Array nur das eine Image zu.

Die Bilder müsstest Du schon mit

Delphi-Quelltext
1:
Ship1Typ[Ship1]:=TImage.Create();                    
erzeugen. Und danach den Bildinhalt noch hinzufügen.

Allerdings ist die Frage ob es vielleicht nicht einfacher wäre eine Instanz eines Bitmap zu verwenden (das ist keine Komponente, nur eine Datenklasse) und dann dieses Bitmap einfach 200 mal auf dein Spielfeld zu zeichnen.
Das wäre wahrscheinlich die schönere und auch schnellere Variante.

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


Xearox - Mo 15.03.10 14:08

Edit: Nun gibt es keine Fehler mehr, hier mein Neuer Code


Jedoch bewegt sich das Bild kein bisschen...
Und es werden keine Zwei Bilder erstellt.


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:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, pngimage;

type
  Ship1ArrayType = Array [1..200of TImage;

  TForm1 = class(TForm)
    Timer1: TTimer;
    BGameStart: TButton;
    Panel2: TPanel;
    BClose: TButton;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BGameStartClick(Sender: TObject);
    procedure VariableInit;
    procedure ObjekteInit;
    procedure CollisionAbfrage;
    procedure BCloseClick(Sender: TObject);
    procedure Ship1Init;
  private
    { Private-Deklarationen }


  public
    { Public-Deklarationen }
  end;

var
  Ship1Typ : Ship1ArrayType;
  ShipProRunde:integer;
  Ship1:integer;
  count:integer;
  Form1: TForm1;
  stepX,stepY,Countdown:integer;
  FBreite,FHoehe:integer;
  PosX:integer;
  RandR,RandU:integer;
  ButtonKlick:boolean;

implementation

{$R *.dfm}


procedure TForm1.Ship1Init;

begin
  for Ship1 := 0  to ShipProRunde -1 do
  begin
    Ship1Typ[Ship1]:=TImage.Create(self);
  end;

end;

procedure TForm1.CollisionAbfrage;//Hier wird die Postion des Objectes überprüft
begin                             //Falls der Rand erreicht wird, wird das Obj.
  for Ship1 := 0  to ShipProRunde -1 do
    begin
      if (Ship1Typ[Ship1].Top>=RandU) then     //wieder zurückgesetzt
        begin
          Ship1Typ[Ship1].Top:=10;
          StepX:=0;
        end;
      if (Ship1Typ[Ship1].Left>=RandR) then
        begin
          Ship1Typ[Ship1].Left:=56;
        end;
    end;
end;


procedure TForm1.VariableInit;//Hier werden die Variablen initialisiert
begin
  Count:=0;
  stepX:=10;
  stepY:=10;
  Countdown:=5;  //Spielgeschwindigkeit
//Form Größe Anpassen
  FBreite:=1024;
  FHoehe:=768;
//Form Position Anpassen
  Form1.Top:=50;
  Form1.Left:=50;
//Ränder für Collisions Abfrage
  RandR:=950;
  RandU:=600;
  PosX:=0;
//Schiff Anzahl
  ShipProRunde:=2;
end;

procedure TForm1.ObjekteInit;//Hier werden die Objecte initialisiert
begin
  Panel2.Height:=FHoehe-100;
  Panel2.Width:=FBreite-100;
  BGameStart.Left:=FBreite-90;
  BGameStart.Top:=FHoehe-750;
  BClose.Left:=FBreite-90;
  BClose.Top:=FHoehe-720;
  ButtonKlick:=true;
  for Ship1 := 0  to ShipProRunde -1 do
    begin
      Ship1Typ[Ship1].Top:=stepX;
      Ship1Typ[Ship1].Left:=stepY;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);//hier wird die Formerstellt und
begin                                        //die Grunddaten initialisert
//intitialsierung
 VariableInit;
 Ship1Init;
 ObjekteInit;
//Timer Deaktivieren
 timer1.Enabled:=false;//timer Deaktiviern
//Form Größe Anpassen
 Form1.Width:=FBreite;
 Form1.Height:=FHoehe;
end;

procedure TForm1.BCloseClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.BGameStartClick(Sender: TObject); //Hier wird das Spiel gestartet
begin                                           //oder auch gestoppt
  if ButtonKlick=true then
    begin
      timer1.Interval:=Countdown;// 1 sekunde.
      timer1.Enabled :=true;//Timer starten
      BGameStart.Caption:=('Stopp');
    end;

  if ButtonKlick=false then
    begin
      BGameStart.Caption:=('Spiel Starten');
      Timer1.Enabled:=False;
      ButtonKlick:=true;
    end;


end;

procedure TForm1.Timer1Timer(Sender: TObject);

begin
  ButtonKlick:=false;
  timer1.Enabled:=false;
  stepX:=stepX+8;
  timer1.Interval:=Countdown;
  timer1.Enabled:=true;
  CollisionAbfrage;
  for Ship1 := 0  to ShipProRunde -1 do
  begin
    Ship1Typ[Ship1].Top:=stepX;
  end;

end;

end.


SvenAbeln - Mo 15.03.10 15:30

Du lädst kein Bild in deine Images, was soll er denn da zeichenen?

Auch musst du mit deinen Schleifen aufpassen, im Moment versuchst du auf Felder zuzugreifen die nicht existieren.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  
 Ship1ArrayType = Array [1..200of TImage;

for Ship1 := 0  to ShipProRunde -1 do
  begin
    Ship1Typ[Ship1].Top:=stepX;
  end;


thepaine91 - Mo 15.03.10 16:09

Das wollte ich auch Schreiben. ;) Es funktioniert zwar, da der Compiler das anpasst trotzdem bleibt es falsch.


Xearox - Mo 15.03.10 16:16


Delphi-Quelltext
1:
2:
3:
4:
for Ship1 := 1  to ShipProRunde -1 do
  begin
    Ship1Typ[Ship1]:=TImage.Create(self);
  end;


ist die schleife irgendwie falsch?

Ship1 = Ist der Wert, welcher für die Array zuständig ist
Ship1Typ = Ship1Typ : Ship1ArrayType; ... Ship1ArrayType = Array [1..200] of TImage;


So, und nun, wie kann ich jetzt jeden Array das Ship1.png zuweisen?


thepaine91 - Mo 15.03.10 17:22

Ich hab das Gefühl das du nicht wirklich weist was du da tust.


Xearox - Mo 15.03.10 19:37

Learning by Doing :D

Aus Fehlern lernt man...
Nun ja, ich versuche mich solang an den Code, bis es nicht mehr weiter geht, nu ist es aber soweit, das es nicht mehr weiter geht, und meine Kenntnisse von Delphi reichen nicht aus, um nun weiter zu arbeiten...jedoch versuche ichs ;)


Georg08 - Mo 15.03.10 21:59

Du vergisst einen Parent zu setzen

Delphi-Quelltext
1:
Image[i].Parent:= self;                    


Xearox - Mo 15.03.10 22:20

wofür ist dieses Parent da?

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

kann mir jemand vllt. meine frage beantworten?
Ich habe keine Ahnung, wo ich das einfügen muss...