![]() |
Ungewollter Zugriff auf in einem Array gespeichertes Objekt
Ich bin grade dabei ein kleines Spiel zu Programmieren. In diesem Spiel verwende ich die Klasse TRobot die ich von TDatabase ableitete. Um eine limitierte Zahl von Robotern im Spiel gleichzeitig verwenden zu können erstellte ich einen Array für die Roboter:
Delphi-Quellcode:
In FormCreate wurden die Roboter, die ich bis dahin brauchte, dann erstellt:
...
var Roboter: Array[1..10] of TRobot; ...
Delphi-Quellcode:
Die Syntax von TRobot.Initialisieren ist (PositionX, PositionY, Startwinkel, Geschwindigkeit) .
procedure TForm1.FormCreate(Sender: TObject);
begin ... Roboter[1]:=TRobot.Create(self); Roboter[2]:=TRobot.Create(self); Roboter[1].Initialisieren(10,10,0,2); Roboter[2].Initialisieren(400,200,Pi,2); ... end; Nun zu meinem Problem: obwohl ich zwei unterschiedliche Objekte anspreche (Roboter[1] & Roboter[2]) überschreibt
Delphi-Quellcode:
die bereits festgelegten Variablen von Roboter[1].
Roboter[2].Initialisieren(400,200,Pi,2);
Das hat zur Folge, das anstatt zwei Robotern auf dem Formular entweder nur eins oder zwei übereinandergelegte Roboter erscheinen (ich kann es nicht genau beurteilen). Woran liegt das? Danke schon im Voraus! |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Zitat:
TRobot ist bestimmt keine Klasse, die man von TDatabase ableiten sollte. Vielleicht braucht TRobot Zugriff auf eine Datenbank, aber Vererbung wäre hier falsch. Zitat:
Greifst du irgendwie auf globale Variablen zu? Gibt es z.B. eine weitere Variable robot:TRobot, auf die du zugreifst? |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Poste am Besten mal die Klasse. Den der Fehler sollte in der Methode Initialisieren zu finden sein
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
@sx2008
Ich weiß auch nicht warum ich TRobot überhaupt abgeleitet habe, denn es verwendent keine der Attribute oder Methoden von TDatabase... Ich glaube ich werde es extrahieren und eigenständig machen. Zu deiner Frage: Ich verwende in der Klasse TRobot eine Variable, die ein TRobot ist:
Delphi-Quellcode:
Diese Methode dient dazu, dass der Roboter den ihm nächsten Feind angreift.
...
var Ziel: TRobot; ... procedure TRobot.ZielAussuchen (Feinde: Array of TRobot; Prioritaet: integer); var i: integer; Entfernung: double; begin Entfernung:=1000000; for i:= 1 to (High(Feinde))+1 do begin if EntfernungMessen(Feinde[i].PPunkt)<Entfernung then begin Entfernung:=EntfernungMessen(Feinde[i].PPunkt); Ziel:=Feinde[i]; Showmessage('Ziel gewählt'); end; end; end; ... Zur restlichen Klasse inklusiv Initialisieren:
Delphi-Quellcode:
Ich hoffe das hilft weiter. Es kann sein, dass euch die Programmierung etwas schlampig vorkommt, aber ich programmiere erst seit kurzem öfters. Danke bereits für die Posts!
unit Robot;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBTables; type TRobot = class(TDatabase) private { Private-Deklarationen } protected { Protected-Deklarationen } public ... procedure Initialisieren(PosX, PosY: integer; StartWinkel, Geschwindigkeit: double); ... { Public-Deklarationen } published { Published-Deklarationen } end; procedure Register; var Position:Array[1..2] of integer; Winkel_1,Speed:double; Ziel: TRobot; implementation ... procedure TRobot.Initialisieren (PosX, PosY: integer; StartWinkel, Geschwindigkeit: double); begin Position[1]:=PosX; Position[2]:=PosY; Winkel_1:=StartWinkel; Speed:=Geschwindigkeit; end; ... end. |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Du verwendest für alle Insatnzen die selben globalen Variablen! Ich würde hierfür Member der Klasse verwenden
Delphi-Quellcode:
unit Robot;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBTables; type TRobot = class(TDatabase) private { Private-Deklarationen } Position:Array[1..2] of integer; Winkel_1,Speed:double; Ziel: TRobot; protected { Protected-Deklarationen } public ... procedure Initialisieren(PosX, PosY: integer; StartWinkel, Geschwindigkeit: double); ... { Public-Deklarationen } published { Published-Deklarationen } end; procedure Register; implementation ... procedure TRobot.Initialisieren (PosX, PosY: integer; StartWinkel, Geschwindigkeit: double); begin Position[1]:=PosX; Position[2]:=PosY; Winkel_1:=StartWinkel; Speed:=Geschwindigkeit; end; ... end. |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Ich habe es genau so gemacht, aber jetzt startet das Programm nicht. Es gibt eine Fehlermeldung sobald der Compiler zur Initialisierung der Roboter kommt. Ab dieser Zeile geht nichts meht
Delphi-Quellcode:
Position[1]:=PositionX;
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Zitat:
Du verwendest globale Variablen, um deine Daten aus der Methode Initialisieren zu speichern. Mache aus diesen Variablen (private) Felder von TRobot. Im Moment verwendet jede Instanz die gleichen Variablen, um die Werte zu speichern.
Delphi-Quellcode:
Hier "besitzt" jeder Roboter sein eigenes Variablenset, welches nur er verwenden kann. Um von aussen hierauf zugreifen zu können, verwende am besten Properties, hierbei kannst du dann eingreifen, wenn jemand den Wert lesen oder schreiben will.
type
TRobot = class(TObject) private FPosition: Array[1..2] of Integer; FWinkel_l: double; FSpeed: double; public procedure Initialisieren(...); end; |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Habe ich gemacht aber es kommt immer noch zu einer Zugriffsverletzung sobald eine Variable verändert werden soll, auch wenn die Veränderung in der Klasse TRobot erfolgt.
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Zeig mal deinen kompletten Code
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Hier der Code. Die Mit >>>> Gekennzeichnete Zeile verursacht den Fehler.
Delphi-Quellcode:
unit Robot;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBTables; type TRobot = class(TDatabase) private { Private-Deklarationen } Position:Array[1..2] of integer; Winkel_1,Speed:double; Ziel: TRobot; protected { Protected-Deklarationen } public procedure Zeichnen(Ziel: TBitmap); function WinkelBestimmen(X,Y:integer): Double; function PPunkt: TPoint; function PosX: integer; function PosY: integer; procedure PositionSetzen(X,Y: integer); function Winkel: double; procedure WinkelSetzen(NeuerWinkel: double); //procedure GeschwindigkeitSetzen(NeueGeschwindigkeit: double); procedure Initialisieren(PositionX, PositionY: integer; StartWinkel, Geschwindigkeit: double); procedure Step; procedure ZielAussuchen(Feinde: Array of TRobot; Prioritaet: integer); function EntfernungMessen (Zielpunkt: TPoint): double; procedure AufZielRichten; { Public-Deklarationen } published { Published-Deklarationen } end; procedure Register; implementation procedure Register; begin RegisterComponents('Robot Wars', [TRobot]); end; procedure TRobot.AufZielRichten; begin WinkelBestimmen(Ziel.PosX,Ziel.PosY); end; function TRobot.EntfernungMessen (Zielpunkt: TPoint): double; var DiffX,DiffY:integer; begin DiffX:=Zielpunkt.x-Position[1]; DiffY:=Zielpunkt.y-Position[2]; EntfernungMessen:=Sqrt(DiffX*DiffX+DiffY*DiffY); end; procedure TRobot.ZielAussuchen (Feinde: Array of TRobot; Prioritaet: integer); var i: integer; Entfernung: double; begin Entfernung:=1000000; for i:= 1 to (High(Feinde))+1 do begin if EntfernungMessen(Feinde[i].PPunkt)<Entfernung then begin Entfernung:=EntfernungMessen(Feinde[i].PPunkt); Ziel:=Feinde[i]; Showmessage('Ziel gewählt'); end; end; end; procedure TRobot.Step; begin Position[1]:=Position[1]-Round(Sin(Winkel_1)*Speed); Position[2]:=Position[2]-Round(Cos(Winkel_1)*Speed); end; procedure TRobot.Initialisieren (PositionX, PositionY: integer; StartWinkel, Geschwindigkeit: double); begin Position[1]:=PositionX; Position[2]:=PositionY; Winkel_1:=StartWinkel; Speed:=Geschwindigkeit; end; procedure GeschwindigkeitSetzen(NeueGeschwindigkeit: double); begin //Speed:=NeueGeschwindigkeit; end; function TRobot.Winkel: double; begin Winkel:=Winkel_1; end; function TRobot.PPunkt: TPoint; begin PPunkt:=Point(Position[1],Position[2]); end; function TRobot.PosX: integer; begin PosX:=Position[1]; end; function TRobot.PosY: integer; begin PosY:=Position[2]; end; procedure TRobot.PositionSetzen(X,Y: integer); begin Position[1]:=X; Position[2]:=Y; end; function TRobot.WinkelBestimmen(X,Y:integer): Double; var Rid:integer; DiffX,DiffY,Plus:real; begin Plus:=0; Rid:=0; DiffX:=X-Position[1]; DiffY:=Y-Position[2]; if DiffX>0 then begin if DiffY>0 then Plus:=Pi/2; if DiffY<0 then begin Plus:=0; Rid:=1; end; if DiffY=0 then Plus:=Pi/2; end; if DiffX<0 then begin if DiffY>0 then begin Plus:=Pi; Rid:=1; end; if DiffY<0 then Plus:=3*Pi/2; if DiffY=0 then Plus:=3*Pi/2; end; if DiffX=0 then begin if DiffY>0 then begin Plus:=Pi; Rid:=1; end; if DiffY<0 then Plus:=2*Pi; if DiffY=0 then Plus:=0; end; DiffX:=abs(DiffX); DiffY:=abs(DiffY); if Rid=1 then begin if DiffY=0 then begin Rid:=3; DiffY:=0.1; end; WinkelBestimmen:=ArcTan(DiffX/DiffY)+Plus; if Rid=3 then Winkelbestimmen:=plus; end else begin if DiffX=0 then begin Rid:=2; DiffX:=0.1; end; WinkelBestimmen:=ArcTan(DiffY/DiffX)+Plus; if Rid=2 then Winkelbestimmen:=plus; end; end; procedure TRobot.Zeichnen(Ziel: TBitmap); var Koord : array[1..3] of TPoint; i :integer; KoordX, KoordY: array[1..3] of integer; Winkelz: array[1..3] of double; begin Winkelz[1]:=pi; Winkelz[2]:=2*Pi/3+pi; Winkelz[3]:=4*Pi/3+pi; for i:= 1 to 3 do begin KoordX[i]:=Round(Position[1]+Sin(Winkel_1+Winkelz[i])*10); KoordY[i]:=Round(Position[2]+Cos(Winkel_1+Winkelz[i])*10); Koord[i]:=Point(KoordX[i],KoordY[i]); end; Ziel.Canvas.Brush.Color:=clred; Ziel.Canvas.Polygon(Koord); end; procedure TRobot.WinkelSetzen(NeuerWinkel: double); begin Winkel_1:=NeuerWinkel; end; end. |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
sry habe vergessen die Zeile zu Markieren :wall: . Es ist die erste Zeile der TRobot.Initialisieren Methode.
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Wie lautet denn die Fehlermeldung?
Grüße Klaus |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation aufgetreten.
'Zugriffsverletzung bei der Adresse 0044C27 im Modul 'Project1.exe' Schreiben von Adresse 00000004'. |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
.. bevor Du die Methode initialisieren aufrufst, hast
Du das TRobot.create ausgeführt? Grüße Klaus |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Ich weiß ich bin blöd genau das war dies Fehlermeldung :wall: :wall: :wall: :wall:
Auf einer Skala von 1 bis Blöd konnte ich keinen Punkt ergattern :oops: |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Ich habe jetzt noch eine Fehlermeldung (auch EAccessViolation) in dieser Programmzeile:
Delphi-Quellcode:
KoordX[i]:=Round(PositionX+Sin(Winkel_1+Winkelz[i])*10);
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Delphi-Quellcode:
Kommt die Fehlermedlung genau in der Zeile
procedure TRobot.Zeichnen(Ziel: TBitmap);
var Koord : array[1..3] of TPoint; i :integer; Winkelz: array[1..3] of double; begin Winkelz[1]:=pi; Winkelz[2]:=2*Pi/3+pi; Winkelz[3]:=4*Pi/3+pi; for i:= 1 to 3 do begin Koord[i].x:=Round(Position[1]+Sin(Winkel_1+Winkelz[i])*10); Koord[i].y:=Round(Position[2]+Cos(Winkel_1+Winkelz[i])*10); end; if assigned(ziel) then begin Ziel.Canvas.Brush.Color:=clred; Ziel.Canvas.Polygon(Koord); end; end; oder kommt sie wenn Du auf dem Bitmap etwas zeichnen willst? Grüße Klaus |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
der Fehler kommt in den Zeilen
Delphi-Quellcode:
Danke für den Code, der ist wesentlich übersichtlicher als mein alter :-D
Koord[i].x:=Round(PositionX+Sin(Winkel_1+Winkelz[i])*10);
Koord[i].y:=Round(PositionY+Cos(Winkel_1+Winkelz[i])*10); |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Zitat:
Delphi-Quellcode:
Warum heißt es bei Dir PositionX und nicht Position[1]?
Koord[i].x:=Round(PositionX+Sin(Winkel_1+Winkelz[i])*10);
Grüße Klaus |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Oh sorry... :wall:
Ich habe aus
Delphi-Quellcode:
zwei integer gemacht (Der übersichtlichkeit wegen).
Position: Array[1..2] of integer;
Aber das sollt an sich nichts ausmachen. |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Hallo,
für besseres Debuggen würde ich das Auseinandernehmen aus
Delphi-Quellcode:
wird
Koord[i].x:=Round(PositionX+Sin(Winkel_1+Winkelz[i])*10);
Delphi-Quellcode:
Wo kommt der Fehler jetzt ?
var
iValue: Integer; iValue:= Round(PositionX+Sin(Winkel_1+Winkelz[i])*10); Koord[i].x:= iValue; Bei Round oder bei Koord[i].x:= iValue ? Auch das Winkel_1+Winkelz[i] könnte man noch in einer lokalen Variable ablegen. Heiko |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Der Fehler kommt bei der Zuweisung eines Werts für iValue (irgendwo in dieser Zeile)
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
.. nun, ich fühle mich etwas blöd es nochmals zu fragen,
aber wann erstellst Du Deine Roboter und wann zeichnest Du sie. Grüße Klaus |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Kein Problem. Das Hier ist nicht die Klasse TRobot sondern die Unit in der ich die Roboter verwende.
Delphi-Quellcode:
...
procedure TForm1.FormCreate(Sender: TObject); begin Buffer:=TBitmap.Create; Buffer.Width:=Clientwidth; Buffer.Height:=Clientheight; Roboter[1]:=TRobot.Create; Roboter[1].Initialisieren(10,10,0,2); Roboter[2]:=TRobot.Create; Roboter[2].Initialisieren(100,100,0,2); end; ... procedure TForm1.Timer1Timer(Sender: TObject); begin Roboter[1].Zeichnen(Buffer); Canvas.Draw(0,0,Buffer); end; ... |
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Aber ich habe den Fehler gefunden: Ich :wall: habe statt wie in dem Quelltext den ich dir gepostet habe Roboter[1].Zeichnen den nichtexistenten Roboter1 zum Zeichnen aufgefordert
|
Re: Ungewollter Zugriff auf in einem Array gespeichertes Obj
Vielden Dank euch allen, das Masterproblem hat sich auch gleich miterledigt! :cheer: :cheer: :cheer: :cheer:
Juhu! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz