Autor Beitrag
speck12
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36



BeitragVerfasst: Di 04.09.07 16:29 
Hallo allerseits!

Ich bin dabei, ein TowerDefense zu programmieren (mit niedrigen Ansprüchen^^)
Nach dem ich es nun geschafft habe, Türme setzten zu lassen und die Monster eine vorgeschriebene Route passieren habe ich ein nächstes Problem. Die "Monster"Klasse TCreep hat die public Variable "HP" die beim Erstellen festgelegt wird. Die Turmklasse TTower bestitzt die public Variablen "Range" und "Damage" und eine function creep_in_range, die überprüft, ob sich das Monster im Radius des Turmes befindet und liefert einen boo'schen Wert zurück.
Falls sich Monster auf dem Spielfeld befinden, wird in einem Timer Event ständig überprüft, ob Leben abgezogen werden soll, oder nicht und alle Eigenschaften werden in der procedure Show_Creep_Info aktualisiert und in einem Panel mit entsprechenden Labels ausgegeben. Mit der Creep Nummer und den Koordinaten klappt es auch wunderbar, nur das Leben wird nicht aktualisiert und bleibt gleich. Nach langem Suchen kann ich eigentlich(^^) einen Fehler in den Abstandsberechnungen ausschließen.

Hier die Quelltexte:

Mainunit:
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:
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:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Creep_Unit, Hintergrund_unit, Tower_Unit;

type
  TForm1 = class(TForm)
    Bild: TImage;
    Button1: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit4: TEdit;
    Label4: TLabel;
    Edit5: TEdit;
    ColorBox1: TColorBox;
    Panel1: TPanel;
    Label5: TLabel;
    Panel2: TPanel;
    creep_number_label: TLabel;
    HP_Label: TLabel;
    POS_Label: TLabel;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BildMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure BildMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button2Click(Sender: TObject);
    

  private
    //
  public
    hintergrund    : THintergrund;
    buffer         : TBitmap     ;
    creep_liste    : TList       ;
    tower_liste    : TList       ;
    t_ja           : Boolean     ;
    Maus           : TPoint      ;
    selected_c     : Integer     ;
    selected_t     : Integer     ;
    x_creep        : Integer     ;
    y_creep        : Integer     ;
    v_creep        : Integer     ;
    x_tower        : Integer     ;
    y_tower        : Integer     ;
    t_damage       : Integer     ;
    t_range        : Integer     ;
    t_frequency    : Integer     ;
    breite_Creep   : Integer     ;
    hoehe_Creep    : Integer     ;
    creep_anzahl   : Integer     ;
    creep_farbe    : TColor      ;
    strassen_farbe : TColor      ;
    refresh_creepI : Boolean     ;
    refresh_creep  : Boolean     ;
    procedure creeps_bewegen     ;
    procedure Init               ;
    procedure Bild_Aktualisieren ;
    procedure Show_Creep_Info    ;
    procedure Show_Game_Info     ;
    procedure Angreifen          ;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Init;
 begin

  breite_creep := StrToInt(Edit1.Text);  {Max : 38}
  hoehe_creep  := StrToInt(Edit2.Text);  {Max : 38}
  v_creep      := StrToInt(Edit3.Text);
  x_creep := 80-(breite_creep div 2) ;
  y_creep := 500;
  creep_farbe := ColorBox1.Selected;
  strassen_farbe := clGray;
  refresh_creepI := false ;
  refresh_creep  := false ;
  t_ja           := false ;
  x_tower := 0;
  y_tower := 1000;
  t_damage := 10   ;
  t_range  := 300  ;
  t_frequency := 10;
 end;


procedure TForm1.Bild_Aktualisieren;
 begin
  buffer.Canvas.Draw(0,0,hintergrund);
  Bild.Canvas.Draw(0,0,buffer)       ;
  hintergrund.Refresh                ;
 end;


procedure TForm1.creeps_bewegen;
var i,n,m,o : integer;

 begin
   for i :=0 to creep_liste.Count - 1  do
     begin
      m := 0;
      if (TCreep(creep_liste.Items[i]).x_Creep < 100and (TCreep(creep_liste.Items[i]).x_Creep > 60then {Zone 1}
        begin
         If TCreep(creep_liste.Items[i]).y_Creep > 90-(hoehe_creep div 2then
          TCreep(creep_liste.Items[i]).y_Creep := TCreep(creep_liste.Items[i]).y_Creep - TCreep(creep_liste.Items[i]).delta_weg
         else
          TCreep(creep_liste.Items[i]).x_Creep := TCreep(creep_liste.Items[i]).x_Creep + TCreep(creep_liste.Items[i]).delta_weg; {Bedingung für Zonenwechsel}
        end;


      if (TCreep(creep_liste.Items[i]).x_Creep < 380and (TCreep(creep_liste.Items[i]).x_Creep >= 100and (TCreep(creep_liste.Items[i]).y_Creep < 280-(hoehe_creep div 2)) then {Zone 2}
        begin
         If TCreep(creep_liste.Items[i]).x_Creep < 380-(breite_creep div 2then
          TCreep(creep_liste.Items[i]).x_Creep := TCreep(creep_liste.Items[i]).x_Creep + TCreep(creep_liste.Items[i]).delta_weg
         else
          TCreep(creep_liste.Items[i]).y_Creep := TCreep(creep_liste.Items[i]).y_Creep + TCreep(creep_liste.Items[i]).delta_weg;
        end;


      if (TCreep(creep_liste.Items[i]).y_Creep <= 300and (TCreep(creep_liste.Items[i]).y_Creep >= 280-(hoehe_creep div 2)) then {Zone 3}
        begin
         If (TCreep(creep_liste.Items[i]).x_Creep >= 380-(hoehe_creep div 2)) and (TCreep(creep_liste.Items[i]).x_Creep <= Bild.Width+50then
          TCreep(creep_liste.Items[i]).x_Creep := TCreep(creep_liste.Items[i]).x_Creep + TCreep(creep_liste.Items[i]).delta_weg;
        end;


      if (TCreep(creep_liste.Items[i]).Noch_Im_Spielfeld(TCreep(creep_liste.Items[i]).x_Creep,TCreep(creep_liste.Items[i]).tot) = 0and (TCreep(creep_liste.Items[i]).nicht_zaehlen = false) then
       begin
        Dec(creep_anzahl);
        TCreep(creep_liste.Items[i]).nicht_zaehlen := true;
        Edit5.Text := IntToStr(creep_anzahl);
       end;

      if creep_anzahl <= 0 then
       begin
        for o := 0 to creep_liste.Count - 1 do
           begin
            creep_liste.Items[o] := nil;
           end;
        refresh_creep  := false;
        refresh_creepI := false;
        Bild_Aktualisieren;
        creep_liste.Pack  ;
        exit;
       end;


      for n := 0 to creep_liste.Count - 1 do
       begin
        if TCreep(creep_liste.Items[n]).Noch_Im_Spielfeld(TCreep(creep_liste.Items[n]).x_Creep,false) = 0 then
          Inc(m);
        if m >= creep_liste.Count then
         begin
          for o := 0 to creep_liste.Count - 1 do
           begin
            creep_liste.Items[o] := nil;
           end;
          creep_anzahl := 0;
          Edit5.Text := IntToStr(creep_anzahl);
          refresh_creep  := false;
          refresh_creepI := false;
          Bild_Aktualisieren;
          creep_liste.Pack  ;
          exit;
         end;
       end;
     end;
     Bild_Aktualisieren;
 end;


procedure TForm1.Show_Creep_Info;
 begin
  Panel2.Color := $002232c6;
  Creep_Number_Label.Visible := true;
  HP_Label.Visible := true;
  POS_Label.Visible := true;
  Creep_Number_Label.Caption := 'Creep-Nummer: ' + IntToStr(selected_c+1);
  HP_Label.Caption := 'Leben: ' + IntToStr(TCreep(creep_liste.Items[selected_c]).HP);
  POS_Label.Caption := '(' + IntToStr(TCreep(creep_liste.Items[selected_c]).x_Creep) + '|' + IntToStr(TCreep(creep_liste.Items[selected_c]).y_Creep) + ')';
  refresh_creepI := true ;
 end;

procedure TForm1.Show_Game_Info;
 begin
  refresh_creepI := false ;
  Panel2.Color := clCream;
  Creep_Number_Label.Visible := false;
  HP_Label.Visible := false;
  POS_Label.Visible := false;
 end;


procedure TForm1.Angreifen;
 var i,n : integer;
  begin
   for i := 0 to creep_liste.Count - 1 do
    begin
     if creep_liste.Items[i] <> nil then
      begin
       for n := 0 to tower_liste.Count - 1 do
        begin
         if tower_liste.Items[n] <> nil then
          begin
           If TTower(tower_liste.Items[n]).creep_in_range(TCreep(creep_liste.Items[i]).creep_pos) = true then
            TCreep(creep_liste.Items[i]).HP := TCreep(creep_liste.Items[i]).HP - TTower(tower_liste.Items[n]).damage;  {falls ein Creep in der Range eines Towers ist, sollte dem Creep Leben abgezogen werden}
          end;
        end;
      end;
    end;
  end;




procedure TForm1.FormCreate(Sender: TObject);
 begin
  Init;
  hintergrund := THintergrund.create(Bild.Width,Bild.Height,clGreen,strassen_farbe);

  buffer := TBitmap.Create;
   with buffer do
    begin
     Height := Bild.Height;
     Width  := Bild.Width ;
    end;

  creep_liste := TList.Create;

  tower_liste := TList.Create;

  Form1.DoubleBuffered := true;

  Show_Game_Info;

  Bild_Aktualisieren;

  Timer1.enabled := true;
 end;

procedure TForm1.Button1Click(Sender: TObject);
 var n : integer;
  begin
   Init;
    for n := 0 to StrToInt(Edit4.Text)-1 do
     begin
      y_creep := 500 + n*(hoehe_creep+20);
      creep_liste.Add(TCreep.Create(breite_creep,hoehe_creep,x_creep,y_creep,v_creep,100,creep_farbe));
     end;
   creep_anzahl := creep_liste.Count;
   Edit5.Text := IntToStr(creep_anzahl);
   refresh_creep := true;
  end;

procedure TForm1.Timer1Timer(Sender: TObject);
 begin
   if refresh_creep = true then
    begin
     creeps_bewegen    ;
     Angreifen         ;
    end;
   Angreifen;
   if (refresh_creepI) and (TCreep(creep_liste.Items[selected_c]).Noch_Im_Spielfeld(TCreep(creep_liste.Items[selected_c]).x_Creep,false) <> 0then
     Show_Creep_Info
   else
     Show_Game_Info;

 end;



procedure TForm1.BildMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
 var c : integer  ;
  begin
   Maus.X := X;
   Maus.Y := Y;
  If NOT t_ja then begin
   for c := 0 to creep_liste.Count - 1 do
    begin
     If TCreep(creep_liste.Items[c]).selected(Maus) then
      begin
       selected_c := c  ;
       Show_Creep_Info;
       exit;
      end;
    end;
  end;
  If t_ja then
   begin
    TTower(tower_liste.Items[selected_t]).x_tower := X;
    TTower(tower_liste.Items[selected_t]).y_tower := Y;
    Bild_Aktualisieren;
   end;
  end;



procedure TForm1.BildMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var i : integer;
  begin
   Maus.X := X;
   Maus.Y := Y;
  If NOT t_ja then begin
   for i := 0 to creep_liste.Count - 1 do
    begin
     If not TCreep(creep_liste.Items[i]).selected(Maus) then
      begin
       Show_Game_Info;
       exit;
      end;
    end;
  end;
  If t_ja then
   t_ja := false;
  end;

procedure TForm1.Button2Click(Sender: TObject);
  begin
   tower_liste.Add(TTower.create(x_tower,y_tower,t_range,t_damage,t_frequency));
   selected_t := tower_liste.Count - 1;
   t_ja := true;
  end;

end.


Die Creepunit:
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:
unit Creep_unit;

interface

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

type TCreep = class(TBitmap)
  public
   x_Creep   : integer;
   y_Creep   : integer;
   delta_weg : integer;
   nicht_zaehlen : Boolean;
   HP        : integer;
   tot       : boolean;
   constructor Create(Breite,Hoehe,x_start,y_start,speed,leben : Integer ; Farbe : TColor);
   function Noch_Im_Spielfeld(x_pos : integer;tot : Boolean) : integer;
   function selected(Cursor_POS : TPoint) : Boolean;
   function creep_pos : TPoint;
   procedure toeten(strassen_farbe : TColor);
   destructor Destroy(); override;
  end;


implementation

constructor TCreep.Create(Breite,Hoehe,x_start,y_start,speed,leben : Integer ; Farbe : TColor);
 begin
  Inherited Create;
  Width  := Breite;
  Height := Hoehe ;
  Canvas.Brush.Color := Farbe;
  Canvas.Pen.Color   := Farbe;
  Canvas.Rectangle(0,0,Width,Height);
  x_creep   := x_start;
  y_creep   := y_start;
  delta_weg := speed  ;
  nicht_zaehlen := false  ;
  tot := false            ;
  HP  := leben            ;
 end;

function TCreep.Noch_Im_Spielfeld(x_pos : integer;tot : Boolean) : integer;
 begin
  If (x_pos > 830or (tot = true) then Result := 0
  else
  Result := 1;
 end;

function TCreep.selected(Cursor_POS : TPoint) : Boolean;
 var d : double;
     M_creep : TPoint;
  begin

   d := 0;
   M_creep.X := abs(x_creep + (Width  DIV 2));
   M_creep.Y := abs(y_creep + (Height DIV 2));

   d := SQRT(SQR(abs(M_creep.X-Cursor_POS.X)) + SQR(abs(M_Creep.Y-Cursor_POS.Y)));


    If d <= 7 then
     Result := true
    else
     Result := false;

end;


function TCreep.creep_pos : TPoint;
 begin
  Result.X := abs(x_creep + (Width  DIV 2));
  Result.Y := abs(y_creep + (Height DIV 2));
 end


procedure TCreep.toeten(strassen_farbe : TColor);
 begin
  With Canvas do
   begin
    pen.Color   := strassen_farbe;
    brush.Color := strassen_farbe;
    Rectangle(0,0,Width,Height);
   end;
  tot := true;
 end;



destructor TCreep.Destroy();
 begin
  Inherited Destroy;
 end;

end.


Die Towerunit:
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:
unit Tower_Unit;

interface

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

type TTower = class(TBitmap)
  public
   x_tower   : Integer;
   y_tower   : Integer;
   range     : Integer;
   damage    : Integer;
   frequency : Integer;
   constructor create(x,y,range,damage,frequency : integer);
   function creep_in_range(creep_pos : TPoint) : Boolean;
   destructor Destroy(); override ;
  end;


implementation

constructor TTower.create(x,y,range,damage,frequency : integer);
 begin
  Inherited Create;
  Width  := 20;
  Height := 20;
  x_tower := x;
  y_tower := y;
   with Canvas do
    begin
     Brush.Color := $00D31487;
     Pen.Color   := $00D31487;
     Rectangle(0,0,Width,Height);
    end;
  end;

function TTower.creep_in_range(creep_pos : TPoint) : Boolean;
 var tm : TPoint;
      d : double;
  begin
   tm.X := abs(x_tower + (Width  DIV 2));
   tm.Y := abs(y_tower + (Height DIV 2));

   d := SQRT(SQR(abs(creep_pos.X - tm.X)) + SQR(abs(creep_pos.Y - tm.Y)));

   if d <= range then
    Result := true
   else
    Result := false;
  end;

destructor TTower.Destroy();
 begin
  Inherited Destroy;
 end

end.


Hoffe ihr könnt mir helfen.
Mfg

P.S.
Ich habe noch ein Archiv mit dem Projekt angehängt
Einloggen, um Attachments anzusehen!
Fabian E.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 554

Windows 7 Ultimate
Visual Studio 2008 Pro, Visual Studion 2010 Ultimate
BeitragVerfasst: Di 04.09.07 16:51 
ich hab mir zwar jetzt nicht den source angesehn, aber so wie das wirkt schießen deine türme nich, d.h. es wird nicht nur nicht die anzeige aktualisiert sondern erst gar kein leben abgezogen1

MfG
speck12 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36



BeitragVerfasst: Di 04.09.07 17:14 
Geschossen werden soll ja noch gar nicht, ist ja auch noch nicht implementiert. Es soll den Creeps einfach nur Leben abgezogen werden, falls sie sich im Radius des Turmes befinden.

Das ist in diesem Abschnitt der Fall :
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Angreifen;  
 var i,n : integer;  
  begin  
   for i := 0 to creep_liste.Count - 1 do  
    begin  
     if creep_liste.Items[i] <> nil then  
      begin  
       for n := 0 to tower_liste.Count - 1 do  
        begin  
         if tower_liste.Items[n] <> nil then  
          begin  
           If TTower(tower_liste.Items[n]).creep_in_range(TCreep(creep_liste.Items[i]).creep_pos) = true then  
            TCreep(creep_liste.Items[i]).HP := TCreep(creep_liste.Items[i]).HP - TTower(tower_liste.Items[n]).damage;  {falls ein Creep in der Range eines Towers ist, sollte dem Creep Leben abgezogen werden}  
          end;  
        end;  
      end;  
    end;  
  end;

mfg