Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem mit For-Schliefe (https://www.delphipraxis.net/168422-problem-mit-schliefe.html)

Kopnop 20. Mai 2012 22:07

Problem mit For-Schliefe
 
Guten Abend,

ich arbeite schon seit ca. 1 1/2 Jahren von der Schule aus mit Delphi, hab aber erst seit ein paar Monaten damit angefangen in meiner Freizeit kleine Spiele zu proggen.
Jetzt hab ich aber ein Problem... oder so etwas Ähnliches^^
Mein Programm funktioniert auch problemlos, wenn ich es so lasse, wies jetzt is, da die Änderung nur im Quelltext zu sehen wäre und nichts am eigentlichen Programm ändern würde, aber ich wüsste gerne generell, ob und wie das geht.
Also, ich hab hier diesen Quelltext (inhaltlich müsst ihr nich drauf eingehen, geht mir nur um die For-Schleifen-Alternative):
(Das ist natürlich nicht der komplette Text aus der FormCreate, lediglich der relevante Teil)
Delphi-Quellcode:
 
procedure TSpielfeld1.FormCreate(Sender: TObject);
begin
  repeat
    hindernis1.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis1.hx)) + sqr(abs(maus.y - hindernis1.hy))) > (maus.r + hindernis1.hr) + 8));
  repeat
    hindernis2.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis2.hx)) + sqr(abs(maus.y - hindernis2.hy))) > (maus.r + hindernis2.hr) + 8));
  repeat
    hindernis3.initiate(clblue, random(image1.width - 20) + 10, random(image1.height - 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis3.hx)) + sqr(abs(maus.y - hindernis3.hy))) > (maus.r + hindernis3.hr) + 8));
  hindernis1.show;
  hindernis2.show;
  hindernis3.show;
end;
Ich arbeite mit Canvas und die Hindernisse sind alle Kreise vom Typ 'THindernis', die Maus ist auch ein Kreis vom Typ 'TMaus'.

Da das ja eigentlich immer das gleiche is - es nur einmal mit dem Hindernis 1, 2 und anschließend 3 gemacht wird, sollte sich das doch auch in eine For-Schleife umschreiben lassen, oder?
Ich hab mir das ungefähr so vorgestellt:
Delphi-Quellcode:
procedure TSpielfeld1.FormCreate(Sender: TObject);
var
i:integer;
begin
  for i:=1 to 3 do
begin
  repeat
    hindernis[i].initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis1.hx)) + sqr(abs(maus.y - hindernis1.hy)))> (maus.r + hindernis1.hr) + 8));
  hindernis[i].show;
end;
end;
oder irgendwie so:
Delphi-Quellcode:
...(hindernis+i).initiate...

Aber wenn ich das so schreibe, erkennt er nich, dass ich 'hindernis1' ansprechen will, also weiß er auch nicth, dass er damit etwas machen soll.
Gibt es da vllt eine Variablenbezeichnung, die das möglich macht?

Ich hoffe, ihr versteht, was ich möchte und könnt mir helfen :)
MfG Kopnop

mkinzler 20. Mai 2012 22:23

AW: Problem mit For-Schliefe
 
Du musst die Hindernis-Objekte in einen Array packen, dann funktioniert dein Code (bessere Lösung) oder du arbeitest mit .FindComponent()_

Delphi-Quellcode:
var
  Hindernis: THindernis;
...
    Hindernis := FindComponent( 'Hindernis'+IntToStr(i));
    Hindernis.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis.hx)) + sqr(abs(maus.y - hindernis.hy)))> (maus.r + hindernis.hr) + 8));
  hindernis.show;
...
end;

Bummi 20. Mai 2012 22:26

AW: Problem mit For-Schliefe
 
Wenn THindernis von TComponent abgeleitet wäre könntest Du per FindComponent('Hindernis'+IntToStr(i)) arbeiten.

Das was Du suchst ist wahrscheinlich ein Array[0..2] // oder 1..3 of THindernis, entweder schon beim Erzeugen verwenden...

ArrHindernis[1]:= THindernis.create

oder, wenn Hindernis1 etc.bereits existieren den Arrayelementen zuweisen

ArrHindernis[1] := Hindernis1;

etc.

Kopnop 20. Mai 2012 23:53

AW: Problem mit For-Schliefe
 
Zitat:

Zitat von mkinzler (Beitrag 1167369)
Du musst die Hindernis-Objekte in einen Array packen, dann funktioniert dein Code (bessere Lösung) oder du arbeitest mit .FindComponent()_

Delphi-Quellcode:
var
  Hindernis: THindernis;
