Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Auf Vorhandensein TShape Objekt prüfen und es löschen


cryl0v - So 21.02.10 20:36
Titel: Auf Vorhandensein TShape Objekt prüfen und es löschen
Hallo Delphine :D,

ich habe per TShape.Create eine Form in mein Projekt erstellt und deren Eigenschaften definiert. Es ist sichtbar und funktioniert einwandfrei.
Da ich ein kleines Spiel programmiere und sich die Steine auf dem Feld ändern, sollen sie gelöscht werden. Wenn auf dem Feld eine 0 liegt und das TShape Objekt vorhanden sind wird gelöscht.

Wie frage ich nun ab ob ein Objekt existiert bspw. stein[i].(Abfrage auf Existenz). Denn um ein Objekt löschen zu können muss es existieren.

Das Löschen würde ich mit stein[i].Destroy lösen. Wäre das richtig um es auf der Form zum Verschwinden zu bringen?

mfg. cryl0v


jaenicke - So 21.02.10 21:02

Hallo und :welcome:

user profile iconcryl0v hat folgendes geschrieben Zum zitierten Posting springen:
Wie frage ich nun ab ob ein Objekt existiert bspw. stein[i].(Abfrage auf Existenz). Denn um ein Objekt löschen zu können muss es existieren.
Du kannst das normalerweise mit Assigned(DeinObjekt) prüfen.
Aber wenn du das brauchst um den Status im Spiel zu prüfen, dann solltest du dein Konzept überdenken. Die Darstellung dient der Darstellung, die Informationen dazu solltest du lieber richtig speichern. Dann stellt sich die Frage auch gar nicht erst.

user profile iconcryl0v hat folgendes geschrieben Zum zitierten Posting springen:
Das Löschen würde ich mit stein[i].Destroy lösen. Wäre das richtig um es auf der Form zum Verschwinden zu bringen?
Nein, denn wie in der Delphi Hilfe auch deutlich steht, sollte man Destroy nie direkt aufrufen. Sondern besser Free. Denn das prüft vorher, ob das Objekt überhaupt existiert.


cryl0v - So 21.02.10 21:12

Hallo jaenicke, die Daten sind in Arrays einzeln gespeichert. Die Werte wurde auf ein 2 dimensionales TShape Array übertragen. Das Spiel heißt die Türme von Hanoi. Wenn ich nun den ersten Stein nehme und ihn versetze, soll der erste Stein auch verschwinden.

Allerdings habe ich mit der Assigned Abfrage und dem Free ein Speicherverletzung


Xion - So 21.02.10 21:19

ich mach das immer so:


Delphi-Quelltext
1:
2:
3:
4:
5:
if ShapeArray[0,0]<>nil then
  begin
    ShapeArray.Free;
    ShapeArray:=nil;
  end;


jaenicke - So 21.02.10 21:23

Für die Türme von Hanoi würde ich allerdings nie auf die Idee kommen ein zweidimensionales Array zu nutzen. Da eignet sich ein Array mit drei TObjectLists doch viel besser. ;-) Da kann man einfach immer das zu verschiebende Shape direkt korrespondierend zur visuellen Darstellung von einer Liste in die andere verschieben.

Dann braucht man da auch die Prüfung gar nicht mehr.


cryl0v - So 21.02.10 21:29

Delphi ist leider nicht meine Hausprogrammiersprache und ich kenne mich wenig aus, deshalb versuch ich erstmal das zu lösen was ich kann. Ist nicht böse gemeint.


Es soll nun unten zusätzlich geprüft werden, ob bei einen neuem Arraywert bspw. der 0 noch immer die Scheibe liegt. Sollte dies nicht der Fall sein springt die Abfrage gar nicht erst an. Ich denke vom Aufbau wird euch nun klar, welche Denkweise ich habe.

Am Besten ich gebe euch die Show Methode

