![]() |
Zugriffsverletzung??
Hallo!
Ich habe ein Problem. Ich programmiere gerade ein Spiel, in dem eine Spielfigur Sterne einsammeln muss. Für die Sterne habe ich eine Klasse aufgemacht: TStar.
Code:
Wenn das Level lädt möchte ich jedem Stern seine Position zuweisen (PosX und PosY), die im Memo-Feld MemoLoadPos steht.
TStar = class
Found : Boolean; PosX, PosY : integer; procedure Shine; ... var Star : Array[1..20] of TStar; //es gibt in jedem Level 20 Sterne
Code:
Delphi sagt, das sei eine Zugriffsverletzung, aber ich bin mir nicht bewusst, irgendjemanden verletzt zu haben.
Star[1].PosX := StrToInt(MemoLoadPos.Lines[2]);
Star[1].PosY := StrToInt(MemoLoadPos.Lines[3]); Vielen Dank im Voraus für eure Antworten! Ich hoffe, die Frage ist nicht zu dämlich, aber ich habe echt keine Ahnung! |
AW: Zugriffsverletzung??
Wieviel Zeilen hat das Memo? (.Lines ist 0-indiziert)
|
AW: Zugriffsverletzung??
Das Memo-Feld hat 22 Zeilen. Vorher lade ich eine txt-Datei in das Memo-Feld, in dem die Positionen der Spielfigur und der Sterne stehen.
|
AW: Zugriffsverletzung??
Hast du die Instanzen der Klasse auch erzeugt?
Delphi-Quellcode:
Star[1] := TStar.Create;
|
AW: Zugriffsverletzung??
Das habe ich auch schon versucht. Ich rufe die Prozedure StarCreate in FormCreate auf
Ich habe eine Prozedur "FormCreate", während der ich die Prozedur StarCreate aufrufe. (In StarCreate macht er die Instanzen
Code:
procedure TFormLvl.StarCreate;
var i : integer; begin for i := 1 to 20 do Star[i].Create; Star[1].PosX := ... //wie oben beschrieben ImgStar1.Left := Star[1].PosX; ImgStag1.Top := Star[1].PosY; end; Wie gesagt rufe ich die Prozedur in procedure FormCreate auf. Das macht er auch alles, aber die nächste ZEile im FormCreate wird als Fehler angezeigt. Dabei ist es egal, welche Zeile als nächstes im FormCreate steht. Delphi meldet immer noch eine Zugriffsverletzung und die nächste Zeile wird blau hinterlegt. |
AW: Zugriffsverletzung??
Füge mal begin..end ein
Delphi-Quellcode:
for i := 1 to 20 do Star[i].Create;
begin Star[1].PosX := ... //wie oben beschrieben ImgStar1.Left := Star[1].PosX ImgStag1.Top := Star[1].PosY; end; |
AW: Zugriffsverletzung??
Aber ich will doch nur das Star[i].Create 20 mal wiederholen. Das andere tipp ich 20 mal ein, weil ich ja jedes einzelne Bild verschieben will und ich keinen Array of Image habe sondern nur 20 einzelne Bilder ImgStar1, ImgStar2, ... Außerdem verwirrt mich diese komische Zugriffsverletzung. Delphi hat irgendein Problem mit meinem TStar bzw. den Instanzen Star[i]. Ich habe schon viel mit denen probiert aber immer gab es eine Zugriffsverletzung. Habe ich vielleicht im Aufbau etwas falsch gemacht oder muss man bei dem Create irgendetwas beachten?
|
AW: Zugriffsverletzung??
Ist das Memo zu dieser Zeit schon gefüllt?
|
AW: Zugriffsverletzung??
Ja, ist es. Zu dem Zeitpunkt stehen 22 verschiedene ganzzahlige Werte im MemoFeld.
|
AW: Zugriffsverletzung??
Poste mal den ganzen Quelltext
|
AW: Zugriffsverletzung??
Hmm, also was mich wundert ist folgendes:
Du hast 22 Zeilen in der Memo und willst 20 Sterne erzeugen. Star[1].PosX := StrToInt(MemoLoadPos.Lines[2]); Star[1].PosY := StrToInt(MemoLoadPos.Lines[3]); Müssten dir da nicht die Zeilen ausgehen? Versuch den Pos fixe Werte erstmal zuzuweisen, es könnte ja auch sein, dass die Einträge in der Memo sich nicht in einen Integer konvertieren lassen. (Da ich die Einträge nicht sehen kann nur ne Vermutung)
Code:
Star[1].PosX := 10;
Star[1].PosY := 10; |
AW: Zugriffsverletzung??
Zitat:
Delphi-Quellcode:
Somit in diesem Beispiel bitte
foo := TFoo.Create;
Delphi-Quellcode:
for i := 1 to 20 do
Star[ i ] := TStar.Create; |
AW: Zugriffsverletzung??
Zitat:
Delphi-Quellcode:
Ansonsten kann es nicht schaden, wenn du in den Projektoptionen mal die Überlauf- und die Bereichsprüfung aktivierst.
for i := 1 to 20 do
begin Star[i] := TStar.Create; Star[i].PosX := ... |
AW: Zugriffsverletzung??
Code:
type TFormLvl = class(TForm) {} end; TSpielfigur = class {} end; TStar = class Found : Boolean; PosX, PosY : integer; procedure Shine; procedure Find; procedure Fly; private { Private-Deklarationen } public { Public-Deklarationen } end; var FormLvl : TFormLvl; Spielfigur : TSpielfigur; Star : Array[1..20] of TStar; MoveRight, MoveLeft, Fall : Boolean; JumpCount, SpLeft, SpTop, SpStartX, SpStartY : integer; implementation {$R *.dfm} procedure TFormLvl.StarCreate3; var i : integer; begin MemoLoadPos.Lines.LoadFromFile('..\Level\1\Pos.txt'); for i := 1 to 20 do Star[i].Create; Star[1].PosX := StrToInt(MemoLoadPos.Lines[2]); Star[1].PosY := StrToInt(MemoLoadPos.Lines[3]); Star[2].PosX := StrToInt(FormLvl.MemoLoadPos.Lines[4]); Star[2].PosY := StrToInt(FormLvl.MemoLoadPos.Lines[5]); Star[3].PosX := StrToInt(FormLvl.MemoLoadPos.Lines[6]); Star[3].PosY := StrToInt(FormLvl.MemoLoadPos.Lines[7]); Star[4].PosX := StrToInt(FormLvl.MemoLoadPos.Lines[8]); Star[4].PosY := StrToInt(FormLvl.MemoLoadPos.Lines[9]); Star[5].PosX := StrToInt(FormLvl.MemoLoadPos.Lines[10]); Star[5].PosY := StrToInt(FormLvl.MemoLoadPos.Lines[11]); Star[6].PosX := StrToInt(FormLvl.MemoLoadPos.Lines[12]); Star[6].PosY := StrToInt(FormLvl.MemoLoadPos.Lines[13]); ImgStar1_1.Left := Star[1].PosX; ImgStar1_1.Top := Star[1].PosY; end; procedure TFormLvl.FormCreate(Sender: TObject); begin DoubleBuffered := true; MediaPlayer1.Play; Spielfigur.BorderLoad; StarCreate3; Spielfigur.Move; //hier wird der Fehler angezeigt SpLeft := SpStartX; // MLeft und MTop sind die aktuellen Koordinaten der Spielfigur, SpTop := SpStartY; // MStartX und MStartY sind die Startkoordinaten am Anfang des Spiels end; procedure TSpielfigur.Move; begin if MoveRight then SpLeft := SpLeft + 10; //MoveRight und MoveLeft werden auf den Cursortasten if MoveLeft then SpLeft := SpLeft - 10; // true oder false gesetzt. Hat noch nie Probleme end; |
AW: Zugriffsverletzung??
Zitat:
Delphi-Quellcode:
Es lag halt nur ein Fehler in der Instanzerzeugung vor :)
begin ... end
Hmmm ... der Fehler ist immer noch in dem Quellcode
Delphi-Quellcode:
Ändern auf
Star[ i ].Create;
Delphi-Quellcode:
Star[ i ] := TStar.Create;
|
AW: Zugriffsverletzung??
WAHNSINN - ES KLAPPT!!!!!! Vielen, vielen Dank für eure Hilfe!
Der Fehler lag wirklich bei dem
Code:
. Stattdessen
Star[i].Create;
Code:
und es funktioniert!!!
Star[i] := TStar.Create
Ihr habt mein Ostern gerettet! 1000 Dank!! |
AW: Zugriffsverletzung??
Noch ein Vorschlag zur Optimierung wo du dir später viel Arbeit sparen wirst:
Zitat:
Delphi-Quellcode:
findcomponent
Code:
Du kannst in einer Schleife alle Zuweisungen machen, bist nicht von der Anzahl der Sterne in einem Level abhängig (also kann ein Level auch mal mehr oder weniger Sterne haben)
TImage(findcomponent('ImgStar'+inttostr(i))).left := Star[i].PosX;
Die ImgStar Bilder kannst du natürlich auch zur Laufzeit erzeugen. So bleibt dein Spiel dynamisch und ein neues Level kann über die Ladefile erstellt werden, auch wenns mehr als 20 Sterne sind. |
AW: Zugriffsverletzung??
Oder noch besser packe diese auch in einen Array oder eine Liste oder verwende eine Imageliste
|
AW: Zugriffsverletzung??
Wow, super Tipp, vielen Dank! Davon habe ich noch nie gehört, aber das ist wirklich eine viel bessere Lösung!!
Denkst du, man kann aus dem Rest auch eine Schleife machen?
Code:
Star[i].PosX müsste von 1 bis 20 gehen, MemoLoadPos.Lines[i] von 2 bis 42. Geht das?Star[1].PosX := StrToInt(MemoLoadPos.Lines[2]); Star[1].PosY := StrToInt(MemoLoadPos.Lines[3]); Star[2].PosX := StrToInt(MemoLoadPos.Lines[4]); Star[2].PosY := StrToInt(MemoLoadPos.Lines[5]); Star[3].PosX := StrToInt(MemoLoadPos.Lines[6]); Star[3].PosY := StrToInt(MemoLoadPos.Lines[7]); ... |
AW: Zugriffsverletzung??
Zitat:
Delphi-Quellcode:
Ciao,
for i := 1 to 20 do Star[i] := TStar.Create; // <==
Star[1].PosX := ... Ralf |
AW: Zugriffsverletzung??
Delphi-Quellcode:
bzw., da nur die ersten 6 befüllt werden
for i := 1 to 20 do
begin Star[i] := TStart.Create; // man könnte sich glatt fragen, wie du den mehrfachen Hinweis mehrer Leute überlesen konntest Star[i].PosX := StrToInt(MemoLoadPos.Lines[i * 2]); Star[i].PosY := StrToInt(MemoLoadPos.Lines[i * 2 + 1]); end;
Delphi-Quellcode:
for i := 1 to 20 do
Star[i] := TStart.Create; for i := 1 to 6 do begin Star[i].PosX := StrToInt(MemoLoadPos.Lines[i * 2]); Star[i].PosY := StrToInt(MemoLoadPos.Lines[i * 2 + 1]); end; |
AW: Zugriffsverletzung??
das war himitsu schneller als ich^^
Grundsätzlich kann man alles in einer Schleife abarbeiten, wenn der Code sehr ähnlich ist. |
AW: Zugriffsverletzung??
Wow, ihr habt meine über 100 Zeilen gerade auf 5 reduziert :) Ich muss wohl noch eine Menge lernen, wenn es ums Programmieren geht! Vielen, vielen Dank nochmal für eure kompetente, schnelle und freundliche Hilfe!!!
|
AW: Zugriffsverletzung??
Zitat:
Immer dann, wenn man sich wiederholt, kann man es besser schreiben ;) |
AW: Zugriffsverletzung??
Zitat:
In einer Schleife von i:=1 bis 20:
Delphi-Quellcode:
Star[i].PosX := StrToInt(MemoLoadPos.Lines[2*i]);
Star[i].PosY := StrToInt(MemoLoadPos.Lines[2*i+1]); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:23 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