![]() |
Problem mit dynamischer Array und eaccessviolation
Hallo ich bin gerade dabei ein Spiel zu Programmieren das ich auf meinem Tascenrechner endeckt habe namens Aspirin.Ziel in dem Spiel ist es so viele Diamanten wie möglich einzusammeln ohne von den Laserstrahlen getroffen zu werden(eigentlich sind es Kugeln :wink: ). Ich habe das ganze jetzt mit zwei dynamischen Arrays versucht zu lösen allerdings sind dann die ganze Zeit diese dämlichen eaccessviolation Meldungen gekommen. Ich hab dann bekonnen alle möglichen Kontrellstrukturen zu lösen hatt auch geklappt es kommt keine Meldung mehr allerdingsbewgt sich ausser der Spielfigur nichts.
Hier sind die Kompletten Programm Datein ![]() Zur erklärung : mit Space ist die Pause Taste und die message die kommt enthält Zahlen die ich zum analysieren des Fehlers programmiert hab |
AW: Problem mit dynamischer Array und eaccessviolation
Da ich lieder keine Zeit mehr für Erklärungen habe hier mal nur der Quelltext:
Damit konnte ich zumindest 2 Diamanten einsammeln ;-)
Delphi-Quellcode:
procedure TForm1.EngineTimer(Sender: TObject);
var Index: word; begin if not Spiel.rPause then form1.Caption := 'Aspirin' + ' ' + 'Punkte: ' + inttostr(Spiel.rPunkte); if Spiel.rPause then form1.Caption := 'Aspirin' + ' ' + 'Pause'; if Spiel.rPunkte > 0 then begin if t1 = 1 then begin //showmessage('Jetzt') ; for index := 0 to Spiel.anzahl-1 do //<----- hier lag der Fehler begin label1.Caption := inttostr(Spiel.anzahl); Spiel.shpos[index].Bewegung(); //Spiel.sh[index].Top := Spiel.shpos[index].rpunkt.Y; // sh2[index].Bewegung; end; end; end; end; |
AW: Problem mit dynamischer Array und eaccessviolation
Ja aber bewegen tut sich immer noch nichts auser der Spielfigur. Bei der Zeile 179 hab ich vergessen die zwei Schrägstriche rauszumachen die gehören raus.
|
AW: Problem mit dynamischer Array und eaccessviolation
Problem gelöst. neues Problem erstanden.
Code:
Was ist an diesem Code falsch? Warum tut er nicht das was er soll.(bezieht sich nur auf das dicke) Normalerweise sollte doch die Richtung auf 2 umschalten sobald rpunkt.y größer als form1.width-33 ist warum tut es das nicht ?
case rRichtung of
1: begin rpunkt.X:= rpunkt.X +3; [B]if rpunkt.Y > form1.Width-33 then rRichtung := 2;[/B] form1.Label1.Caption := inttostr(rRichtung); // Sleep(25); end; 2: begin rpunkt.X:= rpunkt.X -3; if rpunkt.X < 0 then rRichtung := 1; // Sleep(25); end; end; end; end; |
AW: Problem mit dynamischer Array und eaccessviolation
weil Du auf Y prüfst ?
|
AW: Problem mit dynamischer Array und eaccessviolation
4 augen sehen eindeutig mehr als 2 Vielen dank jetzt hab ich den ganzen abend rumprobiert und auf so was banales bin ich nicht gekommen. Das hatt man von der angeblichen Arbeitserleichterung namens copy+paste :)
|
AW: Problem mit dynamischer Array und eaccessviolation
Du solltest auf Zugriffe wie
Delphi-Quellcode:
verzichten.
form1
Innerhalb der Form-Methoden kannst du die Eigenschaften direkt ansprechen
Delphi-Quellcode:
oder auch mit
Width
Delphi-Quellcode:
. Denn ein Umbenennen der Form (z.B. in etwas Sinnvolles wie
Self.Width
Delphi-Quellcode:
) haut dir den Code auseinander, genauso, wenn du eine weitere Instanz der Form erzeugst.
FSpiel
In deiner Anwendung hast du diese Routine innerhalb von
Delphi-Quellcode:
. Dort hast du ein Feld
TPunkt
Delphi-Quellcode:
, welches wohl auf die Form verweisen soll, dann benutze das Feld doch auch ;)
Fenster
Weiterhin fällt mir auf, dass du mit
Delphi-Quellcode:
arbeitest ... möchtest du den Rand des Fensters berücksichtigen?
Width - 33
Entweder fragst du die Form und das System, wie breit der Rand denn wirklich ist, oder (viel einfacher) du nimmst
Delphi-Quellcode:
, das ist exakt die innere Breite ohne Rand :) - analog gibt es dazu natürlich auch
ClientWidth
Delphi-Quellcode:
ClientHeight
Delphi-Quellcode:
und den gesamten Code bekommt man auch noch kürzer:
case rRichtung of
1: begin rpunkt.X:= rpunkt.X +3; if rpunkt.Y > Fenster.ClientWidth then rRichtung := 2; end; 2: begin rpunkt.X:= rpunkt.X -3; if rpunkt.X < 0 then rRichtung := 1; // Sleep(25); end; end; Fenster.Label1.Caption := inttostr( rRichtung ); // Sleep(25);
Delphi-Quellcode:
// rRichtung ist entweder 1 oder -1
rPunkt.X := rPunkt.X + rRichtung * 3; if ( rPunkt.X < 0 ) or ( rPunkt.X > Fenster.ClientWidth ) then rRichtung := - rRichtung; Fenster.Label1.Caption := inttostr( rRichtung ); // Sleep(25); |
AW: Problem mit dynamischer Array und eaccessviolation
Und das du unbedingt noch machen solltest, wenn du eigenartige Reaktionen bekommst, beim Zugriff auf ein Array:
Die Bereichsprüfung in deinen Projektoptionen aktivieren oder ![]() |
AW: Problem mit dynamischer Array und eaccessviolation
width-33 hat den Sinn das der kreis nicht vom Fenster verschwindet(natürlich wäre clientwidth sinnvoller). Tja ich hab wohl vergessen das ich form1 bereits als Fenster deklariert habe. Diene Idee ist schlau mit den Vorzeichen darauf wärer ich kar nicht gekommmen vielen dank :)
|
AW: Problem mit dynamischer Array und eaccessviolation
So nach dem der erste Teil jetzt fertig ist hab ich mich an den zweiten gemacht und es hatt sich wieder ein fehler eigeschlichen. Beim zweiten teil des spieles geht es darum vor der Polizei zu entwischen.
Delphi-Quellcode:
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm2 = class; TPolizei = class; TSpiel2 = class; TPolizei = class(Tobject) private { Private-Deklarationen } Fenster : TForm2; rpunkt : TPoint; Haupt : Tspiel2; public { Public-Deklarationen } procedure Bewegung(); end; TSpiel2 = class private { Private-Deklarationen } rSpielfigur : TImage; rPause : Boolean; rDiamant : Timage; Polizei : TPolizei; rkollison1 : Tshape; sh : array of TImage; shpos : array of TPolizei; rZeit : Integer; anzahl : integer; Fenster : Tform2; public { Public-Deklarationen } procedure Polizeierstellen(); procedure Erstellen(); constructor Create; destructor Destroy; override; end; TForm2 = class(TForm) Engine: TTimer; kollision: TTimer; Special: TTimer; procedure FormCreate(Sender: TObject); procedure Onclose(Sender: TObject; var Action: TCloseAction); procedure OnkeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure EngineTimer(Sender: TObject); procedure kollisionTimer(Sender: TObject); procedure SpecialTimer(Sender: TObject); private { Private-Deklarationen } Spiel2 : Tspiel2; Laser : TPolizei; Aktiv : Boolean; Zeit : String; z1,z2 : integer; public { Public-Deklarationen } end; var Form2: TForm2; T,T1 : integer; X : integer; F : integer; implementation {$R *.dfm} procedure TPolizei.Bewegung; begin if haupt.rSpielfigur.Top < rpunkt.Y then rpunkt.Y := rpunkt.Y -1; if haupt.rSpielfigur.Top > rpunkt.Y then rpunkt.Y := rpunkt.Y +1; if haupt.rSpielfigur.Left < rpunkt.X then rpunkt.X := rpunkt.X -1; if haupt.rSpielfigur.Left > rpunkt.X then rpunkt.X := rpunkt.X +1; end; constructor Tspiel2.Create; begin Polizei := TPolizei.Create; rkollison1 := TShape.create(nil); rkollison1.Parent := fenster; rkollison1.Visible:= false; rSpielfigur := Timage.Create(nil); rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\rechts.bmp'); rSpielfigur.Top:= 0; rSpielfigur.Left:= 30; rSpielfigur.AutoSize := true; rSpielfigur.Picture.Bitmap.TransparentColor := clyellow; rSpielfigur.Picture.Bitmap.Transparent := true; rSpielfigur.Transparent:=true; rSpielfigur.Parent := fenster; rkollison1.Height := rSpielfigur.Height; rkollison1.Width := rSpielfigur.Width -13; T:= 1; F := 1; Polizeierstellen; end; procedure TForm2.EngineTimer(Sender: TObject); var index : word; begin If not Spiel2.rPause then form2.Caption := 'Aspirin'+' '+ Zeit ; If Spiel2.rPause then form2.Caption := 'Aspirin'+' '+'Pause'; if Spiel2.rZeit > 0 then begin if t1 = 1 then begin //showmessage('Jetzt') ; for index := 0 to Spiel2.anzahl-1 do begin Spiel2.shpos[index].Bewegung(); Spiel2.sh[index].Top := Spiel2.shpos[index].rpunkt.Y; Spiel2.sh[index].Left := Spiel2.shpos[index].rpunkt.X; // sh2[index].Bewegung; end; end; end; end; procedure TForm2.FormCreate(Sender: TObject); begin Zeit := '2:00'; form2.Width := 800; form2.Height := 600; Spiel2 := TSpiel2.Create; Spiel2.rPause := true; Form2.DoubleBuffered:=True; end; procedure TForm2.kollisionTimer(Sender: TObject); var index : word; r : Trect; begin if t1 = 1 then begin for index := 0 to Spiel2.anzahl-1 do begin if intersectrect(r, Spiel2.rkollison1.BoundsRect, Spiel2.sh[index].BoundsRect ) then begin showmessage('Sie wurden erwischt'); application.Terminate; end; end; end; end; procedure TForm2.Onclose(Sender: TObject; var Action: TCloseAction); begin Spiel2.Free; end; procedure TForm2.OnkeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if not Spiel2.rPause then begin case key of vk_down: begin if Spiel2.rSpielfigur.Top< 520 then begin Spiel2.rSpielfigur.Top := Spiel2.rSpielfigur.Top + 4; Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top; Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8; end; end; vk_up: begin if not Spiel2.rSpielfigur.Top<0 then begin Spiel2.rSpielfigur.Top := Spiel2.rSpielfigur.Top -4; Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top; Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8; end; end; vk_left: begin if not Spiel2.rSpielfigur.Left<0 then begin Spiel2.rSpielfigur.Left:= Spiel2.rSpielfigur.Left -4; Spiel2.rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\links.bmp'); Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top; Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8; end; end; vk_right: begin if Spiel2.rSpielfigur.Left < 730 then begin Spiel2.rSpielfigur.Left:= Spiel2.rSpielfigur.Left +4; Spiel2.rSpielfigur.Picture.Bitmap.LoadFromFile(ExtractFilePath(Application.ExeName) + '\Bilder\rechts.bmp'); Spiel2.rkollison1.Top := Spiel2.rSpielfigur.Top; Spiel2.rkollison1.Left := Spiel2.rSpielfigur.Left +8; end; end; end; end; if key = vk_space then begin case T of 0: begin Spiel2.rPause :=true; T:=1; end; 1: begin Spiel2.rPause := false; T:=0; end; end; end; end; procedure TForm2.SpecialTimer(Sender: TObject); var sl: TStrings; r : integer; begin spiel2.rZeit:= spiel2.rZeit +1; sl := TStringlist.Create; sl.Delimiter := ':'; sl.DelimitedText := Zeit; z1 := strtoint(sl[0]); z2 := strtoint(sl[1]); if z2 = 0 then begin z1 := z1 -1; z2 := 59; end; z2:= z2-1; Zeit := inttostr(z1)+ ':' + inttostr(z2); sl.Free; r := r+1; if r=15 then begin Spiel2.Polizeierstellen; r:=0; end; if spiel2.rZeit = 7200 then Special.Enabled:= false; end; destructor Tspiel2.Destroy; begin rSpielfigur.Free; Polizei.Free; setlength(sh, 0); setlength(shpos, 0); end; procedure Tspiel2.Erstellen; begin shpos[anzahl]:= TPolizei.Create; shpos[anzahl].Bewegung; shpos[anzahl].rpunkt.X := 400; shpos[anzahl].rpunkt.Y := 600; sh[anzahl] := TImage.Create(nil); sh[anzahl].Parent:= form2; sh[anzahl].Top := 600; sh[anzahl].Left := 400; sh[anzahl].Picture.Bitmap.LoadFromFile(extractfilepath(application.ExeName) + '\Bilder\Polizei_rechts.bmp'); sh[anzahl].AutoSize:=true; sh[anzahl].Picture.Bitmap.TransparentColor:= clwhite; sh[anzahl].Picture.Bitmap.Transparent :=true; sh[anzahl].Transparent:=true; t1 := 1; end; procedure TSpiel2.Polizeierstellen; begin t1 := 0; x :=length(shpos); //showmessage(inttostr(x)+ ' ' + inttostr(length(shpos))+ ' '+ inttostr(anzahl)+ ' ' + inttostr(length(sh))); setlength(sh,x+1); setlength(shpos, x+1); erstellen; if length(shpos)>0 then anzahl := length(shpos); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:49 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