Aber leide funktioniert es noch immer nicht und ich kriege ständig eine Speicherzugriffsverletzung

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:
procedure TForm1.show(s:SpielfeldT);
   var i,j, top, tmp, dummy:KeyT;
   type stellen = array[1..3of TShape;
   var  anzeige: array[1..3of stellen;
    begin
    top:=200;
     for i:=1 to 3 do
      begin
      tmp:=0;
       for j:=1 to 3 do
        begin
         if (s[i][j] <> 0then
          begin
           case i of
           1:
            begin
             dummy:=s[i][j];
             anzeige[i][j]:=TShape.Create(Self);
             anzeige[i][j].Brush.Color:=scheiben[dummy].SFarbe;
             anzeige[i][j].Height:=scheiben[dummy].SHeight;
             anzeige[i][j].Width:=scheiben[dummy].SWidth;
             anzeige[i][j].Left:=scheiben[dummy].SLeft;
             anzeige[i][j].Top:=top+tmp;
             anzeige[i][j].Parent:=Self;
             tmp:=tmp-21;
            end;
           2:
            begin
             dummy:=s[i][j];
             anzeige[i][j]:=TShape.Create(Self);
             anzeige[i][j].Brush.Color:=scheiben[dummy].SFarbe;
             anzeige[i][j].Height:=scheiben[dummy].SHeight;
             anzeige[i][j].Width:=scheiben[dummy].SWidth;
             anzeige[i][j].Left:=scheiben[dummy].SLeft+148;
             anzeige[i][j].Top:=top+tmp;
             anzeige[i][j].Parent:=Self;
             tmp:=tmp-21;
            end;
           3:
            begin
             dummy:=s[i][j];
             anzeige[i][j]:=TShape.Create(Self);
             anzeige[i][j].Brush.Color:=scheiben[dummy].SFarbe;
             anzeige[i][j].Height:=scheiben[dummy].SHeight;
             anzeige[i][j].Width:=scheiben[dummy].SWidth;
             anzeige[i][j].Left:=scheiben[dummy].SLeft+308;
             anzeige[i][j].Top:=top+tmp;
             anzeige[i][j].Parent:=Self;
             tmp:=tmp-21;
            end;
           end;
          end;

          if anzeige[i,j]<>nil then
           begin
            anzeige[i,j].Free;
            anzeige[i,j]:=nil;

           end;
         end;
        end;
       end;

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt

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

Zur Aktualisierung:

Wie kann ich nun die TShape Form löschen? Mit den Varianten habe ich es bereits versucht, aber es kommt immer eine Zugriffsverletzung.


Narses - Mo 22.02.10 00:36

Moin und :welcome: im Forum!

user profile iconcryl0v hat folgendes geschrieben Zum zitierten Posting springen:
Delphi ist leider nicht meine Hausprogrammiersprache und ich kenne mich wenig aus, deshalb versuch ich erstmal das zu lösen was ich kann.
[...]
Aber leide funktioniert es noch immer nicht und ich kriege ständig eine Speicherzugriffsverletzung
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Für die Türme von Hanoi würde ich allerdings nie auf die Idee kommen ein zweidimensionales Array zu nutzen. Da eignet sich ein Array mit drei TObjectLists doch viel besser. ;-) Da kann man einfach immer das zu verschiebende Shape direkt korrespondierend zur visuellen Darstellung von einer Liste in die andere verschieben.

Dann braucht man da auch die Prüfung gar nicht mehr.
Du hast - nach eigener Aussage - keine Ahnung von Delphi, bekommst einen guten Tipp von einem erfahrenen Delphi-Entwickler und willst ihn nicht annehmen, nein, du verweist sogar darauf, dass du keine Ahnung hast und deshalb lieber deine eigene (wohlgemerkt: nicht funktionierende) Suppe kochen willst. :gruebel: Sorry, aber dann kann man dir nicht helfen. :nut:

user profile iconcryl0v hat folgendes geschrieben Zum zitierten Posting springen:
Ist nicht böse gemeint.
Dito. ;) Aber dein Ansatz ist nunmal Wurst, da beisst die Maus keinen Faden ab. Mach das Konzept vernünftig, dann hast du erst gar nicht die Probleme, die du jetzt lösen musst. :nixweiss:

Ist doch auch dem "natürlichen" Ansatz viel näher: du hast die entsprechende Anzahl von Shapes und verschiebst diese nur zwischen den Säulen :arrow: einmal die Shapes erzeugen (deren Eigenschaften mit Ausnahme der Position sich auch nicht mehr ändern) und dann nur noch die Zugehörigkeit anpassen, fertig. :idea:

cu
Narses