...
    Hindernis := FindComponent( 'Hindernis'+IntToStr(i));
    Hindernis.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - hindernis.hx)) + sqr(abs(maus.y - hindernis.hy)))> (maus.r + hindernis.hr) + 8));
  hindernis.show;
...
end;

Danke schonmal, ich hab den Quelltext so geändert, wie du meintest. Jetzt meckert er aber in der Zeile
Delphi-Quellcode:
      hindernis := FindComponent('Hindernis'+inttostr(i));

, dass mein selbsterstellter Typ THindernis mit dem Typ TComponent inkompatibel sei, womit er ja auch durchaus recht hat.

Mein Typ sieht so aus:
Delphi-Quellcode:
type
  thindernis = class hx, hy, hr: single;
    hfarbe: tcolor;
    procedure initiate(fhneu: tcolor; xhneu, yhneu, rhneu: single);
    procedure show;
  end;
ist global definiert und wird in der initialization aufgerufen:
Delphi-Quellcode:
var
Hindernis, Hindernis1, Hindernis2, Hindernis3: tHindernis;  // 'Hindernis' hab ich dazu geschrieben, war vorher nich drin
...
initialization
  Hindernis1 := thindernis.create;
  Hindernis2 := thindernis.create;
  Hindernis3 := thindernis.create;

sx2008 21. Mai 2012 02:44

AW: Problem mit For-Schliefe
 
Du könntest schon Einiges an Klarheit schaffen, wenn du Unterfunktionen benützen würdest.
Bei 3 Objekten braucht man noch nicht unbedingt eine Schleife, aber bei 3 maliger Wiederholung von gleichem Code braucht man Funtkionen!
Das hier:
Delphi-Quellcode:
sqrt(sqr(abs(maus.x - hindernis.hx)) + sqr(abs(maus.y - hindernis.hy))
ist doch nix anderes als die abgewandelte Formel von Phytagoras.
Delphi-Quellcode:
function Abstand(x,y:Integer):Double;
begin
  result := sqrt(sqr(x)+sqr(y));
end;
Der Aufruf von abs() ist übrigens völlig überflüssig.
Und schon sieht der Code besser aus:
Delphi-Quellcode:
repeat
    hindernis1.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until (Abstand(maus.x - hindernis1.hx, maus.y - hindernis1.hy) > (maus.r + hindernis1.hr) + 8));
Jetzt müsste man noch den Ausdruck nach Until vereinfachen.
Dazu ist es wichtig, dass maus und hindernis von der gleichen Kreisklasse abgeleitet sind.
Dann könnte man nämlich den Abstand der Kreisobjekte in einer Funtkion berechnen:
Delphi-Quellcode:
function TKreis.KreisrandAbstand(v:TKreis):double;
begin
  result := Abstand(x - v.x, y - v.y) - (r + v.r);
end;
Delphi-Quellcode:
repeat
    hindernis1.initiate(clblue, random(image1.width - 20) + 10,random(image1.height- 20) + 10, random(40) + 81);
  until maus.KreisrandAbstand(hindernis1) > 8;

mkinzler 21. Mai 2012 09:15

AW: Problem mit For-Schliefe
 
Besser einen Array verwenden
Delphi-Quellcode:
var
Hindernis: Array[1..3] of tHindernis; // 'Hindernis' hab ich dazu geschrieben, war vorher nich drin
...
initialization
  Hindernis[1] := thindernis.create;
  Hindernis[2] := thindernis.create;
  Hindernis[3] := thindernis.create;

Blup 21. Mai 2012 10:35

AW: Problem mit For-Schliefe
 
Als einfachste Lösung kann man eine Unterfunktion bilden und die Variable(n) übergeben:
Delphi-Quellcode:
procedure TSpielfeld1.InitiateHindernis(AHindernis: THindernis);
begin
  repeat
    AHindernis.initiate(clblue, random(image1.width - 20) + 10, random(image1.height - 20) + 10, random(40) + 81);
  until ((sqrt(sqr(abs(maus.x - AHindernis.hx)) + sqr(abs(maus.y - AHindernis.hy))) > (maus.r + AHindernis.hr) + 8));
end;

procedure TSpielfeld1.FormCreate(Sender: TObject);
begin
  InitiateHindernis(hindernis1);
  InitiateHindernis(hindernis2);
  InitiateHindernis(hindernis3);
  hindernis1.show;
  hindernis2.show;
  hindernis3.show;
end;
Für die Hindernisse scheint ein Array eine gute Idee zu sein.

DeddyH 21. Mai 2012 10:43

AW: Problem mit For-Schliefe
 
Übrigens gibt es in der Unit math die Funktion hypot, damit spart man sich das Quadrieren und Wurzelziehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz